English
preview
MQL5取引ツールキット(第5回):ポジション関数による履歴管理EX5ライブラリの拡張

MQL5取引ツールキット(第5回):ポジション関数による履歴管理EX5ライブラリの拡張

MetaTrader 5 | 22 4月 2025, 10:20
24 0
Wanateki Solutions LTD
Kelvin Muturi Muigua

はじめに

前回の記事では、HistoryManager EX5ライブラリの主要な関数の開発を開始しました。このライブラリは、注文、約定、未決注文、ポジションなど、さまざまなタイプの履歴データを取得・分類・整理するコアエンジンの役割を担います。これらの関数の多くはライブラリの内部でバックグラウンド処理され、ユーザーからは直接利用できない設計となっていました。エクスポート可能だったのは、注文、約定、未決注文、ポジションの簡単な一覧をMetaTrader 5のログに出力するためのPrint関数のみでした。

本記事では、前回作成した基本関数を土台として、ユーザーが直接利用できる新たな関数を追加し、HistoryManager.mq5のソースコードをさらに拡張していきます。これらの新機能により、ライブラリのユーザーは取引履歴データを簡単に取得・分析できるようになります。たとえば、直近でクローズされたポジションの取引時間(秒単位)、開始および終了の約定チケット、ポジションが未決注文から発生したのか、あるいは成行でエントリーされたのかといった情報、また、pipベースの利益、ストップロス、テイクプロフィット、さらに手数料やスワップを考慮した純利益などを取得することができるようになります。これにより、EX5ライブラリをMQL5プロジェクトに組み込み、簡単な関数呼び出しだけで複数ポジションの履歴を最小限の労力で照会できるようになります。

作業を始めるにあたり、まずは前回の記事で使用したHistoryManager.mq5ファイルを開き、GetTotalDataInfoSize関数の作成から進めていきます。元のHistoryManager.mq5ソースファイルは、前回の記事の末尾、または本記事の末尾(HistoryManager_Part1.mq5)にも添付されています。前回の作業が終了したPrintPendingOrdersHistory関数の直後から、コードを追加していきましょう。


GetTotalDataInfoSize関数

GetTotalDataInfoSize関数は、指定された履歴データ配列のサイズを取得して返すように設計されています。この関数はFetchHistoryByCriteria関数と連携して動作し、特定のデータ構造で使用可能なデータの量を動的に決定できるようにします。その主な役割は、どのデータセット(取引、注文、ポジション、未決注文)に関心があるかを識別し、そのデータセット内の要素の合計数を返すことです。

GetTotalDataInfoSize関数は、さまざまな履歴データセットへの動的なアクセスが必要な操作を効率化するのに役立ちます。適切な基準を引数として渡すことで、関連するデータ構造のサイズを効率的に照会します。

まず関数シグネチャを定義します。この関数は、指定されたデータ配列のサイズを表す整数を返すため、int型の戻り値を使用します。入力パラメータまたは引数は符号なし整数(uint)であり、これにより、クエリするデータのタイプを指定するために定義済みの定数を渡すことができます。

int GetTotalDataInfoSize(uint dataToGet)
  {
//-- Our function's code will go here
  }

次に、要求されたデータセットのサイズを格納するローカル変数totalDataInfoを宣言します。

int totalDataInfo = 0;

switch文を使用して、dataToGetパラメータの値を確認し、その値に応じて、対応するデータセットを識別し、ArraySize関数を使用してそのサイズを決定します。

  • 取引履歴データGET_DEALS_HISTORY_DATAと等しい場合、dealInfo配列のサイズを計算し、totalDataInfoに保存します。
  • 注文履歴データGET_ORDERS_HISTORY_DATAと等しい場合、orderInfo配列のサイズを計算し、totalDataInfoに保存します。
  • ポジション履歴データGET_POSITIONS_HISTORY_DATAと等しい場合、positionInfo配列のサイズを計算し、totalDataInfoに保存します。
  • 未決注文データGET_PENDING_ORDERS_HISTORY_DATAと等しい場合、pendingOrderInfo配列のサイズを計算し、totalDataInfoに保存します。
  • デフォルトケース:定義済みの定数のいずれとも等しくない場合は、フォールバックとしてtotalDataInfo0に設定します。

最後に、switchを終了した後、totalDataInfoに格納されている値を返します。これにより、関数は指定されたデータ型の正しいサイズを出力するか、有効なデータ型が指定されていない場合は0を出力するようになります。

switch(dataToGet)
  {
   case GET_DEALS_HISTORY_DATA:
      totalDataInfo = ArraySize(dealInfo);
      break;

   case GET_ORDERS_HISTORY_DATA:
      totalDataInfo = ArraySize(orderInfo);
      break;

   case GET_POSITIONS_HISTORY_DATA:
      totalDataInfo = ArraySize(positionInfo);
      break;

   case GET_PENDING_ORDERS_HISTORY_DATA:
      totalDataInfo = ArraySize(pendingOrderInfo);
      break;

   default:
      totalDataInfo = 0;
      break;
  }
return(totalDataInfo);

以下は、すべてのコードセグメントを適切な順序で並べた、GetTotalDataInfoSize関数の完全な実装です。

int GetTotalDataInfoSize(uint dataToGet)
  {
   int totalDataInfo = 0; //- Saves the total elements of the specified history found
   switch(dataToGet)
     {
      case GET_DEALS_HISTORY_DATA: //- Check if we have any available deals history data
         totalDataInfo = ArraySize(dealInfo); //- Save the total deals found
         break;

      case GET_ORDERS_HISTORY_DATA: //- Check if we have any available orders history data
         totalDataInfo = ArraySize(orderInfo); //- Save the total orders found
         break;

      case GET_POSITIONS_HISTORY_DATA: //- Check if we have any available positions history data
         totalDataInfo = ArraySize(positionInfo); //- Save the total positions found
         break;

      case GET_PENDING_ORDERS_HISTORY_DATA: //- Check if we have any available pending orders history data
         totalDataInfo = ArraySize(pendingOrderInfo); //- Save the total pending orders found
         break;

      default: //-- Unknown entry
         totalDataInfo = 0;
         break;
     }
   return(totalDataInfo);
  }


FetchHistorybyCriteria関数

特定の銘柄における直近の5件の決済済み買いポジションなど、MQL5を用いて最近の履歴データを照会する場合、貴重なリソースを無駄にしないためにも、サーバーから口座履歴全体を取得する必要はありません。代わりに、まずは当日など、直近の期間に限定して取引履歴をクエリするという最適なアプローチを取るべきです。目的のデータがその期間内に見つからない場合には、徐々に時間範囲を広げていくことで、必要なデータを効率的に取得することができます。この方法により、効率性を維持しつつ、リソース消費を最小限に抑えながら、必要な履歴データを高いパフォーマンスで取得することが可能となります。

FetchHistoryByCriteria関数は、特定の条件に基づいて履歴データを体系的に取得する機能を担い、まずは過去24時間の履歴から検索を開始し、必要に応じて取得期間を段階的に拡張していきます。最初に最新データをチェックし、関連データが見つからなければ、週単位で徐々に過去にさかのぼり、最大で1年間までのデータをスキャンします。それでもデータが見つからない場合には、最終的に利用可能なすべての口座履歴を取得するよう試みます。

FetchHistoryByCriteria関数は、異なる期間から取引データを効率的に取得するための重要なユーティリティとして機能し、EX5ライブラリが必要なデータを見つけるまで履歴を継続的にスキャン・取得できるようにします。関連データが見つからなかった場合でも、ライブラリは古い履歴や全履歴の取得を自動的に試行するため、柔軟かつ堅牢な履歴検索が可能となります。

まず関数シグネチャを定義しましょう。この関数はライブラリコアモジュールによって内部的に使用されるため、エクスポートできません。

bool FetchHistoryByCriteria(uint dataToGet)
  {
//-- Our function's code will go here
  }

履歴の取得期間を調整する間隔変数を定義します。最初は、24時間の範囲で開始するために1に設定されています。

int interval = 1;

24時間前から現在までの時間範囲を計算します。

datetime fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_D1) * interval);
datetime toDateTime = TimeCurrent();

次に、GetHistoryData関数を使用して、定義された時間範囲内のデータを取得します。

GetHistoryData(fromDateTime, toDateTime, dataToGet);

過去24時間以内にデータが見つからない場合は、間隔を1週間ずつ増やすループに入ります。このプロセスは、1年間(53週)にわたってスキャンするまで継続されます。各反復中に、追加の週を反映するように時間範囲が更新されます。

while(GetTotalDataInfoSize(dataToGet) <= 0)
  {
   interval++;
   fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_W1) * interval);
   toDateTime = TimeCurrent();
   GetHistoryData(fromDateTime, toDateTime, dataToGet);

   if(interval > 53)
     {
      break;
     }
  }

1年間分スキャンしてもデータが見つからない場合は、口座履歴全体エポックから現在まで)をカバーするように時間範囲をリセットします。これにより、利用可能なすべての履歴がチェックされます。

fromDateTime = 0;
toDateTime = TimeCurrent();
GetHistoryData(fromDateTime, toDateTime, dataToGet);

最後に、履歴が正常に取得されたかどうかを確認します。口座履歴全体をスキャンしてもデータが見つからない場合は、失敗をログに記録し、falseを返します。データが見つかった場合は、成功を示すためにtrueを返します。

if(GetTotalDataInfoSize(dataToGet) <= 0)
  {
   return(false);
  }
else
  {
   return(true);
  }

すべてのコードセグメントが含まれたFetchHistoryByCriteria関数の完全な実装を次に示します。

bool FetchHistoryByCriteria(uint dataToGet)
  {
   int interval = 1; //- Modulates the history period

//- Save the history period for the last 24 hours
   datetime fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_D1) * interval);
   datetime toDateTime = TimeCurrent();

//- Get the specified history
   GetHistoryData(fromDateTime, toDateTime, dataToGet);

//- If we have no history in the last 24 hours we need to keep increasing the retrieval
//- period by one week untill we scan a full year (53 weeks)
   while(GetTotalDataInfoSize(dataToGet) <= 0)
     {
      interval++;
      fromDateTime = TimeCurrent() - 1 * (PeriodSeconds(PERIOD_W1) * interval);
      toDateTime = TimeCurrent();
      GetHistoryData(fromDateTime, toDateTime, dataToGet);

      //- If no history is found after a one year scanning period, we exit the while loop
      if(interval > 53)
        {
         break;
        }
     }

//- If we have not found any trade history in the last year, we scan and cache the intire account history
   fromDateTime = 0; //-- 1970 (Epoch)
   toDateTime = TimeCurrent(); //-- Time now
   GetHistoryData(fromDateTime, toDateTime, dataToGet);

//- If we still havent retrieved any history in the account, we log this info by
//- printing it and exit the function by returning false
   if(GetTotalDataInfoSize(dataToGet) <= 0)
     {
      return(false); //- Specified history not found, exit and return false
     }
   else
     {
      return(true); //- Specified history found, exit and return true
     }
  }


GetLastClosedPositionData関数

GetLastClosedPositionData関数は、最新のクローズされたポジションのプロパティを取得し、提供されたlastClosedPositionInfoの参照にこのデータを保存する役割を担います。この関数は、FetchHistoryByCriteria関数を利用して関連する取引履歴データを取得し、必要なポジション情報にアクセスできるようにします。クローズされたポジションが見つからない場合、関数はエラーメッセージを記録し、falseを返します。成功した場合、データを取得してtrueを返します。

まず関数シグネチャを定義しましょう。この関数は外部使用を目的としているため、エクスポートされ、他のMQL5ソースファイルによってインポートできます。

bool GetLastClosedPositionData(PositionData &lastClosedPositionInfo) export
  {
//-- Our function's code will go here
  }

まず、GET_POSITIONS_HISTORY_DATA引数を指定してFetchHistoryByCriteria関数を呼び出して、利用可能なポジション履歴データの取得を試みます。この関数呼び出しは、利用可能な取引履歴を検索して、ポジション関連のデータを取得します。

if(!FetchHistoryByCriteria(GET_POSITIONS_HISTORY_DATA))
  {
   Print(__FUNCTION__, ": No trading history available. Last closed position can't be retrieved.");
   return(false);
  }

ポジション履歴データが利用できない場合(つまり、FetchHistoryByCriteria関数がfalseを返す場合)、Print関数を使用してエラーメッセージをログに記録します。これにより、失敗に関するデバッグに有用な情報が提供されます。この関数はfalseを返し、最後のクローズポジションを取得できなかったことを示します。

ポジション履歴データが正常に取得された場合、最後にクローズされたポジションの情報がlastClosedPositionInfo変数に保存されます。これは、positionInfo配列の最初の要素をlastClosedPositionInfoに割り当てることによっておこなわれます。この配列にはすべてのポジションの履歴が含まれており、最新のクローズされたポジションが配列の先頭にあるためです。関数を終了するには、最後にクローズしたポジションデータが正常に取得され、指定された参照変数に格納されたことを示すためにtrueを返します。

lastClosedPositionInfo = positionInfo[0];
return(true);

すべてのコードセグメントが含まれたGetLastClosedPositionData関数の完全な実装を次に示します。

bool GetLastClosedPositionData(PositionData &lastClosedPositionInfo) export
  {
   if(!FetchHistoryByCriteria(GET_POSITIONS_HISTORY_DATA))
     {
      Print(__FUNCTION__, ": No trading history available. Last closed position can't be retrieved.");
      return(false);
     }

//-- Save the last closed position data in the referenced lastClosedPositionInfo variable
   lastClosedPositionInfo = positionInfo[0];
   return(true);
  }


LastClosedPositionType関数

LastClosedPositionType関数は、取引口座で最後にクローズされたポジションのタイプを決定し、それを参照される変数lastClosedPositionTypeに格納する役割を担います。この関数はGetLastClosedPositionData関数の論理拡張であり、その関数を活用して最後にクローズされたポジションを取得し、その特定のタイプを抽出します。

LastClosedPositionType関数は、買いポジションと売りポジションを区別したり、ポジションタイプに基づいてより複雑な戦略を識別したりするなど、最新の取引のタイプを分析する必要があるシナリオに必要です。

まず関数シグネチャを定義しましょう。この関数は、EX5 ライブラリをインポートするMQL5 ファイルで使用することを目的としているため、エクスポート可能としてマークします。これにより、関数が外部からアクセス可能になり、モジュール性と使いやすさの両方が向上します。

bool LastClosedPositionType(ENUM_POSITION_TYPE &lastClosedPositionType) export
  {
//-- Our function's code will go here
  }

まず、PositionData型のローカル変数lastClosedPositionInfoを宣言します。この変数には、最後にクローズしたポジションの詳細が一時的に保存され、GetLastClosedPositionData関数を使用して抽出されます。

PositionData lastClosedPositionInfo;

lastClosedPositionInfoを引数として渡して、GetLastClosedPositionData関数を呼び出します。関数がtrueを返す場合、最後にクローズしたポジションのデータが正常に取得されたことを意味します。

if(GetLastClosedPositionData(lastClosedPositionInfo))
{
   //- Process the retrieved data
}

GetLastClosedPositionDataが失敗した場合(falseを返す場合)、この関数は直ちに終了し、操作を完了できなかったことを示すfalseを返します。

ifブロック内では、lastClosedPositionInfoからtypeプロパティを抽出し、参照されている変数lastClosedPositionTypeに割り当てます。これにより、呼び出し元のコードが最後にクローズしたポジションのタイプにアクセスできるようになります。タイプを正常に保存したら、操作が成功したことを示すためにtrueを返し、関数を終了します。

lastClosedPositionType = lastClosedPositionInfo.type;
return(true);

最後にクローズしたポジションの取得に失敗した場合、関数はifブロックをスキップし、直接falseを返します。これは、ポジションタイプを判別できなかったことを示します。

return(false);

以下は、すべてのコードセグメントが正しい順序で並んだLastClosedPositionType関数の完全な実装です。

bool LastClosedPositionType(ENUM_POSITION_TYPE &lastClosedPositionType) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionType = lastClosedPositionInfo.type;
      return(true);
     }
   return(false);
  }


LastClosedPositionVolume関数

LastClosedPositionVolume関数は、取引履歴で最後にクローズされたポジションの出来高を取得する役割を果たします。この出来高は、参照変数lastClosedPositionVolumeに保存されます。最後にクローズしたポジションのデータを正常に取得すると、lastClosedPositionVolume変数を出来高値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionVolume変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionVolume(double &lastClosedPositionVolume) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionVolume = lastClosedPositionInfo.volume;
      return(true);
     }
   return(false);
  }


LastClosedPositionSymbol関数

LastClosedPositionSymbol関数は、取引履歴で最後にクローズされたポジションの銘柄を取得する役割を果たします。この銘柄は、参照変数lastClosedPositionSymbolに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionSymbol変数を銘柄値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionSymbol変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionSymbol(string &lastClosedPositionSymbol) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionSymbol = lastClosedPositionInfo.symbol;
      return(true);
     }
   return(false);
  }


LastClosedPositionTicket関数

LastClosedPositionTicket関数は、取引履歴で最後にクローズされたポジションのチケット番号を取得する役割を担います。このチケット番号は、参照変数lastClosedPositionTicketに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionTicket変数をチケット番号で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionTicket変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionTicket(ulong &lastClosedPositionTicket) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionTicket = lastClosedPositionInfo.ticket;
      return(true);
     }
   return(false);
  }


LastClosedPositionProfit関数

LastClosedPositionProfit関数は、取引履歴で最後にクローズされたポジションの利益を取得する役割を果たします。この利益は、参照変数lastClosedPositionProfitに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionProfit変数を利益値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionProfit変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionProfit(double &lastClosedPositionProfit) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionProfit = lastClosedPositionInfo.profit;
      return(true);
     }
   return(false);
  }


LastClosedPositionNetProfit関数

LastClosedPositionNetProfit関数は、取引履歴で最後にクローズされたポジションの純利益を取得する役割を果たします。ポジションの純利益は、ポジション利益から手数料スワップなどのすべての費用を差し引いた後の最終値です。この純利益は、参照変数lastClosedPositionNetProfitに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionNetProfit変数を純利益値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionNetProfit変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionNetProfit(double &lastClosedPositionNetProfit) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionNetProfit = lastClosedPositionInfo.netProfit;
      return(true);
     }
   return(false);
  }


LastClosedPositionPipProfit関数

LastClosedPositionPipProfit関数は、取引履歴で最後にクローズされたポジションのpip利益を取得する役割を果たします。このpip利益は参照変数lastClosedPositionPipProfitに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionPipProfit変数をpip利益値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionPipProfit変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionPipProfit(int &lastClosedPositionPipProfit) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionPipProfit = lastClosedPositionInfo.pipProfit;
      return(true);
     }
   return(false);
  }


LastClosedPositionClosePrice関数

LastClosedPositionClosePrice関数は、取引履歴で最後にクローズされたポジションの終値を取得する役割を果たします。この終値は、参照変数lastClosedPositionClosePriceに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionClosePrice変数を終値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionClosePrice変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionClosePrice(double &lastClosedPositionClosePrice) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionClosePrice = lastClosedPositionInfo.closePrice;
      return(true);
     }
   return(false);
  }


LastClosedPositionOpenPrice関数

LastClosedPositionOpenPrice関数は、取引履歴で最後にクローズされたポジションの始値を取得する役割を果たします。この始値は、参照変数lastClosedPositionOpenPriceに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionOpenPrice変数を始値の値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionOpenPrice変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionOpenPrice(double &lastClosedPositionOpenPrice) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionOpenPrice = lastClosedPositionInfo.openPrice;
      return(true);
     }
   return(false);
  }


LastClosedPositionStopLossPrice関数

LastClosedPositionSlPrice関数は、取引履歴で最後にクローズされたポジションのストップロス価格を取得する役割を果たします。このストップロス価格を参照変数lastClosedPositionSlPriceに保存します。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionSlPrice変数をストップロス価格値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionSlPrice変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionSlPrice(double &lastClosedPositionSlPrice) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionSlPrice = lastClosedPositionInfo.slPrice;
      return(true);
     }
   return(false);
  }


LastClosedPositionTpPrice関数

LastClosedPositionTpPrice関数は、取引履歴で最後にクローズされたポジションのテイクプロフィット価格を取得する役割を果たします。このテイクプロフィット価格を参照変数lastClosedPositionTpPriceに保存します。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionTpPrice変数をテイクプロフィット価格の値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionTpPrice変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionTpPrice(double &lastClosedPositionTpPrice) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionTpPrice = lastClosedPositionInfo.tpPrice;
      return(true);
     }
   return(false);
  }


LastClosedPositionSlPips関数

LastClosedPositionSlPips関数は、最後にクローズしたポジションのストップロス値をポイント(pips)単位で取得する役割を担います。このストップロス値は、参照変数lastClosedPositionSlPipsに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionSlPips変数をストップ ロス値(pips)で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionSlPips変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionSlPips(int &lastClosedPositionSlPips) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionSlPips = lastClosedPositionInfo.slPips;
      return(true);
     }
   return(false);
  }


LastClosedPositionTpPips関数

LastClosedPositionTpPips関数は、最後にクローズしたポジションのテイクプロフィット値をポイント(pips)単位で取得する役割を担います。このテイクプロフィット値は、参照変数lastClosedPositionTpPipsに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、 lastClosedPositionTpPips変数をpips 単位テイクプロフィット値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionTpPips変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionTpPips(int &lastClosedPositionTpPips) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionTpPips = lastClosedPositionInfo.tpPips;
      return(true);
     }
   return(false);
  }


LastClosedPositionOpenTIme関数関数

LastClosedPositionOpenTime関数は、最後にクローズされたポジションの開始時刻を取得する役割を果たします。この開始時刻を参照変数lastClosedPositionOpenTimeに保存します。最後にクローズしたポジションのデータを正常に取得した場合、 lastClosedPositionOpenTime変数を開始時刻の値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、 lastClosedPositionOpenTime変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionOpenTime(datetime &lastClosedPositionOpenTime) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionOpenTime = lastClosedPositionInfo.openTime;
      return(true);
     }
   return(false);
  }


LastClosedPositionCloseTime関数

LastClosedPositionCloseTime関数は、最後にクローズされたポジションの終了時刻を取得する役割を果たします。この終了時刻を参照変数lastClosedPositionCloseTimeに保存します。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionCloseTime変数を終了時刻の値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionCloseTime変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionCloseTime(datetime &lastClosedPositionCloseTime) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionCloseTime = lastClosedPositionInfo.closeTime;
      return(true);
     }
   return(false);
  }


LastClosedPositionSwap関数

LastClosedPositionSwap関数は、最後にクローズしたポジションのスワップ値を取得する役割を果たします。このスワップ値は、参照変数lastClosedPositionSwapに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionSwap変数をスワップ値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionSwap変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionSwap(double &lastClosedPositionSwap) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionSwap = lastClosedPositionInfo.swap;
      return(true);
     }
   return(false);
  }


LastClosedPositionCommission関数

LastClosedPositionCommission関数は、最後にクローズしたポジションの手数料値を取得する役割を果たします。この手数料値は、参照変数lastClosedPositionCommissionに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionCommission変数を手数料の値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionCommission変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionCommission(double &lastClosedPositionCommission) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionCommission = lastClosedPositionInfo.commission;
      return(true);
     }
   return(false);
  }


LastClosedPositionInitiatingOrderType関数

LastClosedPositionInitiatingOrderType関数は、最後にクローズされたポジションの開始注文タイプを取得する役割を担います。これにより、ポジションが未決注文 (買い逆指値、買い指値、売り逆指値、売り指値、買いストップリミット、売りストップリミット)によって開始されたのか、直接市場エントリー注文によって開始されたのかを知ることができます。この開始注文タイプを参照変数lastClosedPositionInitiatingOrderTypeに保存します。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionInitiatingOrderType変数を開始注文タイプの値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionInitiatingOrderType変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionInitiatingOrderType(ENUM_ORDER_TYPE &lastClosedPositionInitiatingOrderType) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionInitiatingOrderType = lastClosedPositionInfo.initiatingOrderType;
      return(true);
     }
   return(false);
  }


LastClosedPositionId関数

LastClosedPositionId関数は、最後にクローズされたポジションのIDを取得する役割を担います。このポジションIDは、参照変数lastClosedPositionIdに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionId変数をポジション ID値で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionId変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionId(ulong &lastClosedPositionId) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionId = lastClosedPositionInfo.positionId;
      return(true);
     }
   return(false);
  }


LastClosedPositionInitiatedbyPendingOrder関数

LastClosedPositionInitiatedByPendingOrder関数は、最後にクローズされたポジションが未決注文から開始されたかどうかを確認する役割を担います。この情報は、参照変数lastClosedPositionInitiatedByPendingOrderに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionInitiatedByPendingOrder変数をその結果で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionInitiatedByPendingOrder変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionInitiatedByPendingOrder(bool &lastClosedPositionInitiatedByPendingOrder) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionInitiatedByPendingOrder = lastClosedPositionInfo.initiatedByPendingOrder;
      return(true);
     }
   return(false);
  }


LastClosedPositionOpeningOrderTicket関数

LastClosedPositionOpeningOrderTicket関数は、最後にクローズされたポジションの開始注文のチケット番号を取得する役割を担います。このチケット番号は、参照変数lastClosedPositionOpeningOrderTicketに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionOpeningOrderTicket変数をチケット番号で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionOpeningOrderTicket変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionOpeningOrderTicket(ulong &lastClosedPositionOpeningOrderTicket) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionOpeningOrderTicket = lastClosedPositionInfo.openingOrderTicket;
      return(true);
     }
   return(false);
  }


LastClosedPositionOpeningDealTicket関数

LastClosedPositionOpeningDealTicket関数は、最後にクローズされたポジションの開始取引チケット番号を取得する役割を担います。この取引チケット番号は、参照変数lastClosedPositionOpeningDealTicketに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionOpeningDealTicket変数を取引チケット番号で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionOpeningDealTicket変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionOpeningDealTicket(ulong &lastClosedPositionOpeningDealTicket) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionOpeningDealTicket = lastClosedPositionInfo.openingDealTicket;
      return(true);
     }
   return(false);
  }


LastClosedPositionClosingDealTicket関数

LastClosedPositionClosingDealTicket関数は、最後にクローズされたポジションのクローズ取引チケット番号を取得する役割を担います。この取引チケット番号は、参照変数lastClosedPositionClosingDealTicketに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionClosingDealTicket変数を取引チケット番号で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionClosingDealTicket変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionClosingDealTicket(ulong &lastClosedPositionClosingDealTicket) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionClosingDealTicket = lastClosedPositionInfo.closingDealTicket;
      return(true);
     }
   return(false);
  }


LastClosedPositionMagic関数

LastClosedPositionMagic関数は、最後にクローズされたポジションのマジック ナンバーを取得する役割を果たします。このマジックナンバーは、参照変数lastClosedPositionMagicに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionMagic変数をマジックナンバーで更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionMagic変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionMagic(ulong &lastClosedPositionMagic) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionMagic = lastClosedPositionInfo.magic;
      return(true);
     }
   return(false);
  }


LastClosedPositionComment関数

LastClosedPositionComment関数は、最後にクローズされたポジションに関連付けられたコメントを取得する役割を担います。このコメントは、参照変数lastClosedPositionCommentに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionComment変数をコメントで更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionComment変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionComment(string &lastClosedPositionComment) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionComment = lastClosedPositionInfo.comment;
      return(true);
     }
   return(false);
  }


LastClosedPositionDuration関数

LastClosedPositionDuration関数は、最後にクローズされたポジションの期間を秒単位で取得する役割を担います。この期間は、参照変数lastClosedPositionDurationに保存されます。最後にクローズしたポジションのデータを正常に取得した場合、lastClosedPositionDuration変数をその期間で更新し、trueを返すことで操作が成功したことを確認します。データの取得に失敗した場合、lastClosedPositionDuration変数は変更されず、関数はfalseを返すことで失敗を示します。

bool LastClosedPositionDuration(long &lastClosedPositionDuration) export
  {
   PositionData lastClosedPositionInfo;
   if(GetLastClosedPositionData(lastClosedPositionInfo))
     {
      lastClosedPositionDuration = lastClosedPositionInfo.duration;
      return(true);
     }
   return(false);
  }


結論

この記事では、最後にクローズされたポジションの特定プロパティを取得するために設計された、小さく焦点の定まったユーティリティ関数が、EX5ライブラリのコードベースにおいて明確性とモジュール性を保ちながら、どのように連携して特定のタスクを達成できるかを学びました。ポジションの各種プロパティを抽出するロジックを関数ごとに分離することで、目的のデータを明確かつ効率的に収集するプロセスが合理化されます。

記事を簡潔かつ目的に沿ったものに保つため、最後に約定された未決注文およびキャンセルされた未決注文の各種プロパティを取得するライブラリ関数の作成については、次回の記事にて取り上げます。次回は、それらの関数を詳細に解説し、既存のフレームワークとの統合を確認していきます。さらにその後は、履歴取引データに基づいた分析レポートを生成する一連の関数群の開発へと進みます。これにより、ユーザーは有益なサマリーや詳細なレポートを生成できるようになります。このように段階的に進めることで、各トピックを明確かつ包括的に解説しつつ、一度に過剰な情報を提示して読者を圧倒することを避けられます。

この記事の末尾には、今回作成したすべての関数に加え、前回紹介した関数も含まれるHistoryManager.mq5ライブラリの最新ソースコードを掲載しています。 最後までお読みいただき、ありがとうございました。次回の記事でまたお会いできるのを楽しみにしています。

MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/16681

添付されたファイル |
HistoryManager.mq5 (55.17 KB)
DiscordとMetaTrader 5の統合:リアルタイム通知機能を備えたトレーディングボットの構築 DiscordとMetaTrader 5の統合:リアルタイム通知機能を備えたトレーディングボットの構築
この記事では、MetaTrader 5とDiscordサーバーを統合し、どこからでもリアルタイムで取引通知を受信する方法について解説します。Discordへのアラート配信を有効にするための、MetaTrader 5側およびDiscord側の設定方法を詳しく説明します。また、このような通知ソリューションでWebRequestやWebhookを利用する際に生じるセキュリティ上の注意点についても取り上げます。
Candlestick Trend Constraintモデルの構築(第10回):戦略的ゴールデンクロスとデスクロス(EA) Candlestick Trend Constraintモデルの構築(第10回):戦略的ゴールデンクロスとデスクロス(EA)
移動平均線のクロスオーバーに基づくゴールデンクロスおよびデッドクロス戦略は、長期的な市場トレンドを見極める上で最も信頼性の高い指標の一つであることをご存知でしょうか。ゴールデンクロスは、短期移動平均線が長期移動平均線を上回るときに強気トレンドの到来を示します。一方、デッドクロスは、短期移動平均線が長期線を下回ることで弱気トレンドの兆候を示します。これらの戦略は非常にシンプルでありながら効果的ですが、手動で運用すると機会の逸失やエントリーの遅れが発生しやすいという課題があります。しかし、MQL5を活用してTrend Constraintエキスパートアドバイザー(EA)内で自動化することで、これらの戦略は独立して機能し、市場の反転に迅速かつ効率的に対応できるようになります。また、制約付きの戦略と組み合わせることで、広範なトレンドと整合性を保つことができます。このアプローチにより、反転戦略とトレンドフォロー戦略のシームレスな統合が実現され、精密なエントリーと一貫したパフォーマンス向上をもたらします。
知っておくべきMQL5ウィザードのテクニック(第51回):SACによる強化学習 知っておくべきMQL5ウィザードのテクニック(第51回):SACによる強化学習
Soft Actor Criticは、Actorネットワーク1つとCriticネットワーク2つ、合計3つのニューラルネットワークを用いる強化学習アルゴリズムです。これらのモデルは、CriticがActorネットワークの予測精度を高めるように設計された、いわばマスタースレーブの関係で連携します。本連載では、ONNXの導入も兼ねて、こうした概念を、ウィザード形式で構築されたエキスパートアドバイザー(EA)内のカスタムシグナルとしてどのように実装・活用できるかを探っていきます。
ログレコードをマスターする(第2回):ログのフォーマット処理 ログレコードをマスターする(第2回):ログのフォーマット処理
この記事では、ライブラリ内でログフォーマッターを作成し、適用する方法について詳しく解説します。フォーマッターの基本構造から実践的な実装例まで幅広く取り上げます。この記事を読み終える頃には、ライブラリ内でログを整形するために必要な知識を習得し、その裏側で何がどのように動作しているのかを理解できるようになります。