2011/07/22

MT4用EA開発時代 - PC障害対策の設計ミスと、デモ口座期限切れ対策



さて前回は、ついに「OrderSelect問題」が再発し、やはりstart()関数の排他制御が必要と結論付けたところまで書きました。今回は、デモ環境を使ってて気付いた、トレード用PC故障時の大域変数引継ぎに関するMT4用EA開発共通部品「ahfw」の設計バグを見つけて、検討している様子と、デモ口座期限切れ時の作業効率化対策を書いてみたいと思います。

コトの発端は、デモ口座が期限切れしたのでデモ口座再申請した後、EA実行再開時に大域変数を削除しないといけなかったんやけど、それを忘れた事。

大域変数に格納されてるデータと実際の状態に不整合が発生すると、ダメなんよね。。

改めて使ってる大域変数を見直してみると、幾つかBarsの値があった。そして口座を切り替える事によって、同じ時刻でもBarsの値が変わってしまうって事に今更気付いた。。



という事は。


もともと、トレード用PC故障時のバックアップ用PCへの切替時は、定期的にNASにバックアップしている大域変数を、バックアップ用PCにコピーする事でデータ引継ぎをして、EAを再開させるつもりやった。

絵にするとこんな感じ。

でも、前述のBarsの値の事を考えると、PC故障時の大域変数引継ぎが上手く動かないって事にやっと気付いた。。。
#イベントが発生したタイミングをBarsを元に大域変数上で管理してるから結構致命的。。





つまり、PC障害に対応

できないという設計バグ。



設計書完成してないけど。。。





どうしようかと考えた挙句、Barsの替わりにTime[]を使って大域変数に保存。共通関数のAPIを変更せずに実現するために、バー数に関するインタフェースの部分は、iBarShift()という関数を使う事で対応する事にした。

つまり、今まで管理していた過去イベント発生時のBarsデータをTime[]で保存しておき、EA固有のコールバック関数や内部管理では、「Bars-iBarShift(Symbol() , 0 , [イベント発生時のTime[]])」に換算すれば今までのロジックを踏襲できる。

なので、結局2つの課題が出た事になっちゃった。。

【課題】
------------------------------------
1.稼動中EAの入れ替え
  EA側プログラム修正は不要だけど、稼動中のEAを入れ替える時に、
  現状Barsで管理している大域データをどう扱うのか。
  案1.変換用スクリプトを用意して変換する
  案2.共通部品で起動時にデータを変換する
  案3.対処しない
2.デモ口座期限切れの時の作業が煩雑
  この共通部品を使ったEAだけだったら、大域変数が格納されているファイルを削除
  するか、一旦EAをチャートから外して大域変数を削除すればOKなんだけど、面倒。
  案1.アカウント変更理由のdeinit()で、使ってた大域変数を削除
  案2.大域変数名の先頭にログインIDを付与する
  案3.対処しない
------------------------------------  

ほんでは、課題ごとに検討してみた。

【課題1.稼動中EAの入れ替え】
-------------------------------------
EA側プログラム修正は不要だけど、稼動中のEAを入れ替える時に、現状Barsで管理している大域変数のデータをどう扱うのか。

まずは、現状Barsの値を使用している大域変数名と用途を整理すると。
#それぞれヘッダとして、MAGICナンバーと通貨ペア名が付与されています。

1.FW_StatGiveupBarIdx
  発注かSL/TP変更に1回失敗して一旦start()関数を抜けた場合に、結局次のバーに
  進むまでやりたかったオーダ操作ができなかった場合に警告メール送信/ログ出力する
  為に利用。現在のBarsと違うかどうかで判定。
2.FW_StatLastBarIdx
  バーが進む毎に呼び出すコールバック関数EAOnBarChanged()を呼ぶかどうかを判定する
  為と、引数に渡す前回呼出し時のBarsを求めるため。現在のBarsと違うかどうかで判定。
3.FW_StatLastModifyBarIdx
  前回SL/TP変更成功時のBarsが格納されている。1つのバーで1回だけSL/TP変更する
  為に利用。現在のBarsと違うかどうかで判定。
4.FW_StatOrderBarIdx
  前回発注成功時のBarsが格納されている。現在のBarsと違うかどうかで、1つのバーでは1回しか
  発注できない様に制御するためと、独自トレードログ出力項目の保有バー数を求めるため。
  他には各種コールバック関数に渡す引数にも利用。

トレードそのものに影響が出そうなのは、上記「2.」と「4.」のケース。

そんな中、以下の3つの案について方式を比較検討

●方式比較
 案1.変換用スクリプトを用意して、手動で変換する
    メリット:1回実行すれば、共通部品内にムダな処理が残らない。
    デメリット:利用者がスクリプトの実行が必要な事に気付かなかったりする。
 案2.共通部品で起動時に、データを自動的に変換する
    メリット:利用者はデータ構造の変更を意識する必要がない
    デメリット:共通部品内にムダなソースが残る。
 案3.対処しない
    メリット:プログラムの修正量が減る
    デメリット:保有中オーダを一旦全て決済しないと、上手く動かないケースがある。

●検討結果
 結局、今後も大域変数の構造変更等が発生するかもしれない。だとすると、変更用スクリプト
 だと、どこからバージョンアップさせるかを意識しながら順番にスクリプトを実行しないといけな
 くなって作業ミスによるトラブルの温床になる。
 今後も発生する事が想定されるのであれば、バージョン管理して変換ロジックを追加していく
 様な仕組みを作れば、無駄なロジックは残るものの、変換ロジックを独立化させる事で、
 プログラムの可読性低下を軽減できる。
 多くなりすぎた時は、バージョンチェックして警告する前提として過去の変換用関数を削除
 する様にすればいい。

 なので、「案2.」にする。
-------------------------------------

さて、次と。。。

【課題2.デモ口座期限切れの時の作業が煩雑】
-------------------------------------
この共通部品を使ったEAだけだったら、大域変数が格納されているファイルを削除するか、一旦EAをチャートから外して大域変数を削除すればOKなんだけど、面倒。

そして、作業ミスすると、警告メールが多数きてしまう。。。
パケ代が。。。

●方式比較
  案1.アカウント変更理由のdeinit()で、使ってた大域変数を削除
     メリット:プログラム修正必要だけど、ロジックはシンプル。
     デメリット:複数のアカウントをいったりきたりできない
  案2.大域変数名の先頭にログインIDを付与する
     メリット:複数のアカウントをいったりきたりできる。
     デメリット:大域変数の移行ロジックも必要になる。無効デモ口座分の大域変数
           がゴミとして残ってしまう。
  案3.対処しない
     メリット:プログラム修正不要
     デメリット:デモ口座変更時の作業が煩雑で、ミスると利用者での対処が難しい。

●検討結果
 えーっと、「案3.」はまず却下。作業が複雑すぎ。
 で、そもそも複数のアカウントをいったりきたりするケースは少ないと思うので、ロジックが
 シンプルになる「案1.」に。しかも「案2.」だと、ほっとくと大域変数の数が増殖していって
 しまう。
-------------------------------------


とりあえず、ブログ書きながら検討して結論出た!!




めでたしめでたし。



ちゃうちゃう。。。





書きかけ設計書の修正と、

プログラムの修正せな。


そして、設計書の修正箇所も多い事にショックを受けながら、「FXシステムトレード初心者奮闘記」の「MT4用EA開発時代」は、設計書を書いて良かった事について進むのでした。
#機能詳細設計書の1回目のレビュー結果も反映してないのに。。。

0 件のコメント:

コメントを投稿