EA実行中にテクニカル指標のパラメータを変えるには?

移動平均やRSIなどのテクニカル指標には、期間や倍率などのパラメータが付き物です。

システムの開発過程では、これらのパラメータの値を色々と変えてバックテストを繰り返すことがありますが、実際にEAとして運用する際には、各パラメータの値は固定することがほとんどです。

今回の記事では、EAの実行中にテクニカル指標のパラメータを変化させることを考えてみます。

パラメータの値を変える目的は色々あるでしょうが、ここでは、次のようなケースを想定します。

パラメータの値を色々と変えてバックテストした結果、下の図のように評価値の高い範囲がある程度広がっているケース

TesterOptgraphReport2015.05.09.1

この図では20がベストですが、バックテストで最適な値が別の期間でも最適である保証はありません。その前後の値も候補として残しておきたいところです。

もちろん、EAをたくさん起動できるのであれば、パラメータをそれぞれ変えて動かせばよいでしょう。しかし、たくさんのEAを動かせない場合や、パラメータの組み合わせの数が多すぎる場合には、すべての候補値を試すことはできません。

そこで、EAの実行中にパラメータの値が定期的に変わるシステムで代用できないかと考えました。

EAのサンプルとして、よくある2本の移動平均の交差によるシステムを取り上げてみます。

仕掛けのプログラムは、黄色本78ページの「Include\MyLib\EntryMA2Cross.mqh」というヘッダファイルを参考にします。

このプログラムでは、短期移動平均の期間「FastMAPeriod」を20、長期移動平均の期間「SlowMAPeriod」を40に固定してあります。

これを、「FastMAPeriod」の値が19から21、「SlowMAPeriod」の値が34から36の中からランダムに選ばれるように変えてみます。

変更する箇所は、テクニカル指標を初期化する条件です。

今回は一定時間毎にパラメータを変化できるよう、テクニカル指標を設定した日時を記憶する変数「MACreateTime」を用意します。そして、これが0の場合か、直近の設定日時から一定時間経過した場合にテクニカル指標を初期化するようにします。

そして、テクニカル指標の設定の際に、「FastMAPeriod」、「SlowMAPeriod」をMathRand()関数で算出してCreate()関数に渡します。

これらの修正を加えた仕掛け関数EntrySignal()を次に示します。

このプログラムでは、TimeCurrent()関数で現在の日時を求め、それが「MACreateTime」より一定時間(1週間の場合、60*60*24*7秒)大きくなったときにテクニカル指標の再設定を行っています。

あと、決まった範囲の乱数の作り方は、MathRand()%3で、0,1,2のいずれかの数を返すので、それに一番小さい候補値19を足すだけです。これで19,20,21のいずれかの数がパラメータとしてセットされます。

このファイルを「EntryMA2CrossRand.mqh」とすると、全体のEAのプログラムは次のようになります。

ここでひとつ注意することは、乱数の初期化です。

MathRand()で生成される乱数は、でたらめな並びで現れるように見えますが、実際には非常に長い周期の数列です。なので、乱数をスタートさせる位置が同じなら、同じ乱数列が出てきます。

それを防ぐために、乱数のスタート位置を変える必要があります。そのための関数がMathSrand()です。引数に毎回違う数値が入るようにすれば、乱数のスタート位置を毎回変えることができます

ここでは、システム起動時からの経過時間をmsで返す関数GetTickCount()を使っています。MathSrand()をEAの最初、つまり、OnInit()関数中に記述しておけばOKです。

このEAを実行すると、1週間毎にパラメータの値がランダムに変化していくことになります。

ただし、このEAをストラテジーテスターでバックテストすると、毎回違う結果が出てくることになります。評価が難しいかもしれませんが、テストする期間を変えても極端に悪いケースが出てこなければ、まあ合格といったところではないでしょうか。


コメントは受け付けていません