Created
February 17, 2023 17:24
-
-
Save nagishin/3cc9348347bc3cae5bb86354dea3bba9 to your computer and use it in GitHub Desktop.
polars_backtest.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "nbformat": 4, | |
| "nbformat_minor": 0, | |
| "metadata": { | |
| "colab": { | |
| "provenance": [], | |
| "toc_visible": true, | |
| "authorship_tag": "ABX9TyNw5VBD4foz8oG3Jl8jpIs6", | |
| "include_colab_link": true | |
| }, | |
| "kernelspec": { | |
| "name": "python3", | |
| "display_name": "Python 3" | |
| }, | |
| "language_info": { | |
| "name": "python" | |
| } | |
| }, | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": { | |
| "id": "view-in-github", | |
| "colab_type": "text" | |
| }, | |
| "source": [ | |
| "<a href=\"https://colab.research.google.com/gist/nagishin/3cc9348347bc3cae5bb86354dea3bba9/polars_backtest.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "---\n", | |
| "# 【DataFrameで高速バックテスト(pandas vs polars)】\n", | |
| "* このnotebookは下記noteで解説されているバックテストをベースにpandasとpolarsのパフォーマンス比較を行っています。\n", | |
| "* ロジックやpandasでの詳細な解説はnoteに記載されているため、本コードを参照する前に一読することをおすすめします。\n", | |
| "\n", | |
| "<b>[参考]</b><br>\n", | |
| "くもすけさん著<br>\n", | |
| "[pandasを用いた超高速バックテスト](https://note.com/kunmosky1/n/nc15678b3dcc2)\n", | |
| "<br><br>\n", | |
| "<b>[注意]</b><br>\n", | |
| "このnotebookはpandasとpolarsのコーディングやパフォーマンス比較を目的としています。<br>\n", | |
| "バックテストのロジック内容や評価方法は一例としてお考えください。\n", | |
| "\n", | |
| "---" | |
| ], | |
| "metadata": { | |
| "id": "1BEKAMEhOzCW" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## 【polarsインストール】" | |
| ], | |
| "metadata": { | |
| "id": "GzpivxK2Finy" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "!pip install polars" | |
| ], | |
| "metadata": { | |
| "id": "nWC3SbV2XPMu" | |
| }, | |
| "execution_count": null, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### 各種バージョン" | |
| ], | |
| "metadata": { | |
| "id": "6qw9YYrM3n5i" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "import os\n", | |
| "import time\n", | |
| "from datetime import datetime\n", | |
| "import pandas as pd\n", | |
| "import polars as pl\n", | |
| "\n", | |
| "!python --version\n", | |
| "print('pandas', pd.__version__)\n", | |
| "print('polars', pl.__version__)" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "id": "TKDre2BA1DCc", | |
| "outputId": "6c1f53fc-53a5-4802-dd57-5b11accce477" | |
| }, | |
| "execution_count": 24, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "Python 3.8.10\n", | |
| "pandas 1.3.5\n", | |
| "polars 0.16.6\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## 【初期設定】\n", | |
| "\n", | |
| "<b>ロジック</b><br>\n", | |
| "* 長期SMAが上がっていて、短期SMAが長期SMAを超えた時にロング\n", | |
| "* 長期SMAが下がっていて、短期SMAが長期SMAを下抜けした時にショート\n", | |
| "* 同方向のエントリーが連続した場合はポジションを積み増し(ピラミッディング)\n", | |
| "* 逆方向のエントリーでドテン" | |
| ], | |
| "metadata": { | |
| "id": "a74yTXcRFojC" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 25, | |
| "metadata": { | |
| "id": "ott94-XvRyj8" | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "SYMBOL = 'BTCUSDT' # 通貨ペア\n", | |
| "PERIOD = '5m' # 時間足\n", | |
| "YEAR = 2022 # 対象年\n", | |
| "\n", | |
| "SHORT_SMA = 20 # 短期 移動平均期間\n", | |
| "LONG_SMA = 47 # 長期 移動平均期間\n", | |
| "PYRAMIDING = 4 # ピラミッディング回数\n", | |
| "COMMISION = 0.075 # taker手数料%\n", | |
| "\n", | |
| "CSV_PATH = f'./ohlcv_{SYMBOL}_{YEAR}_{PERIOD}.csv' # CSVパス(取得したOHLCV保存)\n", | |
| "\n", | |
| "NANOSECONDS = 1_000_000_000 # nano秒単位" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## 【OHLCV取得 & CSV保存】\n", | |
| "<b>対象データ</b>\n", | |
| "* OHLCVデータ : Binance 5m OHLCV\n", | |
| "\n", | |
| "<b>対象期間</b>\n", | |
| "* 2022-01-01 ~ 2022-12-31" | |
| ], | |
| "metadata": { | |
| "id": "0gqut-tpF7LB" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "# ファイル存在チェック\n", | |
| "df_ohlcv_base = None\n", | |
| "if os.path.isfile(CSV_PATH):\n", | |
| " # ローカルCSV読み込み\n", | |
| " df_ohlcv_base = pd.read_csv(CSV_PATH)\n", | |
| "else:\n", | |
| " # csvをDataFrameに読み込み\n", | |
| " for month in range(1,13):\n", | |
| " df = pd.read_csv(f'https://data.binance.vision/data/spot/monthly/klines/{SYMBOL}/{PERIOD}/{SYMBOL}-{PERIOD}-{YEAR}-{month:02}.zip',\n", | |
| " usecols=[0,1,2,3,4,5],\n", | |
| " names=['timestamp', 'open', 'high', 'low', 'close', 'volume'],\n", | |
| " dtype={'timestamp':'int', 'open':'float', 'high':'float', 'low':'float', 'close':'float', 'volume':'float'})\n", | |
| " if df is not None and len(df.index) > 0:\n", | |
| " if df_ohlcv_base is None:\n", | |
| " df_ohlcv_base = df\n", | |
| " else:\n", | |
| " df_ohlcv_base = pd.concat([df_ohlcv_base, df])\n", | |
| " # UnixTime(timestamp)順ソート\n", | |
| " df_ohlcv_base.sort_values(by='timestamp', ascending=True, inplace=True)\n", | |
| " df_ohlcv_base.reset_index(drop=True, inplace=True)\n", | |
| " df_ohlcv_base['timestamp'] = (df_ohlcv_base['timestamp'] / 1000).astype(int) # ms->s\n", | |
| " # ローカルに保存\n", | |
| " df_ohlcv_base.to_csv(CSV_PATH, header=True, index=False)\n", | |
| "\n", | |
| "display(df_ohlcv_base)" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 424 | |
| }, | |
| "id": "8i83tLdXFvva", | |
| "outputId": "2d523e8d-7146-4d32-c1e0-dbedfef6f8c4" | |
| }, | |
| "execution_count": 26, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| " timestamp open high low close volume\n", | |
| "0 1640995200 46216.93 46391.49 46208.37 46321.34 185.67558\n", | |
| "1 1640995500 46321.34 46527.26 46280.00 46371.11 123.43577\n", | |
| "2 1640995800 46369.79 46394.00 46276.22 46332.51 77.54574\n", | |
| "3 1640996100 46332.52 46332.52 46236.27 46293.90 101.14315\n", | |
| "4 1640996400 46295.42 46421.27 46286.25 46395.53 135.32479\n", | |
| "... ... ... ... ... ... ...\n", | |
| "105115 1672529700 16538.17 16551.24 16536.84 16545.68 501.06148\n", | |
| "105116 1672530000 16545.68 16550.26 16543.45 16546.13 277.70571\n", | |
| "105117 1672530300 16546.14 16550.55 16536.62 16539.05 292.41232\n", | |
| "105118 1672530600 16538.39 16541.26 16534.92 16540.42 180.18579\n", | |
| "105119 1672530900 16540.42 16544.47 16535.05 16542.40 227.06684\n", | |
| "\n", | |
| "[105120 rows x 6 columns]" | |
| ], | |
| "text/html": [ | |
| "\n", | |
| " <div id=\"df-efc288c4-612a-4708-934a-789eec15a15c\">\n", | |
| " <div class=\"colab-df-container\">\n", | |
| " <div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>timestamp</th>\n", | |
| " <th>open</th>\n", | |
| " <th>high</th>\n", | |
| " <th>low</th>\n", | |
| " <th>close</th>\n", | |
| " <th>volume</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>1640995200</td>\n", | |
| " <td>46216.93</td>\n", | |
| " <td>46391.49</td>\n", | |
| " <td>46208.37</td>\n", | |
| " <td>46321.34</td>\n", | |
| " <td>185.67558</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>1640995500</td>\n", | |
| " <td>46321.34</td>\n", | |
| " <td>46527.26</td>\n", | |
| " <td>46280.00</td>\n", | |
| " <td>46371.11</td>\n", | |
| " <td>123.43577</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>1640995800</td>\n", | |
| " <td>46369.79</td>\n", | |
| " <td>46394.00</td>\n", | |
| " <td>46276.22</td>\n", | |
| " <td>46332.51</td>\n", | |
| " <td>77.54574</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>3</th>\n", | |
| " <td>1640996100</td>\n", | |
| " <td>46332.52</td>\n", | |
| " <td>46332.52</td>\n", | |
| " <td>46236.27</td>\n", | |
| " <td>46293.90</td>\n", | |
| " <td>101.14315</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>4</th>\n", | |
| " <td>1640996400</td>\n", | |
| " <td>46295.42</td>\n", | |
| " <td>46421.27</td>\n", | |
| " <td>46286.25</td>\n", | |
| " <td>46395.53</td>\n", | |
| " <td>135.32479</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>...</th>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>105115</th>\n", | |
| " <td>1672529700</td>\n", | |
| " <td>16538.17</td>\n", | |
| " <td>16551.24</td>\n", | |
| " <td>16536.84</td>\n", | |
| " <td>16545.68</td>\n", | |
| " <td>501.06148</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>105116</th>\n", | |
| " <td>1672530000</td>\n", | |
| " <td>16545.68</td>\n", | |
| " <td>16550.26</td>\n", | |
| " <td>16543.45</td>\n", | |
| " <td>16546.13</td>\n", | |
| " <td>277.70571</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>105117</th>\n", | |
| " <td>1672530300</td>\n", | |
| " <td>16546.14</td>\n", | |
| " <td>16550.55</td>\n", | |
| " <td>16536.62</td>\n", | |
| " <td>16539.05</td>\n", | |
| " <td>292.41232</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>105118</th>\n", | |
| " <td>1672530600</td>\n", | |
| " <td>16538.39</td>\n", | |
| " <td>16541.26</td>\n", | |
| " <td>16534.92</td>\n", | |
| " <td>16540.42</td>\n", | |
| " <td>180.18579</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>105119</th>\n", | |
| " <td>1672530900</td>\n", | |
| " <td>16540.42</td>\n", | |
| " <td>16544.47</td>\n", | |
| " <td>16535.05</td>\n", | |
| " <td>16542.40</td>\n", | |
| " <td>227.06684</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "<p>105120 rows × 6 columns</p>\n", | |
| "</div>\n", | |
| " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-efc288c4-612a-4708-934a-789eec15a15c')\"\n", | |
| " title=\"Convert this dataframe to an interactive table.\"\n", | |
| " style=\"display:none;\">\n", | |
| " \n", | |
| " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", | |
| " width=\"24px\">\n", | |
| " <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n", | |
| " <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n", | |
| " </svg>\n", | |
| " </button>\n", | |
| " \n", | |
| " <style>\n", | |
| " .colab-df-container {\n", | |
| " display:flex;\n", | |
| " flex-wrap:wrap;\n", | |
| " gap: 12px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert {\n", | |
| " background-color: #E8F0FE;\n", | |
| " border: none;\n", | |
| " border-radius: 50%;\n", | |
| " cursor: pointer;\n", | |
| " display: none;\n", | |
| " fill: #1967D2;\n", | |
| " height: 32px;\n", | |
| " padding: 0 0 0 0;\n", | |
| " width: 32px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert:hover {\n", | |
| " background-color: #E2EBFA;\n", | |
| " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
| " fill: #174EA6;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert {\n", | |
| " background-color: #3B4455;\n", | |
| " fill: #D2E3FC;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert:hover {\n", | |
| " background-color: #434B5C;\n", | |
| " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
| " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
| " fill: #FFFFFF;\n", | |
| " }\n", | |
| " </style>\n", | |
| "\n", | |
| " <script>\n", | |
| " const buttonEl =\n", | |
| " document.querySelector('#df-efc288c4-612a-4708-934a-789eec15a15c button.colab-df-convert');\n", | |
| " buttonEl.style.display =\n", | |
| " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
| "\n", | |
| " async function convertToInteractive(key) {\n", | |
| " const element = document.querySelector('#df-efc288c4-612a-4708-934a-789eec15a15c');\n", | |
| " const dataTable =\n", | |
| " await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
| " [key], {});\n", | |
| " if (!dataTable) return;\n", | |
| "\n", | |
| " const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
| " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
| " + ' to learn more about interactive tables.';\n", | |
| " element.innerHTML = '';\n", | |
| " dataTable['output_type'] = 'display_data';\n", | |
| " await google.colab.output.renderOutput(dataTable, element);\n", | |
| " const docLink = document.createElement('div');\n", | |
| " docLink.innerHTML = docLinkHtml;\n", | |
| " element.appendChild(docLink);\n", | |
| " }\n", | |
| " </script>\n", | |
| " </div>\n", | |
| " </div>\n", | |
| " " | |
| ] | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## 【バックテスト】" | |
| ], | |
| "metadata": { | |
| "id": "pBaWX2fGGS2h" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### pandas" | |
| ], | |
| "metadata": { | |
| "id": "N-JKYYucGXUh" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### CSV読み込み" | |
| ], | |
| "metadata": { | |
| "id": "4ag9sF2sJcZN" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# csvをDataFrameに読み込み\n", | |
| "df_ohlcv_pd = pd.read_csv(CSV_PATH)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')" | |
| ], | |
| "metadata": { | |
| "id": "Z87Xv3pMRJRD", | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "outputId": "58032fe7-bf19-4e67-faa1-43061e9aaba0" | |
| }, | |
| "execution_count": 27, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 103.784 ms\n", | |
| "\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### バックテスト関数\n", | |
| "このコードの詳細な解説は下記noteを参照してください。<br>\n", | |
| "\n", | |
| "くもすけさん著<br>\n", | |
| "[pandasを用いた超高速バックテスト](https://note.com/kunmosky1/n/nc15678b3dcc2)" | |
| ], | |
| "metadata": { | |
| "id": "jLKJFD7vJqlp" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "def backtest_pandas(short_sma:int, long_sma:int, pyramid:int, df_ohlcv:pd.DataFrame=None) -> pd.DataFrame:\n", | |
| " \"\"\"**【バックテスト(pandas)】**\n", | |
| "\n", | |
| " 短期/長期移動平均のゴールデンクロス/デッドクロスでエントリー \n", | |
| " 同方向に注文が重なった場合は指定回数まで積み増し\n", | |
| "\n", | |
| " :param short_sma: 短期 移動平均期間\n", | |
| " :param long_sma: 長期 移動平均期間\n", | |
| " :param pyramid: 積み増し回数\n", | |
| " :param df_ohlcv: OHLCV DataFrame(pandas)\n", | |
| "\n", | |
| " :return: 処理結果 DataFrame\n", | |
| " \"\"\"\n", | |
| " global df_ohlcv_pd\n", | |
| "\n", | |
| " if df_ohlcv is None:\n", | |
| " df = df_ohlcv_pd.copy()\n", | |
| " else:\n", | |
| " df = df_ohlcv.copy()\n", | |
| "\n", | |
| " # UnixTime(timestamp)からdatetime列生成\n", | |
| " df['datetime'] = pd.to_datetime(df['timestamp'], unit='s', utc=True)\n", | |
| " # datetimeをindexに設定\n", | |
| " df.set_index('datetime', inplace=True)\n", | |
| "\n", | |
| " # SMA計算\n", | |
| " df['short_sma'] = df['close'].rolling(short_sma, min_periods=1).mean()\n", | |
| " df['long_sma'] = df['close'].rolling(long_sma, min_periods=1).mean()\n", | |
| "\n", | |
| " # エントリー判定\n", | |
| " def crossover(x, y):\n", | |
| " return ((x - y) > 0) & ((x.shift(1) - y) < 0)\n", | |
| " def crossunder(x, y):\n", | |
| " return ((x - y) < 0) & ((x.shift(1) - y) > 0)\n", | |
| " df['long'] = (df['long_sma'].diff(1) > 0) & crossover(df['long_sma'], df['short_sma'])\n", | |
| " df['short'] = (df['long_sma'].diff(1) < 0) & crossunder(df['long_sma'], df['short_sma'])\n", | |
| "\n", | |
| " # ポジション計算(ドテン&ピラミッディング)\n", | |
| " df['order'] = 0\n", | |
| " df['order'] = df['order'].where(df['long'] != True, 1)\n", | |
| " df['order'] = df['order'].where(df['short'] != True, -1)\n", | |
| " df['pos'] = df['order'].where(df['order'] != 0,).fillna(method='ffill').fillna(0)\n", | |
| " df['pos'] = df.groupby((df['pos'] * df['pos'].shift(1) < 0).cumsum().fillna(0))['order'].cumsum()\n", | |
| " df['pos'] = df['pos'].where(df['pos'] <= pyramid, pyramid) \n", | |
| " df['pos'] = df['pos'].where(df['pos'] >= -pyramid, -pyramid)\n", | |
| " df['pos'] /= pyramid\n", | |
| "\n", | |
| " # 損益計算\n", | |
| " df['return']= -df['open'].diff(-1)\n", | |
| " df['commision'] = df['open'].shift(-1) * COMMISION / 100 * abs(df['pos'] - df['pos'].shift(1))\n", | |
| " df['profit'] = df['return'] * df['pos'].shift(1) - df['commision']\n", | |
| " df['pnl'] = df['profit'].cumsum()\n", | |
| " df['pnl'] = df['pnl'].fillna(method='ffill')\n", | |
| "\n", | |
| " return df" | |
| ], | |
| "metadata": { | |
| "id": "1Fks-_RfHmDK" | |
| }, | |
| "execution_count": 28, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### バックテスト実行" | |
| ], | |
| "metadata": { | |
| "id": "hCeRoPc2J1qz" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# バックテスト\n", | |
| "df_result_pd = backtest_pandas(SHORT_SMA, LONG_SMA, PYRAMIDING, df_ohlcv_pd)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')\n", | |
| "\n", | |
| "# 結果表示\n", | |
| "display(df_result_pd)\n", | |
| "# 結果表示(ポジション変化が有ったところだけ)\n", | |
| "#display(df_result_pd[df_result_pd['pos'].diff(1) != 0][['open','long','short','pos','pnl']])" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 707 | |
| }, | |
| "id": "USKdfuYnS9B-", | |
| "outputId": "2ec28e43-1a89-40e2-be3b-42d1d8c1cd03" | |
| }, | |
| "execution_count": 44, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 76.425 ms\n", | |
| "\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| " timestamp open high low close \\\n", | |
| "datetime \n", | |
| "2022-01-01 00:00:00+00:00 1640995200 46216.93 46391.49 46208.37 46321.34 \n", | |
| "2022-01-01 00:05:00+00:00 1640995500 46321.34 46527.26 46280.00 46371.11 \n", | |
| "2022-01-01 00:10:00+00:00 1640995800 46369.79 46394.00 46276.22 46332.51 \n", | |
| "2022-01-01 00:15:00+00:00 1640996100 46332.52 46332.52 46236.27 46293.90 \n", | |
| "2022-01-01 00:20:00+00:00 1640996400 46295.42 46421.27 46286.25 46395.53 \n", | |
| "... ... ... ... ... ... \n", | |
| "2022-12-31 23:35:00+00:00 1672529700 16538.17 16551.24 16536.84 16545.68 \n", | |
| "2022-12-31 23:40:00+00:00 1672530000 16545.68 16550.26 16543.45 16546.13 \n", | |
| "2022-12-31 23:45:00+00:00 1672530300 16546.14 16550.55 16536.62 16539.05 \n", | |
| "2022-12-31 23:50:00+00:00 1672530600 16538.39 16541.26 16534.92 16540.42 \n", | |
| "2022-12-31 23:55:00+00:00 1672530900 16540.42 16544.47 16535.05 16542.40 \n", | |
| "\n", | |
| " volume short_sma long_sma long \\\n", | |
| "datetime \n", | |
| "2022-01-01 00:00:00+00:00 185.67558 46321.340000 46321.340000 False \n", | |
| "2022-01-01 00:05:00+00:00 123.43577 46346.225000 46346.225000 False \n", | |
| "2022-01-01 00:10:00+00:00 77.54574 46341.653333 46341.653333 False \n", | |
| "2022-01-01 00:15:00+00:00 101.14315 46329.715000 46329.715000 False \n", | |
| "2022-01-01 00:20:00+00:00 135.32479 46342.878000 46342.878000 False \n", | |
| "... ... ... ... ... \n", | |
| "2022-12-31 23:35:00+00:00 501.06148 16530.430500 16551.263404 False \n", | |
| "2022-12-31 23:40:00+00:00 277.70571 16530.540000 16550.433191 False \n", | |
| "2022-12-31 23:45:00+00:00 292.41232 16529.683500 16549.552553 False \n", | |
| "2022-12-31 23:50:00+00:00 180.18579 16528.435500 16548.920213 False \n", | |
| "2022-12-31 23:55:00+00:00 227.06684 16528.974500 16548.307660 False \n", | |
| "\n", | |
| " short order pos return commision profit \\\n", | |
| "datetime \n", | |
| "2022-01-01 00:00:00+00:00 False 0 0.0 104.41 NaN NaN \n", | |
| "2022-01-01 00:05:00+00:00 False 0 0.0 48.45 0.0 0.000 \n", | |
| "2022-01-01 00:10:00+00:00 False 0 0.0 -37.27 0.0 -0.000 \n", | |
| "2022-01-01 00:15:00+00:00 False 0 0.0 -37.10 0.0 -0.000 \n", | |
| "2022-01-01 00:20:00+00:00 False 0 0.0 100.11 0.0 0.000 \n", | |
| "... ... ... ... ... ... ... \n", | |
| "2022-12-31 23:35:00+00:00 False 0 0.5 7.51 0.0 3.755 \n", | |
| "2022-12-31 23:40:00+00:00 False 0 0.5 0.46 0.0 0.230 \n", | |
| "2022-12-31 23:45:00+00:00 False 0 0.5 -7.75 0.0 -3.875 \n", | |
| "2022-12-31 23:50:00+00:00 False 0 0.5 2.03 0.0 1.015 \n", | |
| "2022-12-31 23:55:00+00:00 False 0 0.5 NaN NaN NaN \n", | |
| "\n", | |
| " pnl \n", | |
| "datetime \n", | |
| "2022-01-01 00:00:00+00:00 NaN \n", | |
| "2022-01-01 00:05:00+00:00 0.000000 \n", | |
| "2022-01-01 00:10:00+00:00 0.000000 \n", | |
| "2022-01-01 00:15:00+00:00 0.000000 \n", | |
| "2022-01-01 00:20:00+00:00 0.000000 \n", | |
| "... ... \n", | |
| "2022-12-31 23:35:00+00:00 7148.928371 \n", | |
| "2022-12-31 23:40:00+00:00 7149.158371 \n", | |
| "2022-12-31 23:45:00+00:00 7145.283371 \n", | |
| "2022-12-31 23:50:00+00:00 7146.298371 \n", | |
| "2022-12-31 23:55:00+00:00 7146.298371 \n", | |
| "\n", | |
| "[105120 rows x 16 columns]" | |
| ], | |
| "text/html": [ | |
| "\n", | |
| " <div id=\"df-92a90e67-7959-43b7-8195-b1602f4ab13a\">\n", | |
| " <div class=\"colab-df-container\">\n", | |
| " <div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>timestamp</th>\n", | |
| " <th>open</th>\n", | |
| " <th>high</th>\n", | |
| " <th>low</th>\n", | |
| " <th>close</th>\n", | |
| " <th>volume</th>\n", | |
| " <th>short_sma</th>\n", | |
| " <th>long_sma</th>\n", | |
| " <th>long</th>\n", | |
| " <th>short</th>\n", | |
| " <th>order</th>\n", | |
| " <th>pos</th>\n", | |
| " <th>return</th>\n", | |
| " <th>commision</th>\n", | |
| " <th>profit</th>\n", | |
| " <th>pnl</th>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>datetime</th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " <th></th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>2022-01-01 00:00:00+00:00</th>\n", | |
| " <td>1640995200</td>\n", | |
| " <td>46216.93</td>\n", | |
| " <td>46391.49</td>\n", | |
| " <td>46208.37</td>\n", | |
| " <td>46321.34</td>\n", | |
| " <td>185.67558</td>\n", | |
| " <td>46321.340000</td>\n", | |
| " <td>46321.340000</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>104.41</td>\n", | |
| " <td>NaN</td>\n", | |
| " <td>NaN</td>\n", | |
| " <td>NaN</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-01-01 00:05:00+00:00</th>\n", | |
| " <td>1640995500</td>\n", | |
| " <td>46321.34</td>\n", | |
| " <td>46527.26</td>\n", | |
| " <td>46280.00</td>\n", | |
| " <td>46371.11</td>\n", | |
| " <td>123.43577</td>\n", | |
| " <td>46346.225000</td>\n", | |
| " <td>46346.225000</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>48.45</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.000</td>\n", | |
| " <td>0.000000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-01-01 00:10:00+00:00</th>\n", | |
| " <td>1640995800</td>\n", | |
| " <td>46369.79</td>\n", | |
| " <td>46394.00</td>\n", | |
| " <td>46276.22</td>\n", | |
| " <td>46332.51</td>\n", | |
| " <td>77.54574</td>\n", | |
| " <td>46341.653333</td>\n", | |
| " <td>46341.653333</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>-37.27</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>-0.000</td>\n", | |
| " <td>0.000000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-01-01 00:15:00+00:00</th>\n", | |
| " <td>1640996100</td>\n", | |
| " <td>46332.52</td>\n", | |
| " <td>46332.52</td>\n", | |
| " <td>46236.27</td>\n", | |
| " <td>46293.90</td>\n", | |
| " <td>101.14315</td>\n", | |
| " <td>46329.715000</td>\n", | |
| " <td>46329.715000</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>-37.10</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>-0.000</td>\n", | |
| " <td>0.000000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-01-01 00:20:00+00:00</th>\n", | |
| " <td>1640996400</td>\n", | |
| " <td>46295.42</td>\n", | |
| " <td>46421.27</td>\n", | |
| " <td>46286.25</td>\n", | |
| " <td>46395.53</td>\n", | |
| " <td>135.32479</td>\n", | |
| " <td>46342.878000</td>\n", | |
| " <td>46342.878000</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>100.11</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.000</td>\n", | |
| " <td>0.000000</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>...</th>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-12-31 23:35:00+00:00</th>\n", | |
| " <td>1672529700</td>\n", | |
| " <td>16538.17</td>\n", | |
| " <td>16551.24</td>\n", | |
| " <td>16536.84</td>\n", | |
| " <td>16545.68</td>\n", | |
| " <td>501.06148</td>\n", | |
| " <td>16530.430500</td>\n", | |
| " <td>16551.263404</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.5</td>\n", | |
| " <td>7.51</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>3.755</td>\n", | |
| " <td>7148.928371</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-12-31 23:40:00+00:00</th>\n", | |
| " <td>1672530000</td>\n", | |
| " <td>16545.68</td>\n", | |
| " <td>16550.26</td>\n", | |
| " <td>16543.45</td>\n", | |
| " <td>16546.13</td>\n", | |
| " <td>277.70571</td>\n", | |
| " <td>16530.540000</td>\n", | |
| " <td>16550.433191</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.5</td>\n", | |
| " <td>0.46</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>0.230</td>\n", | |
| " <td>7149.158371</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-12-31 23:45:00+00:00</th>\n", | |
| " <td>1672530300</td>\n", | |
| " <td>16546.14</td>\n", | |
| " <td>16550.55</td>\n", | |
| " <td>16536.62</td>\n", | |
| " <td>16539.05</td>\n", | |
| " <td>292.41232</td>\n", | |
| " <td>16529.683500</td>\n", | |
| " <td>16549.552553</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.5</td>\n", | |
| " <td>-7.75</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>-3.875</td>\n", | |
| " <td>7145.283371</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-12-31 23:50:00+00:00</th>\n", | |
| " <td>1672530600</td>\n", | |
| " <td>16538.39</td>\n", | |
| " <td>16541.26</td>\n", | |
| " <td>16534.92</td>\n", | |
| " <td>16540.42</td>\n", | |
| " <td>180.18579</td>\n", | |
| " <td>16528.435500</td>\n", | |
| " <td>16548.920213</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.5</td>\n", | |
| " <td>2.03</td>\n", | |
| " <td>0.0</td>\n", | |
| " <td>1.015</td>\n", | |
| " <td>7146.298371</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2022-12-31 23:55:00+00:00</th>\n", | |
| " <td>1672530900</td>\n", | |
| " <td>16540.42</td>\n", | |
| " <td>16544.47</td>\n", | |
| " <td>16535.05</td>\n", | |
| " <td>16542.40</td>\n", | |
| " <td>227.06684</td>\n", | |
| " <td>16528.974500</td>\n", | |
| " <td>16548.307660</td>\n", | |
| " <td>False</td>\n", | |
| " <td>False</td>\n", | |
| " <td>0</td>\n", | |
| " <td>0.5</td>\n", | |
| " <td>NaN</td>\n", | |
| " <td>NaN</td>\n", | |
| " <td>NaN</td>\n", | |
| " <td>7146.298371</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "<p>105120 rows × 16 columns</p>\n", | |
| "</div>\n", | |
| " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-92a90e67-7959-43b7-8195-b1602f4ab13a')\"\n", | |
| " title=\"Convert this dataframe to an interactive table.\"\n", | |
| " style=\"display:none;\">\n", | |
| " \n", | |
| " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", | |
| " width=\"24px\">\n", | |
| " <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n", | |
| " <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n", | |
| " </svg>\n", | |
| " </button>\n", | |
| " \n", | |
| " <style>\n", | |
| " .colab-df-container {\n", | |
| " display:flex;\n", | |
| " flex-wrap:wrap;\n", | |
| " gap: 12px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert {\n", | |
| " background-color: #E8F0FE;\n", | |
| " border: none;\n", | |
| " border-radius: 50%;\n", | |
| " cursor: pointer;\n", | |
| " display: none;\n", | |
| " fill: #1967D2;\n", | |
| " height: 32px;\n", | |
| " padding: 0 0 0 0;\n", | |
| " width: 32px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert:hover {\n", | |
| " background-color: #E2EBFA;\n", | |
| " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
| " fill: #174EA6;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert {\n", | |
| " background-color: #3B4455;\n", | |
| " fill: #D2E3FC;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert:hover {\n", | |
| " background-color: #434B5C;\n", | |
| " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
| " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
| " fill: #FFFFFF;\n", | |
| " }\n", | |
| " </style>\n", | |
| "\n", | |
| " <script>\n", | |
| " const buttonEl =\n", | |
| " document.querySelector('#df-92a90e67-7959-43b7-8195-b1602f4ab13a button.colab-df-convert');\n", | |
| " buttonEl.style.display =\n", | |
| " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
| "\n", | |
| " async function convertToInteractive(key) {\n", | |
| " const element = document.querySelector('#df-92a90e67-7959-43b7-8195-b1602f4ab13a');\n", | |
| " const dataTable =\n", | |
| " await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
| " [key], {});\n", | |
| " if (!dataTable) return;\n", | |
| "\n", | |
| " const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
| " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
| " + ' to learn more about interactive tables.';\n", | |
| " element.innerHTML = '';\n", | |
| " dataTable['output_type'] = 'display_data';\n", | |
| " await google.colab.output.renderOutput(dataTable, element);\n", | |
| " const docLink = document.createElement('div');\n", | |
| " docLink.innerHTML = docLinkHtml;\n", | |
| " element.appendChild(docLink);\n", | |
| " }\n", | |
| " </script>\n", | |
| " </div>\n", | |
| " </div>\n", | |
| " " | |
| ] | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### polars" | |
| ], | |
| "metadata": { | |
| "id": "8adUlBikI7Ia" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### CSV読み込み" | |
| ], | |
| "metadata": { | |
| "id": "kFxI4R6xJ97h" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# csvをDataFrameに読み込み\n", | |
| "df_ohlcv_pl = pl.read_csv(CSV_PATH)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')" | |
| ], | |
| "metadata": { | |
| "id": "EIhmesRnR5Qj", | |
| "colab": { | |
| "base_uri": "https://localhost:8080/" | |
| }, | |
| "outputId": "55409498-70c5-4f64-ee49-40ee16215afa" | |
| }, | |
| "execution_count": 30, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 41.912 ms\n", | |
| "\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### バックテスト関数\n", | |
| "上記のbacktest_pandas関数をpolarsに置き換えたコードになります。" | |
| ], | |
| "metadata": { | |
| "id": "A9YmBDxQKEEm" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "def backtest_polars(short_sma:int, long_sma:int, pyramid:int, df_ohlcv:pl.DataFrame=None) -> pl.DataFrame:\n", | |
| " \"\"\"**【バックテスト(polars)】**\n", | |
| "\n", | |
| " 短期/長期移動平均のゴールデンクロス/デッドクロスでエントリー \n", | |
| " 同方向に注文が重なった場合は指定回数まで積み増し\n", | |
| "\n", | |
| " :param short_sma: 短期 移動平均期間\n", | |
| " :param long_sma: 長期 移動平均期間\n", | |
| " :param pyramid: 積み増し回数\n", | |
| " :param df_ohlcv: OHLCV DataFrame(polars)\n", | |
| "\n", | |
| " :return: 処理結果 DataFrame\n", | |
| " \"\"\"\n", | |
| " global df_ohlcv_pl\n", | |
| "\n", | |
| " if df_ohlcv is None:\n", | |
| " df = df_ohlcv_pl.clone()\n", | |
| " else:\n", | |
| " df = df_ohlcv.clone()\n", | |
| "\n", | |
| " # DataFrame生成\n", | |
| " df = (\n", | |
| " df.lazy()\n", | |
| " .with_columns([ # SMA計算\n", | |
| " # datetime\n", | |
| " (pl.col('timestamp') * NANOSECONDS) # timestamp(秒)をnano秒単位に\n", | |
| " .cast(pl.Datetime(time_unit='ns')) # datetime(nano秒)変換\n", | |
| " .dt.replace_time_zone('UTC') # タイムゾーン設定\n", | |
| " .alias('datetime'),\n", | |
| " # short_sma\n", | |
| " pl.col('close').rolling_mean(short_sma, min_periods=1).alias('short_sma'),\n", | |
| " # long_sma\n", | |
| " pl.col('close').rolling_mean(long_sma, min_periods=1).alias('long_sma'),\n", | |
| " ])\n", | |
| " .with_columns([ # エントリー判定\n", | |
| " # long\n", | |
| " ((pl.col('long_sma').diff(n=1, null_behavior='ignore') > 0) &\n", | |
| " (pl.col('long_sma') - pl.col('short_sma') > 0) &\n", | |
| " (pl.col('long_sma').shift(periods=1) - pl.col('short_sma') < 0)).alias('long'),\n", | |
| " # short\n", | |
| " ((pl.col('long_sma').diff(n=1, null_behavior='ignore') < 0) &\n", | |
| " (pl.col('long_sma') - pl.col('short_sma') < 0) &\n", | |
| " (pl.col('long_sma').shift(periods=1) - pl.col('short_sma') > 0)).alias('short'),\n", | |
| " ])\n", | |
| " .with_columns([ # 注文\n", | |
| " # order\n", | |
| " pl.when(pl.col('long') == True).then(1)\n", | |
| " .when(pl.col('short') == True).then(-1)\n", | |
| " .otherwise(0).alias('order'),\n", | |
| " ])\n", | |
| " .with_columns([ # ポジション計算(ドテン&ピラミッディング)\n", | |
| " # pos\n", | |
| " pl.when(pl.col('order') != 0).then(pl.col('order'))\n", | |
| " .otherwise(None).fill_null(strategy='forward').fill_null(0).alias('pos'),\n", | |
| " ])\n", | |
| " .with_columns([ # ポジション方向がドテンする単位でグループNo.を設定\n", | |
| " # doten_group\n", | |
| " (pl.col('pos') * pl.col('pos').shift(periods=1) < 0).cumsum().fill_null(0).alias('doten_group'),\n", | |
| " ])\n", | |
| " .collect()\n", | |
| " )\n", | |
| "\n", | |
| " # ドテンするグループ内でポジションを積み増し\n", | |
| " df = (\n", | |
| " df.lazy()\n", | |
| " .with_columns(\n", | |
| " # pos\n", | |
| " df.groupby('doten_group')\n", | |
| " .agg(pl.col('order').cumsum())\n", | |
| " .explode('order')\n", | |
| " .sort(by='doten_group')\n", | |
| " .select(pl.col('order').alias('pos'))\n", | |
| " )\n", | |
| " .with_columns([ # ピラミッディング回数でポジションサイズ調整\n", | |
| " # pos\n", | |
| " pl.when(pl.col('pos') > pyramid).then(1)\n", | |
| " .when(pl.col('pos') < -pyramid).then(-1)\n", | |
| " .otherwise(pl.col('pos') / pyramid).alias('pos'),\n", | |
| " ])\n", | |
| " .with_columns([ # 損益計算\n", | |
| " # return\n", | |
| " (pl.col('open').shift(periods=-1) - pl.col('open')).alias('return'),\n", | |
| " # commision\n", | |
| " (pl.col('open').shift(periods=-1) * COMMISION / 100 * abs(pl.col('pos') - pl.col('pos').shift(periods=1))).alias('commision'),\n", | |
| " ])\n", | |
| " .with_columns([\n", | |
| " # profit\n", | |
| " (pl.col('return') * pl.col('pos').shift(periods=1) - pl.col('commision')).alias('profit'),\n", | |
| " ])\n", | |
| " .with_columns([\n", | |
| " # pnl\n", | |
| " (pl.col('profit').cumsum().fill_null(strategy='forward').fill_null(0)).alias('pnl'),\n", | |
| " ])\n", | |
| " .collect()\n", | |
| " )\n", | |
| "\n", | |
| " return df" | |
| ], | |
| "metadata": { | |
| "id": "jTYX40cqH-kh" | |
| }, | |
| "execution_count": 31, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### バックテスト実行" | |
| ], | |
| "metadata": { | |
| "id": "ApdiP5uAKMmv" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# バックテスト\n", | |
| "df_result_pl = backtest_polars(SHORT_SMA, LONG_SMA, PYRAMIDING, df_ohlcv_pl)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')\n", | |
| "\n", | |
| "# 結果表示\n", | |
| "display(df_result_pl)\n", | |
| "# 結果表示(ポジション変化が有ったところだけ)\n", | |
| "#display(df_result_pl.filter(pl.col('pos').diff(n=1, null_behavior='ignore') != 0).select(pl.col(['open','long','short','pos','pnl'])))" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 1000 | |
| }, | |
| "id": "Lo0sTQSdblY2", | |
| "outputId": "0f336c5b-87cb-4f23-e61b-691a9fd3bc7b" | |
| }, | |
| "execution_count": 42, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 50.098 ms\n", | |
| "\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "shape: (105120, 18)\n", | |
| "┌────────────┬──────────┬──────────┬──────────┬─────┬────────┬───────────┬────────┬─────────────┐\n", | |
| "│ timestamp ┆ open ┆ high ┆ low ┆ ... ┆ return ┆ commision ┆ profit ┆ pnl │\n", | |
| "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │\n", | |
| "│ i64 ┆ f64 ┆ f64 ┆ f64 ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", | |
| "╞════════════╪══════════╪══════════╪══════════╪═════╪════════╪═══════════╪════════╪═════════════╡\n", | |
| "│ 1640995200 ┆ 46216.93 ┆ 46391.49 ┆ 46208.37 ┆ ... ┆ 104.41 ┆ null ┆ null ┆ 0.0 │\n", | |
| "│ 1640995500 ┆ 46321.34 ┆ 46527.26 ┆ 46280.0 ┆ ... ┆ 48.45 ┆ 0.0 ┆ 0.0 ┆ 0.0 │\n", | |
| "│ 1640995800 ┆ 46369.79 ┆ 46394.0 ┆ 46276.22 ┆ ... ┆ -37.27 ┆ 0.0 ┆ -0.0 ┆ 0.0 │\n", | |
| "│ 1640996100 ┆ 46332.52 ┆ 46332.52 ┆ 46236.27 ┆ ... ┆ -37.1 ┆ 0.0 ┆ -0.0 ┆ 0.0 │\n", | |
| "│ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... │\n", | |
| "│ 1672530000 ┆ 16545.68 ┆ 16550.26 ┆ 16543.45 ┆ ... ┆ 0.46 ┆ 0.0 ┆ 0.23 ┆ 7149.158371 │\n", | |
| "│ 1672530300 ┆ 16546.14 ┆ 16550.55 ┆ 16536.62 ┆ ... ┆ -7.75 ┆ 0.0 ┆ -3.875 ┆ 7145.283371 │\n", | |
| "│ 1672530600 ┆ 16538.39 ┆ 16541.26 ┆ 16534.92 ┆ ... ┆ 2.03 ┆ 0.0 ┆ 1.015 ┆ 7146.298371 │\n", | |
| "│ 1672530900 ┆ 16540.42 ┆ 16544.47 ┆ 16535.05 ┆ ... ┆ null ┆ null ┆ null ┆ 7146.298371 │\n", | |
| "└────────────┴──────────┴──────────┴──────────┴─────┴────────┴───────────┴────────┴─────────────┘" | |
| ], | |
| "text/html": [ | |
| "<div>\n", | |
| "<style>\n", | |
| ".pl-dataframe > thead > tr > th {\n", | |
| " text-align: right;\n", | |
| "}\n", | |
| "</style>\n", | |
| "\n", | |
| "<table border=\"1\" class=\"dataframe pl-dataframe\">\n", | |
| "<small>shape: (105120, 18)</small>\n", | |
| "<thead>\n", | |
| "<tr>\n", | |
| "<th>\n", | |
| "timestamp\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "open\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "high\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "low\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "close\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "volume\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "datetime\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "short_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "long_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "long\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "short\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "order\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "pos\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "doten_group\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "return\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "commision\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "profit\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "pnl\n", | |
| "</th>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "datetime[ns, UTC]\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "bool\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "bool\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "i32\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "u32\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</thead>\n", | |
| "<tbody>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640995200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46216.93\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46391.49\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46208.37\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "185.67558\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:00:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "104.41\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640995500\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46527.26\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46280.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46371.11\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "123.43577\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:05:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46346.225\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46346.225\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "48.45\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640995800\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46369.79\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46394.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46276.22\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46332.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "77.54574\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:10:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46341.653333\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46341.653333\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-37.27\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640996100\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46332.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46332.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46236.27\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46293.9\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "101.14315\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:15:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46329.715\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46329.715\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-37.1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640996400\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46295.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46421.27\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46286.25\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46395.53\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "135.32479\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:20:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46342.878\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46342.878\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "100.11\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640996700\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46395.53\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46400.38\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46345.1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46375.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "83.53179\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:25:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46348.301667\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46348.301667\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-20.11\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640997000\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46375.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46446.47\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46360.19\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46443.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "81.82606\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:30:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46361.922857\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46361.922857\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "68.23\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640997300\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46443.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46590.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46443.64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46530.7\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "113.11574\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:35:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46383.02\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46383.02\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "87.06\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640997600\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46530.71\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46689.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46503.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46610.81\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "191.13897\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:40:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46408.33\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46408.33\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "80.1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640997900\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46610.81\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46731.39\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46575.76\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46693.74\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "168.66367\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:45:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46436.871\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46436.871\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "82.94\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640998200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46693.75\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46708.59\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46628.6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46659.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "133.40734\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:50:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46457.123636\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46457.123636\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-34.09\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1640998500\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46659.66\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46690.16\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46630.46\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46656.13\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "108.52235\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-01-01 00:55:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46473.7075\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46473.7075\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-3.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672527600\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16520.28\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16524.91\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16500.24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16506.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "767.72112\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:00:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16542.4405\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16559.298085\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-14.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-7.07\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7129.158371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672527900\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16506.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16514.99\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16490.78\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16495.24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "558.92871\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:05:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16539.0105\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16557.58\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-10.13\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-5.065\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7124.093371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672528200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16496.01\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16503.97\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16487.74\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16502.67\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "555.3314\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:10:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16536.248\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16556.038936\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6.66\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3.33\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7127.423371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672528500\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16502.67\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16526.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16500.73\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16523.86\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "618.0961\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:15:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16534.4375\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16555.104681\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "21.19\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "10.595\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7138.018371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672528800\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16523.86\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16529.54\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16520.91\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16525.92\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "302.37991\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:20:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16532.707\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16554.120638\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2.68\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7139.358371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672529100\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16526.54\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16527.01\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16517.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16524.64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "262.99128\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:25:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16531.1315\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16552.990213\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-1.89\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.945\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7138.413371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672529400\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16524.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16540.59\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16520.44\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16538.17\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "429.55241\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:30:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16530.5605\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16551.932766\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "13.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6.76\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7145.173371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672529700\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16538.17\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16551.24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16536.84\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16545.68\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "501.06148\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:35:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16530.4305\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16551.263404\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3.755\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7148.928371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672530000\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16545.68\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16550.26\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16543.45\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16546.13\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "277.70571\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:40:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16530.54\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16550.433191\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.46\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.23\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7149.158371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672530300\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16546.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16550.55\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16536.62\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16539.05\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "292.41232\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:45:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16529.6835\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16549.552553\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-7.75\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-3.875\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7145.283371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672530600\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16538.39\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16541.26\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16534.92\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16540.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "180.18579\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:50:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16528.4355\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16548.920213\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2.03\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1.015\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7146.298371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "1672530900\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16540.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16544.47\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16535.05\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16542.4\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "227.06684\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2022-12-31 23:55:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16528.9745\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16548.30766\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "false\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "440\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7146.298371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ] | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### (調整版)バックテスト関数\n", | |
| "上記のbacktest_polars関数をベースにピラミッディングのポジション計算にgroupbyを使用せず、損益計算までワンライナーで処理するように調整したコードになります。" | |
| ], | |
| "metadata": { | |
| "id": "_hrrqn9YKi2S" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "def backtest_polars2(short_sma:int, long_sma:int, pyramid:int, df_ohlcv:pl.DataFrame=None) -> pl.DataFrame:\n", | |
| " \"\"\"**【バックテスト(polars)】**\n", | |
| "\n", | |
| " 短期/長期移動平均のゴールデンクロス/デッドクロスでエントリー \n", | |
| " 同方向に注文が重なった場合は指定回数まで積み増し\n", | |
| "\n", | |
| " :param short_sma: 短期 移動平均期間\n", | |
| " :param long_sma: 長期 移動平均期間\n", | |
| " :param pyramid: 積み増し回数\n", | |
| " :param df_ohlcv: OHLCV DataFrame(polars)\n", | |
| "\n", | |
| " :return: 処理結果 DataFrame\n", | |
| " \"\"\"\n", | |
| " global df_ohlcv_pl\n", | |
| "\n", | |
| " if df_ohlcv is None:\n", | |
| " df = df_ohlcv_pl.clone()\n", | |
| " else:\n", | |
| " df = df_ohlcv.clone()\n", | |
| "\n", | |
| " # DataFrame生成\n", | |
| " df = (\n", | |
| " df.lazy()\n", | |
| " .with_columns([ # SMA計算\n", | |
| " # datetime\n", | |
| " (pl.col('timestamp') * NANOSECONDS) # timestamp(秒)をnano秒単位に\n", | |
| " .cast(pl.Datetime(time_unit='ns')) # datetime(nano秒)変換\n", | |
| " .dt.replace_time_zone('UTC') # タイムゾーン設定\n", | |
| " .alias('datetime'),\n", | |
| " # short_sma\n", | |
| " pl.col('close').rolling_mean(short_sma, min_periods=1).alias('short_sma'),\n", | |
| " # long_sma\n", | |
| " pl.col('close').rolling_mean(long_sma, min_periods=1).alias('long_sma'),\n", | |
| " ])\n", | |
| " .with_columns([ # エントリー判定\n", | |
| " # long(1)\n", | |
| " pl.when((pl.col('long_sma').diff(n=1, null_behavior='ignore') > 0) &\n", | |
| " (pl.col('long_sma') - pl.col('short_sma') > 0) &\n", | |
| " (pl.col('long_sma').shift(periods=1) - pl.col('short_sma') < 0)).then(1)\n", | |
| " # short(-1)\n", | |
| " .when((pl.col('long_sma').diff(n=1, null_behavior='ignore') < 0) &\n", | |
| " (pl.col('long_sma') - pl.col('short_sma') < 0) &\n", | |
| " (pl.col('long_sma').shift(periods=1) - pl.col('short_sma') > 0)).then(-1)\n", | |
| " # none(0)\n", | |
| " .otherwise(0).alias('order'),\n", | |
| " ])\n", | |
| " .with_columns([ # ポジション方向(ドテン判定のため)\n", | |
| " # side\n", | |
| " pl.when(pl.col('order') != 0).then(pl.col('order'))\n", | |
| " .otherwise(None).fill_null(strategy='forward').fill_null(0).alias('side'),\n", | |
| " ])\n", | |
| " .with_columns([ # ポジション方向がドテンする単位でグループNo.を設定\n", | |
| " # doten_group\n", | |
| " (pl.col('side') * pl.col('side').shift(periods=1) < 0).cumsum().fill_null(0).alias('doten_group'),\n", | |
| " # order_cumsum\n", | |
| " pl.col('order').cumsum().alias('order_cumsum'), # ポジションサイズ計算のため、order累積和\n", | |
| " ])\n", | |
| " .with_columns([ # ドテン時にorder累積和をリセットする調整サイズ\n", | |
| " # doten_reset\n", | |
| " pl.when(pl.col('doten_group').diff(n=1, null_behavior='ignore') != 0).then(pl.col('order_cumsum').shift(periods=1) * -1)\n", | |
| " .otherwise(None).fill_null(strategy='forward').fill_null(0).alias('doten_reset'),\n", | |
| " ])\n", | |
| " .with_columns([ # ポジション計算(order累積和&調整サイズ)\n", | |
| " # pos\n", | |
| " (pl.col('order_cumsum') + pl.col('doten_reset')).alias('pos'),\n", | |
| " ])\n", | |
| " .with_columns([ # ピラミッディング回数でポジションサイズ調整\n", | |
| " # pos\n", | |
| " pl.when(pl.col('pos') > pyramid).then(1)\n", | |
| " .when(pl.col('pos') < -pyramid).then(-1)\n", | |
| " .otherwise(pl.col('pos') / pyramid).alias('pos'),\n", | |
| " ])\n", | |
| " .with_columns([ # 損益計算\n", | |
| " # return\n", | |
| " (pl.col('open').shift(periods=-1) - pl.col('open')).alias('return'),\n", | |
| " # commision\n", | |
| " (pl.col('open').shift(periods=-1) * COMMISION / 100 * abs(pl.col('pos') - pl.col('pos').shift(periods=1))).fill_null(0).alias('commision'),\n", | |
| " ])\n", | |
| " .with_columns([\n", | |
| " # profit\n", | |
| " (pl.col('return') * pl.col('pos').shift(periods=1) - pl.col('commision')).alias('profit'),\n", | |
| " ])\n", | |
| " .with_columns([\n", | |
| " # pnl\n", | |
| " (pl.col('profit').cumsum().fill_null(strategy='forward').fill_null(0)).alias('pnl'),\n", | |
| " ])\n", | |
| " .collect()\n", | |
| " )\n", | |
| "\n", | |
| " return df" | |
| ], | |
| "metadata": { | |
| "id": "JJRzi7YGPM8a" | |
| }, | |
| "execution_count": 33, | |
| "outputs": [] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### (調整版)バックテスト実行" | |
| ], | |
| "metadata": { | |
| "id": "jmbjOdA4LxNE" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# バックテスト\n", | |
| "df_result_pl2 = backtest_polars2(SHORT_SMA, LONG_SMA, PYRAMIDING, df_ohlcv_pl)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')\n", | |
| "\n", | |
| "# 結果表示\n", | |
| "display(df_result_pl2.select(pl.col(['datetime','open','high','low','close','volume','short_sma','long_sma','order','pos','return','commision','profit','pnl'])))\n", | |
| "# 結果表示(ポジション変化が有ったところだけ)\n", | |
| "#display(df_result_pl2.filter(pl.col('pos').diff(n=1, null_behavior='ignore') != 0).select(pl.col(['open','long','short','pos','pnl'])))" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 917 | |
| }, | |
| "id": "Dd4LMw3sUbrL", | |
| "outputId": "4a0826ff-5268-4a26-cf29-b7854195b82a" | |
| }, | |
| "execution_count": 39, | |
| "outputs": [ | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 38.621 ms\n", | |
| "\n" | |
| ] | |
| }, | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "shape: (105120, 14)\n", | |
| "┌───────────────┬──────────┬──────────┬──────────┬─────┬────────┬───────────┬────────┬─────────────┐\n", | |
| "│ datetime ┆ open ┆ high ┆ low ┆ ... ┆ return ┆ commision ┆ profit ┆ pnl │\n", | |
| "│ --- ┆ --- ┆ --- ┆ --- ┆ ┆ --- ┆ --- ┆ --- ┆ --- │\n", | |
| "│ datetime[ns, ┆ f64 ┆ f64 ┆ f64 ┆ ┆ f64 ┆ f64 ┆ f64 ┆ f64 │\n", | |
| "│ UTC] ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "╞═══════════════╪══════════╪══════════╪══════════╪═════╪════════╪═══════════╪════════╪═════════════╡\n", | |
| "│ 2022-01-01 ┆ 46216.93 ┆ 46391.49 ┆ 46208.37 ┆ ... ┆ 104.41 ┆ 0.0 ┆ null ┆ 0.0 │\n", | |
| "│ 00:00:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ 2022-01-01 ┆ 46321.34 ┆ 46527.26 ┆ 46280.0 ┆ ... ┆ 48.45 ┆ 0.0 ┆ 0.0 ┆ 0.0 │\n", | |
| "│ 00:05:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ 2022-01-01 ┆ 46369.79 ┆ 46394.0 ┆ 46276.22 ┆ ... ┆ -37.27 ┆ 0.0 ┆ -0.0 ┆ 0.0 │\n", | |
| "│ 00:10:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ 2022-01-01 ┆ 46332.52 ┆ 46332.52 ┆ 46236.27 ┆ ... ┆ -37.1 ┆ 0.0 ┆ -0.0 ┆ 0.0 │\n", | |
| "│ 00:15:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... ┆ ... │\n", | |
| "│ 2022-12-31 ┆ 16545.68 ┆ 16550.26 ┆ 16543.45 ┆ ... ┆ 0.46 ┆ 0.0 ┆ 0.23 ┆ 7149.158371 │\n", | |
| "│ 23:40:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ 2022-12-31 ┆ 16546.14 ┆ 16550.55 ┆ 16536.62 ┆ ... ┆ -7.75 ┆ 0.0 ┆ -3.875 ┆ 7145.283371 │\n", | |
| "│ 23:45:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ 2022-12-31 ┆ 16538.39 ┆ 16541.26 ┆ 16534.92 ┆ ... ┆ 2.03 ┆ 0.0 ┆ 1.015 ┆ 7146.298371 │\n", | |
| "│ 23:50:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "│ 2022-12-31 ┆ 16540.42 ┆ 16544.47 ┆ 16535.05 ┆ ... ┆ null ┆ 0.0 ┆ null ┆ 7146.298371 │\n", | |
| "│ 23:55:00 UTC ┆ ┆ ┆ ┆ ┆ ┆ ┆ ┆ │\n", | |
| "└───────────────┴──────────┴──────────┴──────────┴─────┴────────┴───────────┴────────┴─────────────┘" | |
| ], | |
| "text/html": [ | |
| "<div>\n", | |
| "<style>\n", | |
| ".pl-dataframe > thead > tr > th {\n", | |
| " text-align: right;\n", | |
| "}\n", | |
| "</style>\n", | |
| "\n", | |
| "<table border=\"1\" class=\"dataframe pl-dataframe\">\n", | |
| "<small>shape: (105120, 14)</small>\n", | |
| "<thead>\n", | |
| "<tr>\n", | |
| "<th>\n", | |
| "datetime\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "open\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "high\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "low\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "close\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "volume\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "short_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "long_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "order\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "pos\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "return\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "commision\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "profit\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "pnl\n", | |
| "</th>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "datetime[ns, UTC]\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "i32\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</thead>\n", | |
| "<tbody>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:00:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46216.93\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46391.49\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46208.37\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "185.67558\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "104.41\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:05:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46321.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46527.26\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46280.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46371.11\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "123.43577\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46346.225\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46346.225\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "48.45\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:10:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46369.79\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46394.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46276.22\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46332.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "77.54574\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46341.653333\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46341.653333\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-37.27\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:15:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46332.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46332.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46236.27\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46293.9\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "101.14315\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46329.715\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46329.715\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-37.1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:20:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46295.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46421.27\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46286.25\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46395.53\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "135.32479\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46342.878\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46342.878\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "100.11\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:25:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46395.53\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46400.38\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46345.1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46375.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "83.53179\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46348.301667\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46348.301667\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-20.11\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:30:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46375.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46446.47\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46360.19\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46443.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "81.82606\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46361.922857\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46361.922857\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "68.23\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:35:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46443.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46590.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46443.64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46530.7\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "113.11574\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46383.02\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46383.02\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "87.06\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:40:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46530.71\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46689.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46503.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46610.81\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "191.13897\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46408.33\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46408.33\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "80.1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:45:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46610.81\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46731.39\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46575.76\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46693.74\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "168.66367\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46436.871\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46436.871\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "82.94\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:50:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46693.75\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46708.59\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46628.6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46659.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "133.40734\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46457.123636\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46457.123636\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-34.09\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-01-01 00:55:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46659.66\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46690.16\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46630.46\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46656.13\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "108.52235\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46473.7075\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "46473.7075\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-3.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:00:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16520.28\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16524.91\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16500.24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16506.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "767.72112\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16542.4405\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16559.298085\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-14.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-7.07\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7129.158371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:05:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16506.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16514.99\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16490.78\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16495.24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "558.92871\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16539.0105\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16557.58\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-10.13\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-5.065\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7124.093371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:10:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16496.01\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16503.97\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16487.74\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16502.67\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "555.3314\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16536.248\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16556.038936\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6.66\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3.33\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7127.423371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:15:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16502.67\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16526.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16500.73\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16523.86\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "618.0961\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16534.4375\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16555.104681\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "21.19\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "10.595\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7138.018371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:20:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16523.86\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16529.54\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16520.91\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16525.92\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "302.37991\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16532.707\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16554.120638\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2.68\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1.34\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7139.358371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:25:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16526.54\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16527.01\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16517.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16524.64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "262.99128\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16531.1315\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16552.990213\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-1.89\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-0.945\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7138.413371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:30:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16524.65\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16540.59\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16520.44\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16538.17\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "429.55241\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16530.5605\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16551.932766\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "13.52\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6.76\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7145.173371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:35:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16538.17\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16551.24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16536.84\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16545.68\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "501.06148\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16530.4305\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16551.263404\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7.51\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3.755\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7148.928371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:40:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16545.68\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16550.26\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16543.45\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16546.13\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "277.70571\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16530.54\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16550.433191\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.46\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.23\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7149.158371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:45:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16546.14\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16550.55\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16536.62\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16539.05\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "292.41232\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16529.6835\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16549.552553\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-7.75\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-3.875\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7145.283371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:50:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16538.39\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16541.26\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16534.92\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16540.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "180.18579\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16528.4355\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16548.920213\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2.03\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1.015\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7146.298371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "2022-12-31 23:55:00 UTC\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16540.42\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16544.47\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16535.05\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16542.4\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "227.06684\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16528.9745\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "16548.30766\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "0.0\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "null\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "7146.298371\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ] | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## 【一括バックテスト】" | |
| ], | |
| "metadata": { | |
| "id": "MkVGGcb3LP5b" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### パラメータ組み合わせ設定\n", | |
| "短期/長期移動平均とピラミッディング回数を定義してパラメータの全組み合わせを作成" | |
| ], | |
| "metadata": { | |
| "id": "a91uES3OLZYE" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "import itertools\n", | |
| "\n", | |
| "#-----------------------------------------------------------\n", | |
| "# [パラメータリスト]\n", | |
| "SMA_LIST = [3,5,6,10,12,15,20,24,30,36,48,60,72,96,100,120,144,200,240,288] # 移動平均期間(short/long)\n", | |
| "PYRAMID_LIST = [1,2,3,4,5] # ピラミッディング(積み増し)回数\n", | |
| "#-----------------------------------------------------------\n", | |
| "\n", | |
| "# パラメータ全組み合わせ(itertools.product : 直積)\n", | |
| "df_params_pd = pd.DataFrame(list(itertools.product(SMA_LIST, SMA_LIST, PYRAMID_LIST,)),\n", | |
| " columns=['short_sma', 'long_sma', 'pyramid'])\n", | |
| "# short_sma < long_smaの組み合わせのみに絞り込み\n", | |
| "df_params_pd = df_params_pd[(df_params_pd['short_sma'] < df_params_pd['long_sma'])]\n", | |
| "# indexリセット\n", | |
| "df_params_pd.reset_index(drop=True, inplace=True)\n", | |
| "\n", | |
| "# polars DataFrameコピー\n", | |
| "df_params_pl = pl.from_pandas(df_params_pd)\n", | |
| "df_params_pl2 = df_params_pl.clone()\n", | |
| "\n", | |
| "# パラメータ組み合わせ表示\n", | |
| "display(df_params_pd)" | |
| ], | |
| "metadata": { | |
| "id": "hrmj3h-gd-Uu", | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 424 | |
| }, | |
| "outputId": "181c73dd-5b80-48d2-b1ce-0891d1f42444" | |
| }, | |
| "execution_count": 35, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| " short_sma long_sma pyramid\n", | |
| "0 3 5 1\n", | |
| "1 3 5 2\n", | |
| "2 3 5 3\n", | |
| "3 3 5 4\n", | |
| "4 3 5 5\n", | |
| ".. ... ... ...\n", | |
| "945 240 288 1\n", | |
| "946 240 288 2\n", | |
| "947 240 288 3\n", | |
| "948 240 288 4\n", | |
| "949 240 288 5\n", | |
| "\n", | |
| "[950 rows x 3 columns]" | |
| ], | |
| "text/html": [ | |
| "\n", | |
| " <div id=\"df-e36a27a8-637d-4b5b-bb6a-8f4fab0e44f4\">\n", | |
| " <div class=\"colab-df-container\">\n", | |
| " <div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>short_sma</th>\n", | |
| " <th>long_sma</th>\n", | |
| " <th>pyramid</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>3</td>\n", | |
| " <td>5</td>\n", | |
| " <td>1</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>3</td>\n", | |
| " <td>5</td>\n", | |
| " <td>2</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>3</td>\n", | |
| " <td>5</td>\n", | |
| " <td>3</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>3</th>\n", | |
| " <td>3</td>\n", | |
| " <td>5</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>4</th>\n", | |
| " <td>3</td>\n", | |
| " <td>5</td>\n", | |
| " <td>5</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>...</th>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>945</th>\n", | |
| " <td>240</td>\n", | |
| " <td>288</td>\n", | |
| " <td>1</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>946</th>\n", | |
| " <td>240</td>\n", | |
| " <td>288</td>\n", | |
| " <td>2</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>947</th>\n", | |
| " <td>240</td>\n", | |
| " <td>288</td>\n", | |
| " <td>3</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>948</th>\n", | |
| " <td>240</td>\n", | |
| " <td>288</td>\n", | |
| " <td>4</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>949</th>\n", | |
| " <td>240</td>\n", | |
| " <td>288</td>\n", | |
| " <td>5</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "<p>950 rows × 3 columns</p>\n", | |
| "</div>\n", | |
| " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-e36a27a8-637d-4b5b-bb6a-8f4fab0e44f4')\"\n", | |
| " title=\"Convert this dataframe to an interactive table.\"\n", | |
| " style=\"display:none;\">\n", | |
| " \n", | |
| " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", | |
| " width=\"24px\">\n", | |
| " <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n", | |
| " <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n", | |
| " </svg>\n", | |
| " </button>\n", | |
| " \n", | |
| " <style>\n", | |
| " .colab-df-container {\n", | |
| " display:flex;\n", | |
| " flex-wrap:wrap;\n", | |
| " gap: 12px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert {\n", | |
| " background-color: #E8F0FE;\n", | |
| " border: none;\n", | |
| " border-radius: 50%;\n", | |
| " cursor: pointer;\n", | |
| " display: none;\n", | |
| " fill: #1967D2;\n", | |
| " height: 32px;\n", | |
| " padding: 0 0 0 0;\n", | |
| " width: 32px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert:hover {\n", | |
| " background-color: #E2EBFA;\n", | |
| " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
| " fill: #174EA6;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert {\n", | |
| " background-color: #3B4455;\n", | |
| " fill: #D2E3FC;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert:hover {\n", | |
| " background-color: #434B5C;\n", | |
| " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
| " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
| " fill: #FFFFFF;\n", | |
| " }\n", | |
| " </style>\n", | |
| "\n", | |
| " <script>\n", | |
| " const buttonEl =\n", | |
| " document.querySelector('#df-e36a27a8-637d-4b5b-bb6a-8f4fab0e44f4 button.colab-df-convert');\n", | |
| " buttonEl.style.display =\n", | |
| " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
| "\n", | |
| " async function convertToInteractive(key) {\n", | |
| " const element = document.querySelector('#df-e36a27a8-637d-4b5b-bb6a-8f4fab0e44f4');\n", | |
| " const dataTable =\n", | |
| " await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
| " [key], {});\n", | |
| " if (!dataTable) return;\n", | |
| "\n", | |
| " const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
| " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
| " + ' to learn more about interactive tables.';\n", | |
| " element.innerHTML = '';\n", | |
| " dataTable['output_type'] = 'display_data';\n", | |
| " await google.colab.output.renderOutput(dataTable, element);\n", | |
| " const docLink = document.createElement('div');\n", | |
| " docLink.innerHTML = docLinkHtml;\n", | |
| " element.appendChild(docLink);\n", | |
| " }\n", | |
| " </script>\n", | |
| " </div>\n", | |
| " </div>\n", | |
| " " | |
| ] | |
| }, | |
| "metadata": {} | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "## 【apply一括処理】\n", | |
| "パラメータ組み合わせDataFrameにバックテスト関数を適用して総当りバックテストを行う" | |
| ], | |
| "metadata": { | |
| "id": "w50NIBOaMBLT" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### pandas" | |
| ], | |
| "metadata": { | |
| "id": "UCDNmQ2oMKgj" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### 一括バックテスト実行" | |
| ], | |
| "metadata": { | |
| "id": "K-wHU70nORuh" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# パラメータ組み合わせにストラテジーを適用\n", | |
| "result = df_params_pd.apply(lambda c: backtest_pandas(c['short_sma'], c['long_sma'], c['pyramid'],)['pnl'].values[-1], axis=1)\n", | |
| "df_params_pd['result'] = result\n", | |
| "df_params_pd = df_params_pd.sort_values('result') # result昇順ソート\n", | |
| "\n", | |
| "# テスト結果表示\n", | |
| "display(df_params_pd)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 458 | |
| }, | |
| "id": "CvzrpVlzvPd7", | |
| "outputId": "5a5ac0e4-2564-4dc4-ec0b-9d2b7901f12a" | |
| }, | |
| "execution_count": 36, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| " short_sma long_sma pyramid result\n", | |
| "95 5 6 1 -302595.554868\n", | |
| "96 5 6 2 -231074.405474\n", | |
| "0 3 5 1 -207403.641505\n", | |
| "270 10 12 1 -187248.424130\n", | |
| "97 5 6 3 -179552.447503\n", | |
| ".. ... ... ... ...\n", | |
| "672 30 288 3 30100.642723\n", | |
| "585 24 96 1 30237.233825\n", | |
| "671 30 288 2 31857.628859\n", | |
| "795 60 200 1 38669.454905\n", | |
| "260 6 240 1 40097.612877\n", | |
| "\n", | |
| "[950 rows x 4 columns]" | |
| ], | |
| "text/html": [ | |
| "\n", | |
| " <div id=\"df-2faaede5-5a33-462e-8946-d4dd2f27378a\">\n", | |
| " <div class=\"colab-df-container\">\n", | |
| " <div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>short_sma</th>\n", | |
| " <th>long_sma</th>\n", | |
| " <th>pyramid</th>\n", | |
| " <th>result</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>95</th>\n", | |
| " <td>5</td>\n", | |
| " <td>6</td>\n", | |
| " <td>1</td>\n", | |
| " <td>-302595.554868</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>96</th>\n", | |
| " <td>5</td>\n", | |
| " <td>6</td>\n", | |
| " <td>2</td>\n", | |
| " <td>-231074.405474</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>3</td>\n", | |
| " <td>5</td>\n", | |
| " <td>1</td>\n", | |
| " <td>-207403.641505</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>270</th>\n", | |
| " <td>10</td>\n", | |
| " <td>12</td>\n", | |
| " <td>1</td>\n", | |
| " <td>-187248.424130</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>97</th>\n", | |
| " <td>5</td>\n", | |
| " <td>6</td>\n", | |
| " <td>3</td>\n", | |
| " <td>-179552.447503</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>...</th>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " <td>...</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>672</th>\n", | |
| " <td>30</td>\n", | |
| " <td>288</td>\n", | |
| " <td>3</td>\n", | |
| " <td>30100.642723</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>585</th>\n", | |
| " <td>24</td>\n", | |
| " <td>96</td>\n", | |
| " <td>1</td>\n", | |
| " <td>30237.233825</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>671</th>\n", | |
| " <td>30</td>\n", | |
| " <td>288</td>\n", | |
| " <td>2</td>\n", | |
| " <td>31857.628859</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>795</th>\n", | |
| " <td>60</td>\n", | |
| " <td>200</td>\n", | |
| " <td>1</td>\n", | |
| " <td>38669.454905</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>260</th>\n", | |
| " <td>6</td>\n", | |
| " <td>240</td>\n", | |
| " <td>1</td>\n", | |
| " <td>40097.612877</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "<p>950 rows × 4 columns</p>\n", | |
| "</div>\n", | |
| " <button class=\"colab-df-convert\" onclick=\"convertToInteractive('df-2faaede5-5a33-462e-8946-d4dd2f27378a')\"\n", | |
| " title=\"Convert this dataframe to an interactive table.\"\n", | |
| " style=\"display:none;\">\n", | |
| " \n", | |
| " <svg xmlns=\"http://www.w3.org/2000/svg\" height=\"24px\"viewBox=\"0 0 24 24\"\n", | |
| " width=\"24px\">\n", | |
| " <path d=\"M0 0h24v24H0V0z\" fill=\"none\"/>\n", | |
| " <path d=\"M18.56 5.44l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94zm-11 1L8.5 8.5l.94-2.06 2.06-.94-2.06-.94L8.5 2.5l-.94 2.06-2.06.94zm10 10l.94 2.06.94-2.06 2.06-.94-2.06-.94-.94-2.06-.94 2.06-2.06.94z\"/><path d=\"M17.41 7.96l-1.37-1.37c-.4-.4-.92-.59-1.43-.59-.52 0-1.04.2-1.43.59L10.3 9.45l-7.72 7.72c-.78.78-.78 2.05 0 2.83L4 21.41c.39.39.9.59 1.41.59.51 0 1.02-.2 1.41-.59l7.78-7.78 2.81-2.81c.8-.78.8-2.07 0-2.86zM5.41 20L4 18.59l7.72-7.72 1.47 1.35L5.41 20z\"/>\n", | |
| " </svg>\n", | |
| " </button>\n", | |
| " \n", | |
| " <style>\n", | |
| " .colab-df-container {\n", | |
| " display:flex;\n", | |
| " flex-wrap:wrap;\n", | |
| " gap: 12px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert {\n", | |
| " background-color: #E8F0FE;\n", | |
| " border: none;\n", | |
| " border-radius: 50%;\n", | |
| " cursor: pointer;\n", | |
| " display: none;\n", | |
| " fill: #1967D2;\n", | |
| " height: 32px;\n", | |
| " padding: 0 0 0 0;\n", | |
| " width: 32px;\n", | |
| " }\n", | |
| "\n", | |
| " .colab-df-convert:hover {\n", | |
| " background-color: #E2EBFA;\n", | |
| " box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);\n", | |
| " fill: #174EA6;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert {\n", | |
| " background-color: #3B4455;\n", | |
| " fill: #D2E3FC;\n", | |
| " }\n", | |
| "\n", | |
| " [theme=dark] .colab-df-convert:hover {\n", | |
| " background-color: #434B5C;\n", | |
| " box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);\n", | |
| " filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));\n", | |
| " fill: #FFFFFF;\n", | |
| " }\n", | |
| " </style>\n", | |
| "\n", | |
| " <script>\n", | |
| " const buttonEl =\n", | |
| " document.querySelector('#df-2faaede5-5a33-462e-8946-d4dd2f27378a button.colab-df-convert');\n", | |
| " buttonEl.style.display =\n", | |
| " google.colab.kernel.accessAllowed ? 'block' : 'none';\n", | |
| "\n", | |
| " async function convertToInteractive(key) {\n", | |
| " const element = document.querySelector('#df-2faaede5-5a33-462e-8946-d4dd2f27378a');\n", | |
| " const dataTable =\n", | |
| " await google.colab.kernel.invokeFunction('convertToInteractive',\n", | |
| " [key], {});\n", | |
| " if (!dataTable) return;\n", | |
| "\n", | |
| " const docLinkHtml = 'Like what you see? Visit the ' +\n", | |
| " '<a target=\"_blank\" href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook</a>'\n", | |
| " + ' to learn more about interactive tables.';\n", | |
| " element.innerHTML = '';\n", | |
| " dataTable['output_type'] = 'display_data';\n", | |
| " await google.colab.output.renderOutput(dataTable, element);\n", | |
| " const docLink = document.createElement('div');\n", | |
| " docLink.innerHTML = docLinkHtml;\n", | |
| " element.appendChild(docLink);\n", | |
| " }\n", | |
| " </script>\n", | |
| " </div>\n", | |
| " </div>\n", | |
| " " | |
| ] | |
| }, | |
| "metadata": {} | |
| }, | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 57940.527 ms\n", | |
| "\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "### polars" | |
| ], | |
| "metadata": { | |
| "id": "4LMe81_SMNJ7" | |
| } | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### 一括バックテスト実行" | |
| ], | |
| "metadata": { | |
| "id": "9xRsOmLqOcIg" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# パラメータ組み合わせにストラテジーを適用\n", | |
| "df_params_pl = (\n", | |
| " df_params_pl.lazy()\n", | |
| " .with_columns(\n", | |
| " pl.struct(['short_sma', 'long_sma', 'pyramid',])\n", | |
| " .apply(lambda c: backtest_polars(c['short_sma'], c['long_sma'], c['pyramid'],).get_column('pnl')[-1])\n", | |
| " .alias('result')\n", | |
| " )\n", | |
| " .sort(pl.col('result')) # result昇順ソート\n", | |
| " .collect()\n", | |
| ")\n", | |
| "\n", | |
| "# テスト結果表示\n", | |
| "display(df_params_pl)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 917 | |
| }, | |
| "id": "oJVh_TcsylGE", | |
| "outputId": "43be4a28-5396-4f0e-afeb-b5c2e4a06707" | |
| }, | |
| "execution_count": 37, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "shape: (950, 4)\n", | |
| "┌───────────┬──────────┬─────────┬────────────────┐\n", | |
| "│ short_sma ┆ long_sma ┆ pyramid ┆ result │\n", | |
| "│ --- ┆ --- ┆ --- ┆ --- │\n", | |
| "│ i64 ┆ i64 ┆ i64 ┆ f64 │\n", | |
| "╞═══════════╪══════════╪═════════╪════════════════╡\n", | |
| "│ 5 ┆ 6 ┆ 1 ┆ -302595.554868 │\n", | |
| "│ 5 ┆ 6 ┆ 2 ┆ -231074.405474 │\n", | |
| "│ 3 ┆ 5 ┆ 1 ┆ -207047.34376 │\n", | |
| "│ 10 ┆ 12 ┆ 1 ┆ -187248.42413 │\n", | |
| "│ ... ┆ ... ┆ ... ┆ ... │\n", | |
| "│ 24 ┆ 96 ┆ 1 ┆ 30237.233825 │\n", | |
| "│ 30 ┆ 288 ┆ 2 ┆ 31857.628859 │\n", | |
| "│ 60 ┆ 200 ┆ 1 ┆ 38669.454905 │\n", | |
| "│ 6 ┆ 240 ┆ 1 ┆ 40097.612877 │\n", | |
| "└───────────┴──────────┴─────────┴────────────────┘" | |
| ], | |
| "text/html": [ | |
| "<div>\n", | |
| "<style>\n", | |
| ".pl-dataframe > thead > tr > th {\n", | |
| " text-align: right;\n", | |
| "}\n", | |
| "</style>\n", | |
| "\n", | |
| "<table border=\"1\" class=\"dataframe pl-dataframe\">\n", | |
| "<small>shape: (950, 4)</small>\n", | |
| "<thead>\n", | |
| "<tr>\n", | |
| "<th>\n", | |
| "short_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "long_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "pyramid\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "result\n", | |
| "</th>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</thead>\n", | |
| "<tbody>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-302595.554868\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-231074.405474\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-207047.34376\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-187248.42413\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-179535.453592\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-179081.129635\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-163407.166508\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-159644.689164\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "4\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-143044.280792\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-137645.271559\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-134197.730481\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "15\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-128849.745035\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28019.389825\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "4\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28252.992011\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "100\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28719.090037\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28763.298202\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "60\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28803.986696\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "72\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "240\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28855.750183\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "96\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "29394.99565\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "30100.642723\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "96\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "30237.233825\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "31857.628859\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "60\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "38669.454905\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "240\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "40097.612877\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ] | |
| }, | |
| "metadata": {} | |
| }, | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 36584.938 ms\n", | |
| "\n" | |
| ] | |
| } | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "source": [ | |
| "#### (調整版)一括バックテスト実行" | |
| ], | |
| "metadata": { | |
| "id": "io5YfkKwOeEo" | |
| } | |
| }, | |
| { | |
| "cell_type": "code", | |
| "source": [ | |
| "s = time.time()\n", | |
| "\n", | |
| "# パラメータ組み合わせにストラテジーを適用\n", | |
| "df_params_pl2 = (\n", | |
| " df_params_pl2.lazy()\n", | |
| " .with_columns(\n", | |
| " pl.struct(['short_sma', 'long_sma', 'pyramid',])\n", | |
| " .apply(lambda c: backtest_polars2(c['short_sma'], c['long_sma'], c['pyramid'],).get_column('pnl')[-1])\n", | |
| " .alias('result')\n", | |
| " )\n", | |
| " .sort(pl.col('result')) # result昇順ソート\n", | |
| " .collect()\n", | |
| ")\n", | |
| "\n", | |
| "# テスト結果表示\n", | |
| "display(df_params_pl2)\n", | |
| "\n", | |
| "ret = round((time.time() - s) * 1000, 3)\n", | |
| "print(f'[処理時間]: {ret} ms\\n')" | |
| ], | |
| "metadata": { | |
| "colab": { | |
| "base_uri": "https://localhost:8080/", | |
| "height": 917 | |
| }, | |
| "id": "r8yEU7EuGtTD", | |
| "outputId": "f63fcaa9-cf8a-4efd-868f-cee92de4c01d" | |
| }, | |
| "execution_count": 38, | |
| "outputs": [ | |
| { | |
| "output_type": "display_data", | |
| "data": { | |
| "text/plain": [ | |
| "shape: (950, 4)\n", | |
| "┌───────────┬──────────┬─────────┬────────────────┐\n", | |
| "│ short_sma ┆ long_sma ┆ pyramid ┆ result │\n", | |
| "│ --- ┆ --- ┆ --- ┆ --- │\n", | |
| "│ i64 ┆ i64 ┆ i64 ┆ f64 │\n", | |
| "╞═══════════╪══════════╪═════════╪════════════════╡\n", | |
| "│ 5 ┆ 6 ┆ 1 ┆ -302595.554868 │\n", | |
| "│ 5 ┆ 6 ┆ 2 ┆ -231074.405474 │\n", | |
| "│ 3 ┆ 5 ┆ 1 ┆ -207047.34376 │\n", | |
| "│ 10 ┆ 12 ┆ 1 ┆ -187248.42413 │\n", | |
| "│ ... ┆ ... ┆ ... ┆ ... │\n", | |
| "│ 24 ┆ 96 ┆ 1 ┆ 30237.233825 │\n", | |
| "│ 30 ┆ 288 ┆ 2 ┆ 31857.628859 │\n", | |
| "│ 60 ┆ 200 ┆ 1 ┆ 38669.454905 │\n", | |
| "│ 6 ┆ 240 ┆ 1 ┆ 40097.612877 │\n", | |
| "└───────────┴──────────┴─────────┴────────────────┘" | |
| ], | |
| "text/html": [ | |
| "<div>\n", | |
| "<style>\n", | |
| ".pl-dataframe > thead > tr > th {\n", | |
| " text-align: right;\n", | |
| "}\n", | |
| "</style>\n", | |
| "\n", | |
| "<table border=\"1\" class=\"dataframe pl-dataframe\">\n", | |
| "<small>shape: (950, 4)</small>\n", | |
| "<thead>\n", | |
| "<tr>\n", | |
| "<th>\n", | |
| "short_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "long_sma\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "pyramid\n", | |
| "</th>\n", | |
| "<th>\n", | |
| "result\n", | |
| "</th>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "i64\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "f64\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</thead>\n", | |
| "<tbody>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-302595.554868\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-231074.405474\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-207047.34376\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-187248.42413\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-179535.453592\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-179081.129635\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-163407.166508\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-159644.689164\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "5\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "4\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-143044.280792\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-137645.271559\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-134197.730481\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "12\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "15\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "-128849.745035\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "...\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "10\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28019.389825\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "4\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28252.992011\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "100\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28719.090037\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28763.298202\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "60\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28803.986696\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "72\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "240\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "28855.750183\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "96\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "29394.99565\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "3\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "30100.642723\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "24\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "96\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "30237.233825\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "30\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "288\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "2\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "31857.628859\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "60\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "200\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "38669.454905\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "<tr>\n", | |
| "<td>\n", | |
| "6\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "240\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "1\n", | |
| "</td>\n", | |
| "<td>\n", | |
| "40097.612877\n", | |
| "</td>\n", | |
| "</tr>\n", | |
| "</tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ] | |
| }, | |
| "metadata": {} | |
| }, | |
| { | |
| "output_type": "stream", | |
| "name": "stdout", | |
| "text": [ | |
| "[処理時間]: 35160.366 ms\n", | |
| "\n" | |
| ] | |
| } | |
| ] | |
| } | |
| ] | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment