Last active
December 13, 2022 03:16
-
-
Save nagishin/8c6210cc96d4128cef97dbec721a39c1 to your computer and use it in GitHub Desktop.
Colaboratoryで簡易バックテスト.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": { | |
"name": "Colaboratoryで簡易バックテスト.ipynb", | |
"provenance": [], | |
"collapsed_sections": [], | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/nagishin/8c6210cc96d4128cef97dbec721a39c1/.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "h6unEC0UyEd8", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# pandas applyで簡易バックテスト\n", | |
"\n", | |
"1. テスト対象期間のデータ取得\n", | |
"2. テストパラメータ組み合わせ作成\n", | |
"3. テストするストラテジー定義\n", | |
"4. テスト実行\n", | |
"5. 各パラメータ別のテスト結果表示\n", | |
"6. 最大パフォーマンスの損益推移を表示\n", | |
"\n", | |
"* [テストデータ]<br>\n", | |
"BitMEX 1時間足 2020-01-01~2020-08-06のOHLCV<br>\n", | |
"\n", | |
"* [テストストラテジー]<br>\n", | |
"OHLCV終値の短期SMAと長期SMAのゴールデンクロス/デッドクロスでドテン注文を繰り返す<br>\n", | |
"\n", | |
"* [パラメータ]<br>\n", | |
"短期/長期SMAそれぞれの移動平均期間<br>\n" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "qVKQVmMZzk-b", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# 1.テスト対象期間のデータ取得\n", | |
"\n", | |
"BitMEX REST APIにてOHLCVデータを取得する\n", | |
"\n", | |
"* PERIOD : 時間足(分)\n", | |
"* FROM : テスト期間(開始)\n", | |
"* TO : テスト期間(終了)\n", | |
"* PRE_BARS : 開始前取得期間(MA計算用)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "jCqgSxt-w6iF", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 450 | |
}, | |
"outputId": "afafc44e-eb8d-4794-af74-60925731be8b" | |
}, | |
"source": [ | |
"# coding: utf-8\n", | |
"import time\n", | |
"import requests\n", | |
"from datetime import datetime\n", | |
"from collections import OrderedDict\n", | |
"import numpy as np\n", | |
"import pandas as pd\n", | |
"pd.set_option(\"display.max_rows\", 10)\n", | |
"\n", | |
"#-----------------------------------------------------------\n", | |
"# [テスト対象期間設定]\n", | |
"PERIOD = 60 # 時間足(分) 1/5/60/1440\n", | |
"FROM = \"2020/01/01 00:00:00\" # テスト開始時刻\n", | |
"TO = \"2020/08/06 00:00:00\" # テスト終了時刻\n", | |
"PRE_BARS = 200 # 開始前取得期間数(MA計算用)\n", | |
"#-----------------------------------------------------------\n", | |
"\n", | |
"# BitMEX OHLCVデータ取得\n", | |
"from_ut = datetime.strptime(FROM + \"+0900\", \"%Y/%m/%d %H:%M:%S%z\").timestamp()\n", | |
"to_ut = datetime.strptime(TO + \"+0900\", \"%Y/%m/%d %H:%M:%S%z\").timestamp()\n", | |
"to_time = int(to_ut)\n", | |
"from_time = int(from_ut) - PRE_BARS * PERIOD * 60\n", | |
"param = {\"period\": PERIOD, \"from\": from_time, \"to\": to_time}\n", | |
"url = \"https://www.bitmex.com/api/udf/history?symbol=XBTUSD&resolution={period}&from={from}&to={to}\".format(**param)\n", | |
"data = requests.get(url).json()\n", | |
"df_ohlcv = pd.DataFrame( \\\n", | |
" OrderedDict(timestamp=data[\"t\"], open=data[\"o\"], high=data[\"h\"], \\\n", | |
" low=data[\"l\"], close=data[\"c\"], volume=data[\"v\"]))\n", | |
"\n", | |
"# UnixTimeから日付変換してindexに設定\n", | |
"df_ohlcv[\"datetime\"] = pd.to_datetime(df_ohlcv[\"timestamp\"], unit=\"s\")\n", | |
"df_ohlcv = df_ohlcv.set_index(\"datetime\")\n", | |
"df_ohlcv.index = df_ohlcv.index.tz_localize(\"UTC\")\n", | |
"df_ohlcv.index = df_ohlcv.index.tz_convert(\"Asia/Tokyo\")\n", | |
"\n", | |
"# 取得結果表示\n", | |
"display(df_ohlcv)" | |
], | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/html": [ | |
"<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", | |
" <tr>\n", | |
" <th>datetime</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>2019-12-23 15:00:00+09:00</th>\n", | |
" <td>1577080800</td>\n", | |
" <td>7555.0</td>\n", | |
" <td>7559.0</td>\n", | |
" <td>7463.5</td>\n", | |
" <td>7482.5</td>\n", | |
" <td>149944245</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2019-12-23 16:00:00+09:00</th>\n", | |
" <td>1577084400</td>\n", | |
" <td>7482.5</td>\n", | |
" <td>7521.5</td>\n", | |
" <td>7479.0</td>\n", | |
" <td>7510.5</td>\n", | |
" <td>70737962</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2019-12-23 17:00:00+09:00</th>\n", | |
" <td>1577088000</td>\n", | |
" <td>7510.5</td>\n", | |
" <td>7542.0</td>\n", | |
" <td>7500.0</td>\n", | |
" <td>7535.0</td>\n", | |
" <td>49674990</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2019-12-23 18:00:00+09:00</th>\n", | |
" <td>1577091600</td>\n", | |
" <td>7535.0</td>\n", | |
" <td>7539.0</td>\n", | |
" <td>7512.0</td>\n", | |
" <td>7537.5</td>\n", | |
" <td>40319992</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2019-12-23 19:00:00+09:00</th>\n", | |
" <td>1577095200</td>\n", | |
" <td>7537.5</td>\n", | |
" <td>7549.5</td>\n", | |
" <td>7520.0</td>\n", | |
" <td>7527.0</td>\n", | |
" <td>43648204</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>2020-08-05 20:00:00+09:00</th>\n", | |
" <td>1596625200</td>\n", | |
" <td>11405.0</td>\n", | |
" <td>11465.0</td>\n", | |
" <td>11400.5</td>\n", | |
" <td>11453.0</td>\n", | |
" <td>68161961</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 21:00:00+09:00</th>\n", | |
" <td>1596628800</td>\n", | |
" <td>11453.0</td>\n", | |
" <td>11608.0</td>\n", | |
" <td>11406.5</td>\n", | |
" <td>11582.0</td>\n", | |
" <td>196546136</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 22:00:00+09:00</th>\n", | |
" <td>1596632400</td>\n", | |
" <td>11582.0</td>\n", | |
" <td>11639.0</td>\n", | |
" <td>11564.5</td>\n", | |
" <td>11630.0</td>\n", | |
" <td>155227124</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 23:00:00+09:00</th>\n", | |
" <td>1596636000</td>\n", | |
" <td>11630.0</td>\n", | |
" <td>11660.0</td>\n", | |
" <td>11520.5</td>\n", | |
" <td>11633.5</td>\n", | |
" <td>169126573</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-06 00:00:00+09:00</th>\n", | |
" <td>1596639600</td>\n", | |
" <td>11633.5</td>\n", | |
" <td>11704.0</td>\n", | |
" <td>11611.5</td>\n", | |
" <td>11675.5</td>\n", | |
" <td>141099720</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5434 rows × 6 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" timestamp open ... close volume\n", | |
"datetime ... \n", | |
"2019-12-23 15:00:00+09:00 1577080800 7555.0 ... 7482.5 149944245\n", | |
"2019-12-23 16:00:00+09:00 1577084400 7482.5 ... 7510.5 70737962\n", | |
"2019-12-23 17:00:00+09:00 1577088000 7510.5 ... 7535.0 49674990\n", | |
"2019-12-23 18:00:00+09:00 1577091600 7535.0 ... 7537.5 40319992\n", | |
"2019-12-23 19:00:00+09:00 1577095200 7537.5 ... 7527.0 43648204\n", | |
"... ... ... ... ... ...\n", | |
"2020-08-05 20:00:00+09:00 1596625200 11405.0 ... 11453.0 68161961\n", | |
"2020-08-05 21:00:00+09:00 1596628800 11453.0 ... 11582.0 196546136\n", | |
"2020-08-05 22:00:00+09:00 1596632400 11582.0 ... 11630.0 155227124\n", | |
"2020-08-05 23:00:00+09:00 1596636000 11630.0 ... 11633.5 169126573\n", | |
"2020-08-06 00:00:00+09:00 1596639600 11633.5 ... 11675.5 141099720\n", | |
"\n", | |
"[5434 rows x 6 columns]" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "yhXWZucA6n-C", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# 2.テストパラメータ組み合わせ作成\n", | |
"短期/長期SMAに設定する期間数のリストを作成し、その全パラメータ組み合わせを作成する\n", | |
"\n", | |
"* SHORT_TERM : 短期SMA期間リスト\n", | |
"* LONG_TERM : 長期SMA期間リスト" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "2bapyoDXz5ac", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 419 | |
}, | |
"outputId": "203faed6-8141-49ae-ca46-1097c4f81609" | |
}, | |
"source": [ | |
"import itertools\n", | |
"\n", | |
"#-----------------------------------------------------------\n", | |
"# [パラメータリスト]\n", | |
"SHORT_TERM = [4, 6, 8, 10, 12, 16, 20, 24, 30, 48, 50, 72, 100, 150] # 短期SMA期間\n", | |
"LONG_TERM = [8, 10, 12, 16, 20, 24, 30, 48, 50, 72, 100, 150, 200] # 長期SMA期間\n", | |
"#-----------------------------------------------------------\n", | |
"\n", | |
"# パラメータ全組み合わせ(itertools.product : 直積)\n", | |
"df_params = pd.DataFrame(list(itertools.product(SHORT_TERM, LONG_TERM)), \\\n", | |
" columns=[\"short\", \"long\"])\n", | |
"# SHORT < LONGの組み合わせのみに絞り込み\n", | |
"df_params = df_params[(df_params[\"short\"] < df_params[\"long\"])]\n", | |
"# indexリセット\n", | |
"df_params.reset_index(drop=True, inplace=True)\n", | |
"\n", | |
"# パラメータ組み合わせ表示\n", | |
"display(df_params)" | |
], | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/html": [ | |
"<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</th>\n", | |
" <th>long</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>4</td>\n", | |
" <td>8</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>4</td>\n", | |
" <td>10</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>4</td>\n", | |
" <td>12</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>4</td>\n", | |
" <td>16</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>4</td>\n", | |
" <td>20</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>...</th>\n", | |
" <td>...</td>\n", | |
" <td>...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>99</th>\n", | |
" <td>72</td>\n", | |
" <td>150</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>100</th>\n", | |
" <td>72</td>\n", | |
" <td>200</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>101</th>\n", | |
" <td>100</td>\n", | |
" <td>150</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>102</th>\n", | |
" <td>100</td>\n", | |
" <td>200</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>103</th>\n", | |
" <td>150</td>\n", | |
" <td>200</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>104 rows × 2 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" short long\n", | |
"0 4 8\n", | |
"1 4 10\n", | |
"2 4 12\n", | |
"3 4 16\n", | |
"4 4 20\n", | |
".. ... ...\n", | |
"99 72 150\n", | |
"100 72 200\n", | |
"101 100 150\n", | |
"102 100 200\n", | |
"103 150 200\n", | |
"\n", | |
"[104 rows x 2 columns]" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "lvY8TVZg8svJ", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# 3.テストするストラテジー定義\n", | |
"df_params.apply()に適用するストラテジー関数を定義します。<br>\n", | |
"apply関数のargsにdf_ohlcvを設定するのでストラテジー内で使用することができます。<br>\n", | |
"\n", | |
"[params]\n", | |
"* params : テストパラメータ(df_paramsの各行データ)\n", | |
"* ohlcv : テストデータ(df_ohlcv)\n", | |
"\n", | |
"[returns]\n", | |
"* total_pl : トータル損益値幅\n", | |
"* total_trades : トータルトレード回数\n", | |
"* lst_pl : 期間毎の損益値幅リスト" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "SbeWtSHI8ZqP", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"# ストラテジー定義\n", | |
"def strategy(params, ohlcv):\n", | |
"\n", | |
" #-----------------------------------------------------------\n", | |
" FEE = 0.075 # 取引手数料(%) BitMEX Taker:0.075/Maker:-0.025\n", | |
" #-----------------------------------------------------------\n", | |
"\n", | |
" # 現在ポジションの約定価格とポジション方向\n", | |
" position = {\"price\":0, \"side\":0} # side: 0-> no, -1->short, 1->long\n", | |
" # トレード回数\n", | |
" total_trades = 0\n", | |
" # 期間毎の損益値幅\n", | |
" lst_pl = []\n", | |
"\n", | |
" # 終値(close)の短期/長期SMAをそれぞれ算出\n", | |
" # ([PRE_BARS:]はSMA計算のために余分に取得した期間のため除去)\n", | |
" close = ohlcv[\"close\"].values[PRE_BARS:]\n", | |
" # 短期SMA\n", | |
" sma_s = ohlcv[\"close\"].rolling(window=params[\"short\"], min_periods=1).mean().values[PRE_BARS:]\n", | |
" # 長期SMA\n", | |
" sma_l = ohlcv[\"close\"].rolling(window=params[\"long\"], min_periods=1).mean().values[PRE_BARS:]\n", | |
"\n", | |
" # 全期間分を順次判定していく\n", | |
" # 短期SMAと長期SMAのゴールデンクロス/デッドクロスでドテン注文を繰り返す\n", | |
" for i in range(len(close) - 1):\n", | |
" pl = 0 # 損益値幅\n", | |
" fee = round(close[i] * FEE / 100, 2)\n", | |
"\n", | |
" # アップトレンド判定 (短期 > 長期)\n", | |
" if (sma_s[i] > sma_l[i]):\n", | |
" if position[\"side\"] == 0:\n", | |
" # ポジションなし ⇒ Longエントリー\n", | |
" pl = -fee\n", | |
" position = {\"price\":close[i], \"side\":1}\n", | |
" total_trades += 1\n", | |
" elif position[\"side\"] == -1:\n", | |
" # ショートポジション ⇒ ドテンロング\n", | |
" pl = position[\"price\"] - close[i] - fee # ポジション約定価格と終値から損益値幅計算\n", | |
" position = {\"price\":close[i], \"side\":1} # Longポジション設定\n", | |
" total_trades += 1\n", | |
"\n", | |
" # ダウントレンド判定 (短期 < 長期)\n", | |
" elif (sma_s[i] < sma_l[i]):\n", | |
" if position[\"side\"] == 0:\n", | |
" # ポジションなし ⇒ Shortエントリー\n", | |
" pl = -fee\n", | |
" position = {\"price\":close[i], \"side\":-1}\n", | |
" total_trades += 1\n", | |
" elif position[\"side\"] == 1:\n", | |
" # ロングポジション ⇒ ドテンショート\n", | |
" pl = close[i] - position[\"price\"] - fee # ポジション約定価格と終値から損益値幅計算\n", | |
" position = {\"price\":close[i], \"side\":-1} # Shortポジション設定\n", | |
" total_trades += 1\n", | |
"\n", | |
" # 損益値幅リスト追加\n", | |
" lst_pl.append(pl)\n", | |
" \n", | |
" # 最後にポジションクローズ\n", | |
" fee = round(close[-1] * FEE / 100, 2)\n", | |
" if position[\"side\"] == -1:\n", | |
" lst_pl.append(position[\"price\"] - close[-1] - fee)\n", | |
" total_trades += 1\n", | |
" elif position[\"side\"] == 1:\n", | |
" lst_pl.append(close[-1] - position[\"price\"] - fee)\n", | |
" total_trades += 1\n", | |
" else:\n", | |
" lst_pl.append(0)\n", | |
"\n", | |
" # トータルPL(獲得値幅)とPL推移リストをreturn\n", | |
" return sum(lst_pl), total_trades, lst_pl\n" | |
], | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "sh8UnuQTCbPa", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# 4.テスト実行\n", | |
"各パラメータ組み合わせに対して定義したテストストラテジーを適用します。<br>\n", | |
"また、ストラテジー引数にテスト期間のohlcvデータを渡します。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "WgWKCU8QCY7j", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 238 | |
}, | |
"outputId": "9146cc10-d911-49f6-f754-2bd6c157f2a8" | |
}, | |
"source": [ | |
"# パラメータ組み合わせにストラテジーを適用\n", | |
"result = df_params.apply(strategy, axis=1, args=(df_ohlcv,))\n", | |
"\n", | |
"# テスト結果表示\n", | |
"print(\"パラメータNo. (トータル損益値幅, トータルトレード回数, [期間毎の損益値幅リスト])\")\n", | |
"display(result)" | |
], | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": [ | |
"パラメータNo. (トータル損益値幅, トータルトレード回数, [期間毎の損益値幅リスト])\n" | |
], | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"0 (-4806.880000000004, 782, [-5.41, -42.88, 0, 0...\n", | |
"1 (-6986.920000000003, 653, [-5.41, 0, 0, 0, 0, ...\n", | |
"2 (-4389.630000000001, 548, [-5.41, -42.88, 0, 0...\n", | |
"3 (-4365.050000000002, 437, [-5.41, 0, 0, 0, 0, ...\n", | |
"4 (-414.4599999999997, 367, [-5.41, 0, 0, 0, 0, ...\n", | |
" ... \n", | |
"99 (-1257.6599999999996, 43, [-5.41, 0, 0, 0, 0, ...\n", | |
"100 (-51.74000000000024, 38, [-5.41, 0, 0, 0, 0, 0...\n", | |
"101 (-559.7799999999997, 48, [-5.41, 0, 0, 0, 0, 0...\n", | |
"102 (1810.17, 34, [-5.41, 0, 0, 0, 0, 0, 0, 0, 0, ...\n", | |
"103 (2860.73, 37, [-5.41, 0, 0, 0, 0, 0, 0, 0, 0, ...\n", | |
"Length: 104, dtype: object" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "LtQ0pnHAC7MK", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# 5.各パラメータ別のテスト結果表示\n", | |
"パラメータ毎のトータル損益値幅を散布図にて表示する" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "hO7h7uuHClcp", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 667 | |
}, | |
"outputId": "2e8021d8-8165-4fda-a87b-049e4331c8f2" | |
}, | |
"source": [ | |
"import matplotlib.pyplot as plt\n", | |
"import matplotlib.dates as mdates\n", | |
"%matplotlib inline\n", | |
"\n", | |
"# パラメータ別トータル損益値幅をDataFrame化\n", | |
"df_total_pl = pd.DataFrame([[r[0], r[1]] for r in result], columns=[\"pl\", \"trades\"])\n", | |
"\n", | |
"# トータル損益値幅表示\n", | |
"display(df_total_pl)\n", | |
"\n", | |
"# 散布図\n", | |
"plt.grid(color=\"gray\")\n", | |
"plt.scatter(x=df_total_pl.index, y=df_total_pl[\"pl\"]) # x:パラメータNo, y:トータル損益値幅\n", | |
"plt.show()" | |
], | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/html": [ | |
"<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>pl</th>\n", | |
" <th>trades</th>\n", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>0</th>\n", | |
" <td>-4806.88</td>\n", | |
" <td>782</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>1</th>\n", | |
" <td>-6986.92</td>\n", | |
" <td>653</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2</th>\n", | |
" <td>-4389.63</td>\n", | |
" <td>548</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>3</th>\n", | |
" <td>-4365.05</td>\n", | |
" <td>437</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>4</th>\n", | |
" <td>-414.46</td>\n", | |
" <td>367</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>...</th>\n", | |
" <td>...</td>\n", | |
" <td>...</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>99</th>\n", | |
" <td>-1257.66</td>\n", | |
" <td>43</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>100</th>\n", | |
" <td>-51.74</td>\n", | |
" <td>38</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>101</th>\n", | |
" <td>-559.78</td>\n", | |
" <td>48</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>102</th>\n", | |
" <td>1810.17</td>\n", | |
" <td>34</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>103</th>\n", | |
" <td>2860.73</td>\n", | |
" <td>37</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>104 rows × 2 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" pl trades\n", | |
"0 -4806.88 782\n", | |
"1 -6986.92 653\n", | |
"2 -4389.63 548\n", | |
"3 -4365.05 437\n", | |
"4 -414.46 367\n", | |
".. ... ...\n", | |
"99 -1257.66 43\n", | |
"100 -51.74 38\n", | |
"101 -559.78 48\n", | |
"102 1810.17 34\n", | |
"103 2860.73 37\n", | |
"\n", | |
"[104 rows x 2 columns]" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"tags": [], | |
"needs_background": "light" | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "P2oWgeKuDHlZ", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"\n", | |
"# 6.最大パフォーマンスの損益推移を表示" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "KuNwqHl_C_s4", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 327 | |
}, | |
"outputId": "4de38edc-74a5-4214-95e3-2a62945a87f4" | |
}, | |
"source": [ | |
"# 条件出力\n", | |
"print(\"[Test term]:{} - {} [Period]:{}[分]\".format(FROM, TO, PERIOD))\n", | |
"\n", | |
"# 最大利益値幅のパラメータNoを取得\n", | |
"max_idx = df_total_pl[\"pl\"].values.argmax()\n", | |
"print(\"[Best params no]:{} [Short]:{} [Long]:{} [Total PL]:{} [Trades]:{}\".format(\n", | |
" max_idx, df_params[\"short\"][max_idx], df_params[\"long\"][max_idx],\n", | |
" round(df_total_pl[\"pl\"][max_idx], 2), df_total_pl[\"trades\"][max_idx]))\n", | |
"\n", | |
"# 最大利益値幅の損益推移を表示\n", | |
"fig, ax = plt.subplots()\n", | |
"ax.set_title(\"Profit and loss graph\") # タイトル\n", | |
"ax.xaxis.set_major_formatter(mdates.DateFormatter(\"%m/%d\\n%H:%M\")) # X軸ラベル\n", | |
"plt.grid(color=\"gray\")\n", | |
"\n", | |
"np_date = df_ohlcv.index.values[PRE_BARS:] # X:OHLCV期間時刻\n", | |
"np_sum_pl = np.cumsum(result[max_idx][2]) # Y:累積損益値幅\n", | |
"plt.plot(np_date, np_sum_pl)\n", | |
"plt.show()" | |
], | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"text": [ | |
"[Test term]:2020/01/01 00:00:00 - 2020/08/06 00:00:00 [Period]:60[分]\n", | |
"[Best params no]:60 [Short]:16 [Long]:24 [Total PL]:11012.31 [Trades]:275\n" | |
], | |
"name": "stdout" | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"image/png": "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\n", | |
"text/plain": [ | |
"<Figure size 432x288 with 1 Axes>" | |
] | |
}, | |
"metadata": { | |
"tags": [], | |
"needs_background": "light" | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "-OffSPTJl-Sw", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"# おまけ\n", | |
"テストデータと最良結果をDataFrameにまとめてCSV出力します。<br>\n", | |
"Excelやお使いのツールなどで分析、可視化にご活用ください。" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "W_QNJhL2DLY5", | |
"colab_type": "code", | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 450 | |
}, | |
"outputId": "1bcc4810-c2e4-4f74-ae71-bce3f08df673" | |
}, | |
"source": [ | |
"from google.colab import files\n", | |
"\n", | |
"df = df_ohlcv.copy()\n", | |
"\n", | |
"# 短期SMA\n", | |
"df[\"sma_s\"] = df[\"close\"].rolling(window=df_params[\"short\"][max_idx], min_periods=1).mean().values\n", | |
"# 長期SMA\n", | |
"df[\"sma_l\"] = df[\"close\"].rolling(window=df_params[\"long\"][max_idx], min_periods=1).mean().values\n", | |
"df = df.iloc[PRE_BARS:]\n", | |
"# 累積PL\n", | |
"df[\"pl\"] = np_sum_pl\n", | |
"# DataFrameをCSV出力\n", | |
"df.to_csv(\"result.csv\")\n", | |
"# CSVダウンロード\n", | |
"files.download(\"result.csv\")\n", | |
"\n", | |
"display(df)" | |
], | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/html": [ | |
"<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>sma_s</th>\n", | |
" <th>sma_l</th>\n", | |
" <th>pl</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", | |
" </tr>\n", | |
" </thead>\n", | |
" <tbody>\n", | |
" <tr>\n", | |
" <th>2019-12-31 23:00:00+09:00</th>\n", | |
" <td>1577800800</td>\n", | |
" <td>7220.5</td>\n", | |
" <td>7298.5</td>\n", | |
" <td>7205.0</td>\n", | |
" <td>7209.0</td>\n", | |
" <td>173526779</td>\n", | |
" <td>7220.93750</td>\n", | |
" <td>7226.375000</td>\n", | |
" <td>-5.41</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-01-01 00:00:00+09:00</th>\n", | |
" <td>1577804400</td>\n", | |
" <td>7209.0</td>\n", | |
" <td>7229.0</td>\n", | |
" <td>7161.0</td>\n", | |
" <td>7171.5</td>\n", | |
" <td>169185919</td>\n", | |
" <td>7218.00000</td>\n", | |
" <td>7223.500000</td>\n", | |
" <td>-5.41</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-01-01 01:00:00+09:00</th>\n", | |
" <td>1577808000</td>\n", | |
" <td>7171.5</td>\n", | |
" <td>7199.0</td>\n", | |
" <td>7166.5</td>\n", | |
" <td>7188.5</td>\n", | |
" <td>49053408</td>\n", | |
" <td>7215.62500</td>\n", | |
" <td>7221.583333</td>\n", | |
" <td>-5.41</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-01-01 02:00:00+09:00</th>\n", | |
" <td>1577811600</td>\n", | |
" <td>7188.5</td>\n", | |
" <td>7189.0</td>\n", | |
" <td>7124.0</td>\n", | |
" <td>7137.5</td>\n", | |
" <td>84997938</td>\n", | |
" <td>7209.59375</td>\n", | |
" <td>7217.312500</td>\n", | |
" <td>-5.41</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-01-01 03:00:00+09:00</th>\n", | |
" <td>1577815200</td>\n", | |
" <td>7137.5</td>\n", | |
" <td>7143.0</td>\n", | |
" <td>7115.0</td>\n", | |
" <td>7142.0</td>\n", | |
" <td>57271863</td>\n", | |
" <td>7205.06250</td>\n", | |
" <td>7213.895833</td>\n", | |
" <td>-5.41</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", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 20:00:00+09:00</th>\n", | |
" <td>1596625200</td>\n", | |
" <td>11405.0</td>\n", | |
" <td>11465.0</td>\n", | |
" <td>11400.5</td>\n", | |
" <td>11453.0</td>\n", | |
" <td>68161961</td>\n", | |
" <td>11269.68750</td>\n", | |
" <td>11246.604167</td>\n", | |
" <td>10638.57</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 21:00:00+09:00</th>\n", | |
" <td>1596628800</td>\n", | |
" <td>11453.0</td>\n", | |
" <td>11608.0</td>\n", | |
" <td>11406.5</td>\n", | |
" <td>11582.0</td>\n", | |
" <td>196546136</td>\n", | |
" <td>11292.81250</td>\n", | |
" <td>11264.104167</td>\n", | |
" <td>10638.57</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 22:00:00+09:00</th>\n", | |
" <td>1596632400</td>\n", | |
" <td>11582.0</td>\n", | |
" <td>11639.0</td>\n", | |
" <td>11564.5</td>\n", | |
" <td>11630.0</td>\n", | |
" <td>155227124</td>\n", | |
" <td>11317.28125</td>\n", | |
" <td>11284.770833</td>\n", | |
" <td>10638.57</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-05 23:00:00+09:00</th>\n", | |
" <td>1596636000</td>\n", | |
" <td>11630.0</td>\n", | |
" <td>11660.0</td>\n", | |
" <td>11520.5</td>\n", | |
" <td>11633.5</td>\n", | |
" <td>169126573</td>\n", | |
" <td>11342.37500</td>\n", | |
" <td>11302.500000</td>\n", | |
" <td>10638.57</td>\n", | |
" </tr>\n", | |
" <tr>\n", | |
" <th>2020-08-06 00:00:00+09:00</th>\n", | |
" <td>1596639600</td>\n", | |
" <td>11633.5</td>\n", | |
" <td>11704.0</td>\n", | |
" <td>11611.5</td>\n", | |
" <td>11675.5</td>\n", | |
" <td>141099720</td>\n", | |
" <td>11372.84375</td>\n", | |
" <td>11321.729167</td>\n", | |
" <td>11012.31</td>\n", | |
" </tr>\n", | |
" </tbody>\n", | |
"</table>\n", | |
"<p>5234 rows × 9 columns</p>\n", | |
"</div>" | |
], | |
"text/plain": [ | |
" timestamp open ... sma_l pl\n", | |
"datetime ... \n", | |
"2019-12-31 23:00:00+09:00 1577800800 7220.5 ... 7226.375000 -5.41\n", | |
"2020-01-01 00:00:00+09:00 1577804400 7209.0 ... 7223.500000 -5.41\n", | |
"2020-01-01 01:00:00+09:00 1577808000 7171.5 ... 7221.583333 -5.41\n", | |
"2020-01-01 02:00:00+09:00 1577811600 7188.5 ... 7217.312500 -5.41\n", | |
"2020-01-01 03:00:00+09:00 1577815200 7137.5 ... 7213.895833 -5.41\n", | |
"... ... ... ... ... ...\n", | |
"2020-08-05 20:00:00+09:00 1596625200 11405.0 ... 11246.604167 10638.57\n", | |
"2020-08-05 21:00:00+09:00 1596628800 11453.0 ... 11264.104167 10638.57\n", | |
"2020-08-05 22:00:00+09:00 1596632400 11582.0 ... 11284.770833 10638.57\n", | |
"2020-08-05 23:00:00+09:00 1596636000 11630.0 ... 11302.500000 10638.57\n", | |
"2020-08-06 00:00:00+09:00 1596639600 11633.5 ... 11321.729167 11012.31\n", | |
"\n", | |
"[5234 rows x 9 columns]" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"application/javascript": [ | |
"\n", | |
" async function download(id, filename, size) {\n", | |
" if (!google.colab.kernel.accessAllowed) {\n", | |
" return;\n", | |
" }\n", | |
" const div = document.createElement('div');\n", | |
" const label = document.createElement('label');\n", | |
" label.textContent = `Downloading \"${filename}\": `;\n", | |
" div.appendChild(label);\n", | |
" const progress = document.createElement('progress');\n", | |
" progress.max = size;\n", | |
" div.appendChild(progress);\n", | |
" document.body.appendChild(div);\n", | |
"\n", | |
" const buffers = [];\n", | |
" let downloaded = 0;\n", | |
"\n", | |
" const channel = await google.colab.kernel.comms.open(id);\n", | |
" // Send a message to notify the kernel that we're ready.\n", | |
" channel.send({})\n", | |
"\n", | |
" for await (const message of channel.messages) {\n", | |
" // Send a message to notify the kernel that we're ready.\n", | |
" channel.send({})\n", | |
" if (message.buffers) {\n", | |
" for (const buffer of message.buffers) {\n", | |
" buffers.push(buffer);\n", | |
" downloaded += buffer.byteLength;\n", | |
" progress.value = downloaded;\n", | |
" }\n", | |
" }\n", | |
" }\n", | |
" const blob = new Blob(buffers, {type: 'application/binary'});\n", | |
" const a = document.createElement('a');\n", | |
" a.href = window.URL.createObjectURL(blob);\n", | |
" a.download = filename;\n", | |
" div.appendChild(a);\n", | |
" a.click();\n", | |
" div.remove();\n", | |
" }\n", | |
" " | |
], | |
"text/plain": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
}, | |
{ | |
"output_type": "display_data", | |
"data": { | |
"application/javascript": [ | |
"download(\"download_400fd595-8cf2-4c1b-af1f-8ce21039686a\", \"result.csv\", 603793)" | |
], | |
"text/plain": [ | |
"<IPython.core.display.Javascript object>" | |
] | |
}, | |
"metadata": { | |
"tags": [] | |
} | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"metadata": { | |
"id": "4JzT2Rnvfjjs", | |
"colab_type": "code", | |
"colab": {} | |
}, | |
"source": [ | |
"" | |
], | |
"execution_count": null, | |
"outputs": [] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment