diff --git a/notebooks/strat_backtestingpy_sma_showcase.ipynb b/notebooks/strat_backtestingpy_sma_showcase.ipynb new file mode 100644 index 0000000..cc37ee2 --- /dev/null +++ b/notebooks/strat_backtestingpy_sma_showcase.ipynb @@ -0,0 +1,187 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "203ae436", + "metadata": {}, + "outputs": [], + "source": [ + "# %%\n", + "# filename: strat_backtestingpy_sma_showcase.ipynb\n", + "\n", + "# --- 1. Imports and Setup ---\n", + "import numpy as np\n", + "import pandas as pd\n", + "import pandas_ta as ta\n", + "import talib\n", + "import tulipy as ti\n", + "from backtesting import Backtest, Strategy\n", + "from backtesting.lib import crossover\n", + "from backtesting.test import EURUSD\n", + "\n", + "# --- 2. Load the Sample Data ---\n", + "print(\"Loading built-in EURUSD sample data...\")\n", + "data = EURUSD.copy()\n", + "print(\"Data loaded successfully.\")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fff685c8", + "metadata": {}, + "outputs": [], + "source": [ + "# %%\n", + "# --- Example 1: Using TA-Lib ---\n", + "print(\"\\n--- Showcase: TA-Lib ---\")\n", + "\n", + "def SMA(array, n):\n", + " \"\"\"Helper function to wrap talib.SMA for use with self.I\"\"\"\n", + " return talib.SMA(array, n)\n", + "\n", + "class SmaCrossTaLib(Strategy):\n", + " fast_period = 10\n", + " slow_period = 40\n", + "\n", + " def init(self):\n", + " self.fast_sma = self.I(SMA, self.data.Close, self.fast_period)\n", + " self.slow_sma = self.I(SMA, self.data.Close, self.slow_period)\n", + "\n", + " def next(self):\n", + " if crossover(self.fast_sma, self.slow_sma):\n", + " self.buy()\n", + " elif crossover(self.slow_sma, self.fast_sma):\n", + " self.position.close()\n", + "\n", + "bt = Backtest(data, SmaCrossTaLib, cash=10000, commission=.002)\n", + "stats = bt.run()\n", + "print(stats)\n", + "bt.plot(resample=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c1c8df83", + "metadata": {}, + "outputs": [], + "source": [ + "# %%\n", + "# --- Example 2: Using pandas-ta ---\n", + "print(\"\\n--- Showcase: pandas-ta ---\")\n", + "\n", + "class SmaCrossPandasTa(Strategy):\n", + " fast_period = 10\n", + " slow_period = 40\n", + "\n", + " def init(self):\n", + " self.fast_sma = self.I(ta.sma, pd.Series(self.data.Close), length=self.fast_period)\n", + " self.slow_sma = self.I(ta.sma, pd.Series(self.data.Close), length=self.slow_period)\n", + "\n", + " def next(self):\n", + " if crossover(self.fast_sma, self.slow_sma):\n", + " self.buy()\n", + " elif crossover(self.slow_sma, self.fast_sma):\n", + " self.position.close()\n", + "\n", + "bt = Backtest(data, SmaCrossPandasTa, cash=10000, commission=.002)\n", + "stats = bt.run()\n", + "print(stats)\n", + "bt.plot(resample=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3368601a", + "metadata": {}, + "outputs": [], + "source": [ + "# %%\n", + "# --- Example 3: Using a Custom Python Function ---\n", + "print(\"\\n--- Showcase: Custom Function ---\")\n", + "\n", + "def my_sma_func(price_series, n):\n", + " return price_series.rolling(n).mean()\n", + "\n", + "class SmaCrossCustom(Strategy):\n", + " fast_period = 10\n", + " slow_period = 40\n", + "\n", + " def init(self):\n", + " self.fast_sma = self.I(my_sma_func, pd.Series(self.data.Close), self.fast_period)\n", + " self.slow_sma = self.I(my_sma_func, pd.Series(self.data.Close), self.slow_period)\n", + "\n", + " def next(self):\n", + " if crossover(self.fast_sma, self.slow_sma):\n", + " self.buy()\n", + " elif crossover(self.slow_sma, self.fast_sma):\n", + " self.position.close()\n", + "\n", + "bt = Backtest(data, SmaCrossCustom, cash=10000, commission=.002)\n", + "stats = bt.run()\n", + "print(stats)\n", + "bt.plot(resample=False)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2121bebf", + "metadata": {}, + "outputs": [], + "source": [ + "# %%\n", + "# --- Example 4: Using tulipy ---\n", + "print(\"\\n--- Showcase: tulipy ---\")\n", + "\n", + "def tulip_sma(price_array, period):\n", + " result = ti.sma(price_array, period=period)\n", + " pad_size = len(price_array) - len(result)\n", + " return np.concatenate([np.full(pad_size, np.nan), result])\n", + "\n", + "class SmaCrossTulip(Strategy):\n", + " fast_period = 10\n", + " slow_period = 40\n", + "\n", + " def init(self):\n", + " self.fast_sma = self.I(tulip_sma, self.data.Close, self.fast_period)\n", + " self.slow_sma = self.I(tulip_sma, self.data.Close, self.slow_period)\n", + "\n", + " def next(self):\n", + " if crossover(self.fast_sma, self.slow_sma):\n", + " self.buy()\n", + " elif crossover(self.slow_sma, self.fast_sma):\n", + " self.position.close()\n", + "\n", + "bt = Backtest(data, SmaCrossTulip, cash=10000, commission=.002)\n", + "stats = bt.run()\n", + "print(stats)\n", + "bt.plot(resample=False)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "strategy-optimizer_env_bck", + "language": "python", + "name": "python3" + }, + "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.12.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}