QuantXでボリンジャーバンドのアルゴリズムを改良してみる


QuantXに初挑戦!

自己紹介

理系大学で、統計を専攻しています。
pythonは初心者で、金融に関してはファイナンスを少しかじってました。
SmartTradeでインターンをすることになりました、よろしくお願いします!!

開発に慣れるためにも、QuantXを使ってアルゴリズムを一つ作ってみました。qiita初投稿としてまとめてみました。

目標

QuantXに慣れる、一つアルゴリズムを作ってみる。

作りたいアルゴリズム

ボリンジャーバンドの特徴を活かしてトレードします。
スクイーズではσバンドで逆張りのシグナル
エクスパンションのときは順張りのシグナル
この2点を踏まえて、順張りと逆張りを切り替えるアルゴリズムを作っていきます。

参考サイト
ボリンジャーバンドの使い方・見方 順張り・逆張りで使えるテクニカル分析

完成コード

完成したコードはこちら

解説

重要な部分だけ少し解説してみます。

1.使用する関数の作成 

エクスパンドを判定してフラグを立てる関数 #6~#16

def judge_expand(ar_upperband,ar_lowerband,m):
    ar_volatility = ar_upperband - ar_lowerband
    list_vol = ar_volatility.tolist()
    list_expand = [0]*len(list_vol)

    for i in range(m,len(list_vol)):
      if list_vol[i] > 3*min(list_vol[i-m:i]):
        list_expand[i]=1

    return np.array(list_expand)

引数に配列ar_upperbandar_lowerband、整数mをとります。

  ar_upperbandar_lowerbandにはボリンジャーバンドの上と下の値が格納されています。ボリンジャーバンドの幅はその差であり、ar_volatilityに格納し、.tolist()でリストlist_volに直します。
  また、エクスパンドしているかどうかの状態を0/1で格納するリストlist_expandlist_volと同じ長さで値は全て0で用意しておきます。

今回はエクスパンドしている状態を、「過去m日のボリンジャーバンドの幅の最小値の3倍をその日のボリンジャーバンドの幅が越えればエキスパンド している」、と定義します。

list_expandへの数字の格納の仕方は下図のようになります。

最後にlist_expandを配列に直して返します。

バンドをはみ出したかを判定してフラグを立てる関数 #18~#26


#バンドの上をはみ出したかどうか判定する関数
def judge_plus_sigma(sr_upperband,sr_price):
  ar_a = np.greater(sr_price,sr_upperband)
  return ar_a.astype(int)

#バンドの下をはみ出したかどうか判定する関数
def judge_minus_sigma(sr_lowerband,sr_price):
  ar_a = np.less(sr_price,sr_lowerband)
  return ar_a.astype(int)

引数はpandasのseriesであるsr_upperbandsr_lowerband)、sr_priceをとります。sr_upperbandsr_lowerband)はボリンジャーバンドの上(下)の値、sr_priceは終値が格納されています。
ボリンジャーバンドの上(下)の値を、終値が超えたら(下回ったら)、trueをar_aに格納します。最後にtrueを1に直して返します。

2.フラグをシグナルに変換する部分 #85~#88

df_ag_buy_sig[sym] = df_minus_sigma[sym] - df_minus_sigma[sym]*df_expand[sym]
df_ag_sell_sig[sym] = df_plus_sigma[sym] - df_plus_sigma[sym]*df_expand[sym]
df_fol_buy_sig[sym] = df_plus_sigma[sym]*df_expand[sym]
df_fol_sell_sig[sym] = df_minus_sigma[sym]*df_expand[sym]

ここでは株価が立てたフラグを、シグナルに変換していきます。

df_が付いているのは、全てindexが日付、columnsが銘柄のpandas.Dataframeです。

  • df_minus_sigma: 終値がボリンジャーバンドの下を下回っていたら1、そうでなければ0、が入っている
  • df_plus_sigma: 終値がボリンジャーバンドの上を超えていたら1、そうでなければ0、が入っている
  • df_expand: エクスパンドしたら1、そうでなければ0、が入っている

この3つは上で用意した関数を使って格納しています。
また、以下のデータフレームに

  • df_ag_buy_sig: 逆張りで買いのシグナル
  • df_ag_sell_sig:逆張りで売りのシグナル
  • df_fol_buy_sig:順張りで買いのシグナル
  • df_fol_sell_sig:順張りで売りのシグナル

を格納していきます。

上3つのフラグのデータフレームから下4つのシグナルのデータフレームへの変換は、コードの式を使えば変換できます。

真偽値表のようなものを見るとわかりやすいでしょうか...
左3つを、右4つに変換します。

超える 下回る エクスパンド 逆張り買い 逆張り売り 順張り買い 順張り売り
1 0 0 0 1 0 0
1 0 0 0 0 1 0
0 1 0 1 0 0 0
0 1 1 0 0 0 1

結果


markdownは大きく、αも小さい...
初アルゴということで許してください笑

個別

一つの銘柄に注目してみると...

三菱総研

順張りのシグナルを表示してみましたが、思い通りに動いていそうですね!

日揮

これは、シグナルがエクスパンド後に出てしまっています、判定の関数のパラメータを変える必要がありそうです。

最後に

とりあえず初アルゴリズムはこれくらいで...
このアルゴリズムのブラッシュアップや、他のアルゴリズムの作成など、どんどん行っていきたいと思います!

勉強会の宣伝

SmartTrade社では毎週水曜日18:00から勉強会を行っています。(https://python-algo.connpass.com/)

免責注意事項

このコードや知識を使った実際の取引で生じた損益に関しては一切の責任を負いかねますので御了承下さい