遺伝的アルゴリズムを用いたシステムトレードの売買ルール構築

#はじめに
今までtwitterの方でシステムトレード関連の話題を書いてきましたが、今回からQiitaを用いる事にします。主に最適化アルゴリズムや学習アルゴリズムを用いたシステムトレード手法についていろいろ書いていこうと思っているのでよろしくお願いします。

さて、記念すべき1回目ですが、遺伝的アルゴリズム（以降GA）を用いたシステムトレードの売買ルール構築について話していきます。システムトレードに用いる売買ルールは従来ならばユーザが独自の判断で決めていたものですが、今回はGAを用いる事でシステムの方で利益が出そうな売買ルールを自動構築していきます。このシステムがあればFXの知識が浅い初心者でも取引が行えますので参考にしていただけたら幸いです。

※本記事はGA、テクニカル指標、MT4の知識がある前提で話を進めていきます。よろしくお願いします。

#GAによる取引戦略の最適化
システムに用いる取引戦略ですが、今回は仕掛けシグナルと手仕舞いシグナルを用いる事にします。また、それぞれのシグナルでテクニカル指標を4つずつ用意する事にします。4*4=16通りのパターンを過去の期間に適応する事により最も利益の得られる売買ルールをGAを使って見つけていくという方法です。その時に各テクニカル指標のパラメータもGAを用いて最適化します。今回用いたテクニカル指標は以下の通りになります。

　　　　　　　　表1:使用したテクニカル指標

|指標|トレンド系| オシレータ系 |
|:-----------:|:------------:|:------------:|
移動平均（SMA）|○| |
RSI |  | ○ |
チャンネルブレイクアウト |○||
ボリンジャーバンド ||○|

※チャンネルブレイクアウトとボリンジャーバンドについては売買条件を変える事でトレンド系とオシレータ系の両方として扱う事が出来ます。今回はチャンネルブレイクアウトをトレンド系、ボリンジャーバンドをオシレータ系として使います。

　　　　　　　　　表2:テクニカル指標で用いたパラメータ

|指標|パラメータ|変化量|
|:-----------:|:------------:|:------------:|
移動平均（SMA）|短期:5～30　長期:10～50|短期:5　長期:10|
RSI | 日数:10～50 | 日数:10 |
チャンネルブレイクアウト |日数:10～100|日数:10|
ボリンジャーバンド |日数:10～30　係数:1.0～3.0| 日数:10 係数:0.5|


　　　　　　　　　　　　　　　　表3:テクニカル指標を使った取引戦略

|指標|仕掛けシグナル|手仕舞いシグナル|
:---:|:---:|:---:
移動平均（SMA） | ゴールデンクロスで買いポジション、デッドクロスで売りポジション | ゴールデンクロスで買い決済、デッドクロスで売り決済  |
RSI | RSIが70以上で買いポジション、30以下で売りポジション | RSIが70以上で買い決済、30以下で売り決済 |
チャンネルブレイクアウト | 現在の価格が過去n日間の高値を上回った時に買いポジジョン、現在の価格が過去n日間の安値を下回った時に売りポジジョン | 現在の価格が過去n日間の高値を上回った時に買い決済、現在の価格が過去n日間の安値を下回った時に売り決済 |
ボリンジャーバンド | バンド上限を上回った時に売りポジション、バンド下限を下回った時に買いポジジョン | バンド上限を上回った時に売り決済、バンド下限を下回った時に買い決済  |


#評価方法
最適化の評価方法ですが、今回はプロフィットファクター（以降PF）と取引回数を用いる事にします。PFとは以下の式で表され、値が高いほど期間中で利益が上げられている事が分かります。

PF=総利益/総損失

そして取引回数は文字通り、取引を行った総回数を表しています。取引回数が少なすぎると1回の利益による影響が大きくなりシステムの正しい性能を計る事が出来ないため、今回は取引回数が100回を超えているものを対象とします。

#シミュレーション設定
今回はMT4の中に内蔵されているGAを使って最適化の方を行っていきます。この時に売買ルールの選択と各テクニカル指標のパラメータ選択は同じEAの中で行っていきます。ソースコードは全て記すと膨大な量になりますので、大まかな流れだけ載せておきます。

```MQ4
//トレードに用いるパラメータ（売買ロットや許容スリップページ等）や各テクニカル指標のパラメータを変数として宣言します。externを用いる事で値を変更する事が出来ます。

int start(){
    //処理に使う変数の宣言

    //オーダーチェック

    //仕掛けシグナルが移動平均のみ
    if(~){
        //ポジションチェック（ポジションなしの場合）
        if(~){
            //買いポジションの条件と処理を記入

            //売りポジションの条件と処理を記入
        }
    }

    //手仕舞いシグナルが移動平均のみ
    if(~){
        //ポジションチェック（ポジション有りの場合）
        if(~){
            //ポジションの選択

            //ポジジョンの確認

            //もし買いポジションなら
            if(~){
                //手仕舞い（売り決済）の条件と処理を記入
            }
            //もし売りポジションなら
            else if(~){
                //手仕舞い（買い決済）の条件と処理を記入
            }
        }
    }

    //以降同じ形でRSIとボリンジャーバンドとチャンネルブレイクアウトの処理を記入

    return(0);
}
```
また、シミュレーションを行う条件は以下の通りになります。

　　　　　表4:シミュレーション条件

|項目|内容|
|:-----------:|:------------:|
通貨ペア|EUR/USD|
売買ロット|1万ユーロ|
許容スリップページ|0|
時間足|1時間足| 
最適化期間|2015/01/01～2015/06/30|
トレード期間|2015/07/01～2015/12/31|

※シミュレーション時にモデルを全ティックにすると最適化にものすごく時間がかかります。そのため今回は最適化期間、トレード期間ともにコントロールポイントを使用します。この辺りは細かい設定になりますので分からない人は[MT4の書籍](https://www.amazon.co.jp/gp/product/B017HFIIEA/ref=as_li_ss_il?ie=UTF8&camp=247&creative=7399&creativeASIN=B017HFIIEA&linkCode=as2&tag=toyolabfx-22 "MT4の書籍")をご覧ください。

#シミュレーション結果（最適化期間）
最適化期間でシミュレーション（以降バックテスト）を行ってみた結果、次のようになりました。

![1.PNG](https://qiita-image-store.s3.amazonaws.com/0/137627/3627222a-77c9-866f-85f5-f34269178538.png)

　　　　　　　　　　　　　　　　　　　　図1:最適化結果

![3.gif](https://qiita-image-store.s3.amazonaws.com/0/137627/c94cb829-f856-ce72-30ca-952c711bd313.gif)

　　　　　　　　　　　　　　　　　　図2:バックテストの資産曲線

図1において赤枠で囲まれている部分が最適解になります。この時の売買ルールは仕掛けシグナルにチャンネルブレイクアウト、手仕舞いシグナルに移動平均線を使ったものになるので、この売買ルールをトレード期間に用いる事にします。また、それぞれのテクニカル指標で用いたパラメータの最適解は次のようになりました。

　　　　　表5:パラメータの最適解

|指標|パラメータ|
|:-----------:|:------------:|
移動平均（SMA）|短期:30　長期:10|
チャンネルブレイクアウト |日数:30|

#シミュレーション結果（トレード期間）
最適化期間で求めた売買ルールと各パラメータを使ってトレード期間でシミュレーション（以降フォワードテスト）を行ってみた結果、次のようになりました。

![5.gif](https://qiita-image-store.s3.amazonaws.com/0/137627/ffcf3593-d4de-9657-a0a6-0565f23e93b5.gif)

　　　　　　　　　　　　　　　　　　図3 フォワードテストの資産曲線

　　　　表6:バックテストとフォワードテストの比較

|---|取引回数|純益[$]|最大DD[$]|PF|
|:-----------:|:------------:|:------------:|:------------:|:------------:|
バックテスト|116|1570.45|546.26|2.01|
フォワードテスト |116|172.08|986.19|1.08|

図2と図3を比較してみると明らかにフォワードテストの方が悪い事が一目で分かりますね。表6に詳しい結果を載せていますが、純益、最大DD、PF全てでバックテストより劣っています。ではなぜ、このような結果になったのでしょう？ちなみにこの結果になる事はシミュレーションを行う前から予想がついていました。

#オーバーフィッティング
取引手法の最適化を行う場合、最適化期間とトレード期間で利益に大きな差が出る事がよくあります。これをオーバーフィッティングといい、最適化期間の相場に対して必要以上に最適化を行っている事が原因でトレード期間の相場では動きが違うために安定した利益が得られないという問題です。オーバーフィッティングの原因としては主に以下のようなものが考えられます。

・最適化期間の中で底と天井の取引を多く行ってしまっている
・各テクニカル指標のパラメータが期間を通して固定されている

オーバーフィッティングの問題を解決するために取引中の損益推移を考慮したりパラメータを時変させたりといった研究が行われていますが、自分はこの解決法に学習アルゴリズムを使っていきたいと考えています。学習アルゴリズムについてはまた別の機会に記事を書きたいと思いますのでそれまでお待ちください。

#むすび
今回は複数のテクニカル指標がある中で売買ルールを自動構築する方法について紹介しました。取引戦略の部分で仕掛けシグナルと手仕舞いシグナルを使いましたが、これは基本的な戦略ですので各自でお好みにフィルタなどを追加すると面白いかもしれませんね。本記事は趣味の1つで書いているので専門家達から見れば所々に間違いがあると思いますが、こういう考え方もあるのかぐらいに見てもらえれば嬉しいので、今後ともよろしくお願いします。