OrderSend

OrderSend() 関数は取引操作の実行に使用され、リクエストを取引サーバに送信します。

bool  OrderSend(
  MqlTradeRequest&  request,      // 問の構造体
  MqlTradeResult&   result       // 答えの構造体
  );

パラメータ

request

[in]  クライエントの取引アクティビティを記述する MqlTradeRequest 型の構造体へのポインタ

result

[in,out]  成功した場合(true が返される場合)取引操作の結果を表す MqlTradeResult 型の構造体へのポインタ

戻り値

基本的な構造体チェック(ポインタチェック)が成功した場合、trueが戻されます。しかし、これは取引操作が成功することを表すものではありません。 関数実行結果の詳細には、result 構造体のフィールドが分析されるべきです。

注意事項

取引リクエストは、サーバ上で複数の段階を踏みます。初めに、request パラメータの必須のフィールドが正しく書き入れられているかどうかがチェックされます。エラーがない場合、サーバは、更なる処理のために注文を受け付けます。注文が正常に取引サーバによって受け入れられると、OrderSend() 関数が true を返します。

取引サーバに送信する前に、リクエストをチェックすることが推奨されます。リクエストをチェックするには OrderCheck() 関数が使用されます。それは、取引を実行するための充分な資金があるかをチェックし、複数の役立つパラメータを 取引リクエストチェックの結果に返します。

  • チェックされたリクエストに含まれるエラーの情報を含むリターンコード
  • 取引操作が実行された後に表示される残高値
  • 取引操作が実行された後に表示される株式価値
  • 取引操作が実行された後に表示される浮動小数点値
  • 取引操作に必要な証拠金
  • 取引操作が実行された後に残る自由資本の金額
  • 取引操作が実行された後に設定される証拠金レベル
  • 返信コードコメント(エラーの説明)

成行注文を送信する場合 (MqlTradeRequest.action=TRADE_ACTION_DEAL)、OrderSend() 関数の正常結果は、注文が実行されたことを意味しません。この場合、'true"によって意味されるのは、注文がその後の実行のために取引システムに正常に配置されたことだけです。トレードサーバーは、OrderSend()への応答を形成する場合にデータがある場合、返された結果構造体dealまたはorderフィールド値に書き入れます。一般に、注文に対応する取引を実行するイベントは、OrderSend() 呼び出しに対する応答を送信した後に発生する可能性があります。したがって、いずれの取引リクエストに対しても、OrderSend()の実行結果を受け取ったときには、まず、結果構造体retcode t取引サーバリレスポンスコードとretcode_external外部システムレスポンスコードを初めに確認するべきです。

受け入れられた注文は、実行に必要な条件の 1 つが準備出来るまで処理を待って取引サーバに格納されます。

  • 期限切れ
  • 反方向のリクエストの出現
  • 指定された実行価格が出現した場合の注文の実行
  • 注文を取り消すリクエストの受信

注文処理時に、取引サーバは端末に取引イベント発生についてのメッセージを送り、これは OnTrade() 関数で処理出来ます。

サーバ上で OrderSend() 関数で送られたリクエストを実行した結果は OnTradeTransaction ハンドラで追跡出来ます。1 つの取引リクエストを実行する際に OnTradeTransaction ハンドラは複数回呼ばれることには留意されるべきです。

例えば、市場の買い注文を送信する際に、注文が処理され、買い注文が口座に記録されます。その後注文が実行されオープン注文の表から削除されて注文履歴に追加されます。約定履歴に追加され新しいポジションが作成されます。OnTradeTransaction 関数はこれらのイベント全部に呼び出されます。

例:

//--- ORDER_MAGIC の値
input long order_magic=55555;
//+------------------------------------------------------------------+
//| スクリプトプログラムを開始する関数                                          |
//+------------------------------------------------------------------+
void OnStart()
 {
//--- これがデモ口座であることを確かめる
  if(AccountInfoInteger(ACCOUNT_TRADE_MODE)==ACCOUNT_TRADE_MODE_REAL)
    {
    Alert("Script operation is not allowed on a live account!");
    return;
    }
//--- 注文を出すか削除する
  if(GetOrdersTotalByMagic(order_magic)==0)
    {
    //--- 現在注文はないので、注文を出す
    uint res=SendRandomPendingOrder(order_magic);
    Print("Return code of the trade server ",res);
    }
  else // 注文があるので削除する
    {
     DeleteAllOrdersByMagic(order_magic);
    }
//---
 }
//+------------------------------------------------------------------+
//| 指定された ORDER_MAGIC で現在の注文数を受け取る                          |
//+------------------------------------------------------------------+
int GetOrdersTotalByMagic(long const magic_number)
 {
  ulong order_ticket;
  int total=0;
//--- 未決注文を全部見る
  for(int i=0;i<OrdersTotal();i++)
    if((order_ticket=OrderGetTicket(i))>0)
        if(magic_number==OrderGetInteger(ORDER_MAGIC)) total++;
//---
  return(total);
 }
//+------------------------------------------------------------------+
//| 指定された ORDER_MAGIC  の未決注文を全て作成する                         |
//+------------------------------------------------------------------+
void DeleteAllOrdersByMagic(long const magic_number)
 {
  ulong order_ticket;
//--- 未決注文を全部見る
  for(int i=OrdersTotal()-1;i>=0;i--)
    if((order_ticket=OrderGetTicket(i))>0)
        //--- 適切な ORDER_MAGIC を持った注文
        if(magic_number==OrderGetInteger(ORDER_MAGIC))
          {
          MqlTradeResult result={0};
          MqlTradeRequest request={0};
           request.order=order_ticket;
           request.action=TRADE_ACTION_REMOVE;
          OrderSend(request,result);
          //--- サーバ返答をログに書く
          Print(__FUNCTION__,": ",result.comment," reply code ",result.retcode);
          }
//---
 }
//+------------------------------------------------------------------+
//| 未決注文をランダムに設定する                                            |
//+------------------------------------------------------------------+
uint SendRandomPendingOrder(long const magic_number)
 {
//--- リクエストを準備する
  MqlTradeRequest request={0};
  request.action=TRADE_ACTION_PENDING;         // 未決注文を設定する
  request.magic=magic_number;                 // ORDER_MAGIC
  request.symbol=_Symbol;                     // シンボル
  request.volume=0.1;                         // 0.1 ロットのボリューム
  request.sl=0;                               // 決済逆指の指定なし
  request.tp=0;                               // 決済指値の指定なし    
//--- 注文の種類を形成する
  request.type=GetRandomType();               // 注文の種類
//--- 未決注文の価格を形成する
  request.price=GetRandomPrice(request.type); // 始値
//--- 取引リクエストを送る
  MqlTradeResult result={0};
  OrderSend(request,result);
//--- サーバ返答をログに書く  
  Print(__FUNCTION__,":",result.comment);
  if(result.retcode==10016) Print(result.bid,result.ask,result.price);
//--- 取引サーバの返答のコードを返す
  return result.retcode;
 }
//+------------------------------------------------------------------+
//| 未決注文の種類をランダムに返す                                           |
//+------------------------------------------------------------------+
ENUM_ORDER_TYPE GetRandomType()
 {
  int t=MathRand()%4;
//---   0<=t<4
  switch(t)
    {
    case(0):return(ORDER_TYPE_BUY_LIMIT);
    case(1):return(ORDER_TYPE_SELL_LIMIT);
    case(2):return(ORDER_TYPE_BUY_STOP);
    case(3):return(ORDER_TYPE_SELL_STOP);
    }
//--- 不正な値
  return(WRONG_VALUE);
 }
//+------------------------------------------------------------------+
//| ランダムな価格を返す                                                   |
//+------------------------------------------------------------------+
double GetRandomPrice(ENUM_ORDER_TYPE type)
 {
  int t=(int)type;
//--- シンボルのストップレベル
  int distance=(int)SymbolInfoInteger(_Symbol,SYMBOL_TRADE_STOPS_LEVEL);
//--- 最終ティックのデータを受け取る
  MqlTick last_tick={0};
  SymbolInfoTick(_Symbol,last_tick);
//--- 種類に応じて価格を計算する
  double price;
  if(t==2 || t==5) // ORDER_TYPE_BUY_LIMIT または ORDER_TYPE_SELL_STOP
    {
     price=last_tick.bid; // 買値から離れる
     price=price-(distance+(MathRand()%10)*5)*_Point;
    }
  else             // ORDER_TYPE_SELL_LIMIT または ORDER_TYPE_BUY_STOP
    {
     price=last_tick.ask; // 売値から離れる
     price=price+(distance+(MathRand()%10)*5)*_Point;
    }
//---
  return(price);
 }

参照

取引操作の種類取引リクエストの構造体リクエストチェック結果の構造体取引リクエスト結果の構造体