さて前回は、1つのMT4上の複数EAが全てstart()が開始されずに停止していた問題(EA無言停止)の対策について検討した所まで書きました。今回は、前回記事での検討内容と以前の記事で書いたデモ口座期限切れ対策での考慮漏れ/新たに判った事について書いてみたいと思います。
まずは「EA無言停止対策」での前回記事からの変更点。
おさらいをすると、「EA無言停止」の具体的な事象は、通信障害復旧後、MT4のstart()が開始されなくなってしまったという事象。
この事象が発生したのは4つのデモ用MT4のうち1つだけで、発生したMT4では10個の
EAを同時に実行していた。この全てのEAのstart()が開始されなくなってしまってから半日以上気付か
なかったという状況。
EAを同時に実行していた。この全てのEAのstart()が開始されなくなってしまってから半日以上気付か
なかったという状況。
#ODL Japan Build228
【EA無言停止対策の変更点】
-----------------------------------
前回記事を元に実際に設計/コーディングをしている最中に気付けた問題点と、
実際に動かして見て気付いた問題点の2種類があった。
1.開発中に気付いた問題点
今回の構造では、各EAがstart()関数に入ったタイミングで大域変数(Global Variable)に
TimeCurrent()を格納。
TimeCurrent()を格納。
監視用EAは、自分で認識しているTimeCurrent()と、大域変数上の値との差分が指定した
閾値以上になっていれば、該当事象が発生したと判断してMT4を強制再起動するというロジック。
閾値以上になっていれば、該当事象が発生したと判断してMT4を強制再起動するというロジック。
そして、各EAは起動時に該当大域変数をゼロクリアしておいて、監視用EA側はゼロであれば
チェックの対象外としていた。
チェックの対象外としていた。
#起動時に監視用EAによるチェックが先に動いてしまうと誤検知してしまうから。
でも、通信障害発生時への考慮ががっつり抜けていた。
つまり、MT4がしばらく動いていて、通信障害復旧したタイミングで、監視用EAのチェックが
先に動いてしまうと、各EAが大域変数に格納しているTimeCurrent()は通信障害発生直前の
値になっているので誤検知してしまう可能性があるということ。
先に動いてしまうと、各EAが大域変数に格納しているTimeCurrent()は通信障害発生直前の
値になっているので誤検知してしまう可能性があるということ。
同じ事が、MT4を起動したままの状態で、週を跨いだ時も言える。
●対応策
これは比較的すぐ対応策を思いついて、以下の様にした。
監視用EAで、前回取得したTimeCurrent()と今回取得したTimeCurrent()の値が一定時間
以上になった場合、ティック受信の通信障害と判断。
以上になった場合、ティック受信の通信障害と判断。
この時、各EAがTimeCurrent()を格納している大域変数のデータを、監視用EAが最後に取得
したTimeCurrent()の値に置き換える事で対処。
したTimeCurrent()の値に置き換える事で対処。
そしてこの書き換える為の閾値を5分間に設定。
EA無言停止判断の閾値は15分なので、通信障害が5分以下でも問題なし。
ここまでは、割と軽い話。
2.実行してみて気付いた問題点
そして前述のバージョンを1つのデモ環境で1日動かして問題発生しない事を確認したあと、
他の3つのデモ環境にリリース。そして、翌日に旅行へ。
すると、旅行に行く最中の電車の乗り換え中に、EA無言停止によるMT4再起動した旨の
メール通知を受信。
メール通知を受信。
処置しておいて良かった~!!!
との喜びもつかの間、数十分置きに同じメールを受信。
そして遂に再起動回数閾値を超過してMT4は完全停止。
また障害発生システムを作ってしまった。。。
3.実行して気付いた問題点の対応策
今回発生のきっかけとなったのはなぜかUSDZARのみ。
ともかく疑ったのは、USDZARの流動性が低く15分という閾値では短すぎるんじゃないかと。
15分って相当長くしてたつもりやってんけど。。。
そして旅行から帰宅後、ログを見てみると、該当時間帯にUSDZARのチャート上、数十分
ティックデータが更新されてなかった。。
ティックデータが更新されてなかった。。
さて、対応策を幾つか考えて見た。
●対策案比較
案1.閾値の15分を1Hに長くする
メリット :修正が楽
デメリット:実際に問題発生した時に同じMT4に同居しているEA
も検出が遅延してしまう。
案2.警告メールを出す様にして、再起動にする閾値は長い時間にする
メリット :実際にMT4の状況を見て柔軟な対応が可能になる
デメリット:警告メール多発対策が面倒。メール受信毎に外出先でも状況を確認しないと
いけない。場合によっては外出先からリモートで処置をしないといけない。
案3.同居しているEAで一番遅延が少ないものだけを判断材料にする
メリット :一部の流動性が低い通貨ペアでの誤検知や、検出時間パラメータを長くする必要
が無いので、検出時間が短くて済むし、自動復旧される。
デメリット:1つの通貨ペアだけでstart()関数開始されないという障害には対処できない。
修正量が案1と比較すると多い。
●検討結果
・流動性が著しく低い通貨ペアは多分トレード対象としないし、トレード対象としたとしても、
流動性が低い通貨ペアに引きづられて検出時間が長くなってしまうのもヘン。
・通常流動性が高い通貨ペアでも、一時的に流動性が低下して誤検知してしまうのもヘン。
・今回発生した通貨ペアのUSDZARのチャートを見てると、1Hぐらい取引が発生していない
ケースもあった。
・そもそもの事の発端となった事象では、全てのEAのstart()が開始されなかった。
・「案2」は運用が面倒
なので、「案3.同居しているEAで一番遅延が少ないものだけを判断材料にする」に決定!!
------------------------------------------
さて、そもそも前回の「あっ!!」と大げさに思わせぶりに書いた点。
実は大したことありません
#デモ口座期限切れ時の、口座切替対策です。
【デモ口座期限切れ対策】
----------------------------------
これは以前の記事で書いた通り、デモ口座期限切れになった場合に、各種大域変数のデータ
が残ってしまい、これが元でデモ口座切替後に正しくトレードができないという事への対策。
以前の記事では、「アカウント変更理由のdeinit()で、使ってた大域変数を削除」という対策
をして、実際に2つのデモ口座のアカウント切替をやってみてちゃんと動いた。
しかし。
土曜日昼にMT4を停止、日曜晩にMT4を起動。
あ、デモ口座期限切れ。。。
そして、新たなデモ口座を申請して、新デモ口座でEAを開始。
念のため、MT4の画面から、大域変数(Global Variable)を確認してみると、
あれ?
データが削除されてない???
そしてログを見てみると、肝心のdeinit()が実行されてない。。。。
つまり、MT4起動している時に口座期限切れが発生して、MT4を起動させたまま新デモ口座
に切り替えた場合はdeinit()が動くが、MT4停止中にデモ口座期限切れになった場合は、
deinit()が動かないみたい。。
が~ん。。。。
となると、MT4既存機能では、デモ口座期限切れになった状態で、新デモ口座に切り替えても
それを知る既存の手段が無いという事。。。
●対応策
結局、割と安直な対策にした。
つまり、口座番号を大域変数に格納しておいて、MT4起動時に取得した口座番号と
異なる番号であれば、不要となる大域変数を削除する様にした。
たったこんだけ。
-----------------------------------------
今回の修正も、
障害発生システムにならなければいいんですが。。
そして、ぼちぼち安定してきたと思いながら、「FXシステムトレード初心者奮闘記」の「MT4用EA開発時代」は、何も起きなければここまでの修正版のリリースに進むのでした。
#「MT4障害監視システム『ahfw_hc』」使ってみます」って拍手コメントもらった!!嬉しい!! 質問・疑問はご遠慮なく!!
0 件のコメント:
コメントを投稿