シグナル生成関数内で、引数から加工用のデータを取得したらあとはそのデータをもとに売買シグナルを生成するだけです。前回、引数datasを加工して cp という変数に FrameData(index=date , columns=symbol) 構造を持つ分割調整済み終値データ(欠損値補填済み)を準備しました。このcpに対して何らかの演算を行うと各dateの各symbol、つまり各銘柄ごとに同じ計算が行われてデータ構造を維持しながら一気に演算処理を行えます。
行列を扱えない状態で同じ処理をするとしたら、dateごと、symbolごとにループ処理して同じ処理を繰り返すことになりますが、行列として一気に処理ができるのでこのあたりがとても楽です。この記事で関数そのものを理解しなくても問題ありません。シグナル算出を行ってその結果を返すということを理解してください。
(3)整形データから売買シグナルを生成する
ここからはアイデアと検証を繰り返して売買シグナルを生成することになります。買いシグナルで単純に思いつくのは移動平均との乖離率が大きくなったら買いシグナルとか、ボリンジャーバンドの下限に達したら買いシグナルなどではないでしょうか。なお、保有している株のリターンが10%超えたら利食いとか、保有期間が30日を超えたら売りなどは保有している株に対する条件なので、この初期設定で行う売買シグナルとは少し違います。ここで設定する判断は保有ポジションとは関係ないエントリーの判定に用いる基礎条件で株の状態として売りなのか買いなのかを判断するものと考えてください。
引数データを整形して作成した、終値データcpもちろん始値や高値などから何かを判定しても良いです)に対して何かを条件に買シグナル、売シグナルを発生させることを考えます。売買シグナルの判定の元になる移動平均線やボリンジャーバンドなど各種関数については都度ライブラリやその使い方を覚えることになります。ここでは最も簡単な25日移動平均線とその乖離率で買いシグナル、売りシグナルを発生させるサンプルを見てみます。
# 終値基準の25日移動平均線データを作成する
m25 = cp.rolling(window=25, center=False).mean()
# 乖離率を算出
ratio = (cp-m25) / m25
# 売シグナル
sell_sig = ratio > 0.20
# 買シグナル
buy_sig = ratio < -0.20
# 売買シグナルの作成
market_sig = pd.DataFrame(data=0.0, columns=cp.columns, index=cp.index)
market_sig[buy_sig==True] += 1.0
market_sig[sell_sig==True] += -1.0
return {
"market:sig" : market_sig
}
簡単すぎると思われるかもしれませんが、これで対象の全銘柄に対して終値の25日移動平均を計算して、そこからの終値の乖離率が+20%を超えて上回っていたら売シグナル、-20%を超えて下回っていたら買シグナルを生成。さらにその結果を参照してmarket_sigに対して、買シグナルが成立していれば1.0、売シグナルが成立していれば-1.0、どちらでもない場合には0をセットする処理になっています。今回はbuy_sigとsel_sigが同時にTrueになることがない処理のためmarket_sig に対する演算が、+1.0、ー1.0としているのは意味がないですが、売シグナルと買シグナルが同時に成立することがありうる判定条件の場合に、market_sigが0となって売買なしの判定とすることができます。
ポイントとしては、行列で一気に全銘柄に対して処理が行えてしまうことと、事前にcpで準備しておいたFrameData(index=date , columns=symbol)構造のcolumnsとindexを利用して、market_sig を pd.DataFrame(data=0.0, columns=cp.columns, index=cp.index)で初期化し、売買シグナルの立っているところを書き換えるところでしょう。
最初の25日移動平均を求める処理 m25 = cp.rolling(window=25, center=False).mean()は少しわかりにくいかもしれません。.ここで詳細を理解しなくても問題ありませんが、終値のDataFrameであるcpに対して、rollingという関数で25個分のデータに何らかの処理(window=25)をして、centerには配置せず最終データの部分に配置(center=False) することを宣言した上で、その何らかの処理としてはmeanによる平均値算出を使用するということです。これにより25個のデータの平均が25個目のデータ位置に格納されます(25日分データが取れない24日目までのところはNaNとなります)なお、centerには配置とは25個のデータであれば13番目のデータということになります。偶数個のデータの場合には中央が2つ存在しますが後ろ側のデータを中央とします。
まとめ
・引数から整形したデータを色々加工して売買シグナルを作成する
・売買シグナルmarket_sigはDataFrame(index=date,columns=symbol) 型であり、引数から整形したデータのindex、columnsをそのまま利用して作成できる。
・作成した売買シグナルは、dict として、”market:sig” : market_sig の形で返値とする。