2011/05/23

MT4用EA開発時代 - 今後のEAテスト計画と、新たに気付いた落とし穴/追加した機能



★★★ 以前の改訂版記事で証拠金維持率の計算式が間違えていたので修正しました ★★★
さて前回は、start()関数内のプログラムの流れについて書きました。今回は、MT4用EAのテスト方法と、テストに向けて、機能追加分とか「落とし穴」の整理してからの話を書いてみたいと思います。

今回の開発は、仕掛けと決済という最低限の機能を作成してから、デモ口座でEAを動かし続けながら、ちょっとづず必要な機能を追加していく方法をとってた。

そして、裏でブログ記事という名のもと、検討を深めて機能を追加したり具体化したり。なので、機能面の追加/変更点を纏めてみた。
※ちなみに、元々予定していた機能を纏めた記事はコレ

まずは、追加した機能。

【追加した機能】
-----------------------
1.発注/決済関連機能
  ・MODE_FREEZELEVEL対策
  ・価格不一致等のエラー検出時に次のティックデータ受信を待つ場合、
   次のバーまでNGであれば、メール通知する機能
  ・自発的手仕舞いエラー発生時にCRITICALエラーにしていたのを、WARNINGに変更
2.マネージメント関連機能
  ・ロット数を制限する機能
   最大ロット数を、証拠金(AccountEquity())の一定率に制限する機能。
   これで制限された場合、[[INFO]]レベルのログ出力を行う。
  ・証拠金維持率が一定以下になると、新規発注停止
   新規発注する際、発注する事で証拠金維持率が一定以下になった場合は、
   発注せずに、[[CRITICAL]]レベルのログ出力及び、通知メール送信。
   そして、新規発注停止状態にする機能。
  ・戦略ストップ機能の詳細化
   ドローダウン率で戦略ストップする事に。
   チェックレベルを2段階設け、1段階目では[[WARNING]]ログ出力と、メール通知のみ。
   2段階目では、[[CRITICAL]]ログ出力、メール通知、新規発注停止。
   この条件で新規発注停止となった場合は、MT4を再起動しても新規発注されない様に。
3.共通部品の追加API
  ・以下のタイミングで売買ルール固有の関数を呼び出す機能の追加
   ペンディング・オーダが約定されたタイミング
   ポジションが決済されたタイミング
   バーが進んだタイミング
   ティック毎
  ・マネージメント関連機能の制約に基づいた最大ロット数を返却するAPI
  ・マネージメント関連機能の制約に基づいて指定されたロット数で発注できるか
   確認するAPI
  ・発注逆指値/ストップロス価格/決済指値の価格/桁数補正するAPI
  ・口座残高からロット数を計算するAPI
4.MarketInfoの各種情報を起動時にログ出力する機能
  [[INFO]]レベルで出力する様にした。
  → サーバ側の設定を記録しておきたいので。
----------------------

次は、実際プログラミングしたりデモ口座で動かしてて、判った「落とし穴」たち。
裏を返すと、こういった事もテスト項目に含めないと。。
#特に、MT4の特徴とか、タイミングのズレに関するものに絞った。一部過去記事と重複あり。

【新たな落とし穴たち】
--------------------------------
1.OrderSelectをループして保有中ポジションを取得するロジック
  保有中ポジションを探す部分で、OrdersTotal()分だけOrderSelect()をループさせて
  いたが、SELECT_BY_POSでインデックスを「0」からしてしまっていた。
  インデックスをOrdersTotal()→「0」の順でしないといけなかった。
  理由は、以下のブログ記事を参照してください。
2.OrderSelectでTRUEが返ってきても実は決済されている事がある
  なので、OrderCloseTime()がゼロである事を確認する必要がある。
  真偽は他で確認できていないが、この対処での追加ロジックで弊害も無いし、
  確かに処理中に裏で決済されていたらありうる話かも。
  これは、以下のブログ記事に書いてあった。
3.価格比較するとき、NormalizeDoubleを使わないといけなかった
  小数点以下桁数変わらない計算式だったから、NormalizeDoubleしなくてもいいと思ったけど
  なぜか、NormalizeDouble()してないと正しく比較できなかった。
4.init()関数終了前にstart()関数が開始してしまう可能性がある事への考慮漏れ
  これはヘルプに書いてあった。init()が終ってなかったら、MT4内のデータが
  まだ完成されていない状態なので良くないらしい。
5.逆指値はMODE_STOPLEVELからさらに1pips離さないといけない
  逆指値として現在のAsk/Bidから最初離さないといけないpips数をMODE_STOPLEVEL
  分離せばいいと思ってたけど、さらに1pips離さないといけなかった。
6.UninitializedReason()で、テスタ実行終了時のコードはゼロ
  テスタ終了時に大域変数を削除する処理をdeiint()で、UninitializedReason()が
  REASON_REMOVEの時かと思ったけど、実は「0」の時だった。
  「0」はヘルプで「Script finished its execution independently.」と書いてあったので、
  スクリプトの場合のみの話かと思ったら、そうじゃなかった。
7.処理中に保有中ポジション決済されていた場合の考慮漏れ
  リトライ中もポジション決済されていたというケースもあるけど、それでも隙間があって、
  OrderModifyやOrderCloseした時に、既に決済されているタイミングもあることへの
  考慮がもれていた。この場合、何かしらのエラーが返ってくるはずなんだけど、
  何が返ってくるか不明。とりあえず「ERR_INVALID_TRADE_PARAMETERS」と想定。
  このエラーの場合、該当Ticketが決済されているかどうかを確認することに。
8.return文が抜けていてもコンパイルエラーにならない
  よく考えたら、C言語でもコンパイラによってはそうだったかもしれない。
  ともかく、return()文が抜けていても気付かない。
--------------------------------

そしてテストするときは、「追加した機能」とか、いろんな「落とし穴」への対策も含めて、MT4用EAで実現したはずの機能が動作するかどうかまでを確認したい。でも、テスタだけでは確認できない機能が多数。
#ちなみに、トレードパフォーマンスはテストの対象外で、あくまでEAのプログラム品質確保のためのテスト。

例えば、以下の課題をクリアしないといけない。

【テストでクリアしないといけない課題】
----------------------
1.エラー検出時
  テスタだと発生しない様なエラーを検出した場合(通信障害とか)。
  今は4H足でトレード回数も少ないので、今のままだといくらデモ環境で
  動かしても、めったにエラーに出くわさない。。。
2.タイミングのズレ対策機能
  ・保有中ポジションに対する処理中に該当ポジションがSL/TPで決済
   された場合等のタイミングのズレ対策を検証するテスト。     
  ・処理中に新たなティックデータが来て大きく価格が動いた場合のテスト
3.運用系機能
  運用中にMT4の再起動や、計画停止指示、大域変数読み込み指示、
  プロパティ変更を保有中ポジション決済後適用等の、運用する為の機能。
  → テスタだと、最初から最後まで動いてしまって、途中でプロパティ変更
   /MT4再起動に関するテストができない。
4.証拠金維持率による閾値チェック機能
  これはプロパティをいじって直ぐに閾値に引っかかる様にすればいいかな?
  それはそれとしても、複数ポジション保有で機能するか確認したい。
5.ブログ記事に載せた機能は割りと大まかなレベルでかいている
  でも、実際のプログラムでは、もっと細かいレベルでいろんな機能があって
  それが、纏まっていない。
6.できればいろんなFX業者で動作する共通部品にしたい
----------------------  

まず、基本的なテストの流れとしては以下の様な感じ。
いかんせん一人でプログラムを作ってるので、通常のやり方からいろいろ効率化しないといけない。






手抜きとも言う。





【テストの流れ】
---------------------
1.細かいレベルの機能を洗い出す
  ブログ記事に書いた機能は割りと大雑把な内容。
  本当はプログラム書く前に、これをさらに詳細な内容にした設計書を作る必要がある。
  でも、なんせ初めてのMT4。結局先にプログラムをちょっとずつ作って、
  テスタとデモ口座で動かしながら、気付いた必要機能も追加していってた。
2.上記「1.」を元に、プログラムを目視で1行1行確認する
  これが実は一番バグをたくさん摘出できるから、目視確認する事に。
  本当は、上記「1.」を元に、関数ごとにプログラムの流れを書いた設計書を
  書いて、それを元に実施するんやけど、そこまでようせん。。
3.テスタで確認できる機能は、プロパティをいじる等して機能しているか確認する
  これは、「1.」を元に項目を洗い出して、テスタでできるものはテスタで実施する。
  本当は、上記「2.」で触れてた、今回割愛した設計書を元にテストしてから
  することだけど、作らないから、無理。
4.一定の確率でエラーを返す関数を用意する。
  OrderSend/OrderModify/OrderClose/OrderSelect/IsConnected/IsTradeAllowed等を
  テスト用の関数に置き換える。一定の比率で正常に本当の関数呼出しをして、結果を
  返すが、一定の確率でエラーを乱数で決めて返却して評価。5分足でテスタで評価する。
5.デモ環境で動作させて、いろんな障害とかを発生させる
  これで実際の擬似障害とかを発生させたり、想定している運用手順を実際にしてみたりする。
---------------------

それでも安心して使えるのは、以前の記事で書いた、「マネージメント機能」で生命線となる2つの機能があるから。これさえちゃんと動けば悲劇的な事は無いはず。(多分。。。)









でも、気が遠くなった。。。




さて、上記「1.」~「4.」はブログ記事にしてもつまらないので、今回は「5.」について。
#ブログネタに困れば「1.」~「4.」も登場するかも。。


実はプログラムの大半は、運用系機能とか、異常系とかタイミングのズレに関するものだったりするのでここを手厚くテストしたいところ。

なので、「5.デモ環境で動作させて、いろんな障害とかを発生させる」に関して、以下の様にもう少し検討してみた。

【デモ環境テスト】
------------------------
1.トレード回数を増やす
  今は4H足で1通貨ペアあたり1ヶ月に一回強程度のトレード回数。
  タイミングのズレとか、指標発表時の大きな値動きとか、サーバ障害に当てるには
  トレード回数を増やさないとなかなかあたらない。
  なので、5分足で評価する。
2.今回のタイミングのズレで一番大きな要素は、処理中のSL決済
  なので、SLにすぐにひっかかる様なパラメータに変更する。
3.過負荷試験
  ・CPU過負荷
   裏で、無限ループする様なプログラムをCPU数分動かして、PCを過負荷状態
   にして動かす時期を設ける。(Windowsで効果あるかな?)
  ・NW過負荷
   NW経由の大量ファイルコピーする様なプログラムを書いて、それを裏で動か
   しておく時期を設ける。
  ・複数FX業者デモ環境同時実行
   いろんなFX業者用のMT4デモ口座を作って、たくさんMT4を同時起動させて
   評価する。トレードする通貨ペアも多めに。PCも重くなるし、いろんなFX業者
   のクセとかもわかると、考慮漏れに気付くかもしれない。
4.障害試験
  ・LANケーブルを抜き挿しを繰り返す。
  ・しばらくLANケーブルを抜いてから挿しなおす。
  ・タスクマネージャから、MT4を強制終了させる
   あんまり意味無いかもしれなけど。。。
  ・サーバ障害試験
   ほんもののサーバ障害はたまに発生する。
   なので、リトライしない様なプロパティの設定にしてしばらく動かす。
  ・ディスク障害試験はしない。。。
   本当にPCが壊れたら嫌だし、実際そうなったらバックアップ用のMT4用PC
   に切り替えて運用すると思うし。
------------------------


ざ~っと思いついたのがこんな感じ。
それぞれ1wkずつ実施しても、結構時間かかるなぁ。。。







さらに気が遠くなった。。。



忘れちゃいけないのが、今回のブログ記事内容のテスト対象はMT4用EAのみって事。
つまり、他に作ろうとしているツールとかはまだ作ってないし、当然テストもしてない。
こういうツールの個別のテストも必要だし、MT4用EAとツールの連携部分もテストしないといけない。






頭クラクラしてきた。。。




そういや、今は1本のソースでプログラム書いてるけど、共通部品部分はライブラリ化したいところ。
さらにいろんなFX業者で動作させようとしたら、ECN対応(※)なるものも実現しないといけないっぽい。
※OrderSendの時にSL/TPを指定できない業者があるらしく、一旦SL/TPを指定せずに
 一旦OrderSendして、その後OrderModifyする必要があるらしい。。なんと恐ろしい仕様だ。。








立ちくらみしてきた。。。









 座ってるけど



そして、まだまだ先が長いことを改めて気付いた状態で、「FXシステムトレード初心者奮闘記」の「MT4用EA開発時代」はどこかに向かっていくのでした。。
#みんなどうやってテストしてるんだろう。。。

0 件のコメント:

コメントを投稿