1;//上記で波形の近似性を見ている。モメンタム合計/絶対値合計*100にて%化している。1);}※利益の増加や損失の減少を保証するものではありません。ご自身の判断にてお取引いただきますようお願いいたします。デバッグログでデバッグ!そして・・発見!EAですが、バックテストから、正しく動作しているかテストは必須です。ストラテジーテスターの操作履歴を追いかけるのもありですが、わかりやすくファイルに出力できれば、テストがはかどります。今回はCSV形式で取引結果をファイルに出力し、シグナルと取引が正しいかどうか確認したいと思います。前回の記事で書いた通り#ifdefを使用してデバッグコードを埋め込みます。シグナルとポジション数をCSVに出力してシグナル通りに売買が行われているか確認したいと思います。Sample1のコードを下記のように追加&修正しました。前回までの売買シグナルと違う値の場合、ポジションをいったん全決済する。シグナルが出ている間、1分毎に時間をずらして購入していく。DEBUG//SendOrderの結果をCSVに出力する。WriteTradeLog(signal);#endif}//トレーリングを行う。signal){//ログファイル名が重複するのを避けるため、後ろに番号をつける。ログなのでファイルオープンできなかった場合は、何もしない。現時点でのオーダー数を取得する。orderCount[5]);FileClose(handle);}#endifコンパイルが通ったので早速バックテストを再度実行します。ここで生成したファイルはWindows7の場合、次のフォルダに出力されていました。c:\Users\(ユーザ名)\AppData\Roaming\MetaQuotes\Terminal\(口座毎のシステムID)\tester\filessample1Log(バックテスト実行日時).csvファイルが作成されていれば成功です。中身を見てみましょう。・・・・・おっと、いきなりシグナルが0状態で売ポジションが1になっています。バグ発見!このようにわかりやすい形でファイルを出力することによりテストが行いやすくなります。ログを工夫することでさまざまなデータをとることが可能です。バグを修正したコードがこちらです。前回までの売買シグナルと違う値の場合、ポジションをいったん全決済する。シグナルが出ている間、1分毎に時間をずらして購入していく。DEBUG//SendOrderの結果をCSVに出力する。WriteTradeLog(signal);#endif}//トレーリングを行う。){Trainling(Limit);}}修正した結果のログはこちらです。シグナルの方向と売買の方向が一致するようになりました。実は、最大ポジション数を増やしても取引数が増えない問題が残っています。バックテスト固有の問題かもしれませんが、モデルを「全ティック」にして実行しても、OnTick内のTimeCurrent()で取得できる時間は、設定されている時間足(たとえば15分であれば、15分毎)になってしまい、時間の比較関数が正しく動作していません。調べてみないといけない項目のようです。(追記)時間について、少し調査してみましたが、TimeCurrent()の値が時間足の値になっているわけではなさそうです。バックテスト中はTimeCurrent()とTimeGMT()が同じ値が戻ってくるというのもちょっとショックです・・・。今作っている休日判断ロジックがバックテスト中は正しく動作しない様子です・・・。(泣)��追記2)落ちとしては、ストラテジーテスタのエキスパート設定を開きパラメータをリセットしたら正しく動作しました・・。ソース上でデフォルト値を変更しても、エキスパート設定でリセットしないとデフォルト値は反映されない事をすっかり失念していました。バグとしてもう一か所、初期化時にMaxPositionの設定をしていない箇所がありましたので修正しました。MaxPosition);return(INIT_SUCCEEDED);}テストは大切!!!ということを改めて感じました。バックテストを実行してみよう。サンプルのEAを作成したため、次はバックテストを行ってみたいと思います。MT4のバックテストはEA開発者だけではなくEAを使う人にも必須の作業のようで、あちこちのページに方法が書かれています。メタトレーダーのバックテスト方法このページを参考にバックテストを実施する為の準備を行います。作成したEAのバックテストを実行してみましょう。エキスパートアドバイザーの選択は、前回の記事で作成したSample1を選択します。「終了日」2014.12.31と14年間を選択します。誤訳かリソース設定ミスかと思いますが開始日のことです。)2,3分放置すると終了します。ま、こんなもんですよね。素直に動作すればよいのですが、実際にはロジックミス等が発生して取引しないことも多々あります。新しいMT4にはデバッガが搭載されていて、動作させながらのデバッグも可能です。豊嶋先生のコラムにやり方が具体的に記載されています。MT5向けですが、新しいMT4ではメタエディタがMT5と統一されているため、MT4でも対応可能です。(豊嶋先生のブログにはいつもお世話になっていてEA開発者として尊敬するばかりです。本も数冊買わせていただきました。)ただし、デバッグを行うときには、現在の選択口座がデモ口座になっているか注意したほうがよさそうです。自動売買を行うチェックを間違えて入れっぱなしにしていた時、大参事になる可能性があります。こちらのデバッグだと、現在の値を見てシグナルを発生させたりしますが、たまにしかシグナルを出さないようなEAだとテストに時間がかかります。その場合は、コード内にPrint文を埋め込んでバックテストの操作履歴タブにて確認していきます。長い期間を行うと操作履歴が大量に発生しますので、「日付と時間を使用」を予想される数トレード分ぐらいにしてから実行して確認していきます。Sample1の中のGetSignal関数に正しく5分おきに過去シグナルを更新しているか確認するPrint文を埋め込んでみました。売買シグナルを取得する。;//確定したモメンタムが100の境界を超えたかどうか。必要な時だけ、パラメーターを計算するようにする。現在のモメンタムがシグナル値と同じ方向にあるかどうか。同じ方向にない場合、シグナルを取り消す。;}操作履歴タブには、埋め込んだPrint文の出力結果が表示されています。バックテストでテストをする場合、基本はPrint文でコツコツと確認していく方法になりそうです。#endifで囲った中に記載しています。DEBUGがどこかに定義してある場合、この中を有効にするというプリプロセッサとなります。DEBUGを入れたり消したりすることでプログラムの動作を変えることができます。if文での判定でも同じ動きをしますが、デバッグコードの場合、#ifdefで行うのが一般的です。これは#fidefはコンパイル時に判定する為、条件が成立しない場合は最終的な実行ファイルにはコードの内容が含まれません。そのため、デバッグコードによるパフォーマンスの低下を避けることが出来ます。ちなみにストラテジテスターの操作履歴は、ファイルとしても残っています。Windows7の場合は下記でした。c:\Users\(ユーザ名)\AppData\Roaming\MetaQuotes\Terminal\(口座毎のシステムID)\tester\logs口座IDはメタエディタのナビゲーターの適当なフォルダのプロパティを表示すると、フォルダのプロパティが表示されます。フォルダプロパティの場所の項目にWindows上でのフォルダが表示されていますので、そこからたどることが可能です。操作履歴ベースでのファイルだと、正しくシグナルが出ているかどうか判定が難しいです。そこで、次回はバックテスト中のシグナル結果をcsvに出力する方法を書いていきたいと思います。オシレーターを作成してみた。RSI(StochRSI)が見当たらなかった為、作ってみました。ストキャスティクスRSIはRSIの値をストキャスティクス計算式に押し込んだグラフとなります。ストキャスティクスやRSIは価格に対する高値低値の割合をベースに計算していますが、RSIの値をストキャスティクスとしてグラフ化することによって、相場の勢いの変化をみるできます。トレンド時の押し目狙いなどに効果を発揮します。バイナリオプションでのハイロー選択の指標にも有効そうです。画像のように小さな値幅でだらだらと一方向に動き続けるような相場ではダミーのシグナルが発生していますが、前回ストキャス値がどこまで行っているかを見ることにより手を出すべきかどうかを判断できます。コードはMT4についていたStochastic.mq4を改造する形で作成しました。RSIの値とStochRSIのグラフを描画するインジケータです。prev_calculated.return(rates_total);}元のコードと比較すると、ちょっとだけ、初期化処理を自分でわかりやすいようにまとめました。初期化の中で次の関数をコールしています。開始位置);これは、たとえば移動平均などで、ある程度のデータがそろってからではないと、描画できないような場合、描画開始する位置をずらすという指示をしています。計算処理の部分は、Stochastic.mq4がArraySetAsSeries関数にて、時系列配列から普通の配列に変更してから計算していたため、その流儀に合わせて作成しています。ほしい方がいらっしゃったら試してみようかな・・・。計算する方法もありますが、MQL4にある程度日付に関する関数がありますので、それを活用します。月頭の0時0分0秒から1秒引いた際の日付を取得しています。モメンタム&トレイリングEAまぁなにあともあれ、作って動かしてみないとよくわかりません。いうことで、適当に作ってみることにしました。・ポジションクローズ戦略があると仮定しました。今回は下記の戦略で考えてみました。確定したモメンタムが100未満なら売りシグナル、100より大きければ買シグナルただし、現在のモメンタムが確定したモメンタムと逆方向の場合シグナルを取り消す。同じ方向にシグナルが出ている間、1分毎にポジションを増やす。最大ポジション数は外部から設定する。外部から与えられたリミット設定を元に、損失を固定する。上値が拡大した場合、ストップ値を移動して損失を減らしていく。他のEAと当らない値を使用する。前回までの売買シグナルと違う値の場合、ポジションをいったん全決済する。シグナルが出ている間、1分毎に時間をずらして購入していく。currentTime;}//トレーリングを行う。サンプルなので通信エラーは考えていない。売買シグナルを取得する。(2)//確定したモメンタムが100の境界を超えたかどうか。必要な時だけ、パラメーターを計算するようにする。現在のモメンタムがシグナル値と同じ方向にあるかどうか。同じ方向にない場合、シグナルを取り消す。;}ソースコード補足です。��1)staticとdatetimeについてstaticを使用してローカル変数を永続化しています。書くと難しいですが、通常、関数内の{}で閉じられた範囲で宣言された変数は、関数の呼び出しの度にリセットされますが、staticをつけておくと、前回の値を記憶するようになります。TimeCurrent();と書いておくと、最初の一回だけ、TimeCurrent();からの値で、beforeTimeは初期化されますが、以後はこの構文は飛ばされます。関数内の前回値を記憶しておきたい場合などに使用します。今回datetime型を使用しています。00:00:00からの秒数を整数値で表した型となります。ちなみにロシア時間基準のようです。今回組み込み関数のiMomentumを使用しています。シフト);シグナル生成処理は気配値更新の度に呼び出されるように記述しています。過去のモメンタムについては確定している物であり毎回計算する必要性がありません。と今回判断時間を比較して、更新必要があるときにのみ計算するようにします。今後説明するバックテストを効率よく行うためにも、時間を確認して必要なときのみ計算を行うテクニックはEAでは必須のようです。)の有り無しで、バックテストの実行時間差は私の環境ではこのようになりました。2:05モメンタムの計算だけでは、それほど大きな差にはならないようです。最適化を行うと、この8秒が何十倍になると思うとやっておくのに越したことはなさそうです。750とか、ほしい・・・・。★相互リンク募集中★トレードステーションと株・FX自動売買で暮らす茶トラがFX検証中。人気の投稿[MT4プログラミング]MT4のチャート上に矢印を表示する。(6)レンジ・エクスパンション・インデックス(REI)を作ってみた。バックテストを実行してみよう。オシレーターを作成してみた。