diff --git a/project-templates/python/custom-data/research.ipynb b/project-templates/python/custom-data/research.ipynb
new file mode 100644
index 0000000000..2dc2dfe356
--- /dev/null
+++ b/project-templates/python/custom-data/research.ipynb
@@ -0,0 +1,148 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "id": "cd-logo",
+ "metadata": {},
+ "source": [
+ "\n",
+ "
\n",
+ "\n",
+ "## Custom Data Research\n",
+ "\n",
+ "This notebook defines the Bitstamp custom data type and builds the daily Bitcoin price series."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cd-setup-md",
+ "metadata": {},
+ "source": [
+ "### Set Up QuantBook\n",
+ "\n",
+ "Create the QuantBook for the custom data history request."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cd-setup",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "qb = QuantBook()\n",
+ "qb.set_start_date(2020, 12, 31)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cd-class-md",
+ "metadata": {},
+ "source": [
+ "### Add Custom Data\n",
+ "\n",
+ "Define a [custom securities](https://www.quantconnect.com/docs/v2/writing-algorithms/importing-data/streaming-data/custom-securities) type and subscribe to it."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cd-class",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "class Bitstamp(PythonData):\n",
+ "\n",
+ " def get_source(self, config: SubscriptionDataConfig, date: datetime, is_live_mode: bool) -> SubscriptionDataSource:\n",
+ " return SubscriptionDataSource(\n",
+ " \"https://raw.githubusercontent.com/QuantConnect/Documentation/master/Resources/datasets/custom-data/bitstampusd.csv\",\n",
+ " SubscriptionTransportMedium.REMOTE_FILE\n",
+ " )\n",
+ "\n",
+ " def reader(self, config: SubscriptionDataConfig, line: str, date: datetime, is_live_mode: bool) -> BaseData:\n",
+ " if not line.strip() or not line[0].isdigit():\n",
+ " return None\n",
+ " data = line.split(',')\n",
+ " coin = Bitstamp()\n",
+ " coin.symbol = config.symbol\n",
+ " coin.value = float(data[4])\n",
+ " if coin.value == 0:\n",
+ " return None\n",
+ " coin.time = datetime.strptime(data[0], \"%Y-%m-%d\")\n",
+ " coin.end_time = coin.time + timedelta(1)\n",
+ " coin[\"Open\"] = float(data[1])\n",
+ " coin[\"High\"] = float(data[2])\n",
+ " coin[\"Low\"] = float(data[3])\n",
+ " coin[\"Close\"] = coin.value\n",
+ " coin[\"VolumeBTC\"] = float(data[5])\n",
+ " coin[\"VolumeUSD\"] = float(data[6])\n",
+ " coin[\"WeightedPrice\"] = float(data[7])\n",
+ " return coin"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cd-add",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "btc = qb.add_data(Bitstamp, \"BTC\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "cd-build-md",
+ "metadata": {},
+ "source": [
+ "### Build Time Series\n",
+ "\n",
+ "Request daily history for the custom type and build the close-price series."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cd-build",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "history = qb.history(btc.symbol, 200, Resolution.DAILY)\n",
+ "history"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "id": "cd-close",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Pull the parsed close price into a single series.\n",
+ "closes = history[\"close\"]\n",
+ "closes"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Foundation-Py-Default",
+ "language": "python",
+ "name": "Foundation-Py-Default"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}