筆者は仮想通貨のシステムトレードを勉強しています。システムトレード(または、メカニカルトレード)は、コンピュータプログラムによる自動トレードのことです。人手によるトレードは裁量トレードといいます。
いろいろ本を読みました。
●真・トレーダーズバイブル
●botterのリアル
●高リターン・低ドローダウン戦略
それらによると、トレードbotは「バックテスト」すべきとのことです。バックテストとは、金融商品の過去の価額データを使って模擬取引し、トレードbotの有効性を検証する作業です。考えてみれば、自作のプログラムをいきなり本番環境で動かして売買を任せるなんて、お金がからむことですから怖いですよね。そこで、バックテストについて調べ、自作botの一部分をバックテストをした結果を記載します。
調べると、いくつかライブラリが見つかりました。トレードを扱うライブラリとバックテストだけを行うライブラリに分かれます。githubを確認し、現在開発が継続されているかを見ました。「Backtrader」と「Backtesting.py」が良いとわかり、日本語の解説が多い「Backtesting.py」を選びました。
Backtesting.pyはPython言語用のライブラリです。Backtesting.pyのホームページはここです。
本稿では、自作のbotが既にある状態から始めます。
pipでBacktesting.pyをインストールします。
pip install backtesting
:
:
:
Successfully built backtesting
Installing collected packages: bokeh, backtesting
Successfully installed backtesting-0.3.3 bokeh-2.4.2
本稿執筆時点では、Backtesting.pyのバージョンは0.3.3でした。
自作botが使用している時間枠(タイムフレーム。1分足、日足など)と同じデータを用意します。トレーダ向けの情報サイトや取引所からダウンロードすることができます。botが作れる人なら、自作ツールでデータを用意することもできます。私はCSVファイルを出力するツールを自作しました。
[参考] これはデータがダウンロードできる情報サイトです:
データを出力するプログラムのソースを掲載します。このプログラムは、取引用ライブラリccxtを使い、json設定ファイルから取引所接続用情報や通貨ペア情報を読み出し、1分足データをダウンロードしてCSVファイルに出力します。2種類の通貨ペアを保存する例です。Backtesting.py側の要求に従い、CSVの列名を"Time", "Open", "High", "Low", "Close", "Volume"としています。
botter(トレードbotを作る人)によってbotの作り方は千差万別ですが、
●何がどうなったら購入処理を行う
●何がどうなったら売却処理を行う
と書かれているのは共通しているはずです。Backtesting.pyを使ったバックテストプログラムは、そのように何がどうなったら模擬購入・模擬売却を行うというように書きます。
本稿では、テクニカル指標CCI、ROC、サイコロジカルラインの3つを使った取引botを模したバックテストプログラムを掲載します。私のbotの一つにtasuuketsubuy.py(多数決購入)というプログラムがあります。このプログラムは、CCI、ボリンジャーバンド、RSI、ストキャスティクスなど複数のテクニカル指標が同時に売買を推奨したら取引するbotです。今回Backtesting.pyの調査によって使えない指標(後述します)が出てきたので、tasuuketsubuy.pyからCCI、ROC、サイコロジカルラインだけ取り出しました。
●CCIを取得する関数get_cci()
●ROCを取得する関数get_roc()
●サイコロジカルラインを取得する関数get_psychologicalline()
を定義し、これら3つの関数がすべて反応したときに模擬購入、どれか2つが反応したときに模擬売却を行います。これらの指標取得関数の呼び出しはself.I()経由で行います。
Strategyクラスを継承したクラスを書きます。クラス内のinit()メンバ関数で指標取得関数の呼び出しを行います。この書き方だと1回しか動かないのでは?と思いがちですがそこはBacktesting.pyがうまくデータ行ごとに毎回呼び出してくれます。next()メンバ関数では、指標取得関数が返却した値がどうなったら買う・売るという処理を書きます。self.buy()、self.sell()を呼び出すことで模擬売買ができます。
私の指標取得関数は自作クラスのメンバ関数としてindicators.pyという別ファイルに定義しています。今回のバックテストプログラムにindicators.pyをインポートして動かしましたがうまく動きませんでした。クラスから指標取得関数を取り出しバックテストプログラムにあらためて定義することで動きました。以下にバックテストプログラムを掲載します。
●データフレームの列名は"Time"、"Open"、"High"、"Low"、"Close"である必要がある。
私のbotは"timestamp"、"open"、"high"、"low"、"close"を使っていましたが名前が違うと以下のようなエラーになります。
File "C:\Python39\lib\site-packages\pandas\core\indexes\base.py", line 3363, in get_loc
raise KeyError(key) from err
KeyError: 'low'
●自作テクニカル指標関数はnumpy.arraysを返さなければならない。
私のbotは自作CCIやボリンジャーバンドなどテクニカル指標関数は計算結果としての値だけを返していましたが、それだと以下のようなエラーになります。
File "C:\Python39\lib\site-packages\backtesting\backtesting.py", line 143, in I
raise ValueError(
ValueError: Indicators must return (optionally a tuple of) numpy.arrays of same length as `data` (data shape: (1677,); indicator "get_bolli…"shape: (2,), returned value: [41585.3213977 41468.7786023])
これはけっこう大きな制約で、入力行数と出力行数は同じでなければなりません。指標によっては行の削除を行っているものもあるので、Backtesting.pyに合わせた指標や売買判断関数に修正する作業はなかなか大変です。
backtest_3ti.pyを実行すると、以下の結果が得られました。通貨ペアはBTC/USDTでした。
データ期間4月20日~25日で7回のトレードが行われ、初期投資額100,000は103,219になりました。個々の指標だけで取引するのはまったくだめだと経験的にわかっていましたが、この結果より他の指標と組み合わせれば有効だということが確かめられました。
python backtest_3ti.py
Start 2022-04-20 12:28:00
End 2022-04-25 12:47:00
Duration 5 days 00:19:00
Exposure Time [%] 64.1845
Equity Final [$] 103219.436
Equity Peak [$] 103302.036
Return [%] 3.219436
Buy & Hold Return [%] -5.201637
Return (Ann.) [%] 587.316555
Volatility (Ann.) [%] 191.366011
Sharpe Ratio 3.069075
Sortino Ratio 70.138626
Calmar Ratio 323.245011
Max. Drawdown [%] -1.816939
Avg. Drawdown [%] -0.411609
Max. Drawdown Duration 2 days 02:15:00
Avg. Drawdown Duration 0 days 03:10:00
# Trades 7
Win Rate [%] 85.714286
Best Trade [%] 1.713241
Worst Trade [%] -0.928552
Avg. Trade [%] 0.573011
Max. Trade Duration 2 days 03:33:00
Avg. Trade Duration 0 days 11:19:00
Profit Factor 5.344782
Expectancy [%] 0.576336
SQN 1.730267
_strategy ThreeIndicatorsS...
_equity_curve ...
_trades Size EntryBa...
dtype: object
バックテスト用ライブラリを使うためには、botの開発が終わってからではなく、開発初期段階から調べ始めるのが重要だとわかりました。開発終了後にバックテストに取り組むと、botの修正量が大きくなってしまいます。
●私のだめな開発手順
1. 戦略の立案
2. 開発
3. 運用
4. システムトレードの学習
5. バックテスト×
●あるべき開発手順
1. システムトレードの学習
2. 戦略の立案
3. 使用するフレームワークの調査
・ccxt
・バックテストツールなど
4. 開発
5. バックテスト○
6. 運用
いくつもbotを作りましたが、どうも時間枠が1分足だとなかなか勝てません。もっと落ち着けということでしょうか。tasuuketsubuy.pyは1分足でしたが、バックテストで5分足の結果を見てみようと思います。
以上