OnTrade

この関数はTradeイベントが発生するときにEAで呼び出され、注文、ポジション、取引リストの変更を処理するためのものです。

void  OnTrade(void);

戻り値

なし

注意事項

OnTrade()はエキスパートアドバイザーでのみ呼び出されます。同じ名前と型の関数をそこに追加しても、指標やスクリプトには使用されません

指値注文の実行、ポジションの開閉、ストップの設定、指値注文の発動などの取引操作によって、注文および取引の履歴、および/またはポジションおよび現在の注文のリストが適切に変更されます。

注文を処理する際、取引サーバは、着信されるTrade イベントに関するメッセージを端末に送信します。履歴から注文と取引に関する関連データを検索するには、まずHistorySelect()を使用して取引履歴リクエストを実行する必要があります。

取引イベントは、次の場合にサーバによって生成されます。

  • アクティブ注文の変更
  • ポジションの変更
  • 約定の変更
  • 取引履歴の変更

 

それぞれの Tradeイベントは、1つまたは複数の取引要求の結果として表示されることがあります。取引リクエストは、 OrderSend()またはOrderSendAsync()を使用してサーバに送信されます。それぞれのリクエストは、いくつかの取引イベントにつながる可能性があります。イベントの処理はいくつかの段階で実行されることがあり、各操作によって注文、ポジション、取引履歴の状態が変更される可能性があるため、「1つのリクエスト - 1つの取引イベント」という声明に頼ることはできません。

 

OnTrade()ハンドラーはOnTradeTransaction()が呼び出された後で呼び出されます。一般に、OnTrade()とOnTradeTransaction()の呼び出しの数には正確な相関関係はありません。1つのOnTrade()コールは、1つまたは複数のOnTradeTransactionコールに対応します。

OnTrade()を持つEAの例

//+------------------------------------------------------------------+
//|                                               OnTrade_Sample.mq5 |
//|                        Copyright 2018, MetaQuotes Software Corp. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2000-2024, MetaQuotes Ltd."
#property link     "https://www.mql5.com"
#property version   "1.00"
 
input   int days=7;           // 取引履歴の日数
//--- グローバルスコープで取引履歴の上限を設定する
datetime     start;             // キャッシュ内の取引履歴の開始日
datetime     end;               // キャッシュ内の取引履歴の終了日
//--- グローバルカウンタ
int          orders;           // アクティブ注文数
int          positions;         // ポジション数
int          deals;             // 取引履歴キャッシュ内の約定数
int          history_orders;   // 取引履歴キャッシュ内の注文数
bool         started=false;     // カウンタ有効性のフラグ
 
//+------------------------------------------------------------------+
//| エキスパート初期化関数                                                 |
//+------------------------------------------------------------------+
int OnInit()
 {
//---
  end=TimeCurrent();
  start=end-days*PeriodSeconds(PERIOD_D1);
  PrintFormat("Limits of the history to be loaded: start - %s, end - %s",
              TimeToString(start),TimeToString(end));
  InitCounters();
//---
  return(0);
 }
//+------------------------------------------------------------------+
//|  ポジション、注文、取引カウンタの初期化                                     |
//+------------------------------------------------------------------+
void InitCounters()
 {
  ResetLastError();
//--- 履歴を読み込む
  bool selected=HistorySelect(start,end);
  if(!selected)
    {
    PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
                __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
    return;
    }
//--- 現在値を取得する
  orders=OrdersTotal();
  positions=PositionsTotal();
  deals=HistoryDealsTotal();
  history_orders=HistoryOrdersTotal();
  started=true;
  Print("Counters of orders, positions and deals successfully initialized");
 }  
//+------------------------------------------------------------------+
//| エキスパートティック関数                                                 |
//+------------------------------------------------------------------+
void OnTick()
 {
  if(started) SimpleTradeProcessor();
  else InitCounters();
 }
//+------------------------------------------------------------------+
//| Tradeイベントが到着すると呼び出される                                     |
//+------------------------------------------------------------------+
void OnTrade()
 {
  if(started) SimpleTradeProcessor();
  else InitCounters();
 }
//+------------------------------------------------------------------+
//| 取引と履歴の変更を処理する例                                           |
//+------------------------------------------------------------------+
void SimpleTradeProcessor()
 {
  end=TimeCurrent();
  ResetLastError();
//--- 指定された間隔でプログラムキャッシュに取引履歴をダウンロードする
  bool selected=HistorySelect(start,end);
  if(!selected)
    {
    PrintFormat("%s. Failed to load history from %s to %s to cache. Error code: %d",
                __FUNCTION__,TimeToString(start),TimeToString(end),GetLastError());
    return;
    }
//--- 現在値を取得する
  int curr_orders=OrdersTotal();
  int curr_positions=PositionsTotal();
  int curr_deals=HistoryDealsTotal();
  int curr_history_orders=HistoryOrdersTotal();
//--- アクティブ注文の数が変更されているかどうかを確認する
  if(curr_orders!=orders)
    {
    //--- アクティブ注文の数が変更されている
    PrintFormat("Number of orders has been changed. Previous value is %d, current value is %d",
                 orders,curr_orders);
    //--- 値を更新する
     orders=curr_orders;
    }
//--- ポジション数の変更
  if(curr_positions!=positions)
    {
    //--- ポジション数が変更されている
    PrintFormat("Number of positions has been changed. Previous value is %d, current value is %d",
                 positions,curr_positions);
    //--- 値を更新する
     positions=curr_positions;
    }
//--- 取引履歴キャッシュ内の約定数の変更
  if(curr_deals!=deals)
    {
    //--- 取引履歴キャッシュ内の約定数が変更されている
    PrintFormat("Number of deals has been changed. Previous value is %d, current value is %d",
                 deals,curr_deals);
    //--- 値を更新する
     deals=curr_deals;
    }
//--- 取引履歴キャッシュ内の履歴注文数の変更
  if(curr_history_orders!=history_orders)
    {
    //--- 取引履歴キャッシュ内の履歴注文数が変更されている
    PrintFormat("Number of orders in history has been changed. Previous value is %d, current value is %d",
                 history_orders,curr_history_orders);
    //--- 値を更新する
    history_orders=curr_history_orders;
    }
//--- キャッシュ内でリクエストされる取引履歴の上限を変更する必要があるかどうかを確認する
  CheckStartDateInTradeHistory();
 }
//+------------------------------------------------------------------+
//|  取引履歴リクエストの開始日の変更                                        |
//+------------------------------------------------------------------+
void CheckStartDateInTradeHistory()
 {
//--- 今すぐ作業を始めると仮定した場合の最初の間隔、
  datetime curr_start=TimeCurrent()-days*PeriodSeconds(PERIOD_D1);
//--- 取引履歴の開始制限が意図された日から1日以上経過して
//--- いないことを確認する
  if(curr_start-start>PeriodSeconds(PERIOD_D1))
    {
    //--- キャッシュに読み込まれる履歴の開始日を修正する
     start=curr_start;
    PrintFormat("New start limit of the trade history to be loaded: start => %s",
                TimeToString(start));
    //---更新された期間の取引履歴を再度読み込む
    HistorySelect(start,end);
    //--- さらなる比較のために約定および注文カウンタを修正する
     history_orders=HistoryOrdersTotal();
     deals=HistoryDealsTotal();
    }
 }
//+------------------------------------------------------------------+
/* 出力例:
  Limits of the history to be loaded: start - 2018.07.16 18:11, end - 2018.07.23 18:11
  The counters of orders, positions and deals are successfully initialized
  Number of orders has been changed. Previous value 0, current value 1
  Number of orders has been changed. Previous value 1, current value 0
  Number of positions has been changed. Previous value 0, current value 1
  Number of deals has been changed. Previous value 0, current value 1
  Number of orders in the history has been changed. Previous value 0, current value 1
*/

参照

OrderSendOrderSendAsyncOnTradeTransaction, Client terminal events