QuantXの初期化関数では使用データを定義(設定)するだけでなく、使用データで売買シグナルを生成する関数(以下シグナル生成関数と呼称)を登録する必要があります。シグナル生成関数についてもルールや基礎的な考え方がありますが、サンプルプログラムとその解説はあっても構造的な部分について詳しい記載がありません。ここは応用が利くように理解しておくことが必要です。
なお、シグナル生成関数については公式ドキュメントの初期化の部分に記載されていますが、全体像と言うよりはサンプル細部の説明となっているので、構造の概要を把握できている人はそちらを参照してください。なお、シグナル生成関数の定義はサンプル同様に初期化関数 def initialize(ctx): 内で行う形とします。
シグナル生成関数の構造と引数
まずシグナル生成関数の名称については任意に決めることができます。サンプルではどのようなシグナルかわかるような名称にしていますが、試行錯誤する開発の勉強中などは特にこだわる必要はないでしょう。以下では、_trade_signal という関数名にしておきます。シグナル生成関数の大まかな構造の代表例は下記のようになります。pythonはインデント位置で構造を示すので(他の言語のように { } でなどで示さない)、def initialize(ctx): の内部で定義するシグナル生成関数は、def initialize(ctx):よりもインデントを下げて定義してください。コメントに記載の内容についてはプログラムの後に掘り下げて記載します。
# シグナル生成関数の定義
def _trade_signal(datas):
### 引数 datasを各種加工して売買シグナルを作成する関数を作成する
### 関数の返値は、dict型(いわゆる辞書型で key:Value 構造)
### dict の Value は DataFrame(index=date, columns=symbol)の形なので
### datasで受け取った構造を加工利用するのが定石
### 以下でpdは、import pandas as pd で読み込み済み前提のライブラリ
# (1)株価データ部分を取得
daily = datas["jp.stock.daily"]
# (2)利用データ(以下では終値)を DataFrame(index=date, columns=symbol) の形式に整形
cp = daily["close_price_adj"].unstack(level="symbol")
# (3)シグナル作成の基礎データにするためにNA(欠損データ)を埋める
cp = cp.fillna(method='ffill')
# (4)各種処理(省略)でシグナル判定のための計算を行う
# DataFrame(index=date, columns=symbol)構造のTrue or False を作成
buy_sig = xxx # 買シグナル
sell_sig = xxx # 売シグナル
# (5)返値を作成して返す
# (必須)market:sig = -1.0〜1.0 (負は売り、正は買いで大きさは確信度)
market_sig = pd.DataFrame(data=0.0, columns=cp.columns, index=cp.index)
market_sig[buy_sig] += 1.0
market_sig[sell_sig] += -1.0
return {
"market:sig" : market_sig
}
(1)株価データ部分を取得(引数の理解)
株価データを取得する部分ですが、これらは引数 datas に入っています。datasについて詳しい説明がマニュアルにはありませんが、初期化関数で設定した “jp.stock.daily” と ‘benchmark’ をkeyとする dict で構成されています。
key ”jp.stock.daily” に対応するValueの Dataframe
Dataframeの ”index”はdate(年月日)、symbol(銘柄コード)の2つ。Dataframeの “columns” については初期化関数で設定したデータのみが含まれる(はず)と考えていましたが、実際に見てみると以下のように利用可能とされるすべてのデータ+α が含まれていました(今後変更される可能性がありますので設定したデータのみが含まれると考えておいた方が良いと思います。)。
データ名 | 内容 | 備考 |
code | 銘柄コード | indexのsymbolと重複(同じもの) |
open_price | 始値 | 分割非考慮 |
high_price | 高値 | 分割非考慮 |
low_price | 安値 | 分割非考慮 |
close_price | 終値 | 分割非考慮 |
volume | 取引高 | 分割非考慮 |
txn_volume | 売買代金 | |
split_ratio | 分割比率 | 推定 |
ex_dividend | 配当権利落 | 推定 |
unit | 単元数 | 推定 |
delisted | 上場廃止 | 推定 |
close_price_adj | 終値 | 分割考慮 |
high_price_adj | 高値 | 分割考慮 |
low_price_adj | 安値 | 分割考慮 |
open_price_adj | 始値 | 分割考慮 |
volume_adj | 取引高 | 分割考慮 |
key ”benchmark“ に対応するValueの Dataframe
これはベンチマーク用にデフォルトで組み込まれるデータの用です。構成としてDataframe の “index”はdate(年月日) のみで、Dataframe の “colmuns” は、symbol(銘柄コード)とclose_price(終値) です。ここでdateは、”jp.stock.daily”同様にバックテストや実際の判定日付、symbolは ”jp.stock.index.n225” 固定、close_piceは当然ながら日経225の対応日の終値となっています。
シグナル生成の為の基礎情報の取得
通常は、自分で設定したデータをベースに売買シグナルを生成するため、以下のように key の ”jp.stock.daily”に対応するValueである Dataframeを一旦キャッシュするのが基本となります。
daily = datas["jp.stock.daily"]
まとめ
・シグナル生成関数は決まった構造をもっているのでまず全体の骨組みを理解する
・シグナル生成関数の引数はベンチマークとなるデータと生成の為の基礎データが含まれている(この内容と構造を理解しておくことが大事)