トップ  >  自作してみる >  エキスパートアドバイザー(EA)作成の基本  >  es2.OrderSend()関数のエラー
スポンサーリンク
検索

↑の検索エンジンが表示されない人は、
↓の古い検索エンジンを使用して下さい。
カスタム検索
MQL4リファレンスツリー
es2.OrderSend()関数のエラー



注意事項:
このページにあるサンプルソースは、実際に売買を行う処理が含まれているので、絶対にライブ口座では実行しないで下さい。 念の為、デモ口座でしか処理しない対策処理を施しています。
これはあくまで勉強用のソースコードです。

注文成功時

OrderSend()関数でエラーが発生した場合の説明の前に、成功時の説明をします。
OrderSend()関数を使った新規注文を発注し、サーバーが注文を受け付けてくれた場合、戻り値にチケットNoを返してくれます。

OrderSendエラー

FXトレーダーでチケットNoを知らない人はいないと思いますが、
これは手動やEAに関係なく全ての注文に対してチケットNoが付与されます。

今保有している注文に対してリミット・ストップ・決済注文をしたい場合は、このチケットNoのポジションに対して行います。
リミット・ストップ・決済注文の方法は長くなるので別途記載しますが、今回はチケットNoのログ出力だけ行います。


ソースコード:
    if ( IsDemo() == false ) {            // デモ口座以外の場合
        Print("デモ口座でのみ動作します");
        return;                            // 処理終了
    }

    int ea_ticket_res = -1; // チケットNo

    ea_ticket_res = OrderSend(                           // 新規エントリー注文
                                Symbol(),                // 通貨ペア
                                OP_BUY,                  // オーダータイプ[OP_BUY / OP_SELL]
                                0.01,                     // ロット[0.01単位]
                                Ask,                      // オーダープライスレート
                                20,                       // スリップ上限    (int)[分解能 0.1pips]
                                0,                        // ストップレート
                                0,                        // リミットレート
                                "テストオーダー",         // オーダーコメント
                                20200518                  // マジックナンバー(識別用)
                               );

    if ( ea_ticket_res != -1) {    // オーダー正常完了
        printf( "【%d】エントリーオーダー正常完了。チケットNo = %d"  , __LINE__ , ea_ticket_res);
    }



OrderSendエラー

まぁMT4が自動でオーダー情報をログ表示してくれるので意味の無い処理ですが、勉強用という事でw
成行注文が約定した直後にリミット・ストップ注文を入れたい場合はここに処理を追加します。
ただリミット・ストップ注文はこの段階で必ず入れなければならないわけでは無く、EA作成者次第になるので今回は説明しません、別ページにて説明します。


注文失敗時

本題のOrderSend()関数を使った発注でエラーになった場合の処理を説明します。

OrderSend()でエラーになった場合、エラー情報を必ずログ出力するようにして下さい。

ログを残さないと一体何が原因でエラーになったか分からなくなります。
特に取引サーバー側の問題によるエラーだった場合、バックテストでは絶対に再現出来ないエラーの可能性が高く、 ログが残っていないとデバッグする事が非常に困難になります。


それではエラーの場合にログ出力する処理を追加しましょう。
OrderSend()はエラーの場合は戻り値に-1を返すので、戻り値が-1の時にエラーログ出力するようにします。
基本的にD3.ログ出力を用いたデバッグと同じ内容の処理ですので詳しくは説明しません。
詳細はD3.ログ出力を用いたデバッグのページを参照して下さい。

ソースコード:
    if ( ea_ticket_res != -1) {    // オーダー正常完了
        printf( "【%d】エントリーオーダー正常完了。チケットNo = %d"  , __LINE__ , ea_ticket_res);

    } else {                       // オーダーエラーの場合

        int    get_error_code   = GetLastError();                   // エラーコード取得
        string error_detail_str = ErrorDescription(get_error_code); // エラー詳細取得

        // エラーログ出力
        printf( "[%d]エントリーオーダーエラー。 エラーコード=%d エラー内容=%s" 
            , __LINE__ ,  get_error_code , error_detail_str
         );        
    }


ErrorDescription()関数はstdlib.mqhインクルードしていないと使えないので注意。
C言語と違ってMQL4ではインクルードを使用する事はあまり無い(上級者は除く)ので、詳細説明は別途します。
今回はとりあえず関数の外に以下ソースコードを追加して下さい。
#include <stdlib.mqh>          // ライブラリインクルード




OrderSendエラー


ランタイムエラーの場合

ログ出力処理を追加したら、実際にエラーになるようにしてみましょう。
一番簡単な方法は異常なロットを指定する事です。

OrderSend()関数のロットの引数設定を0に変更して、スクリプトを実行してみて下さい。

結果:
[45]エントリーオーダーエラー。 エラーコード=4051 エラー内容=invalid function parameter value

4桁のエラーコードとエラー内容がログ出力されたと思います。
「引数の値が無効」というエラー内容です。
4桁のエラーコードはランタイムエラーなのでサーバーへの発注は行われていません。
この場合は完全にソースコード自体に問題があるエラーになります。


トレードサーバーが返すエラーの場合


次はサーバー側が約定拒否をした場合のエラーを確認しましょう。
今度はロットの設定を0.001(百通貨)にして試して下さい。

結果:
[45]エントリーオーダーエラー。 エラーコード=131 エラー内容=invalid trade volume

今度は3桁のエラーコードがログ出力されました。
「無効なトレード量(lot数)です」というエラー内容です。

3桁のエラーコードはトレードサーバーが返すエラーなので、 サーバーへの発注が行われ、その注文が拒否された時のエラーです。
この手のエラーはバックテスト中では発生しないケースもあります。

今回のケースではソースコード自体に問題がありますが、
3桁のエラーコードの場合は必ずしもソースコードが問題とは限らない場合があるので、エラーコードをログ出力していないと原因を見つける事が困難になる場合があります。
(トレードサーバーが返すエラーの場合、通常ログは「エキスパート」では無く「取引履歴」の方に表示されます。 )

例えば「136:ERR_OFF_QUOTES(レートが提示されていません)」はトレードサーバー側の都合によるエラーになります。
高速取引していた時はこのエラーが頻繁に出ました。あまりにも流動性が低下すると気配値表示されていても約定拒否される事があります。 この場合はプログラムが悪いわけでは無いのでどうしようもありません。

完成したサンプルソースコード


ソースコード:
//+------------------------------------------------------------------+
//|                                          Test_TradeOrderSend.mq4 |
//|                                                             yuki |
//|                                      https://yukifx.web.fc2.com/ |
//+------------------------------------------------------------------+
#property copyright "yuki"
#property link      "https://yukifx.web.fc2.com/"
#property version   "1.00"
#property strict // strictは絶対に削除しない事

#include <stdlib.mqh>          // ライブラリインクルード

//+------------------------------------------------------------------+
//| スクリプトプログラムスタート
//+------------------------------------------------------------------+
void OnStart()
{
    if ( IsDemo() == false ) {            // デモ口座以外の場合
        Print("デモ口座でのみ動作します");
        return;                            // 処理終了
    }

    int ea_ticket_res = -1; // チケットNo

    ea_ticket_res = OrderSend(                           // 新規エントリー注文
                                Symbol(),                // 通貨ペア
                                OP_BUY,                  // オーダータイプ[OP_BUY / OP_SELL]
                                0.01,                     // ロット[0.01単位]
                                Ask,                      // オーダープライスレート
                                20,                       // スリップ上限    (int)[分解能 0.1pips]
                                0,                        // ストップレート
                                0,                        // リミットレート
                                "テストオーダー",         // オーダーコメント
                                20200518                  // マジックナンバー(識別用)
                               );   

    if ( ea_ticket_res != -1) {    // オーダー正常完了
        printf( "【%d】エントリーオーダー正常完了。チケットNo = %d"  , __LINE__ , ea_ticket_res);

    } else {                       // オーダーエラーの場合

        int    get_error_code   = GetLastError();                   // エラーコード取得
        string error_detail_str = ErrorDescription(get_error_code); // エラー詳細取得

        // エラーログ出力
        printf( "[%d]エントリーオーダーエラー。 エラーコード=%d エラー内容=%s" 
            , __LINE__ ,  get_error_code , error_detail_str
         );        
    }

}








スポンサーリンク


Copyright ©2015 MT4でEA自作しちゃお~ All Rights Reserved.


Top

inserted by FC2 system