【注意】maron0.0.1で実行しています!!!新エンジン(maron0.0.5)での実行については保証できないので注意してください!!
対象の読者
- QuantX FactoryとQuantX SDKの基本的な使い方は知っていて、QuantX SDKのより詳しい使い方を知りたい人。
- 「QuantX SDKチョットワカル」と自信を持って言えるようになりたい人。
始めに
この記事は、QuantX SDKを使用する上で気づいた私の細かな知見を共有する記事です。基本的な使用方法はこの記事を参照してください。また、QuantX SDKの基本的な使い方は知っているものとして話を進めていきます。
quantx_sdk.root module
from quantx_sdk import QX
qx = QX(access_key, secret_key)
SDKを使う時に最初に生成するqxのことです。個人的に便利に感じたroot moduleの便利なメソッドを紹介します。
current_rate_limit()
現在のレートリミットを取得します。
使用例
ret = api.current_rate_limit()
# limit値
limit = ret["limit"]
# 残り呼び出し回数
remaining = ret["remaining"]
Tips
SDKでは大量のバックテスト処理を行うことが多いかと思います。しかし、あまり多くのバックテストを実行するとAPI制限を食らってしまうことがあります。そこでremainingを利用することにより残りの呼び出し回数によって処理を変えることができます。
while(true):
# ---
# バックテストを行うような何かしらの処理
# ---
ret = api.current_rate_limit()
remaining = ret["remaining"]
if remaining < 100:
time.sleep(60 * 10)
quantx_sdk.backtest_result module
res = project.backtest(bt_params)
res = res.join()
名前の通り、バックテストの結果です。次はこのbacktest_moduleが持つ便利関数を紹介します。
benchmark()
損益率の推移を取得します。戻り値はpandas.DataFrameになっています。
このDataFrameのcolumnは
Index(['portfolio_value', 'cash', 'positions_value', 'returns', 'pnl',
'portfolio_daily_returns', 'benchmark', 'benchmark_cumulative_returns',
'benchmark_daily_returns', 'portfolio_cumulative_returns'])
となっていて、各行に各日付のデータが入っています。
イメージ
portfolio_value cash ... benchmark_daily_returns portfolio_cumulative_returns
index ...
2016-06-06 10000000 10000000 ... NaN 0.0
2016-06-07 10000000 10000000 ... 0.005754 0.0
2016-06-08 10000000 10000000 ... 0.009325 0.0
2016-06-09 10000000 10000000 ... -0.009655 0.0
2016-06-10 10000000 10000000 ... -0.004020 0.0
使用例
df = res.benchmark()
log()
バックテストのログを返す関数です。つまりctx.logger.debug()
関数などによってQuantXのログの部分に出力される文字列を取得できます。
使用例
print(res.log())
signal_history_by_symbol(symbol)
引数でjp.stock.xxxx
(文字列)のような銘柄コードを指定して、その銘柄のシグナル履歴を取得できます。つまりアルゴリズムで定義したinitalize()関数の_my_signal()関数の戻り値の部分の各日付の値を取得できます。
使用例
言葉だけではあまり伝わらないと思うので実際に使ってみます。_my_signal()関数の戻り値をこのように定義します。
return {
"wma5":s_wma,
"wma25":m_wma,
"wma75":l_wma,
"buy:sig": buy_sig,
"sell:sig": sell_sig,
}
このアルゴリズムのバックテストをSDKで実行しres.signal_history_by_symbol('jp.stock.9943')
を見てみましょう。
# 先頭5つを抜粋
buy:sig sell:sig wma25 wma5 wma75
2016-06-06 0.0 0.0 1864.698462 1866.000000 1873.122807
2016-06-07 0.0 0.0 1864.504615 1864.400000 1872.653684
2016-06-08 0.0 0.0 1864.400000 1863.866667 1872.208772
2016-06-09 0.0 0.0 1864.378462 1863.733333 1871.788772
2016-06-10 0.0 0.0 1864.104615 1862.533333 1871.292982
確かにシグナルを取得できています。
この表を可視化して、取得した値が正しいのか確認してみましょう。
from matplotlib import pyplot as plt
# dfに9943の銘柄のシグナルを入れる
df = res.signal_history_by_symbol('jp.stock.9943')
# DataFrameが持つplot関数で可視化
df.plot(y=['wma5'])
plt.show()
このような結果となりました。QuantX Fuctoryの方で全く同じコードを同じ条件で実行しwma5を見てみると、たしかに概形が同じであることを確認できました。
Tips
アルゴリズムの戻り値定義の部分を
return {
"wma5":s_wma,
"wma25":m_wma,
"wma75":l_wma,
"cpa": data["close_price_adj"],
"buy:sig": buy_sig,
"sell:sig": sell_sig,
}
SDK実行側のコードを
df = res.signal_history_by_symbol('jp.stock.9943')
df['cpa']
のようにすることで終値の取得もできます。
他にも始値や出来高等も取得できます。なにを取得できるかはドキュメントを参照してください。
trade_history_by_symbol(symbol)
引数に指定した銘柄の取引履歴を取得します。戻り値は注文日、完了日、値段、量などが入ったDataFrame型です。
使用例
df2 = res.trade_history_by_symbol('jp.stock.9943')
print(df2)
#先頭5つ抜粋
date order_date complete_date price amount comission comment
0 jp.stock.9943 2016-07-11 2016-07-12 1874 4200 0 SIGNAL BUY
1 jp.stock.9943 2017-03-06 2017-03-07 2044 -100 0 SIGNAL BUY
2 jp.stock.9943 2017-03-29 2017-03-30 2021 100 0 SIGNAL BUY
3 jp.stock.9943 2017-05-17 2017-05-18 2056 -100 0 SIGNAL BUY
4 jp.stock.9943 2017-08-31 2017-09-01 2273 -100 0 SIGNAL BUY
Tips
先程のsignal_history_by_symbol
関数と合わせると、QuantX Factoryで描画されるグラフとほとんど同じものをローカルで描画できるようになります。(需要があるかはわかりませんが…)
コード例
df = res.signal_history_by_symbol('jp.stock.9943')
df2 = res.trade_history_by_symbol('jp.stock.9943')
plt.plot(df.index, df['wma75'])
plt.plot(df.index, df['cpa'])
for complete_date, amount in zip(df2['complete_date'], df2['amount']):
complete_date = str(complete_date).split()[0]
if amount >= 0:
plt.scatter(complete_date, df['cpa'][complete_date], color='r')
else:
plt.scatter(complete_date, df['cpa'][complete_date], color='b')
plt.show()
結果
おしまい
ここまで読んでいただきありがとうございました。間違ってるところがあれば教えてください。