【EA開発ガイド】Part 3 MQL4開発基本 – Chapter 7 エラー処理を実装する

EAでエラーが発生していて調べたらリトライ可能なものだったので修正した。発生したエラーは複数の発注が同時にさらたときに発生するもの。前の発注処理が完全に終わる前に次の発注をしているのでエラーになっていると思われる。なのでタイミングを少しだけずらせば発注は成功する。

注意事項

本記事はFXの自動売買について紹介していますが内容を保証するものではありません。金銭にかかわる内容であるためご注意ください。参考にする場合は自己責任でお願いします。

一般的なエラー処理

思い付くエラー処理の種類を上げてみた。

継続不可能な致命的エラー

これは予測できない致命的なエラーで基本的にはシステムを停止もしくは一時停止することがある。例えばデータベースやストレージに全くアクセスできず回復不可能なエラーコードが返ってくるとか。業務システムより低いレイヤー(ハードより)で起きた場合など。いきなり処理を中断すると再開示に問題が起きる可能性があるので、可能な限り終了処理を実行してから停止状態に入る。メモリリークによりメモリ枯渇などもここに含まれる。ようするに「お手上げ」なエラーなのである。

リトライで可能性のあるエラー

何らなの理由で処理でが継続できない場合処理を中断する場合がある。例えば連携するシステムがたまたま運悪くビジー状態でエラーになった場合など。昨今のシステムは並列処理で作られているのでこのようなリトライエラーは少ないハズ。ただし、データベースへのコミット(更新処理の確定)タイミングでの排他処理(同時処理できない作業)がある場合はビジー状態になることも考えられる。

FXの場合は約定に時間がかかることがあるためこのビジー状態になりやすい気がしている。通常の業務処理に比べ約定処理は高コストのようだ。やはりお金が絡むシステムなのでこのあたりの作りは慎重になっているのが原因だろう。

タイムアウトエラー

依頼した処理に想定以上の時間がかかってしまった場合に発生するエラー。連携システムで無限ループやデッドロック(同期制御系エラー)が原因となることが多い。ウェブサービスの場合はアクセスが集中して処理落ちする場合もこれにあたる。大人数がアクセスするサービス以外でタイムアウトが発生したらシステム的な問題がある可能性が高く致命的エラーに近くなる。

業務エラー

例えば業務設計的にありえない組み合わせになってしまった場合など。入力時に法律で決められた値の範囲内に限定しているにも関わらず、すでに範囲外の数値が入力されているとか。EAで言うなら買いシグナルがでているのに売りで発注をだしてしまったりとか。コードの記述ミスが原因になることが多い。各処理セクションごとに適切な業務エラーチェックを入れておけばエラーによる矛盾をいち早く検知することができる。EAの場合も同様で矛盾する引数や処理結果が入ってこないかチェックしておくとバグを防ぐことができる。

EAで発生するエラー

31種類のエラーがあるが今のところは146しか確認できていない。

受発注時のエラー

OrderSend(発注)時のエラーはGetLastError()でエラーコードを取得できる。こちらがエラーコード一覧。詳しくはこちら

Code ID Description
0 ERR_NO_ERROR No error returned
1 ERR_NO_RESULT No error returned, but the result is unknown
2 ERR_COMMON_ERROR Common error
3 ERR_INVALID_TRADE_PARAMETERS Invalid trade parameters
4 ERR_SERVER_BUSY Trade server is busy
5 ERR_OLD_VERSION Old version of the client terminal
6 ERR_NO_CONNECTION No connection with trade server
7 ERR_NOT_ENOUGH_RIGHTS Not enough rights
8 ERR_TOO_FREQUENT_REQUESTS Too frequent requests
9 ERR_MALFUNCTIONAL_TRADE Malfunctional trade operation
64 ERR_ACCOUNT_DISABLED Account disabled
65 ERR_INVALID_ACCOUNT Invalid account
128 ERR_TRADE_TIMEOUT Trade timeout
129 ERR_INVALID_PRICE Invalid price
130 ERR_INVALID_STOPS Invalid stops
131 ERR_INVALID_TRADE_VOLUME Invalid trade volume
132 ERR_MARKET_CLOSED Market is closed
133 ERR_TRADE_DISABLED Trade is disabled
134 ERR_NOT_ENOUGH_MONEY Not enough money
135 ERR_PRICE_CHANGED Price changed
136 ERR_OFF_QUOTES Off quotes
137 ERR_BROKER_BUSY Broker is busy
138 ERR_REQUOTE Requote
139 ERR_ORDER_LOCKED Order is locked
140 ERR_LONG_POSITIONS_ONLY_ALLOWED Buy orders only allowed
141 ERR_TOO_MANY_REQUESTS Too many requests
145 ERR_TRADE_MODIFY_DENIED Modification denied because order is too close to market
146 ERR_TRADE_CONTEXT_BUSY Trade context is busy
147 ERR_TRADE_EXPIRATION_DENIED Expirations are denied by broker
148 ERR_TRADE_TOO_MANY_ORDERS The amount of open and pending orders has reached the limit set by the broker
149 ERR_TRADE_HEDGE_PROHIBITED An attempt to open an order opposite to the existing one when hedging is disabled
150 ERR_TRADE_PROHIBITED_BY_FIFO An attempt to close an order contravening the FIFO rule

エラー処理の実装

上記のエラー表を見ると正常処理を除いて31種類のエラーがある。いきなりエラーごとのエラー処理をする必要はない。なぜなら、発生頻度が異常に少ないものが多い可能性があるからだ。何なら一生お目にかかることがないエラーも存在するだろう。はじめは正常終了かエラーかのどちらか程度のレベルで良い。

エラー処理について

基本は発生したエラーだけに対応すればいい。未確認のエラーはポップアップメッセージで表示し直ぐに確認できるようにしておく。筆者が現在確認しているエラーは146の「Trade context is busy」だけ。

【EA開発ガイド】Part 7 フォワードテスト基礎 – Chapter 4 フォワードテスト中にエラー発生する

エラー処理例

エラー146は処理が集中しているだけなのでリトライすれば何とかなる可能性が高い。なので146エラーだけはリトライさせるように実装する。

以下はエラー実装の抜粋。OrderSendの復帰値が-1ならエラーなのでコードに合わせて処理。146エラーが発生したらエラーメッセージだけ出力しリトライする。それ以外のエラーはレポートを出力して処理を中断。未対応のエラーが発生したら逐次実装していく。

if(g_ticketNumber == -1)
{
    // エラーコードを取得
    int errorCode = GetLastError();
    
    if(errorCode == 146)
    {
        // ビジー状態なのでリトライする
        errorPrint("エントリーでエラーが発生しました。", magicNumber);
    }
    else
    {
        errorReport("エントリーでエラーが発生しました。", magicNumber);
    }

    return false;
}

 

まとめ

146エラーをポップアップしない仕様にしたので今後146エラーがどの程度発生したかはログ等で確認する必要がある。毎回ログファイルを確認するのも大変なので専用ファイルにエラーをレポートする処理を実装でもしようかな。

ポイント
  • EAのエラー処理は必要になってから実装
  • 致命的エラーでは無ければリトライが無難
  • GetLastError()で詳細エラーコードを取得できる

バックテストでは146エラーが発生しないので成績が悪くないそうな気がします。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です