Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save nagishin/122e4884183e695716cddfbd8b91c74c to your computer and use it in GitHub Desktop.
Save nagishin/122e4884183e695716cddfbd8b91c74c to your computer and use it in GitHub Desktop.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<B> pandas DataFrameのapply関数を用いて時系列データの汎用的な簡易バックテストを行うサンプル </B>\n",
"1. テスト対象期間のデータを取得\n",
"2. テストパラメータ組み合わせ作成\n",
"3. テストするストラテジー定義\n",
"4. テスト実行\n",
"5. 各パラメータ別のテスト結果表示\n",
"6. 最大パフォーマンスの損益推移を表示\n",
"<BR><BR>\n",
"[2.各パラメータ組み合わせ(df_params)]にapply関数を用いて<BR>\n",
"[1.テストデータ(df_ohlcv)]を与えて[3.ストラテジー(def strategy)]を実行します。\n",
"<BR><BR>\n",
"[1.テストデータ], [2.ストラテジー]をカスタマイズすることで様々なテストを作成できます。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"本サンプルは以下の条件とサンプルロジックを例に説明しています。<BR><BR>\n",
"- [テストデータ]<BR>\n",
" - BitMEX 1分足 直近1週間分のOHLCV<BR>\n",
"- [テストストラテジー]<BR>\n",
" - OHLCV終値の短期SMAと長期SMAのゴールデンクロス/デッドクロスでドテン注文を繰り返す<BR>\n",
"- [パラメータ]<BR>\n",
" - 短期/長期SMAそれぞれの移動平均期間<BR>\n",
"\n",
"【注意】ロジックも評価方法も解説のためのサンプルであり、有効なテスト結果ではありません。"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### テスト対象期間のデータを取得\n",
"<BR>\n",
"BitMEX REST APIにて時間足と期間数を取得してOHLCVデータを取得する\n",
"* PERIOD : 時間足(分) \n",
"* BARS : 期間数 "
]
},
{
"cell_type": "code",
"execution_count": 102,
"metadata": {},
"outputs": [
{
"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-05-14 19:23:00+09:00</th>\n",
" <td>1557829380</td>\n",
" <td>8024.0</td>\n",
" <td>8032.0</td>\n",
" <td>8015.5</td>\n",
" <td>8016.0</td>\n",
" <td>4146640</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-14 19:24:00+09:00</th>\n",
" <td>1557829440</td>\n",
" <td>8016.0</td>\n",
" <td>8022.5</td>\n",
" <td>8005.5</td>\n",
" <td>8021.0</td>\n",
" <td>4138129</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-14 19:25:00+09:00</th>\n",
" <td>1557829500</td>\n",
" <td>8021.0</td>\n",
" <td>8020.5</td>\n",
" <td>7988.5</td>\n",
" <td>7988.5</td>\n",
" <td>3155079</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-14 19:26:00+09:00</th>\n",
" <td>1557829560</td>\n",
" <td>7988.5</td>\n",
" <td>8019.0</td>\n",
" <td>7988.5</td>\n",
" <td>8012.5</td>\n",
" <td>3760529</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-14 19:27:00+09:00</th>\n",
" <td>1557829620</td>\n",
" <td>8012.5</td>\n",
" <td>8013.0</td>\n",
" <td>7993.0</td>\n",
" <td>7993.0</td>\n",
" <td>2983371</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>2019-05-21 19:18:00+09:00</th>\n",
" <td>1558433880</td>\n",
" <td>7940.0</td>\n",
" <td>7944.5</td>\n",
" <td>7939.5</td>\n",
" <td>7944.5</td>\n",
" <td>2240989</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-21 19:19:00+09:00</th>\n",
" <td>1558433940</td>\n",
" <td>7944.5</td>\n",
" <td>7950.0</td>\n",
" <td>7941.0</td>\n",
" <td>7941.5</td>\n",
" <td>4931035</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-21 19:20:00+09:00</th>\n",
" <td>1558434000</td>\n",
" <td>7941.5</td>\n",
" <td>7952.5</td>\n",
" <td>7941.0</td>\n",
" <td>7952.5</td>\n",
" <td>1381971</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-21 19:21:00+09:00</th>\n",
" <td>1558434060</td>\n",
" <td>7952.5</td>\n",
" <td>7952.5</td>\n",
" <td>7948.5</td>\n",
" <td>7951.5</td>\n",
" <td>854896</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2019-05-21 19:22:00+09:00</th>\n",
" <td>1558434120</td>\n",
" <td>7951.5</td>\n",
" <td>7951.5</td>\n",
" <td>7941.5</td>\n",
" <td>7943.5</td>\n",
" <td>2762757</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>10080 rows × 6 columns</p>\n",
"</div>"
],
"text/plain": [
" timestamp open high low close volume\n",
"datetime \n",
"2019-05-14 19:23:00+09:00 1557829380 8024.0 8032.0 8015.5 8016.0 4146640\n",
"2019-05-14 19:24:00+09:00 1557829440 8016.0 8022.5 8005.5 8021.0 4138129\n",
"2019-05-14 19:25:00+09:00 1557829500 8021.0 8020.5 7988.5 7988.5 3155079\n",
"2019-05-14 19:26:00+09:00 1557829560 7988.5 8019.0 7988.5 8012.5 3760529\n",
"2019-05-14 19:27:00+09:00 1557829620 8012.5 8013.0 7993.0 7993.0 2983371\n",
"... ... ... ... ... ... ...\n",
"2019-05-21 19:18:00+09:00 1558433880 7940.0 7944.5 7939.5 7944.5 2240989\n",
"2019-05-21 19:19:00+09:00 1558433940 7944.5 7950.0 7941.0 7941.5 4931035\n",
"2019-05-21 19:20:00+09:00 1558434000 7941.5 7952.5 7941.0 7952.5 1381971\n",
"2019-05-21 19:21:00+09:00 1558434060 7952.5 7952.5 7948.5 7951.5 854896\n",
"2019-05-21 19:22:00+09:00 1558434120 7951.5 7951.5 7941.5 7943.5 2762757\n",
"\n",
"[10080 rows x 6 columns]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# coding: utf-8\n",
"import time\n",
"import requests\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 = 1 # 時間足(分)\n",
"BARS = 10080 # 期間数\n",
"#------------------------------------\n",
"\n",
"# BitMEX OHLCVデータ取得 (1m足 直近1週間)\n",
"to_time = int(time.time())\n",
"from_time = to_time - 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",
"df_ohlcv = df_ohlcv.iloc[:BARS]\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)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### テストパラメータ組み合わせ作成\n",
"短期SMAと長期SMAに設定する期間数のリストを作成し、その全パラメータ組み合わせを作成する\n",
"* SHORT_TERM : 短期SMA期間リスト\n",
"* LONG_TERM : 長期SMA期間リスト"
]
},
{
"cell_type": "code",
"execution_count": 103,
"metadata": {},
"outputs": [
{
"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>1</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>1</td>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1</td>\n",
" <td>15</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>1</td>\n",
" <td>30</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>85</th>\n",
" <td>720</td>\n",
" <td>1440</td>\n",
" </tr>\n",
" <tr>\n",
" <th>86</th>\n",
" <td>720</td>\n",
" <td>2880</td>\n",
" </tr>\n",
" <tr>\n",
" <th>87</th>\n",
" <td>720</td>\n",
" <td>4320</td>\n",
" </tr>\n",
" <tr>\n",
" <th>88</th>\n",
" <td>1440</td>\n",
" <td>2880</td>\n",
" </tr>\n",
" <tr>\n",
" <th>89</th>\n",
" <td>1440</td>\n",
" <td>4320</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>90 rows × 2 columns</p>\n",
"</div>"
],
"text/plain": [
" short long\n",
"0 1 3\n",
"1 1 5\n",
"2 1 10\n",
"3 1 15\n",
"4 1 30\n",
".. ... ...\n",
"85 720 1440\n",
"86 720 2880\n",
"87 720 4320\n",
"88 1440 2880\n",
"89 1440 4320\n",
"\n",
"[90 rows x 2 columns]"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import itertools\n",
"\n",
"#------------------------------------\n",
"# [パラメータリスト]\n",
"SHORT_TERM = [1, 3, 5, 10, 15, 30, 60, 120, 240, 480, 720, 1440] # 短期SMA期間\n",
"LONG_TERM = [3, 5, 10, 15, 30, 60, 120, 240, 480, 720, 1440, 2880, 4320] # 長期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)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### テストするストラテジー定義\n",
"\n",
"df_params.apply()に適用するストラテジー関数を定義します。<BR>\n",
"apply関数のargsにdf_ohlcvを設定するのでストラテジー内で使用することができます。<BR>\n",
"\n",
"[params]\n",
"* params : テストパラメータ(df_paramsの各行データ) <BR>\n",
"* ohlcv : テストデータ(df_ohlcv)<BR>\n",
"\n",
"[returns]<BR>\n",
"* total_pl : トータル損益値幅<BR>\n",
"* total_trades : トータルトレード回数<BR>\n",
"* lst_pl : 期間毎の損益値幅リスト<BR>\n"
]
},
{
"cell_type": "code",
"execution_count": 104,
"metadata": {},
"outputs": [],
"source": [
"# ストラテジー定義\n",
"def strategy(params, ohlcv):\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",
" close = ohlcv[\"close\"].values # 終値ndarray\n",
" # 短期SMA\n",
" sma_s = ohlcv[\"close\"].rolling(window=params[\"short\"], min_periods=1).mean().values\n",
" # 長期SMA\n",
" sma_l = ohlcv[\"close\"].rolling(window=params[\"long\"], min_periods=1).mean().values\n",
"\n",
" # 全期間分を順次判定していく\n",
" # GC/DCでドテンするロジック\n",
" for i in range(1,len(close)):\n",
" pl = 0 # 損益値幅\n",
"\n",
" # ゴールデンクロス判定\n",
" if (sma_s[i-1] <= sma_l[i-1] and sma_s[i] > sma_l[i]):\n",
" if position[\"side\"] == 0:\n",
" # ポジションがない場合、Longポジション設定\n",
" position = {\"price\":close[i], \"side\":1}\n",
" total_trades += 1\n",
" elif position[\"side\"] == -1:\n",
" # ショートポジションの場合、ドテンロング\n",
" pl = position[\"price\"] - close[i] # ポジション約定価格と終値から損益値幅計算\n",
" position = {\"price\":close[i], \"side\":1} # Longポジション設定\n",
" total_trades += 1\n",
"\n",
" # デッドクロス判定\n",
" elif (sma_s[i-1] >= sma_l[i-1] and sma_s[i] < sma_l[i]):\n",
" if position[\"side\"] == 0:\n",
" # ポジションがない場合、Shortポジション設定\n",
" position = {\"price\":close[i], \"side\":-1}\n",
" total_trades += 1\n",
" elif position[\"side\"] == 1:\n",
" # ロングポジションの場合、ドテンショート\n",
" pl = close[i] - position[\"price\"] # ポジション約定価格と終値から損益値幅計算\n",
" position = {\"price\":close[i], \"side\":-1} # Shortポジション設定\n",
" total_trades += 1\n",
"\n",
" # 損益値幅リスト追加\n",
" lst_pl.append(pl)\n",
" \n",
" # 最後にポジションクローズ\n",
" if position[\"side\"] == -1:\n",
" lst_pl.append(position[\"price\"] - close[-1])\n",
" total_trades += 1\n",
" elif position[\"side\"] == 1:\n",
" lst_pl.append(close[-1] - position[\"price\"])\n",
" total_trades += 1\n",
"\n",
" # トータルPL(獲得値幅)とPL推移リストをreturn\n",
" return sum(lst_pl), total_trades, lst_pl"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### テスト実行\n",
"\n",
"各パラメータ組み合わせに対して定義したテストストラテジーを適用します。<BR>\n",
"また、ストラテジー引数にテスト期間のohlcvデータを渡します。"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"パラメータNo. (トータル損益値幅, トータルトレード回数, [期間毎の損益値幅リスト])\n"
]
},
{
"data": {
"text/plain": [
"0 (1101.5, 3561, [0, -32.5, -24.0, -19.5, 0, -0....\n",
"1 (6163.5, 2473, [0, -32.5, -24.0, -19.5, 0, 0, ...\n",
"2 (4983.5, 1639, [0, -32.5, -24.0, -19.5, 0, 0, ...\n",
"3 (2756.5, 1347, [0, -32.5, -24.0, -19.5, 0, 0, ...\n",
"4 (501.5, 1033, [0, -32.5, -24.0, -19.5, 0, 0, 0...\n",
" ... \n",
"85 (-103.5, 9, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...\n",
"86 (698.5, 7, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...\n",
"87 (-298.5, 5, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...\n",
"88 (963.0, 8, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0...\n",
"89 (-420.0, 7, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ...\n",
"Length: 90, dtype: object"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# パラメータ組み合わせにストラテジーを適用\n",
"result = df_params.apply(strategy, axis=1, args=(df_ohlcv,))\n",
"\n",
"# テスト結果表示\n",
"print(\"パラメータNo. (トータル損益値幅, トータルトレード回数, [期間毎の損益値幅リスト])\")\n",
"display(result)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 各パラメータ別のテスト結果表示\n",
"\n",
"パラメータ毎のトータル損益値幅を散布図にて表示する"
]
},
{
"cell_type": "code",
"execution_count": 106,
"metadata": {},
"outputs": [
{
"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",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1101.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>6163.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>4983.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>2756.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>501.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>85</th>\n",
" <td>-103.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>86</th>\n",
" <td>698.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>87</th>\n",
" <td>-298.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>88</th>\n",
" <td>963.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>89</th>\n",
" <td>-420.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>90 rows × 1 columns</p>\n",
"</div>"
],
"text/plain": [
" pl\n",
"0 1101.5\n",
"1 6163.5\n",
"2 4983.5\n",
"3 2756.5\n",
"4 501.5\n",
".. ...\n",
"85 -103.5\n",
"86 698.5\n",
"87 -298.5\n",
"88 963.0\n",
"89 -420.0\n",
"\n",
"[90 rows x 1 columns]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"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] for r in result], columns=[\"pl\"])\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()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 最大パフォーマンスの損益推移を表示"
]
},
{
"cell_type": "code",
"execution_count": 107,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"best params no:1 short:1 long:5 total pl:6163.5\n"
]
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# 最大利益値幅のパラメータNoを取得\n",
"max_idx = df_total_pl[\"pl\"].values.argmax()\n",
"print(\"best params no:{} short:{} long:{} total pl:{}\".format(\n",
" max_idx, df_params[\"short\"][max_idx], df_params[\"long\"][max_idx], df_total_pl[\"pl\"][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 # X:OHLCV期間時刻\n",
"np_sum_pl = np.cumsum(result[max_idx][2]) # Y:累積損益値幅\n",
"plt.plot(np_date, np_sum_pl)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.2"
},
"toc": {
"nav_menu": {},
"number_sections": true,
"sideBar": true,
"skip_h1_title": false,
"title_cell": "Table of Contents",
"title_sidebar": "Contents",
"toc_cell": false,
"toc_position": {},
"toc_section_display": true,
"toc_window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment