トップ  >  リファレンス  >  取引関数  >  OrderSend
スポンサーリンク
検索
カスタム検索
リファレンスツリー
オススメ
OrderSend




スポンサーリンク




OrderSend

新規成行注文や新規指値注文を行います


関数書式:
int  OrderSend(
   string   symbol,              // 通貨ペア名
   int      cmd,                 // 注文タイプ
   double   volume,              // ロット数
   double   price,               // 注文価格
   int      slippage,            // スリップページ
   double   stoploss,            // ストップロス価格
   double   takeprofit,          // リミット価格
   string   comment=NULL,        // コメント
   int      magic=0,             // マジックナンバー(識別用)
   datetime expiration=0,        // 有効期限
   color    arrow_color=clrNONE  // 色
   );



■引数
引数名 初期値 I/O 詳細
symbol - In 取引する通貨ペア名
cmd - In 注文タイプ。
オーダータイプ列挙の値を指定します
volume - In ロット数
price - In 注文価格
slippage - In 許容するスリップページ
(Instant Execution用、注文執行方式は業者によって異なります。
Market Executionの場合はスリップページ設定は効きません)
stoploss - In ストップロス価格
takeprofit - In リミット価格
comment NULL In 注文コメント。
コメントの末尾は取引サーバーによって変更されます。
magic 0 In マジックナンバー。
ユーザーがEAを識別する為に使用します。
expiration 0 In 注文の有効期限(指値注文のみ)
arrow_color clrNONE In チャート上の注文矢印の色。
パラメータを設定しない又はCLR_NONEを設定した場合は描画しません。



■戻り値
取引サーバーによって割り当てられたチケット番号を返します。
エラーの場合は-1を返します。
エラーコードの確認はGetLastError()関数を使用します。



■備考
成行き注文(cmd=OP_SELL,OP_BUY)では、注文価格(price)にBid(売値)とAsk(買値)のみ使用します。

もし現在と異なる有価証券で実行する場合、
その有価証券の最新クォートを取得する為に、MarketInfo()関数でMODE_BID,MODE_ASKプロパティの値を取得する必要があります。

算出した価格が正規化されていない場合、その価格は適用する事が出来ません。
通貨ペアの小数点以下の桁数に応じた価格を適用していない場合、エラー129(ERR_INVALID_PRICE)が生成されます。

注文価格の期限が切れてしまっている場合はエラー138(ERR_REQUOTE)が生成されます。
注文価格が古くなっているが、スレッド内に注文が残っている場合、
市場提示クォートがスリップページ(slippage)で設定した範囲内(price±slippage)にある場合のみ、その注文価格で約定されます。


ストップロス価格(stoploss)とリミット価格(takeprofit)は市場提示レートに近い値を設定出来ません。
ストップロスとの距離の許容範囲はMarketInfo()関数でMODE_STOPLEVELプロパティで調べる事が出来ます。
正規化されていない価格を設定した場合はエラー130(ERR_INVALID_STOPS)が生成されます。


指値注文の場合、市場が提示しているクォートに近い注文価格を設定する事は出来ません。
指値の注文価格との距離の許容範囲はMarketInfo()関数でMODE_STOPLEVELプロパティで調べる事が出来ます。
正規化されていない価格を設定した場合はエラー130(ERR_INVALID_STOPS)が生成されます。

指値注文の有効期限は取引サーバー側で無効にする事が出来ます。
取引サーバーによって無効にされている場合に、有効期限に0以外の値を設定した場合は
エラー147(ERR_TRADE_EXPIRATION_DENIED)が生成されます。

取引サーバー側でエントリー中の注文と保留中の注文合計を制限する事が出来ます。
この制限に達した場合、新規注文は出来ません。
新規注文を行った場合エラー148(ERR_TRADE_TOO_MANY_ORDERS)が生成されます。


サンプルソース
#property strict
#property script_show_confirm


#include <stderror.mqh>
#include <stdlib.mqh>

static bool EntryBool = false;


void OnStart(){

    int order_resend_num;        // エントリー試行回数
    int ea_ticket_res;           // チケットNo
    int errorcode;               // エラーコード
    double ea_order_entry_price; // エントリーレート

    if ( EntryBool == false ) {
        EntryBool = true;
    } else {
        return;
    }


    if ( IsDemo() == false ) {
        MessageBox("実際に新規オーダーするので、デモ口座で動作させて下さい。","エラー",MB_ICONEXCLAMATION);
        return;                // 処理終了
    }

    ea_order_entry_price = Ask; // 現在の買値でエントリー

    for( order_resend_num = 0; order_resend_num < 10; order_resend_num++ ) {    // エントリー試行回数上限:10回
    
        if ( IsDemo() == true ) {
            
            // FXCMでは新規エントリー時にストップ/リミットを設定出来ない。
            ea_ticket_res = OrderSend(   // 新規エントリー注文
                Symbol(),                // 通貨ペア
                OP_BUY,                  // オーダータイプ[OP_BUY / OP_SELL]
                0.01,                     // ロット[0.01単位]
                ea_order_entry_price,     // オーダープライスレート
                20,                       // スリップ上限    (int)[分解能 0.1pips]
                0,                        // ストップレート
                0,                        // リミットレート
                "テストオーダー",         // オーダーコメント
                999,                      // マジックナンバー(識別用)
                0,                        // オーダーリミット時間
                clrRed                   // オーダーアイコンカラー
                );
        }
        
        if ( ea_ticket_res == -1) {            // オーダーエラー
            errorcode = GetLastError();      // エラーコード取得

            if( errorcode != ERR_NO_ERROR) { // エラー発生
                printf("エラーコード:%d , 詳細:%s ",errorcode , ErrorDescription(errorcode));

                if ( errorcode == ERR_TRADE_NOT_ALLOWED ) { // 自動売買が許可されていない
                    MessageBox(ErrorDescription(errorcode),"オーダーエラー",MB_ICONEXCLAMATION);
                    return;
                }
            }

            Sleep(1000);                                           // 1000msec待ち
            RefreshRates();                                        // レート更新
            ea_order_entry_price = Ask;                            // 更新した買値でエントリーレートを再設定
            printf("再エントリー要求回数:%d, 更新エントリーレート:%g",order_resend_num+1 ,ea_order_entry_price);

        } else {    // 注文約定
            Print("新規注文約定。 チケットNo=",ea_ticket_res);
            Sleep(300);                                           // 300msec待ち(オーダー要求頻度が多過ぎるとエラーになる為)
            
            // エントリー中ポジションの注文変更
            LimitStop_Set(ea_ticket_res);
            break;
        }
    }
}


// エントリー中のポジションのリミット・ストップを変更
void LimitStop_Set( int in_ticket_no ) {

    double limit_rate,stop_rate;
    int    modify_resend_num;       // 変更試行回数
    bool   modify_ret;              // 変更判定
    int    errorcode;
    bool   selbool;

    selbool = OrderSelect(in_ticket_no, SELECT_BY_TICKET); // オーダー中のチケット選択(チケットNo指定)

    limit_rate = OrderOpenPrice() + ( 10 * Point() * 10); // リミット価格     = 約定価格 + 10.0pips
    stop_rate  = OrderOpenPrice() - ( 10 * Point() * 10); // ストップロス価格 = 約定価格 - 10.0pips

    limit_rate = NormalizeDouble(limit_rate,Digits);      // リミット価格    を正規化
    stop_rate  = NormalizeDouble(stop_rate ,Digits);      // ストップロス価格を正規化
    

    for( modify_resend_num = 0; modify_resend_num < 20; modify_resend_num++ ) { // 試行回数上限:20
        modify_ret = OrderModify(
                                 OrderTicket(),      // チケットNo
                                 OrderOpenPrice(),  // 注文価格
                                 stop_rate,            // ストップロス価格
                                 limit_rate,           // リミット価格
                                 OrderExpiration(), // 有効期限
                                 clrRed               // 色

                     );

        if ( modify_ret == false ) {             // 注文変更拒否
            Sleep(300);                         // 300msec待ち
            errorcode = GetLastError();        // エラーコード取得
            printf( "%d回目:注文変更拒否。エラーコード:%d , 詳細:%s ",
                                                       modify_resend_num+1, errorcode ,  ErrorDescription(errorcode));
        } else {                                 // 決済注文約定
            Print("注文変更完了。 チケットNo=",in_ticket_no);
            break;
        }
    }
}


結果:
open #15196788 buy 0.01 EURUSD at 1.11952 ok
新規注文約定。 チケットNo=15196788
modify #15196788 buy 0.01 EURUSD at 1.11952 sl: 1.11852 tp: 1.12052 ok
注文変更完了。 チケットNo=15196788






   
管理人の勝手なコメント:

FXCMでは、新規注文(OrderSend)時にストップ・リミット設定は出来ません。
FXCMジャパン証券の公式HP上でも説明されています。
この辺は業者毎に異なるので、確認が必要です。

FXCM EAガイド リンク:http://www.fxcm.co.jp/common/pdf/ea.pdf
EAガイドの"5. 注文(OrderSend関数についてのご注意"参照


デモ口座では設定出来ますが、リアル口座では設定出来ないので注意が必要です。
対策としてOrderSend関数で新規注文が約定された後に、OrderModify関数でストップ・リミット設定を行う必要があります。
新規注文約定直後にOrderModify関数を呼び出すとサーバーが要求過多で拒否されるので、
100msec程のインターバル(Sleep(100))をおいてから行った方が余計なエラーが発生せずに済みます。


また本文にもありますが、正規化されていない価格で設定した場合はエラーになりますので、
算出した価格を設定する場合は、NormalizeDouble()関数で正規化する事をお勧めします
(但し、正規視していなくても対応する通貨ペアの精度と合っていれば大丈夫です)。


【追記:2016/1/17】
OederSendでオーダーして、サーバー側が約定したにも関わらずエラーコード6(ERR_NO_CONNECTION:トレードサーバーに接続していません)を返す場合があります。
ERR_NO_CONNECTIONを検出した場合は、サーバー側にオーダーしたポジションが無いかチェックした方が良さそうです。
実際の発生例はブログ( 【MT4】新規エントリーオーダーがエラーだったのに約定された件) にて紹介しています。

■よくあるエラー例
// OrderSend error 130:無効なストップロス設定
OrderSend(
    Symbol()               , // 通貨ペア
    OP_BUY                 , // 注文タイプ
    0.01                   , // ロット数
    Ask                    , // 注文価格
    20                     , // スリップページ
    Ask                    , // ストップロス価格    【ストップロス価格がクォート価格に近すぎる】
    0                        // リミット価格
);

OrderSend(
    Symbol()               , // 通貨ペア
    OP_BUY                 , // 注文タイプ
    0.01                   , // ロット数
    Ask                    , // 注文価格
    20                     , // スリップページ
    Ask + ( Point / 3)     , // ストップロス価格     【通貨ペアの価格精度を超過している(買値+0.0000033333333…)】
    0                        // リミット価格
);

// 現在の通貨ペアの精度に正規化する方法
Print(NormalizeDouble(Ask + ( Point / 3) , Digits));


// OrderSend error 131: 無効なトレード量(lot数)です
OrderSend(
    Symbol()               , // 通貨ペア
    OP_BUY                 , // 注文タイプ
    0.001                  , // ロット数         【FXCMの最小lotは0.01です】
    Ask                    , // 注文価格
    20                     , // スリップページ
    0                      , // ストップロス価格
    0                        // リミット価格
);

OrderSend(
    Symbol()               , // 通貨ペア
    OP_BUY                 , // 注文タイプ
    501.00                 , // ロット数         【FXCMの上限lotは500.00です】
    Ask                    , // 注文価格
    20                     , // スリップページ
    0                      , // ストップロス価格
    0                        // リミット価格
);
//lotの上限・下限を調べる方法
Print("最大ロット =",MarketInfo(Symbol(),MODE_MAXLOT));
Print("最小ロット =",MarketInfo(Symbol(),MODE_MINLOT));


// OrderSend error 134:証拠金不足(証拠金が沢山ある場合は発生しません)
#define MAX_LOT 500.00
if ( IsDemo() == true) { // このコードをコピペして、うっかりリアル口座で動作させてしまった場合の対策。
OrderSend(
    Symbol()               , // 通貨ペア
    OP_BUY                 , // 注文タイプ
    MAX_LOT                , // ロット数         【5千万通貨(500lot)でエントリーするには約2億円程の証拠金が必要です】
    Ask                    , // 注文価格
    20                     , // スリップページ
    0                      , // ストップロス価格
    0                        // リミット価格
);
}


// OrderSend error 4051:無効な引数設定
OrderSend(
    Symbol()               , // 通貨ペア
    10                     , // 注文タイプ          【注文タイプの設定範囲は0〜5】
    0.01                   , // ロット数
    Ask                    , // 注文価格
    20                     , // スリップページ
    0                      , // ストップロス価格
    0                        // リミット価格
);


スポンサーリンク



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


Top

inserted by FC2 system