さて前回は、設計書を書いて良かった点と今後の予定について書きました。今回は、以前のブログ記事で対応を決めた、デモ口座期限切れ時の作業効率化対応している時に解ったMT4の挙動について書いてみたいと思います。
おさらいからすると、開発したMT4用EA共通部品「ahfw」は大域変数(Global Variable)をたくさん使ってて、デモ口座が期限切れになると、一旦大域変数を削除しなきゃいけないけど、それが面倒。
なので、対応策としてアカウント変更理由のdeinit()で、使ってた大域変数を削除する事にした。
こんなん楽チン!
なぁ~んて、甘くは無かった。。。
元々は、deinit()関数内で、UninitializeReason()がREASON_ACCOUNTだったら、AccountNumber()をキーにした大域変数を削除する予定だった。
つまり、このタイミングで返却されるAccountNumber()は、アカウント変更前のユーザIDが返却されると思ってた。ところがなんと、返却されたのはアカウント変更後のユーザID。
企画倒れ。。
いやいや、init()関数内で、最初にEAを読み込んだ時に、AccountNumber()の結果を変数に格納しておいて、それを使って大域変数を削除すればいい話。
そして、プログラムを修正して実行してみると、なんか変なエラーが。。。
仕方なく、単純なEAを作って色々MT4の挙動を確認することにした。
【アカウント切替時のMT4の挙動確認】
---------------------------------
1.テストに使ったEA
なんてことはない、単に各関数でAccountNumber()を出力するだけのEA。
//+------------------------------------------------------------------+//| expert initialization function |//+------------------------------------------------------------------+int init(){//----Print("init() : AccountNumber("+AccountNumber()+")");//----return(0);}//+------------------------------------------------------------------+//| expert deinitialization function |//+------------------------------------------------------------------+int deinit(){//----Print("deinit() : AccountNumber("+AccountNumber()+")");//----return(0);}//+------------------------------------------------------------------+//| expert start function |//+------------------------------------------------------------------+int start(){//----Print("start() : AccountNumber("+AccountNumber()+")");//----return(0);}
2.検証方法
2つのデモアカウントを切り替えた時に、AccountNumber()が切替前か切替後のどちらを返却し、
どういう順序で処理がされるかを幾つかのパターンで検証。
以下が検証結果。
A.EAを停止して、アカウント切替確認後、EAを再開
02:58:36 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)02:58:37 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)02:58:41 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)03:06:33 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)03:06:33 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)03:06:35 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)03:06:36 XAccountChange EURUSDfxf.,M5: deinit() : AccountNumber(156540)03:06:36 XAccountChange EURUSDfxf.,M5: deinitialized03:06:36 XAccountChange EURUSDfxf.,M5: uninit reason 603:06:36 XAccountChange EURUSDfxf.,M5: init() : AccountNumber(156540)03:06:36 XAccountChange EURUSDfxf.,M5: initialized03:07:49 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:07:49 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:07:52 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:08:01 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)
いたって普通の結果。
B.EAを停止せずに、アカウント切替直後、EAを再開
ちょっと乱暴な使い方にチャレンジしてみた。
02:56:35 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:56:39 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:56:44 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:56:46 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:58:21 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:58:21 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:58:22 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)02:58:26 Experts are disabled because the account has been changed02:58:28 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)02:58:28 XAccountChange EURUSDfxf.,M5: deinit() : AccountNumber(147890)02:58:28 XAccountChange EURUSDfxf.,M5: deinitialized02:58:28 XAccountChange EURUSDfxf.,M5: uninit reason 602:58:28 XAccountChange EURUSDfxf.,M5: init() : AccountNumber(147890)02:58:28 XAccountChange EURUSDfxf.,M5: initialized02:58:36 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)02:58:37 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)02:58:41 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)
んが???deinit()が始まる前に、start()が認識しているAccountNumber()が
変更になってる。。
ちょっとやり過ぎたかな??
変更になってる。。
ちょっとやり過ぎたかな??
C.EAを停止して、アカウント切替直後、EAを再開
乱暴すぎたっぽいので、今回EAを一旦停止してから、アカウント切替後にすぐEAを開始。
03:16:29 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:16:29 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:16:37 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:16:38 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(156540)03:17:01 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)03:17:01 XAccountChange EURUSDfxf.,M5: deinit() : AccountNumber(147890)03:17:01 XAccountChange EURUSDfxf.,M5: deinitialized03:17:01 XAccountChange EURUSDfxf.,M5: uninit reason 603:17:01 XAccountChange EURUSDfxf.,M5: init() : AccountNumber(147890)03:17:01 XAccountChange EURUSDfxf.,M5: initialized03:17:01 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)03:17:10 XAccountChange EURUSDfxf.,M5: start() : AccountNumber(147890)
EA一旦停止してもあかんのか。。。
-------------------------------------------
え~っと、コレってMT4の
仕様バグじゃないんでしょうか??
アカウント切り替えた時に、deinit()もinit()も動いてないのに、start()を動かしちゃだめだし、start()内で切替後のAccountNumber()返却したらダメでしょ?
だって、init()完了しないとstart()開始されない様になってるのに、アンバランスやん。。。
さては、デモ環境がゆえんの
使い方だから手を抜いたな?
使い方だから手を抜いたな?
さて、対処方法を考えてみた。
#なんか、デモ環境の為だけのロジックって気が進まないけど。。
【対処方法】
----------------------------------
これは迷う余地もなく、start()開始直後に、AccountNumber()を取得して、init()時に取得したAccountNumber()と異なっていたら、何もせずにリターンする様に修正する。
厳密に言うと、既にstart()内の処理に入ってる場合に誤動作する可能性あるけど、わざわざデモ環境のためだけにそんな事してられないので、以上。
もし対処するとしたら、トレードサーバからエラーが返却された時、AccountNumber()がinit()時に取得したAccountNumber()と違っていれば、成功とするぐらい。
----------------------------------
ちなみにデモ口座切替対応として、内部管理しているチケット番号がゼロ(保有オーダなし)の状態なのに、OrderSelect()ループで、オーダを発見した場合は、該当オーダを決済する様にも修正。
結果的に、以前の「OrderSelect問題パート2が再発。絶対MT4のバグ!」への対応にもなったし。よしよし。
え?こんなの常識?
そして、小ネタでお茶を濁しながら、「FXシステムトレード初心者奮闘記」の「MT4用EA開発時代」は、設計書レビュー結果に進むのでした。
#PC障害時の、MT4用EAを動かすPC切替と、その後の処理が上手く動いた!!切り戻しもOK!!
0 件のコメント:
コメントを投稿