【MQL5】MqlTradeTransaction構造体について

MQL5リファレンス
スポンサーリンク
スポンサーリンク
  1. MqlTradeTransaction構造体とは
    1. トランザクションとは
  2. MqlTradeTransaction構造体のフィールド(メンバ変数)について
  3. dealフィールドについて
  4. orderフィールドについて
  5. symbolフィールドについて
  6. typeフィールドについて
  7. order_typeフィールドについて
  8. order_stateフィールドについて
    1. ENUM_ORDER_STATEについて
      1. ORDER_STATE_STARTED
      2. ORDER_STATE_PLACED
      3. ORDER_STATE_CANCELED
      4. ORDER_STATE_PARTIAL
      5. ORDER_STATE_FILLED
      6. ORDER_STATE_REJECTED
      7. ORDER_STATE_EXPIRED
  9. deal_typeフィールドについて
    1. ENUM_DEAL_TYPEについて
      1. DEAL_TYPE_BUY
      2. DEAL_TYPE_SELL
      3. DEAL_TYPE_BALANCE
      4. DEAL_TYPE_CREDIT
  10. time_typeフィールドについて
    1. ENUM_ORDER_TYPE_TIMEについて
      1. ORDER_TIME_GTC
      2. ORDER_TIME_DAY
      3. ORDER_TIME_SPECIFIED
      4. ORDER_TIME_SPECIFIED_DAY
  11. time_expirationフィールドについて
  12. priceフィールドについて
  13. price_triggerフィールドについて
    1. ストップリミット注文とは?
  14. price_slフィールドについて
  15. price_tpフィールドについて
  16. volumeフィールドについて
  17. positionフィールドについて
  18. position_byフィールドについて
  19. MqlTradeTransaction構造体を使用したサンプルコード
  20. 解説1:グローバル領域での定義
    1. CTradeクラスのインクルードとインスタンスの宣言
    2. フラグの定義
    3. 待機注文チケットの定義
  21. 解説2:OnInit関数
    1. MagicNumberの設定
    2. 非同期モードの設定
    3. 変数の初期化
    4. 関数の戻り値
  22. 解説3:OnTick関数その1
    1. 待機注文の設定
    2. 現在のAsk価格の取得
    3. 待機注文価格の計算
    4. 待機注文の送信
    5. 待機注文が成功した場合の処理
    6. 待機注文が設定されたことを記録
    7. 取引結果の取得
    8. リクエストIDの取得
    9. コンソールへの出力
    10. 注文チケットの保存
    11. 関数の終了
  23. 解説4:OnTick関数その2
    1. 待機注文の削除
    2. 追加のチェック
    3. 待機注文の削除を試みる
    4. 削除リクエストの結果を出力
    5. 削除リクエストが成功した場合の処理
    6. 待機注文が削除されたことを記録
    7. リクエストの実行結果を取得
    8. リクエストIDの取得
    9. 操作ログへの出力
    10. 注文チケットの修正
  24. 解説5:OnTradeTransaction関数
    1. OnTradeTransaction関数の概要
    2. トランザクション型の取得
    3. トランザクションが取引リクエストの場合
      1. トランザクションの種類の表示
      2. リクエストの詳細表示
      3. リクエスト結果の詳細表示
      4. 注文チケットの保存
    4. その他のトランザクションの場合
      1. トランザクションの詳細表示
  25. 解説6:TransactionDescription関数(オリジナル関数)
    1. 関数の概要
    2. トランザクションの種類の記述
    3. シンボルの記述
    4. 約定チケットの記述
    5. 約定の種類の記述
    6. 注文チケットの記述
    7. 注文の種類の記述
    8. 注文状態の記述
    9. 注文の作用時間の種類の記述
    10. 注文の期限の記述
    11. 価格の記述
    12. ストップリミット注文の価格の記述
    13. 決済逆指値の記述
    14. 決済指値の記述
    15. ボリュームの記述
    16. 文字列を戻り値として返す。
  26. 解説7:RequestDescription関数(オリジナル関数)
    1. 関数の概要
    2. リクエストのアクションの記述
    3. シンボルの記述
    4. マジックナンバーの記述
    5. 注文チケットの記述
    6. 注文の種類の記述
    7. 注文のフィリングタイプの記述
    8. 注文の作用時間の種類の記述
    9. 注文の期限の記述
    10. 価格の記述
    11. 価格のスリッページの記述
    12. ストップロスの記述
    13. テイクプロフィットの記述
    14. ストップリミットの記述
    15. ボリュームの記述
    16. コメントの記述
    17. 文字列を戻り値として返す
  27. 解説8:TradeResultDescription関数(オリジナル関数)
    1. 関数の概要
    2. リクエスト結果のコードの記述
    3. リクエストIDの記述
    4. 注文チケットの記述
    5. 約定チケットの記述
    6. ボリュームの記述
    7. 価格の記述
    8. Ask価格の記述
    9. Bid価格の記述
    10. コメントの記述
    11. 文字列を戻り値として返す

MqlTradeTransaction構造体とは

MqlTradeTransaction構造体は、取引トランザクションの詳細を保持するための構造体です。
この構造体は、取引が実行される際に発生する様々なアクションに関連する情報を格納します。

MQL5では、取引リクエストの送信、待機注文の変更、注文履歴の変更、約定履歴の変更、ポジションの変更など、取引口DEAL_TYPE_BUY座に対する操作が行われると、これらの操作の結果として取引トランザクションが生成されます。
MqlTradeTransaction構造体は、これらの取引トランザクションに関する詳細な情報を提供し、取引処理の状態を管理するために使用されます。

トランザクションとは

MT5およびMQL5において、トランザクションは取引口座に対して行われるすべての操作やアクションを指します。
これには、取引リクエストの送信や実行、待機注文の設定や変更、ポジションの開閉、注文および約定の履歴の更新などが含まれます。トランザクションは、これらのアクションがどのように実行され、どのような結果が生じたかを詳細に記録する役割を果たします。

MqlTradeTransaction構造体のフィールド(メンバ変数)について

MqlTradeTransaction構造体のフィールド(メンバ変数)については以下の通りです。

struct MqlTradeTransaction
 {
  ulong                         deal;             // 約定チケット
  ulong                         order;            // 注文チケット
  string                        symbol;           // 取引銘柄名
  ENUM_TRADE_TRANSACTION_TYPE   type;             // 取引トランザクションの種類
  ENUM_ORDER_TYPE               order_type;       // 注文の種類
  ENUM_ORDER_STATE              order_state;      // 注文状態
  ENUM_DEAL_TYPE                deal_type;        // 約定の種類
  ENUM_ORDER_TYPE_TIME          time_type;        // 作用時間の注文種類
  datetime                      time_expiration;  // 注文の期限
  double                        price;            // 価格
  double                        price_trigger;    // ストップリミット注文アクティベーションの価格
  double                        price_sl;         // 決済逆指値レベル
  double                        price_tp;         // 決済指値レベル
  double                        volume;           // ボリューム(ロット単位)
  ulong                         position;         // ポジションチケット
  ulong                         position_by;      // 反対ポジションのチケット
 };

各フィールド(メンバ変数)の役割は以下の通りです。

dealフィールドについて

dealフィールドは、取引に関連する約定チケットを格納します。約定チケットは、特定の約定を一意(1つしか存在しない)に識別するための番号です。この番号は取引が成立した際に生成され、後のトランザクション処理や履歴の追跡に使用されます。約定チケットは通常、サーバー側で生成され、取引の詳細を確認するために使用されます。

orderフィールドについて

orderフィールドは、取引に関連する注文チケットを格納します。注文チケットは、特定の注文を一意(1つしか存在しない)に識別するための番号です。この番号は取引リクエストが送信された際に生成され、注文の管理や履歴の追跡に使用されます。

dealフィールドとの違いは、orderフィールドが注文に対して生成されるのに対し、dealフィールドはその注文が約定した後に生成されることです。つまり、orderフィールドは取引の発注段階を管理し、dealフィールドは取引の約定段階を管理します。

symbolフィールドについて

symbolフィールドは、取引が行われる取引銘柄名を格納します。取引銘柄名は、具体的にどの金融商品が取引の対象となっているかを識別するために使用されます。例えば、通貨ペアや株式のティッカーシンボルなどが含まれます。

このフィールドは、取引トランザクションがどの銘柄に関連しているかを明確にするために重要です。取引の記録や履歴の追跡を行う際に、このフィールドを参照することで、どの銘柄に対する注文や約定が行われたのかを容易に確認することができます。

typeフィールドについて

typeフィールドは、取引トランザクションの種類を格納します。このフィールドの値はENUM_TRADE_TRANSACTION_TYPE列挙型のいずれかであり、具体的には以下のような取引トランザクションの種類を示します。

typeフィールドは、取引トランザクションがどのような操作に関連しているかを識別するために使用されます。これにより、プログラムは特定の種類のトランザクションに対して適切な処理を行うことができます。例えば、注文の追加や更新、削除など、異なる種類のトランザクションに応じて異なるロジックを適用することができます。

ENUM_TRADE_TRANSACTION_TYPE列挙型については↓の記事をご参照ください。

order_typeフィールドについて

order_typeフィールドは、取引注文の種類を格納します。このフィールドの値はENUM_ORDER_TYPE列挙型のいずれかであり、具体的には以下のような注文の種類を示します。

order_typeフィールドは、取引がどのような注文形態で行われたかを識別するために使用されます。これにより、プログラムは特定の注文タイプに対して適切な処理を行うことができます。
例えば、リミット注文やストップ注文など、異なる種類の注文に応じて異なるロジックを適用することができます。

order_stateフィールドについて

order_stateフィールドは、取引注文の状態を格納します。このフィールドの値はENUM_ORDER_STATE列挙型のいずれかであり、具体的には以下のような注文の状態を示します。

ENUM_ORDER_STATEについて

ENUM_ORDER_STATEとは、取引注文の現在の状態を表す列挙型です。この列挙型は、注文が処理される各段階を明確に識別するために使用されます。
これにより、プログラムは注文がどのような状態にあるかを把握し、それに応じた適切な処理を行うことができます。

ORDER_STATE_STARTED

ORDER_STATE_STARTEDは、注文が開始された状態を示します。これは、注文がまだ処理中であり、取引サーバーによって正式に受理される前の段階です。

ORDER_STATE_PLACED

ORDER_STATE_PLACEDは、注文が正式に配置された状態を示します。取引サーバーによって注文が受理され、市場での実行待ちの状態です。

ORDER_STATE_CANCELED

ORDER_STATE_CANCELEDは、注文がキャンセルされた状態を示します。これは、取引が実行される前にトレーダーまたはシステムによって注文が取り消されたことを意味します。

ORDER_STATE_PARTIAL

ORDER_STATE_PARTIALは、注文が部分的に約定された状態を示します。注文の一部が市場で実行され、残りの部分がまだ未実行の状態です。

ORDER_STATE_FILLED

ORDER_STATE_FILLEDは、注文が完全に約定された状態を示します。注文全体が市場で実行され、トレーダーの取引が完了したことを意味します。

ORDER_STATE_REJECTED

ORDER_STATE_REJECTEDは、注文が拒否された状態を示します。取引サーバーによって注文が受理されず、取引が成立しなかったことを意味します。

ORDER_STATE_EXPIRED

ORDER_STATE_EXPIREDは、注文が有効期限切れになった状態を示します。注文が指定された有効期限を過ぎたため、自動的に無効となり、取引が実行されないことを意味します。


deal_typeフィールドについて

deal_typeフィールドは、約定の種類を格納します。このフィールドの値はENUM_DEAL_TYPE列挙型のいずれかであり、具体的には以下のような約定の種類を示します。

ENUM_DEAL_TYPEについて

DEAL_TYPE_BUY

DEAL_TYPE_BUYは、買い注文が約定されたことを示します。この種類の約定は、トレーダーが特定の価格で資産を購入したことを意味します。

DEAL_TYPE_SELL

DEAL_TYPE_SELLは、売り注文が約定されたことを示します。この種類の約定は、トレーダーが特定の価格で資産を売却したことを意味します。

DEAL_TYPE_BALANCE

DEAL_TYPE_BALANCEは、口座残高の変更を示します。この種類の約定は、入金や出金などによって口座の資金が増減したことを意味します。

DEAL_TYPE_CREDIT

DEAL_TYPE_CREDITは、口座にクレジットが適用されたことを示します。この種類の約定は、ボーナスやその他のクレジットが口座に追加されたことを意味します。

ENUM_DEAL_TYPE列挙型についての詳細は↓の記事をご参照ください。

time_typeフィールドについて

time_typeフィールドは、注文の作用時間の種類(注文の有効期限に関する決まり事)を格納します。このフィールドの値はENUM_ORDER_TYPE_TIME列挙型のいずれかであり、具体的には以下のような注文の作用時間の種類を示します。

ENUM_ORDER_TYPE_TIMEについて

ORDER_TIME_GTC

ORDER_TIME_GTCは、「Good Till Canceled(キャンセルされるまで有効)」を意味します。この種類の注文は、トレーダーが明示的にキャンセルするまで市場で有効です。

ORDER_TIME_DAY

ORDER_TIME_DAYは、その日の取引終了時まで有効な注文を示します。取引日の終了と共に、注文は自動的にキャンセルされます。

ORDER_TIME_SPECIFIED

ORDER_TIME_SPECIFIEDは、トレーダーが指定した日時まで有効な注文を示します。この種類の注文は、設定された日時を過ぎると自動的にキャンセルされます。

ORDER_TIME_SPECIFIED_DAY

ORDER_TIME_SPECIFIED_DAYは、トレーダーが指定した日にちの取引終了時まで有効な注文を示します。この種類の注文は、指定された日の取引終了と共に自動的にキャンセルされます。

time_expirationフィールドについて

time_expirationフィールドは、注文の期限を格納します。このフィールドはdateTime型で、特定の待機注文が有効である期限を示します。

待機注文の有効期限を設定することで、指定した日時を過ぎると注文が自動的にキャンセルされます。time_typeフィールド設定がORDER_TIME_SPECIFIEDまたはORDER_TIME_SPECIFIED_DAYはの場合、このtime_expirationフィールドが使用されます。これにより、トレーダーは注文の有効期限を細かくコントロールすることができます。

priceフィールドについて

priceフィールドは、取引の価格を格納します。このフィールドはdouble型で、取引トランザクションの種類によって異なる意味を持ちます。

買い注文や売り注文の場合、priceフィールドには注文が出された価格が格納されます。待機注文の場合は、指定された価格に達したときに注文が実行されます。約定の場合は、取引が実際に行われた価格が格納されます。

このフィールドは、取引の詳細を理解し、取引履歴を追跡する上で非常に重要です。価格の設定や管理を通じて、トレーダーは市場での取引を効果的に行うことができます。

price_triggerフィールドについて

price_triggerフィールドは、ストップリミット注文がアクティベートされる価格を格納します。このフィールドはdouble型で、特定の条件が満たされたときに注文が実行される価格を示します。

具体的には、ストップリミット注文(買いストップリミット注文および売りストップリミット注文)の場合、このフィールドにはストップ注文が発動する価格が設定されます。この価格に市場価格が達したとき、リミット注文が有効になり、指定された価格またはそれ以上の有利な価格で注文が実行されます。

price_triggerフィールドは、取引戦略において特定の価格レベルに達したときに自動的に取引を開始するために使用されます。これにより、トレーダーは市場の動きを効果的に活用し、望ましい取引を自動的に行うことができます。

ストップリミット注文とは?

ストップリミット注文とは、特定の価格に達したときにリミット注文が発動される複合注文です。これは、ストップ注文とリミット注文の要素を組み合わせたもので、以下のように機能します。

  1. ストップ注文:
    • 市場価格が指定されたストップ価格に達すると、リミット注文が発動します。
  2. リミット注文:
    • ストップ価格に達した後、リミット注文が設定された価格またはそれ以上の有利な価格で実行されます。

例えば、買いストップリミット注文の場合、現在の市場価格よりも高いストップ価格を設定します。市場価格がそのストップ価格に達すると、リミット価格で買い注文が発動されます。これにより、トレーダーは価格が特定のレベルに達したときに自動的に取引を開始し、さらに有利な価格で取引を行うことができます。
トレンドが発生した後、一時的な反発の動きがある事を想定している時等にストップリミット注文は使われます。

price_slフィールドについて

price_slフィールドは、決済逆指値レベルを格納します。このフィールドはdouble型で、特定の価格に達した場合にポジションを決済するために設定された逆指値注文の価格を示します。

決済逆指値(ストップロス)注文は、損失を限定するために使用されます。このフィールドに設定された価格に市場価格が達すると、ポジションが自動的に決済され、さらなる損失を防ぎます。

price_tpフィールドについて

price_tpフィールドは、決済指値レベルを格納します。このフィールドはdouble型で、特定の価格に達した場合にポジションを決済するために設定された指値注文の価格を示します。

決済指値(テイクプロフィット)注文は、利益を確定するために使用されます。このフィールドに設定された価格に市場価格が達すると、ポジションが自動的に決済され、利益が確定されます。

volumeフィールドについて

volumeフィールドは、取引のボリュームを格納します。このフィールドはdouble型で、取引されるロット数を示します。

取引のボリュームは、トレーダーが特定の取引でどれだけの資産を売買するかを決定する重要な要素です。例えば、1ロットは通常、特定の基準に基づく標準的な取引単位を意味します。

positionフィールドについて

positionフィールドは、取引に関連するポジションチケットを格納します。このフィールドはulong型で、特定のポジションを一意(1つしか存在しない)に識別するための番号です。

ポジションチケットは、取引が成立した際に生成され、現在保有しているポジションの管理や追跡に使用されます。このフィールドを参照することで、トレーダーは特定のポジションの詳細情報を取得したり、ポジションを管理するための操作を行ったりすることができます。

position_byフィールドについて

position_byフィールドは、反対ポジションのチケットを格納します。このフィールドはulong型で、特定の反対ポジションを一意(1つしか存在しない)に識別するための番号です。

反対ポジションのチケットは、同じシンボルで逆方向に保有されているポジションを指します。このフィールドは、特に反対ポジションを決済する注文(クローズ・バイ注文)の際に使用されます。

position_byフィールドは、反対ポジションを識別し、それに関連する取引を管理するために重要です。トレーダーはこのフィールドを使用して、関連する反対ポジションの詳細情報を取得し、効率的なポジション管理とリスクヘッジを行うことができます。

MqlTradeTransaction構造体を使用したサンプルコード

以下に、MqlTradeTransaction構造体を使用したサンプルコードを示します。このコードは、OnTradeTransaction関数で取引トランザクションを処理する方法を示しています。

input int MagicNumber=1234567;
 
//--- CTrade 取引クラスを有効にしてクラス変数を宣言する
#include <Trade\Trade.mqh>
CTrade trade;
//--- 待機注文インストールと削除のフラグ
bool pending_done=false;
bool pending_deleted=false;
//--- 待機注文チケットはここに保存される
ulong order_ticket;

//+------------------------------------------------------------------+
//| エキスパート初期化に使用される関数                              |
//+------------------------------------------------------------------+
int OnInit()
 {
    //--- MagicNumber を設定して全ての注文をマークする
    trade.SetExpertMagicNumber(MagicNumber);
    //--- 取引リクエストは OrderSendAsync() 関数を使用して非同期モードで送信される
    trade.SetAsyncMode(true);
    //--- 変数をゼロで初期化する
    order_ticket=0;
    //---
    return(INIT_SUCCEEDED);
 }

//+------------------------------------------------------------------+
//| エキスパートティック関数                                         |
//+------------------------------------------------------------------+
void OnTick()
 {
    //--- 待機注文のインストール
    if(!pending_done)
    {
        double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
        double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
        bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
        //--- BuyStop() 関数が成功
        if(res)
        {
            pending_done=true;
            //--- ctrade から送信リクエストした結果の取得
            MqlTradeResult trade_result;
            trade.Result(trade_result);
            //--- 送信されたリクエストの request_id を取得
            uint request_id=trade_result.request_id;
            Print("Request has been sent to set a pending order. Request_ID=",request_id);
            //--- 注文チケットを保存する(CTrade への送信に非同期モードを使用する場合はゼロ)
            order_ticket=trade_result.order;
            //--- 完成。 OnTick() ハンドラ—を早期終了する。
            return;
        }
    }
    
    //--- 待機注文の削除
    if(!pending_deleted)
    {
        //--- 追加のチェック
        if(pending_done && (order_ticket!=0))
        {
            //--- 待機注文の削除を試みる
            bool res=trade.OrderDelete(order_ticket);
            Print("OrderDelete=",res);
            //--- 削除リクエスト送信に成功
            if(res)
            {
                pending_deleted=true;
                //--- リクエストの実行結果を取得
                MqlTradeResult trade_result;
                trade.Result(trade_result);
                //--- 結果から request ID と取得
                uint request_id=trade_result.request_id;
                //--- 操作ログに表示
                Print("The request has been sent to delete a pending order #",order_ticket,
                      ". Request_ID=",request_id,
                      "\r\n");
                //--- リクエスト結果から注文チケットを修正
                order_ticket=trade_result.order;
            }
        }
    }
}

//+------------------------------------------------------------------+
//| TradeTransaction 関数                                            |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                      const MqlTradeRequest &request,
                      const MqlTradeResult &result)
{
    //--- トランザクション型を列挙値として取得する
    ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;
    
    //--- トランザクションが結果処理のリクエストの場合は、名称のみを表示する
    if(type==TRADE_TRANSACTION_REQUEST)
    {
        Print(EnumToString(type));
        //--- 取り扱つかわれたリクエストの文字列名を表示する
        Print("------------RequestDescription\r\n",RequestDescription(request));
        //--- リクエスト結果の記述を表示する
        Print("------------ResultDescription\r\n",TradeResultDescription(result));
        //--- OnTick() の次のハンドルで削除されるよう、チケットを保存する
        if(result.order!=0)
        {
            //--- 次の OnTick() の呼び出しでこの注文をチケットによって削除する
            order_ticket=result.order;
            Print(" Pending order ticket ",order_ticket,"\r\n");
        }
    }
    else // 別の種類のトランザクションの完全記述を表示する
    {
        //--- 受け取ったトランザクションの記述を操作ログに表示する
        Print("------------TransactionDescription\r\n",TransactionDescription(trans));
    }
}

//+------------------------------------------------------------------+
//| トランザクションのテキスト形式の記述を返す                      |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
{
    //--- トランザクションの記述を作成する
    string desc=EnumToString(trans.type)+"\r\n";
    desc+="Symbol: "+trans.symbol+"\r\n";
    desc+="Deal ticket: "+(string)trans.deal+"\r\n";
    desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
    desc+="Order ticket: "+(string)trans.order+"\r\n";
    desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
    desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
    desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
    desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
    desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
    desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
    desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
    desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
    desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
    //--- 取得した文字列を返す
    return desc;
}

//+------------------------------------------------------------------+
//| 取引リクエストのテキスト形式の記述を返す                        |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
{
    //--- リクエストの記述を作成する
    string desc=EnumToString(request.action)+"\r\n";
    desc+="Symbol: "+request.symbol+"\r\n";
    desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
    desc+="Order ticket: "+(string)request.order+"\r\n";
    desc+="Order type: "+EnumToString(request.type)+"\r\n";
    desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
    desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
    desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
    desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
    desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
    desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
    desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
    desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
    desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
    desc+="Comment: "+request.comment+"\r\n";
    //--- 取得した文字列を返す
    return desc;
}

//+------------------------------------------------------------------+
//| リクエスト処理結果の記述ををテキスト形式で返す                 |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
{
    //--- リクエスト結果の記述を作成する
    string desc="Retcode "+(string)result.retcode+"\r\n";
    desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
    desc+="Order ticket: "+(string)result.order+"\r\n";
    desc+="Deal ticket: "+(string)result.deal+"\r\n";
    desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
    desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
    desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
    desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
    desc+="Comment: "+result.comment+"\r\n";
    //--- 取得した文字列を返す
    return desc;
}

解説1:グローバル領域での定義

input int MagicNumber=1234567;
 
//--- CTrade 取引クラスを有効にしてクラス変数を宣言する
#include <Trade\Trade.mqh>
CTrade trade;
//--- 待機注文インストールと削除のフラグ
bool pending_done=false;
bool pending_deleted=false;
//--- 待機注文チケットはここに保存される
ulong order_ticket;

MagicNumberは、エキスパートアドバイザEA)が発注した注文を識別するためのユニークな番号です。これにより、異なるEAが発注した注文を区別することができます。ユーザーは、この番号を使って特定のEAの注文のみをフィルタリングして操作することができます。

CTradeクラスのインクルードとインスタンスの宣言

<Trade\Trade.mqh>は、は、MQL5の標準ライブラリに含まれるトレード機能を提供するヘッダファイル(プログラムで使用される関数変数の宣言をまとめたファイル)です。
このヘッダファイルをインクルードすることで、取引関連の関数クラスを利用できるようになります。CTradeクラスは、取引操作を簡単に行うためのクラスであり、そのインスタンスであるtradeを宣言しています。

フラグの定義

bool pending_done=false;とbool pending_deleted=false;は、待機注文の設定と削除の状態を追跡するために使用されます。

待機注文チケットの定義

ulong order_ticketは、待機注文のチケット番号を格納するための変数です。チケット番号は、取引サーバーが注文を識別するための一意(1つしか存在しない)の番号です。この変数を使用して、特定の待機注文を追跡および管理します。

解説2:OnInit関数

int OnInit()
{
    //--- MagicNumber を設定して全ての注文をマークする
    trade.SetExpertMagicNumber(MagicNumber);
    //--- 取引リクエストは OrderSendAsync() 関数を使用して非同期モードで送信される
    trade.SetAsyncMode(true);
    //--- 変数をゼロで初期化する
    order_ticket=0;
    //---
    return(INIT_SUCCEEDED);
}

MagicNumberの設定

trade.SetExpertMagicNumber(MagicNumber)は、MagicNumberを設定し、エキスパートアドバイザEA)が発注する全ての注文をこの番号でマークします。これにより、異なるEAが発注した注文を識別することが容易になります。

非同期モードの設定

trade.SetAsyncMode(true)は、取引リクエストを非同期モードで送信する設定を行います。非同期モードでは、取引リクエストが送信された後、サーバーからの応答を待たずに次の処理に進むことができます。これにより、EAのパフォーマンスが向上し、他の処理がブロックされることを防ぎます。

変数の初期化

order_ticket=0は、待機注文のチケット番号を格納する変数order_ticketをゼロに初期化します。これにより、変数が使用される前に適切な初期値が設定され、予期しない動作を防ぐことができます。

関数の戻り値

return(INIT_SUCCEEDED)は、OnInit関数の実行が成功したことを示します。この値を返すことで、エキスパートアドバイザの初期化が正常に完了したことを示します。

解説3:OnTick関数その1

void OnTick()
{
    //--- 待機注文の設定
    if(!pending_done)
    {
        double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
        double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));
        bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);
        //--- BuyStop() 関数が成功
        if(res)
        {
            pending_done=true;
            //--- ctrade から送信リクエストした結果の取得
            MqlTradeResult trade_result;
            trade.Result(trade_result);
            //--- 送信されたリクエストの request_id を取得
            uint request_id=trade_result.request_id;
            Print("Request has been sent to set a pending order. Request_ID=",request_id);
            //--- 注文チケットを保存する(CTrade への送信に非同期モードを使用する場合はゼロ)
            order_ticket=trade_result.order;
            //--- 完成。 OnTick() ハンドラ—を早期終了する。
            return;
        }
    }
}

待機注文の設定

if(!pending_done)は、待機注文が設定されていない場合に処理を行います。この条件が真の場合、待機注文を設定します。

現在のAsk価格の取得

double ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);は、現在のシンボルのAsk価格を取得します。Ask価格は、買い注文を行う際の価格です。

待機注文価格の計算

double buy_stop_price=NormalizeDouble(ask+1000*_Point,(int)SymbolInfoInteger(_Symbol,SYMBOL_DIGITS));は、現在のAsk価格に1000ポイントを加えた価格を待機注文価格として計算します。価格は小数点以下の桁数に合わせて正規化されます。

待機注文の送信

bool res=trade.BuyStop(0.1,buy_stop_price,_Symbol);は、指定したボリュームと価格で買いのストップ注文を送信します。この関数が成功すると、trueが返されます。

待機注文が成功した場合の処理

if(res)は、待機注文が成功した場合の処理を行います。

待機注文が設定されたことを記録

pending_done=true;は、待機注文が設定されたことを記録します。

取引結果の取得

MqlTradeResult trade_result; trade.Result(trade_result);は、取引結果を格納するためのMqlTradeResult構造体を宣言し、trade.Result関数を使用して結果を取得します。

リクエストIDの取得

uint request_id=trade_result.request_id;は、取引結果からリクエストIDを取得します。リクエストIDは、特定の取引リクエストを識別するために使用されます。

コンソールへの出力

Print(“Request has been sent to set a pending order. Request_ID=”,request_id);は、リクエストIDを含むメッセージをエキスパートログに出力します。

注文チケットの保存

order_ticket=trade_result.order;は、取引結果から注文チケットを取得し、order_ticket変数に保存します。注文チケットは、特定の注文を識別するために使用されます。

関数の終了

return;は、OnTick関数を早期終了します。これにより、待機注文が設定された後の余分な処理を防ぎます。

解説4:OnTick関数その2

   //--- 待機注文の削除
    if(!pending_deleted)
    {
        //--- 追加のチェック
        if(pending_done && (order_ticket!=0))
        {
            //--- 待機注文の削除を試みる
            bool res=trade.OrderDelete(order_ticket);
            Print("OrderDelete=",res);
            //--- 削除リクエスト送信に成功
            if(res)
            {
                pending_deleted=true;
                //--- リクエストの実行結果を取得
                MqlTradeResult trade_result;
                trade.Result(trade_result);
                //--- 結果から request ID と取得
                uint request_id=trade_result.request_id;
                //--- 操作ログに表示
                Print("The request has been sent to delete a pending order #",order_ticket,
                      ". Request_ID=",request_id,
                      "\r\n");
                //--- リクエスト結果から注文チケットを修正
                order_ticket=trade_result.order;
            }
        }
    }
}

待機注文の削除

if(!pending_deleted)は、待機注文がまだ削除されていない場合に処理を行います。この条件が真の場合、待機注文の削除を試みます。

追加のチェック

if(pending_done && (order_ticket!=0))は、待機注文が設定されており、かつ注文チケットがゼロでない場合に処理を行います。この条件が真の場合、待機注文を削除します。

待機注文の削除を試みる

bool res=trade.OrderDelete(order_ticket);は、指定した注文チケットに基づいて待機注文の削除を試みます。この関数が成功すると、trueが返されます。

削除リクエストの結果を出力

Print(“OrderDelete=”,res);は、待機注文の削除リクエストの結果をエキスパートログに出力します。

削除リクエストが成功した場合の処理

if(res)は、待機注文の削除リクエストが成功した場合の処理を行います。

待機注文が削除されたことを記録

pending_deleted=true;は、待機注文が削除されたことを記録します。

リクエストの実行結果を取得

MqlTradeResult trade_result; trade.Result(trade_result);は、取引結果を格納するためのMqlTradeResult構造体を宣言し、trade.Result関数を使用して結果を取得します。

リクエストIDの取得

uint request_id=trade_result.request_id;は、取引結果からリクエストIDを取得します。リクエストIDは、特定の取引リクエストを識別するために使用されます。

操作ログへの出力

Print(“The request has been sent to delete a pending order #”,order_ticket, “. Request_ID=”,request_id, “\r\n”);は、削除リクエストの送信に成功したことを示すメッセージをエキスパートログに出力します。

注文チケットの修正

order_ticket=trade_result.order;は、取引結果から注文チケットを取得し、order_ticket変数に保存します。注文チケットは、特定の注文を識別するために使用されます。

この一連の処理により、待機注文の削除が完了し、その結果が適切にログに記録されます。

解説5:OnTradeTransaction関数

//+------------------------------------------------------------------+
//| TradeTransaction 関数                                            |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction &trans,
                      const MqlTradeRequest &request,
                      const MqlTradeResult &result)
{
    //--- トランザクション型を列挙値として取得する
    ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;

    //--- トランザクションが結果処理のリクエストの場合は、名称のみを表示する
    if(type==TRADE_TRANSACTION_REQUEST)
    {
        Print(EnumToString(type));
        //--- 取り扱つかわれたリクエストの文字列名を表示する
        Print("------------RequestDescription\r\n",RequestDescription(request));
        //--- リクエスト結果の記述を表示する
        Print("------------ResultDescription\r\n",TradeResultDescription(result));
        //--- OnTick() の次のハンドルで削除されるよう、チケットを保存する
        if(result.order!=0)
        {
            //--- 次の OnTick() の呼び出しでこの注文をチケットによって削除する
            order_ticket=result.order;
            Print(" Pending order ticket ",order_ticket,"\r\n");
        }
    }
    else // 別の種類のトランザクションの完全記述を表示する
    {
        //--- 受け取ったトランザクションの記述を操作ログに表示する
        Print("------------TransactionDescription\r\n",TransactionDescription(trans));
    }
}

OnTradeTransaction関数の概要

OnTradeTransaction関数は、取引トランザクションが発生したときに自動的に呼び出されるイベントハンドラです。
この関数は、取引の詳細を示すMqlTradeTransaction構造体、および関連する取引リクエストと結果を引数として受け取ります。

トランザクション型の取得

ENUM_TRADE_TRANSACTION_TYPE type=(ENUM_TRADE_TRANSACTION_TYPE)trans.type;は、取引トランザクションの種類を列挙値として取得します。これにより、どのタイプのトランザクションが発生したかを識別できます。

トランザクションが取引リクエストの場合

if(type==TRADE_TRANSACTION_REQUEST)は、トランザクションが取引リクエストの結果である場合の処理を行います。この条件が真の場合、以下の処理が行われます。

トランザクションの種類の表示

Print(EnumToString(type));は、トランザクションの種類を文字列としてエキスパートログに出力します。

リクエストの詳細表示

Print(“————RequestDescription\r\n”,RequestDescription(request));は、取引リクエストの詳細をエキスパートログに表示します。RequestDescription関数は、取引リクエストの詳細を文字列形式で返します。

リクエスト結果の詳細表示

Print(“————ResultDescription\r\n”,TradeResultDescription(result));は、取引リクエストの結果をエキスパートログに表示します。TradeResultDescription関数は、取引結果の詳細を文字列形式で返します。

注文チケットの保存

if(result.order!=0)は、取引結果に注文チケットが含まれている場合の処理を行います。この条件が真の場合、order_ticket=result.order;は、取引結果から注文チケットを取得し、order_ticket変数に保存します。次のOnTick関数の呼び出しでこの注文を削除するために使用されます。

その他のトランザクションの場合

elseは、トランザクションが取引リクエスト以外の場合の処理を行います。

トランザクションの詳細表示

Print(“————TransactionDescription\r\n”,TransactionDescription(trans));は、受け取ったトランザクションの詳細をエキスパートログに表示します。TransactionDescription関数は、トランザクションの詳細を文字列形式で返します。

この関数は、取引トランザクションの種類に応じて適切な処理を行い、その詳細をエキスパートログに記録することで、取引の追跡と管理を行います。

解説6:TransactionDescription関数(オリジナル関数)

//+------------------------------------------------------------------+
//| トランザクションのテキスト形式の記述を返す                      |
//+------------------------------------------------------------------+
string TransactionDescription(const MqlTradeTransaction &trans)
{
    //--- トランザクションの記述を作成する
    string desc=EnumToString(trans.type)+"\r\n";
    desc+="Symbol: "+trans.symbol+"\r\n";
    desc+="Deal ticket: "+(string)trans.deal+"\r\n";
    desc+="Deal type: "+EnumToString(trans.deal_type)+"\r\n";
    desc+="Order ticket: "+(string)trans.order+"\r\n";
    desc+="Order type: "+EnumToString(trans.order_type)+"\r\n";
    desc+="Order state: "+EnumToString(trans.order_state)+"\r\n";
    desc+="Order time type: "+EnumToString(trans.time_type)+"\r\n";
    desc+="Order expiration: "+TimeToString(trans.time_expiration)+"\r\n";
    desc+="Price: "+StringFormat("%G",trans.price)+"\r\n";
    desc+="Price trigger: "+StringFormat("%G",trans.price_trigger)+"\r\n";
    desc+="Stop Loss: "+StringFormat("%G",trans.price_sl)+"\r\n";
    desc+="Take Profit: "+StringFormat("%G",trans.price_tp)+"\r\n";
    desc+="Volume: "+StringFormat("%G",trans.volume)+"\r\n";
    //--- 取得した文字列を返す
    return desc;
}

関数の概要

TransactionDescription関数は、MqlTradeTransaction構造体トランザクション情報を文字列形式で返します。この関数は、トランザクションの各フィールドを文字列に変換し、一つの文字列にまとめて返します。

トランザクションの種類の記述

EnumToString(trans.type)は、トランザクションの種類を表すENUM_TRADE_TRANSACTION_TYPE列挙型を文字列に変換します。

シンボルの記述

trans.symbolは、取引銘柄名を文字列として取得し、記述に追加します。

約定チケットの記述

trans.dealは、約定チケットを文字列に変換し、記述に追加します。

約定の種類の記述

EnumToString(trans.deal_type)は、約定の種類を表すENUM_DEAL_TYPE列挙型を文字列に変換し、記述に追加します。

注文チケットの記述

trans.orderは、注文チケットを文字列に変換し、記述に追加します。

注文の種類の記述

EnumToString(trans.order_type)は、注文の種類を表すENUM_ORDER_TYPE列挙型を文字列に変換し、記述に追加します。

注文状態の記述

EnumToString(trans.order_state)は、注文状態を表すENUM_ORDER_STATE列挙型を文字列に変換し、記述に追加します。

注文の作用時間の種類の記述

EnumToString(trans.time_type)は、注文の作用時間の種類を表すENUM_ORDER_TYPE_TIME列挙型を文字列に変換し、記述に追加します。

注文の期限の記述

TimeToString(trans.time_expiration)は、注文の期限を文字列に変換し、記述に追加します。

価格の記述

StringFormat(“%G”, trans.price)は、価格を文字列に変換し、記述に追加します。

ストップリミット注文の価格の記述

StringFormat(“%G”, trans.price_trigger)は、ストップリミット注文のアクティベーション価格を文字列に変換し、記述に追加します。

決済逆指値の記述

StringFormat(“%G”, trans.price_sl)は、決済逆指値レベルを文字列に変換し、記述に追加します。

決済指値の記述

StringFormat(“%G”, trans.price_tp)は、決済指値レベルを文字列に変換し、記述に追加します。

ボリュームの記述

StringFormat(“%G”, trans.volume)は、ボリュームを文字列に変換し、記述に追加します。

文字列を戻り値として返す。

最後に、desc変数にまとめられたトランザクションの詳細を含む文字列を返します。これにより、トランザクションの全体像を文字列として簡単に取得することができます。

解説7:RequestDescription関数(オリジナル関数)

//+------------------------------------------------------------------+
//| 取引リクエストのテキスト形式の記述を返す                        |
//+------------------------------------------------------------------+
string RequestDescription(const MqlTradeRequest &request)
{
    //--- リクエストの記述を作成する
    string desc=EnumToString(request.action)+"\r\n";
    desc+="Symbol: "+request.symbol+"\r\n";
    desc+="Magic Number: "+StringFormat("%d",request.magic)+"\r\n";
    desc+="Order ticket: "+(string)request.order+"\r\n";
    desc+="Order type: "+EnumToString(request.type)+"\r\n";
    desc+="Order filling: "+EnumToString(request.type_filling)+"\r\n";
    desc+="Order time type: "+EnumToString(request.type_time)+"\r\n";
    desc+="Order expiration: "+TimeToString(request.expiration)+"\r\n";
    desc+="Price: "+StringFormat("%G",request.price)+"\r\n";
    desc+="Deviation points: "+StringFormat("%G",request.deviation)+"\r\n";
    desc+="Stop Loss: "+StringFormat("%G",request.sl)+"\r\n";
    desc+="Take Profit: "+StringFormat("%G",request.tp)+"\r\n";
    desc+="Stop Limit: "+StringFormat("%G",request.stoplimit)+"\r\n";
    desc+="Volume: "+StringFormat("%G",request.volume)+"\r\n";
    desc+="Comment: "+request.comment+"\r\n";
    //--- 取得した文字列を返す
    return desc;
}

関数の概要

RequestDescription関数は、MqlTradeRequest構造体の取引リクエスト情報を文字列形式で返します。この関数は、取引リクエストの各フィールドを文字列に変換し、一つの文字列にまとめて返します。

リクエストのアクションの記述

EnumToString(request.action)は、取引リクエストのアクションを表すENUM_TRADE_REQUEST_ACTIONS列挙型を文字列に変換します。

シンボルの記述

request.symbolは、取引銘柄名を文字列として取得し、記述に追加します。

マジックナンバーの記述

StringFormat(“%d”, request.magic)は、マジックナンバー文字列に変換し、記述に追加します。マジックナンバーは、EAが発注した注文を識別するための番号です。

注文チケットの記述

request.orderは、注文チケットを文字列に変換し、記述に追加します。

注文の種類の記述

EnumToString(request.type)は、注文の種類を表すENUM_ORDER_TYPE列挙型を文字列に変換し、記述に追加します。

注文のフィリングタイプの記述

EnumToString(request.type_filling)は、注文のフィルポリシーを表すENUM_ORDER_TYPE_FILLING列挙型を文字列に変換し、記述に追加します。

注文の作用時間の種類の記述

EnumToString(request.type_time)は、注文の作用時間(注文の有効期限に関する決まり事)の種類を表すENUM_ORDER_TYPE_TIME列挙型を文字列に変換し、記述に追加します。

注文の期限の記述

TimeToString(request.expiration)は、注文の期限を文字列に変換し、記述に追加します。

価格の記述

StringFormat(“%G”, request.price)は、価格を文字列に変換し、記述に追加します。

価格のスリッページの記述

StringFormat(“%G”, request.deviation)は、価格のスリッページ文字列に変換し、記述に追加します。

ストップロスの記述

StringFormat(“%G”, request.sl)は、ストップロス価格を文字列に変換し、記述に追加します。

テイクプロフィットの記述

StringFormat(“%G”, request.tp)は、テイクプロフィット価格を文字列に変換し、記述に追加します。

ストップリミットの記述

StringFormat(“%G”, request.stoplimit)は、ストップリミット価格を文字列に変換し、記述に追加します。

ボリュームの記述

StringFormat(“%G”, request.volume)は、取引ボリュームを文字列に変換し、記述に追加します。

コメントの記述

request.commentは、取引リクエストに関連するコメントを文字列として取得し、記述に追加します。

文字列を戻り値として返す

最後に、desc変数にまとめられた取引リクエストの詳細を含む文字列を返します。これにより、取引リクエストの全体像を文字列として簡単に取得することができます。

解説8:TradeResultDescription関数(オリジナル関数)

//+------------------------------------------------------------------+
//| リクエスト処理結果の記述ををテキスト形式で返す                 |
//+------------------------------------------------------------------+
string TradeResultDescription(const MqlTradeResult &result)
{
    //--- リクエスト結果の記述を作成する
    string desc="Retcode "+(string)result.retcode+"\r\n";
    desc+="Request ID: "+StringFormat("%d",result.request_id)+"\r\n";
    desc+="Order ticket: "+(string)result.order+"\r\n";
    desc+="Deal ticket: "+(string)result.deal+"\r\n";
    desc+="Volume: "+StringFormat("%G",result.volume)+"\r\n";
    desc+="Price: "+StringFormat("%G",result.price)+"\r\n";
    desc+="Ask: "+StringFormat("%G",result.ask)+"\r\n";
    desc+="Bid: "+StringFormat("%G",result.bid)+"\r\n";
    desc+="Comment: "+result.comment+"\r\n";
    //--- 取得した文字列を返す
    return desc;
}

関数の概要

TradeResultDescription関数は、MqlTradeResult構造体の取引リクエスト結果情報を文字列形式でまとめます。この関数は、MqlTradeResult構造体の各フィールドを文字列に変換し、一つの文字列にまとめて出力します。

リクエスト結果のコードの記述

“Retcode “+(string)result.retcodeは、取引リクエスト結果のリターンコード文字列に変換し、記述に追加します。リターンコードは、取引リクエストが成功したかどうかを示します。

リクエストIDの記述

“Request ID: “+StringFormat(“%d”,result.request_id)は、リクエストIDを文字列に変換し、記述に追加します。リクエストIDは、特定の取引リクエストを識別するために使用されます。

注文チケットの記述

“Order ticket: “+(string)result.orderは、注文チケットを文字列に変換し、記述に追加します。

約定チケットの記述

“Deal ticket: “+(string)result.dealは、約定チケットを文字列に変換し、記述に追加します。

ボリュームの記述

“Volume: “+StringFormat(“%G”,result.volume)は、取引ボリューム(ロット)を文字列に変換し、記述に追加します。

価格の記述

“Price: “+StringFormat(“%G”,result.price)は、取引価格を文字列に変換し、記述に追加します。

Ask価格の記述

“Ask: “+StringFormat(“%G”,result.ask)は、Ask価格を文字列に変換し、記述に追加します。Ask価格は、買い注文を行う際の価格です。

Bid価格の記述

“Bid: “+StringFormat(“%G”,result.bid)は、Bid価格を文字列に変換し、記述に追加します。Bid価格は、売り注文を行う際の価格です。

コメントの記述

“Comment: “+result.commentは、取引リクエストに関連するコメントを文字列として取得し、記述に追加します。

文字列を戻り値として返す

最後に、desc変数にまとめられた取引リクエスト結果の詳細を含む文字列を出力します。これにより、取引リクエスト結果の全体像を文字列として簡単に取得することができます。

コメント

タイトルとURLをコピーしました