English Русский Español Deutsch
preview
MQL5取引ツールキット(第3回):未決注文管理EX5ライブラリの開発

MQL5取引ツールキット(第3回):未決注文管理EX5ライブラリの開発

MetaTrader 5 |
137 0
Wanateki Solutions LTD
Kelvin Muturi Muigua

はじめに

第1回および第2回の記事では、EX5ライブラリをゼロから開発し、プログラミングする方法や、エンドユーザーがMQL5プロジェクトに実装する際に役立つ詳細なドキュメントの作成手法について説明しました。また、さまざまなMQL5アプリケーションでそれらのライブラリをインポートし、実装するための実践的なステップバイステップのデモンストレーションも提供しました。

本記事では、包括的な未決注文管理EX5ライブラリを開発し、GU(グラフィカルユーザーインターフェイス)Iパネルを作成して、それをインポートおよび実装する方法を、実用的な例を通じて学びます。この未決注文管理ライブラリは、MQL5標準関数のみを使用して、さまざまなタイプの未決注文をオープン、変更、削除することができます。特に、シンプルな機能から高度な未決注文管理モジュールのコーディング方法を学びたい新しいMQL5プログラマーにとって、貴重な学習リソースとなるでしょう。また、さまざまな条件に基づいて未決注文をフィルタリングおよび並べ替える方法も解説します。

ここで作成する関数はEX5ライブラリにエクスポートされ、コンパイルされます。このライブラリは、将来のMQL5プロジェクトの開発時間を劇的に短縮する貴重な資産となるでしょう。未決注文管理EX5ライブラリをインポートするだけで、これらの機能を簡単に実装でき、コードベースや開発プロセス全体の効率が大幅に向上します。


EX5ライブラリソースコードファイル(.mq5)の新規作成

まず、MetaEditor IDEを開き、新規作成メニューアイテムボタンを使ってMQLウィザードを起動します。次に、PendingOrdersManager.mq5という名前の新しいライブラリソースコードファイルを作成します。このファイルには、未決注文を管理するためのコア機能が含まれます。このファイルは、最初の記事で設定したLibrariesToolkitフォルダに保存します。このディレクトリは、以前にポジションマネージャーEX5ライブラリを保存した場所と同じであり、プロジェクトを整理し、一貫性を保つことができます。

PendingOrdersManager.mql5 Saved_Directory

MQL5でEX5ライブラリを作成する方法をもう一度確認したい場合は、ぜひ最初の記事をご覧ください。そこでは、フォルダ構造の設定方法やライブラリ作成の手順について、ステップバイステップで詳しく解説しています。この手順に従うことで、開発プロセスを効率化できるだけでなく、将来のMQL5プロジェクトにおけるライブラリの保守や再利用も一段と簡単になります。


プリプロセッサ指令、グローバル変数、ポジションマネージャEX5ライブラリのインポート

新しく作成したPendingOrdersManager.mq5ライブラリのソースコードファイルでは、まずプリプロセッサ指令、グローバル変数、ライブラリのインポート、取引構造をすべて定義します。これにより、未決注文管理ライブラリ全体でこれらを活用でき、必要に応じてさまざまな関数で再利用することが可能になります。

まず、#defineを使用してプリプロセッサマクロを定義し、空の文字列を表す定数を作成します。この定数はALL_SYMBOLSと名付けられ、銘柄文字列を入力パラメータとして必要とする未決注文管理関数においてプレースホルダーとして機能します。この空文字列を関数に渡すことで、単一の銘柄だけでなく、利用可能なすべての銘柄に指定されたアクションを適用するコマンドとして解釈されます。

この方法は非常にシンプルでありながら、特に複数の金融商品を管理する際には非常に効果的です。異なる銘柄間の未決注文を処理するプロセスを大幅に効率化することができます。これを実装するには、ALL_SYMBOLS定数を定義し、コード内の#propertyディレクティブの直下に配置します。

#define ALL_SYMBOLS "" //-- Used as a function parameter to select all symbols

取引サーバーへの注文送信が失敗した場合に備え、以下の2つの追加定数を定義する必要があります。1つ目は再試行できる最大回数を定義するもので、2つ目は再試行間の遅延時間を設定するものです。これにより、急激な連続リクエストによる取引サーバーへの過負荷を防ぐことができます。最初の定数はMAX_ORDER_RETRIESとし、その値を600とします。2番目の定数はORDER_RETRY_DELAYとし、値は500(ミリ秒)です。

これにより、重大なエラーが発生しない限り、注文のオープン、変更、または削除を最大600回まで試みることができます。各試行の後、この関数は次の試行に進む前に0.5秒(500ミリ秒)の遅延を挟みます。この遅延設定により、取引サーバーへの過剰な負荷を回避し、リソースを効率的に利用することができます。また、市場の不活発やティックデータの利用不可といった遅延が発生した場合でも、すべての再試行が完了する前に状況が解消される可能性があり、注文執行の成功率を高めることが期待されます。

#define MAX_ORDER_RETRIES 600 //-- Sets the order sending retry limit
#define ORDER_RETRY_DELAYS 500//-- Sets the duration to pause before re-sending a failed order request in milliseconds

次に、MQL5のMqlTradeRequestおよびMqlTradeResultデータ構造体を追加します。これらの構造体は、さまざまな未決注文をオープン、変更、削除する際に取引サーバーとの通信を処理するため、非常に重要です。tradeRequest構造体は、実行する取引アクションの詳細を格納する役割を担います。この中には、価格、ストップロス、テイクプロフィットなどの注文パラメータが含まれます。一方、tradeResult構造体は、取引操作の結果をキャプチャし保存します。これにより、サーバーからのフィードバックを通じて、リクエストが成功したのか、あるいはエラーが発生したのかを確認することができます。

//-- Trade operations request and result data structures global variables
MqlTradeRequest tradeRequest;
MqlTradeResult  tradeResult;

さまざまな未決注文のステータスを追跡・保存するために、このステータス情報を保持するいくつかの種類の変数を作成する必要があります。これらの注文ステータス変数は、ライブラリ内のすべてのスコープからアクセスできるように、グローバル変数として宣言します。これにより、どの関数からでもこれらの変数を参照および更新することが可能になります。これらの変数は宣言時にデフォルト値で初期化し、その後、この記事で後述するGetPendingOrdersData(...)関数内で、リアルタイムの正確なデータに基づいて更新されます。この方法により、すべての未決注文のステータスが常に一貫性を保ち、呼び出し元の関数の実行中に正確に更新されることを保証します。

//-- Pending orders status global variables
//-------------------------------------------------------------------------------------------------------------------
int accountBuyStopOrdersTotal = 0, accountSellStopOrdersTotal = 0,
    accountBuyLimitOrdersTotal = 0, accountSellLimitOrdersTotal = 0,

    symbolPendingOrdersTotal = 0,
    symbolBuyStopOrdersTotal = 0, symbolSellStopOrdersTotal = 0,
    symbolBuyLimitOrdersTotal = 0, symbolSellLimitOrdersTotal = 0,

    magicPendingOrdersTotal = 0,
    magicBuyStopOrdersTotal = 0, magicSellStopOrdersTotal = 0,
    magicBuyLimitOrdersTotal = 0, magicSellLimitOrdersTotal = 0;

double accountPendingOrdersVolumeTotal = 0.0,
       accountBuyStopOrdersVolumeTotal = 0.0, accountSellStopOrdersVolumeTotal = 0.0,
       accountBuyLimitOrdersVolumeTotal = 0.0, accountSellLimitOrdersVolumeTotal = 0.0,

       symbolPendingOrdersVolumeTotal = 0.0,
       symbolBuyStopOrdersVolumeTotal = 0.0, symbolSellStopOrdersVolumeTotal = 0.0,
       symbolBuyLimitOrdersVolumeTotal = 0.0, symbolSellLimitOrdersVolumeTotal = 0.0,

       magicPendingOrdersVolumeTotal = 0.0,
       magicBuyStopOrdersVolumeTotal = 0.0, magicSellStopOrdersVolumeTotal = 0.0,
       magicBuyLimitOrdersVolumeTotal = 0.0, magicSellLimitOrdersVolumeTotal = 0.0;

注文を開いたり、変更したり、削除したりする際には、さまざまな種類のエラーが発生することがよくあります。これらのエラーを効率的に処理し、解決するためには、専用のエラー管理関数が必要です。また、取引をおこなう前に、EAが取引を許可されているか、端末でアルゴリズム取引が有効になっているか、ブローカーが口座でアルゴリズム取引を許可しているかどうかのような重要な取引権限を確認する関数も必要です。

幸いにも、前回の記事で開発したPositionsManager.ex5ライブラリには、これらの要件を満たす関数が既に含まれています。このため、新たに関数を再作成する必要はなく、このライブラリをインポートするだけで、エラー処理関数や取引権限確認関数を未決注文管理ライブラリ内で直接利用することができます。ErrorAdvisor(...)およびTradingIsAllowed()関数をインポートします。

//+----------------------------------------------------------------------------+
//| PositionsManager.ex5 imports                                               |
//+----------------------------------------------------------------------------+
#import "Toolkit/PositionsManager.ex5" //-- Opening import directive
//-- Function descriptions for the imported function prototypes

//-- Error Handling and Permission Status Functions
bool   ErrorAdvisor(string callingFunc, string symbol, int tradeServerErrorCode);
bool   TradingIsAllowed();

#import //--- Closing import directive


PrintOrderDetails関数

PrintOrderDetails(...)関数は、MetaTrader 5内のEAログに、取引リクエストとサーバーの応答に関する詳細情報を記録するためのものです。この関数は、カスタムメッセージを保持するheaderと、処理対象の取引銘柄または商品を表すsymbolという2つの文字列パラメータを受け取ります。この関数は、銘柄、注文タイプ、数量、価格、ストップロス、テイクプロフィット、コメント、マジックナンバー乖離などのような重要な注文詳細を含む包括的なレポートを出力します。さらに、サーバーからの応答や実行時のエラーなど、取引結果に関する重要な情報もログに記録します。この関数の主な目的は、各注文のパラメータとステータスを明確なフォーマットで提供することにより、取引操作のデバッグと監視を効率的にサポートすることです。

void PrintOrderDetails(string header, string symbol)
  {
   string orderDescription;
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
//-- Print the order details
   orderDescription += "_______________________________________________________________________________________\r\n";
   orderDescription += "--> "  + tradeRequest.symbol + " " + EnumToString(tradeRequest.type) + " " + header +
                       " <--\r\n";
   orderDescription += "Volume: " + StringFormat("%d", tradeRequest.volume) + "\r\n";
   orderDescription += "Price: " + DoubleToString(tradeRequest.price, symbolDigits) + "\r\n";
   orderDescription += "Stop Loss: " + DoubleToString(tradeRequest.sl, symbolDigits) + "\r\n";
   orderDescription += "Take Profit: " + DoubleToString(tradeRequest.tp, symbolDigits) + "\r\n";
   orderDescription += "Comment: " + tradeRequest.comment + "\r\n";
   orderDescription += "Magic Number: " + StringFormat("%d", tradeRequest.magic) + "\r\n";
   orderDescription += "Order filling: " + EnumToString(tradeRequest.type_filling)+ "\r\n";
   orderDescription += "Deviation points: " + StringFormat("%G", tradeRequest.deviation) + "\r\n";
   orderDescription += "RETCODE: " + (string)(tradeResult.retcode) + "\r\n";
   orderDescription += "Runtime Code: " + (string)(GetLastError()) + "\r\n";
   orderDescription += "---";
   Print(orderDescription);
  }


OpenBuyLimit関数

OpenBuyLimit(...)関数は、MetaTrader 5取引端末で新規の買い指値注文を出すために設計されています。この関数は、注文リクエストを送信する前に、必要なすべての条件が満たされていることを確認するため、潜在的な問題を管理する組み込みのエラー処理を備えています。また、すべてのパラメータが有効であり、ブローカーの要件に準拠していることを検証します。さらに、この関数には再試行ループが実装されており、発注の成功率を高めるため、未決注文を管理する信頼性の高い効率的なツールとなっています。包括的なエラー処理機能とログ機能を備えており、発注プロセス中に発生する可能性のある問題を特定し、解決することをサポートします。 この関数は、指値買い注文の発注に成功した場合はtrue、失敗した場合はfalseboolean値を返します。

買い指値注文とは?


買い指値注文(Buy Limit Order)は、指定された注文入力価格以下のAsk価格で買いをリクエストする注文です。買い指値のエントリー価格は、現在の市場価格が注文のエントリー価格より高い場合にのみ有効です。この注文タイプは、銘柄の価格が希望のエントリーレベルまで下がり、その後上昇すると予想される場合に適しており、この上昇から利益を得ることを可能にします。

買い指値注文

この関数は、買い指値注文を出す過程で、それぞれ特定の役割を持つ7つのパラメータを受け取ります。この関数はエクスポートが可能で、EX5ライブラリの外部からのアクセスが可能になります。これらのパラメータは以下の通りです。

  1. magicNumber (unsigned long):取引の一意の識別子。EAが発注した注文を他の注文と区別するために使用されます。
  2. symbol (string):注文が出される取引商品または銘柄(EURUSDなど
  3. entryPrice (double):買い指値注文がトリガーされる価格レベル。その資産を購入する際の目標価格です。
  4. lotSize (double):発注する注文の数量またはサイズで、何ロットの資産が取引されるかを表します。
  5. sl (int):損切り値(pips単位)。取引が自動的にクローズされるまでに発生する最大損失を定義します。
  6. tp (int):利食い値(pips単位)。注文を決済することで自動的に利益が確保される価格レベルを定義します。
  7. orderComment (string):識別または追跡の目的で注文に添付されるコメントまたはメモ
bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {

関数とそのパラメータを定義した後、関数での最初のステップは、アルゴリズムまたはEA取引がMetaTrader 5で有効になっているかどうかを確認することです。無効になっている場合、注文がおこなわれないよう、即座に関数を終了します。

if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

次に、tpPriceslPrice変数を作成し、利食い価格と損切り価格の値を保存し、小数点以下の桁数(digits)、最小ストップレベル、スプレッドなど、取引銘柄に関する主要な情報を取得します。これらの詳細は、エントリー価格と注文パラメータが選択した銘柄に対して正しく設定されていることを確認するのに役立ちます。

double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY_LIMIT;

注文を送信する前に、エントリー価格が有効かどうかを確認し、価格が市場価格に近すぎたり、ブローカーのストップレベルを下回っていないことを確認する必要があります。価格が無効な場合は、エラーを記録して関数を終了します。

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_ASK) - (symbolStopLevel * symbolPoint) <
      entryPrice + (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

ストップロス(SL)とテイクプロフィット(TP)の値がブローカーの最低条件を満たしていることを確認しましょう。必要であれば、SLTPをこれらのルールに適合するように調整してから続行します。

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice - sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice + tp * symbolPoint, symbolDigits) : 0;

価格とその他のパラメータを確認したら、注文タイプ、銘柄、価格、数量、ストップロス、テイクプロフィット、コメントなどの詳細を含むtradeRequest構造体を準備します。また、ロットサイズがブローカーの許容範囲内であることを確認し、以前の取引結果やエラーをリセットします。

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a buy limit order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

注文リクエストが有効であれば、ブローカーの取引サーバーに送信を試みます。発注に失敗した場合、再試行する前に半秒(500ミリ秒)間を置きながら、最大600回まで注文リクエストの再送信を試み、注文が正常に出されるように何度も試行します。この再試行の仕組みにより、特にネットワークやサーバーに一時的な問題が発生した場合に、注文が正常に出される可能性が大幅に高まります。

注文が正常に出されると、注文の詳細が記録され、取引サーバーが注文を処理したことが確認されます。何度試みても注文が失敗する場合は、PositionsManager.ex5ライブラリからインポートしたErrorAdvisor(...)関数を使用して問題を診断し、注文が出されなかったことを示すfalseを返します。

for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }

以下は、すべてのコードセグメントを正しい順序で並べた完全な関数です。OpenBuyLimit(...)関数に以下のコードが完全に含まれていることを確認してください。

bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY_LIMIT;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_ASK) - (symbolStopLevel * symbolPoint) <
      entryPrice + (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice - sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice + tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a buy limit order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


OpenBuyStop関数

OpenBuyStop(...)関数は、新規の買い逆指値注文を出します。これは、前述したOpenBuyLimit(...)関数と同様のアプローチです。この関数は、逆指値の買い注文に成功すればtrueを返し、失敗すればfalseを返します。

買い逆指値注文とは?


買い逆指値注文(Buy Stop Order)は、指定された注文入力価格以上のAsk価格で買いをリクエストする注文です。買い逆指値のエントリー価格は、現在の市場価格が注文のエントリー価格より低い場合にのみ有効です。このタイプの注文は、銘柄の価格が指定されたエントリーレベルまで上昇し、その後も上昇を続けると予想される場合に有効で、強気トレンドから利益を得ることができます。

買い逆指値

以下は、OpenBuyStop(...)関数で、コードの各部分がどのように機能するかをすぐに理解できるように、説明を加えたコメントです。

bool OpenBuyStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_BUY_STOP;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_ASK) + (symbolStopLevel * symbolPoint) >
      entryPrice + (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }


//--- Validate Stop Loss (sl) and Take Profit (tp)
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice - sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice + tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a buy stop order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


OpenSellLimit関数

OpenSellLimit(...)関数は、新規の指値売り注文を出します。この関数は、売り指値注文が正常に出された場合はtrueを返し、注文リクエストが失敗した場合はfalseを返します。

売り指値注文とは?


売り指値注文(Sell Limit Order)は、指定された注文入力価格以上のBid価格で売りをリクエストする注文です。売り指値のエントリー価格は、現在の市場価格が注文のエントリー価格より低い場合にのみ有効です。このタイプの注文は、銘柄の価格が指定されたエントリー価格レベルまで上昇し、その後方向が反転すると予想される場合に有効で、予想される下降または弱気トレンドから利益を得ることができます。

売り指値注文

以下はOpenSellLimit(...)関数で、コードの各部分がどのように動作するかをよりよく理解できるように、説明のコメントが付いています。

bool OpenSellLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double tpPrice = 0.0, slPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_SELL_LIMIT;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_BID) + (symbolStopLevel * symbolPoint) >
      entryPrice - (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice + sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice - tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a sell limit order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


OpenSellStop関数

OpenSellStop(...)関数は、新規の売り逆指値注文を出すように設計されています。この関数は、売り逆指値注文が正常に出された場合にtrueを返し、リクエストが問題なく処理されたことを示します。何らかの理由で発注に失敗した場合は、失敗を意味するfalseを返します。

売り逆指値注文とは?


売り逆指値注文(Sell Stop Order)は、指定された注文入力価格以下のBid価格で売りをリクエストする注文です。売り逆指値のエントリー価格は、現在の市場価格が注文のエントリー価格より高い場合にのみ有効です。このタイプの注文は、銘柄の価格が指定されたエントリーレベルまで下落し、その後も下落が続くと予想する場合に有効で、予想される下降または弱気トレンドから利益を得ることができます。

売り逆指値注文

OpenSellStop(...)関数は、コードの各部分の機能をガイドするための詳細なコメントとともに、以下に提供されます。

bool OpenSellStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   double slPrice = 0.0, tpPrice = 0.0;

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(symbol, SYMBOL_DIGITS);
   int symbolStopLevel = (int)SymbolInfoInteger(symbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(symbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(symbol, SYMBOL_SPREAD);

//-- Save the order type enumeration
   ENUM_ORDER_TYPE orderType = ORDER_TYPE_SELL_STOP;

//-- check if the entry price is valid
   if(
      SymbolInfoDouble(symbol, SYMBOL_BID) - (symbolStopLevel * symbolPoint) <
      entryPrice - (spread * symbolPoint)
   )
     {
      Print(
         "\r\n", __FUNCTION__, ": Can't open a new ", EnumToString(orderType),
         ". (Reason --> INVALID ENTRY PRICE: ", DoubleToString(entryPrice, symbolDigits), ")\r\n"
      );
      return(false); //-- Invalid entry price, log the error, exit the function and return false
     }

//-- Check the validity of the sl and tp
   if(sl > 0 && sl < symbolStopLevel)
     {
      sl = symbolStopLevel;
     }
   if(tp > 0 && tp < symbolStopLevel)
     {
      tp = symbolStopLevel;
     }

   slPrice = (sl > 0) ? NormalizeDouble(entryPrice + sl * symbolPoint, symbolDigits) : 0;
   tpPrice = (tp > 0) ? NormalizeDouble(entryPrice - tp * symbolPoint, symbolDigits) : 0;

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to open a sell stop order
   tradeRequest.type = orderType;
   tradeRequest.action = TRADE_ACTION_PENDING;
   tradeRequest.magic = magicNumber;
   tradeRequest.symbol = symbol;
   tradeRequest.price = NormalizeDouble(entryPrice, symbolDigits);
   tradeRequest.tp = tpPrice;
   tradeRequest.sl = slPrice;
   tradeRequest.comment = orderComment;
   tradeRequest.deviation = SymbolInfoInteger(symbol, SYMBOL_SPREAD) * 2;

//-- Set and moderate the lot size or volume
//-- Verify that volume is not less than allowed minimum
   lotSize = MathMax(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN));

//-- Verify that volume is not more than allowed maximum
   lotSize = MathMin(lotSize, SymbolInfoDouble(symbol, SYMBOL_VOLUME_MAX));

//-- Round down to nearest volume step
   lotSize = MathFloor(lotSize / SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP)) * SymbolInfoDouble(symbol, SYMBOL_VOLUME_STEP);
   tradeRequest.volume = lotSize;

//--- Reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function
   ResetLastError();

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try opening the order until it is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Print the order details
         PrintOrderDetails("Sent OK", symbol);

         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(
               __FUNCTION__, ": CONFIRMED: Successfully openend a ", symbol,
               " ", EnumToString(orderType), " #", tradeResult.order, ", Price: ", tradeResult.price
            );
            PrintFormat("retcode=%u  deal=%I64u  order=%I64u", tradeResult.retcode, tradeResult.deal, tradeResult.order);
            Print("_______________________________________________________________________________________");
            return(true); //-- exit the function
            //break; //--- success - order placed ok. exit the for loop
           }
        }
      else //-- Order request failed
        {
         //-- Print the order details
         PrintOrderDetails("Sending Failed", symbol);

         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, symbol, tradeResult.retcode) || IsStopped())
           {
            Print(
               __FUNCTION__, ": ", symbol, " ERROR opening a ", EnumToString(orderType),
               " at: ", tradeRequest.price, ", Lot\\Vol: ", tradeRequest.volume
            );
            Print("_______________________________________________________________________________________");
            return(false); //-- exit the function
            //break; //-- exit the for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


ModifyPendingOrderbyTicket関数

ModifyPendingOrderByTicket(...)関数は、有効な未決注文のストップロス(SL)、テイクプロフィット(TP)、またはエントリー価格を変更するように設計されています。変更がブローカーのルールの範囲内であることを確認するための検証をおこない、進行状況と発生する可能性のあるエラーをログに記録し、失敗した場合や不利な注文入力条件の場合に修正を複数回試みる再試行機構を使用します。

この関数は4つのパラメータを受け取ります。

  1. orderTicket (ulong):注文の一意の識別子。このチケット番号は、変更したい特定の注文を参照するために使用されます。
  2. newEntryPrice (double):未決注文の新しいエントリー価格。値が0に設定された場合、関数は現在のエントリー価格を保持します。
  3. newSl (int):新しいストップロス(SL)値をポイントで表します。値が0に設定された場合、SLは削除されるか変更されません。
  4. newTp (int):新しい利益確定(TP)値をポイントで表します。値が0に設定された場合、TPは削除されるか、変更されません。

この関数はbool型であり、注文の変更に成功した場合はブール値trueを返し、無効なパラメータ、注文の選択エラー、またはサーバーの問題により変更が失敗した場合はブール値falseを返します。まずは、以下の関数定義をコーディングしてみましょう。

bool ModifyPendingOrderByTicket(ulong orderTicket, double newEntryPrice, int newSl, int newTp) export
  {

注文を修正する前に、取引環境がアルゴリズム取引を許可していることを確認しなければなりません。これを確認するために、TradingIsAllowed()関数を使用します。

if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

正しい注文を変更していることを確認するために、標準のMQL5OrderSelect()関数とorderTicket関数パラメータを使用して注文を選択する必要があります。注文チケットが有効でない、または正常に選択されなかった場合、このエラーをログに記録し、関数を終了してブール値falseを返します。注文チケットの選択が成功した場合、短いログメッセージが表示され、注文処理が開始されます。

//--- Confirm and select the order using the provided orderTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(OrderSelect(orderTicket))
     {
      //---Order selected
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Order with ticket:", orderTicket, " selected and ready to set SLTP.");
     }
   else
     {
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Selecting order with ticket:", orderTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

注文が選択されたら、テイクプロフィット価格ストップロス価格を格納するためにdouble型の変数をいくつか作成し、デフォルト値のゼロ(0.0)で初期化します。その後、検証や修正に必要な注文の詳細(銘柄、出来高、現在のSL/TPなど)を取得します。

double newTpPrice = 0.0, newSlPrice = 0.0;

//--- Order ticket selected, save the order properties
   string orderSymbol = OrderGetString(ORDER_SYMBOL);
   double currentEntryPrice = OrderGetDouble(ORDER_PRICE_OPEN);
   double volume = OrderGetDouble(ORDER_VOLUME_INITIAL);
   double currentOrderSlPrice = OrderGetDouble(ORDER_SL);
   double currentOrderTpPrice = OrderGetDouble(ORDER_TP);
   ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
   double orderPriceCurrent = OrderGetDouble(ORDER_PRICE_CURRENT);

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(orderSymbol, SYMBOL_DIGITS); //-- Number of symbol decimal places
   int symbolStopLevel = (int)SymbolInfoInteger(orderSymbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(orderSymbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD);

次に、注文タイプ(例:買い指値、買い逆指値、売り逆指値、売り指値)に基づいて、新しいエントリー価格が正しいかどうかを検証します。これにより、無効な価格を早期に発見し、拒否することができます。

if(newEntryPrice > 0.0)
     {
      if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_ASK) + (symbolStopLevel * symbolPoint) >
            newEntryPrice - (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }

      if(orderType == ORDER_TYPE_BUY_LIMIT || orderType == ORDER_TYPE_SELL_STOP)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_BID) - (symbolStopLevel * symbolPoint) <
            newEntryPrice + (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }
     }
   else
     {
      newEntryPrice = currentEntryPrice; //-- Do not modify the entry price
     }

また、入力パラメータに基づいて新しいストップロス価格とテイクプロフィット価格を計算し、これらの値をブローカーのストップレベルと照らし合わせて検証する必要があります。

if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_BUY_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice - (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice + (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newEntryPrice - newSlPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newTpPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

   if(orderType == ORDER_TYPE_SELL_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice + (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice - (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newSlPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newEntryPrice - newTpPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

これですべての値が検証されたので、適切なパラメータを設定して、未決注文を変更する取引リクエストを準備します。まず、tradeRequestデータ構造体をリセットし、検証済みの有効な注文データで初期化します。

   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to set the sltp
   tradeRequest.action = TRADE_ACTION_MODIFY; //-- Trade operation type for modifying the pending order
   tradeRequest.order = orderTicket;
   tradeRequest.symbol = orderSymbol;
   tradeRequest.price = newEntryPrice;
   tradeRequest.sl = newSlPrice;
   tradeRequest.tp = newTpPrice;
   tradeRequest.deviation = SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD) * 2;

次に、最初の試みが失敗した場合に修正リクエストを複数回再送する再試行機構を実装し、注文の修正に成功する可能性を高める。クリティカルエラーが発生した場合、あるいはすべての再試行を試行し尽くした場合、この関数はfalseを返して終了します。注文が正常に変更された場合、この関数はtrueを返して終了します。急激な連続リクエストで取引サーバーを圧倒するのを避けるため、Sleep(...)関数を使用して反復間に遅延を導入します。

ResetLastError(); //--- reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try modifying the price open, sl, and tp until the request is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            PrintFormat("Successfully modified Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            PrintFormat("retcode=%u  runtime_code=%u", tradeResult.retcode, GetLastError());
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(true); //-- exit function
            //break; //--- success - order placed ok. exit for loop
           }
        }
      else  //-- Order request failed
        {
         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, orderSymbol, tradeResult.retcode) || IsStopped())
           {
            PrintFormat("ERROR modifying Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(false); //-- exit function
            //break; //-- exit for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }

ここに、欠落している部分を含む完全な関数コードを、すべてのコードセグメントを正しい順序で記します。

bool ModifyPendingOrderByTicket(ulong orderTicket, double newEntryPrice, int newSl, int newTp) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

//--- Confirm and select the order using the provided orderTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(OrderSelect(orderTicket))
     {
      //---Order selected
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Order with ticket:", orderTicket, " selected and ready to set SLTP.");
     }
   else
     {
      Print("\r\n_______________________________________________________________________________________");
      Print(__FUNCTION__, ": Selecting order with ticket:", orderTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

//-- create variables to store the calculated tp and sl prices to send to the trade server
   double newTpPrice = 0.0, newSlPrice = 0.0;

//--- Order ticket selected, save the order properties
   string orderSymbol = OrderGetString(ORDER_SYMBOL);
   double currentEntryPrice = OrderGetDouble(ORDER_PRICE_OPEN);
   double volume = OrderGetDouble(ORDER_VOLUME_INITIAL);
   double currentOrderSlPrice = OrderGetDouble(ORDER_SL);
   double currentOrderTpPrice = OrderGetDouble(ORDER_TP);
   ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);
   double orderPriceCurrent = OrderGetDouble(ORDER_PRICE_CURRENT);

//-- Get some information about the orders symbol
   int symbolDigits = (int)SymbolInfoInteger(orderSymbol, SYMBOL_DIGITS); //-- Number of symbol decimal places
   int symbolStopLevel = (int)SymbolInfoInteger(orderSymbol, SYMBOL_TRADE_STOPS_LEVEL);
   double symbolPoint = SymbolInfoDouble(orderSymbol, SYMBOL_POINT);
   int spread = (int)SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD);

//-- Check the validity of the newEntryPrice
   if(newEntryPrice > 0.0)
     {
      if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_ASK) + (symbolStopLevel * symbolPoint) >
            newEntryPrice - (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }

      if(orderType == ORDER_TYPE_BUY_LIMIT || orderType == ORDER_TYPE_SELL_STOP)
        {
         if(
            SymbolInfoDouble(orderSymbol, SYMBOL_BID) - (symbolStopLevel * symbolPoint) <
            newEntryPrice + (spread * symbolPoint)
         )
           {
            Print(
               "\r\n", __FUNCTION__, ": Can't MODIFY ", EnumToString(orderType),
               ". (Reason --> INVALID NEW ENTRY PRICE: ", DoubleToString(newEntryPrice, symbolDigits), ")\r\n"
            );
            return(false); //-- Invalid new entry price, log the error, exit the function and return false
           }
        }
     }
   else
     {
      newEntryPrice = currentEntryPrice; //-- Do not modify the entry price
     }

//-- Calculate and store the non-validated sl and tp prices
   if(orderType == ORDER_TYPE_BUY_STOP || orderType == ORDER_TYPE_BUY_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice - (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice + (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newEntryPrice - newSlPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newTpPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

   if(orderType == ORDER_TYPE_SELL_STOP || orderType == ORDER_TYPE_SELL_LIMIT)
     {
      if(newSl == 0)
        {
         newSlPrice = 0.0; //-- Remove the sl
        }
      else
        {
         newSlPrice = newEntryPrice + (newSl * symbolPoint);
        }
      if(newTp == 0)
        {
         newTpPrice = 0.0; //-- Remove the tp
        }
      else
        {
         newTpPrice = newEntryPrice - (newTp * symbolPoint);
        }

      //-- Check the validity of the newSlPrice
      if(newSlPrice > 0 && newSlPrice - newEntryPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW SL PRICE: ", DoubleToString(newSlPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid sl price, log the error, exit the function and return false
        }

      //-- Check the validity of the newTpPrice
      if(newTpPrice > 0 && newEntryPrice - newTpPrice < symbolStopLevel * symbolPoint)
        {
         Print(
            "\r\n", __FUNCTION__, ": Can't modify ", EnumToString(orderType),
            ". (Reason --> INVALID NEW TP PRICE: ", DoubleToString(newTpPrice, symbolDigits), ")\r\n"
         );
         return(false); //-- Invalid tp price, log the error, exit the function and return false
        }
     }

//-- Print order properties before modification
   string orderProperties = "--> "  + orderSymbol + " " + EnumToString(orderType) + " SLTP Modification Details" +
                            " <--\r\n";
   orderProperties += "------------------------------------------------------------\r\n";
   orderProperties += "Ticket: " + (string)orderTicket + "\r\n";
   orderProperties += "Volume: " + DoubleToString(volume, symbolDigits) + "\r\n";
   orderProperties += "Price Open: " + DoubleToString(currentEntryPrice, symbolDigits) +
                      "   -> New Proposed Price Open: " + DoubleToString(newEntryPrice, symbolDigits) + "\r\n";
   orderProperties += "Current SL: " + DoubleToString(currentOrderSlPrice, symbolDigits) +
                      "   -> New Proposed SL: " + DoubleToString(newSlPrice, symbolDigits) + "\r\n";
   orderProperties += "Current TP: " + DoubleToString(currentOrderTpPrice, symbolDigits) +
                      "   -> New Proposed TP: " + DoubleToString(newTpPrice, symbolDigits) + "\r\n";
   orderProperties += "Comment: " + OrderGetString(ORDER_COMMENT) + "\r\n";
   orderProperties += "Magic Number: " + (string)OrderGetInteger(ORDER_MAGIC) + "\r\n";
   orderProperties += "---";

//-- Print verified order properties before modification
   orderProperties += "--> Validated and Confirmed NewEntry, SL, and TP Prices: <--\r\n";
   orderProperties += "Order Price Current: " + DoubleToString(orderPriceCurrent, symbolDigits) + "\r\n";
   orderProperties += "Current Entry Price: " + DoubleToString(currentEntryPrice, symbolDigits) +
                      ", New Entry Price: " + DoubleToString(newEntryPrice, symbolDigits) + "\r\n";
   orderProperties += "Current SL: " + DoubleToString(currentOrderSlPrice, symbolDigits) +
                      "   -> New SL: " + DoubleToString(newSlPrice, symbolDigits) + "\r\n";
   orderProperties += "Current TP: " + DoubleToString(currentOrderTpPrice, symbolDigits) +
                      "   -> New TP: " + DoubleToString(newTpPrice, symbolDigits) + "\r\n";
   Print(orderProperties);

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the parameters to set the sltp
   tradeRequest.action = TRADE_ACTION_MODIFY; //-- Trade operation type for modifying the pending order
   tradeRequest.order = orderTicket;
   tradeRequest.symbol = orderSymbol;
   tradeRequest.price = newEntryPrice;
   tradeRequest.sl = newSlPrice;
   tradeRequest.tp = newTpPrice;
   tradeRequest.deviation = SymbolInfoInteger(orderSymbol, SYMBOL_SPREAD) * 2;

   ResetLastError(); //--- reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try modifying the price open, sl, and tp until the request is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            PrintFormat("Successfully modified Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            PrintFormat("retcode=%u  runtime_code=%u", tradeResult.retcode, GetLastError());
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(true); //-- exit function
            //break; //--- success - order placed ok. exit for loop
           }
        }
      else  //-- Order request failed
        {
         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, orderSymbol, tradeResult.retcode) || IsStopped())
           {
            PrintFormat("ERROR modifying Pending Order: #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            Print("_______________________________________________________________________________________\r\n\r\n");
            return(false); //-- exit function
            //break; //-- exit for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


DeletePendingOrderByTicket関数

DeletePendingOrderByTicket(...)関数は、一意のチケット番号を使用して、未決注文を削除します。まず、アルゴリズム取引が有効かどうかを確認し、注文を選択し、取引サーバーから削除しようとします。そのプロセスを通じて、この関数はさまざまな段階で注文に関する重要な詳細を記録し、削除が成功する可能性を最大化するために再試行メカニズムを採用し、必要に応じて複数回再試行します。

この関数は、ulong型のパラメータを1つ受け取ります。このパラメータは、削除される注文の一意のチケット番号を表すorderTicketです。trueは未決注文が正常に削除されたことを示し、falseは削除に失敗したか、重大なエラーが発生したことを示すboolを返します。

以下は、理解を容易にするために詳細なコメントを添えた関数コード全文です。

bool DeletePendingOrderByTicket(ulong orderTicket) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

//--- Confirm and select the order using the provided orderTicket
   ResetLastError(); //--- Reset error cache incase of ticket selection errors
   if(OrderSelect(orderTicket))
     {
      //---Order selected
      Print("...........................................................................................");
      Print(__FUNCTION__, ": Order with ticket:", orderTicket, " selected and ready to be deleted.");
     }
   else
     {
      Print("...........................................................................................");
      Print(__FUNCTION__, ": Selecting order with ticket:", orderTicket, " failed. ERROR: ", GetLastError());
      return(false); //-- Exit the function
     }

//--- Order ticket selected, save the order properties
   string orderSymbol = OrderGetString(ORDER_SYMBOL);
   double orderVolume = OrderGetDouble(ORDER_VOLUME_CURRENT);
   int symbolDigits = (int)SymbolInfoInteger(orderSymbol, SYMBOL_DIGITS);
   ENUM_ORDER_TYPE orderType = (ENUM_ORDER_TYPE)OrderGetInteger(ORDER_TYPE);

//-- Print order properties before deleting it
   string orderProperties;
   orderProperties += "-- "  + orderSymbol + " " + EnumToString(orderType) + " Details" +
   " -------------------------------------------------------------\r\n";
   orderProperties += "Ticket: " + (string)orderTicket + "\r\n";
   orderProperties += "Volume: " + DoubleToString(orderVolume) + "\r\n";
   orderProperties += "Price Open: " + DoubleToString(OrderGetDouble(ORDER_PRICE_OPEN), symbolDigits) + "\r\n";
   orderProperties += "SL: " + DoubleToString(OrderGetDouble(ORDER_SL), symbolDigits) + "\r\n";
   orderProperties += "TP: " + DoubleToString(OrderGetDouble(ORDER_TP), symbolDigits) + "\r\n";
   orderProperties += "Comment: " + OrderGetString(ORDER_COMMENT) + "\r\n";
   orderProperties += "Magic Number: " + (string)OrderGetInteger(ORDER_MAGIC) + "\r\n";
   orderProperties += "_______________________________________________________________________________________";
   Print(orderProperties);

//-- reset the the tradeRequest and tradeResult values by zeroing them
   ZeroMemory(tradeRequest);
   ZeroMemory(tradeResult);

//-- initialize the trade reqiest parameters to delete the order
   tradeRequest.action = TRADE_ACTION_REMOVE; //-- Trade operation type for deleting an order
   tradeRequest.order = orderTicket;

   ResetLastError(); //--- reset error cache so that we get an accurate runtime error code in the ErrorAdvisor function

   for(int loop = 0; loop <= MAX_ORDER_RETRIES; loop++) //-- try deleting the order until the request is successful
     {
      //--- send order to the trade server
      if(OrderSend(tradeRequest, tradeResult))
        {
         //-- Confirm order execution
         if(tradeResult.retcode == 10008 || tradeResult.retcode == 10009)
           {
            Print(__FUNCTION__, "_________________________________________________________________________");
            PrintFormat("Successfully deleted order #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            PrintFormat("retcode=%u  runtime_code=%u", tradeResult.retcode, GetLastError());
            Print("_______________________________________________________________________________________");
            return(true); //-- exit function
            //break; //--- success - order placed ok. exit for loop
           }
        }
      else  //-- order deleting request failed
        {
         //-- order not sent or critical error found
         if(!ErrorAdvisor(__FUNCTION__, orderSymbol, tradeResult.retcode) || IsStopped())
           {
            Print(__FUNCTION__, "_________________________________________________________________________");
            PrintFormat("ERROR deleting order #%I64d %s %s", orderTicket, orderSymbol, EnumToString(orderType));
            Print("_______________________________________________________________________________________");
            return(false); //-- exit function
            //break; //-- exit for loop

            Sleep(ORDER_RETRY_DELAYS);//-- Small pause before retrying to avoid overwhelming the trade server
           }
        }
     }
   return(false);
  }


DeleteAllPendingOrders関数

DeleteAllPendingOrders(...)関数は、指定された銘柄マジックナンバーの未決注文をすべて削除するように設計されています。次に、アルゴリズム取引が有効になっていることを確認します。この関数は、すべての未決済注文を繰り返し、それらが指定された銘柄マジックナンバーに一致するかどうかを確認し、それらを1つずつ削除しようとします。一部の注文が即座に削除できない場合、この関数はコールバックと再試行メカニズムを使用して、対象となる注文がすべて削除されるまで継続的に削除を試みます。プロセス全体を通して、エラーを記録し、重要な問題を確認することで、無限ループによる潜在的なロックを回避します。

この関数は、2つのオプションのパラメータを受け付けます。

  1. symbol (string):取引銘柄を表す文字列パラメータ。デフォルトはALL_SYMBOLSで、特定の銘柄が指定されない限り、すべての銘柄の注文を対象とします。
  2. magicNumber (ulong):注文の一意のマジックナンバーを表すunsigned long integer型のパラメータ。デフォルトは0であり、これは特定の値が与えられない限り、マジックナンバーに関係なくすべての注文を対象とすることを意味します。

この関数はブール値(bool)を返し、trueは対象となるすべての未決注文が正常に削除されたことを示し、falseは一部またはすべての注文の削除に失敗した場合、または重大なエラーが発生した場合を示します。

以下は、理解しやすいようにコメントを加えた関数コードの全文です。

bool DeleteAllPendingOrders(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number for the specified orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);

      //-- Filter orders by symbol and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Delete the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllPendingOrders(symbol, magicNumber); //-- We still have some open orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

//-- Final confirmations that all targeted orders have been closed
   if(SymbolOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true; //-- Save this status for the function return value
     }

   return(returnThis);
  }

すべての未決注文をすばやく削除するために、DeleteAllPendingOrders(...)関数に引数を取らない2番目のバージョンをオーバーロードします。呼び出されると、口座内のすべての未決注文が削除されます。以下は、オーバーロードされたDeleteAllPendingOrders()関数です。

bool DeleteAllPendingOrders() export
  {
   return(DeleteAllPendingOrders(ALL_SYMBOLS, 0));
  }


DeleteAllBuyStops関数

DeleteAllBuyStops(...)関数は、指定された銘柄マジックナンバーの未決済の買い逆指値注文をすべて削除します。他の削除機能と同様に、まずアルゴリズム取引が有効かどうかを確認します。次に、この関数はすべての未決済注文をスキャンし、銘柄、マジックナンバー注文タイプ買い逆指値)に一致する注文を特定し、それらの注文を削除しようとします。最初のパスで注文が削除されなかった場合、この関数はコールバックと再試行メカニズムを使用して、継続的に削除を試みます。セーフガードを設定し、エラーを確認することで、無限ループが発生しないようにします。プロセス全体を通して、この機能は関連情報を記録し、重大なエラーを管理します。

この関数は、2つのオプションのパラメータを受け付けます。

  1. symbol (string):取引銘柄を表す文字列。デフォルトはALL_SYMBOLSで、特定の銘柄が指定されない限り、すべての銘柄買い逆指値注文を対象とします。
  2. magicNumber (ulong):注文に割り当てられた一意のマジックナンバーを表すunsigned long integer。デフォルトは0です。つまり、特定のマジックナンバーが指定されない限り、マジックナンバーに関係なく、すべての買い逆指値注文を対象とします。

この関数はブール値(bool)を返し、trueは対象となるすべての買い逆指値注文が正常に削除されたことを示し、falseは一部またはすべての注文の削除に失敗したか、重大な問題が発生したことを示します。

以下は、理解を容易にするために役立つコメントを添えた関数コード全文です。

bool DeleteAllBuyStops(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific buy stop orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_BUY_STOP) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the buy stop orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolBuyStopOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllBuyStops(symbol, magicNumber); //-- We still have some open buy stop orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolBuyStopOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


DeleteAllBuyLimits関数

DeleteAllBuyLimits(...)関数は、指定された銘柄マジックナンバーの未決済の買い指値注文をすべて削除します。この関数はブール値(bool)を返し、trueは対象となるすべての買い指値注文が正常に削除されたことを示し、falseは一部またはすべての注文の削除に失敗したか、重大な問題が発生したことを示します。

bool DeleteAllBuyLimits(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific buy limit orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_BUY_LIMIT) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the buy limit orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolBuyLimitOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllBuyLimits(symbol, magicNumber); //-- We still have some open buy limit orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolBuyLimitOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


DeleteAllSellStops関数

DeleteAllSellStops(...)関数は、特定の銘柄マジックナンバーに関連付けられている未決売り逆指値注文をすべて削除します。この関数はブール値(bool)を返します。trueは対象となるすべての売り逆指値注文が正常に削除されたことを示し、falseは、一部またはすべての注文の削除に失敗したか、重大なエラーが発生したことを示します。

bool DeleteAllSellStops(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific sell stop orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_SELL_STOP) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the sell stop orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolSellStopOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllSellStops(symbol, magicNumber); //-- We still have some open sell stop orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolSellStopOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


DeleteAllSellLimits関数

DeleteAllSellLimits(...)関数は、特定の銘柄マジックナンバーにリンクされた未決済の売り指値注文をすべて削除します。この関数は、指定されたすべての指値売り注文が正常に削除された場合はtrueを、一部またはすべての注文を削除できなかった場合や重大なエラーが発生した場合はfalseのブール値(bool)を返します。

bool DeleteAllSellLimits(string symbol = ALL_SYMBOLS, ulong magicNumber = 0) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Scan for symbol and magic number specific sell limit orders and close them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      ulong orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      string selectedSymbol = OrderGetString(ORDER_SYMBOL);
      ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      ulong orderType = OrderGetInteger(ORDER_TYPE);

      //-- Filter order by symbol, type and magic number
      if(
         (symbol != ALL_SYMBOLS && symbol != selectedSymbol) || (orderType != ORDER_TYPE_SELL_LIMIT) ||
         (magicNumber != 0 && orderMagicNo != magicNumber)
      )
        {
         continue;
        }

      //-- Close the order
      DeletePendingOrderByTicket(orderTicket);
     }

//-- Confirm that we have closed all the sell limit orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(SymbolSellLimitOrdersTotal(symbol, magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllSellLimits(symbol, magicNumber); //-- We still have some open sell limit orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, symbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(SymbolSellLimitOrdersTotal(symbol, magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


DeleteAllMagicOrders関数

DeleteAllMagicOrders(...)関数は、特定のマジックナンバーに関連付けられている未決注文をすべて削除します。この関数はブール値(bool)を返し、trueは関連するすべてのマジック注文が正常に削除されたことを示し、falseは注文の一部またはすべての削除に失敗したか、重大なエラーが発生したことを示します。

bool DeleteAllMagicOrders(ulong magicNumber) export
  {
//-- first check if the EA is allowed to trade
   if(!TradingIsAllowed())
     {
      return(false); //--- algo trading is disabled, exit function
     }

   bool returnThis = false;

//-- Variables to store the selected orders data
   ulong orderTicket, orderMagicNo;
   string orderSymbol;

//-- Scan for magic number specific orders and delete them
   int totalOpenOrders = OrdersTotal();
   for(int x = 0; x < totalOpenOrders; x++)
     {
      //--- Get order properties
      orderTicket = OrderGetTicket(x); //-- Get ticket to select the order
      orderMagicNo = OrderGetInteger(ORDER_MAGIC);
      orderSymbol = OrderGetString(ORDER_SYMBOL);

      //-- Filter orders by magic number
      if(magicNumber == orderMagicNo)
        {
         //-- Delete the order
         DeletePendingOrderByTicket(orderTicket);
        }
     }

//-- Confirm that we have deleted all the orders being targeted
   int breakerBreaker = 0; //-- Variable that safeguards and makes sure we are not locked in an infinite loop
   while(MagicOrdersTotal(magicNumber) > 0)
     {
      breakerBreaker++;
      DeleteAllMagicOrders(magicNumber); //-- We still have some open orders, do a function callback
      Sleep(ORDER_RETRY_DELAYS); //-- Micro sleep to pace the execution and give some time to the trade server

      //-- Check for critical errors so that we exit the loop if we run into trouble
      if(!ErrorAdvisor(__FUNCTION__, orderSymbol, GetLastError()) || IsStopped() || breakerBreaker > MAX_ORDER_RETRIES)
        {
         break;
        }
     }

   if(MagicOrdersTotal(magicNumber) == 0)
     {
      returnThis = true;
     }
   return(returnThis);
  }


GetPendingOrdersData関数

どのような自律的なアルゴリズム取引システムやEAでも、信頼性が高く、最終的に一貫して利益を上げるためには、口座内のすべてのポジションと注文の状態を把握していなければなりません。第2回目の記事では、すべてのポジションのデータを収集するポジションモニター機能を開発しました。この記事では未決注文に焦点を当てるので、すべての未決注文のデータをスキャンして保存する関数を作成し、他の関数で使用できるようにライブラリ全体で利用できるようにします。この記事の冒頭で設定したグローバル変数を使ってこれを実現します。

これらのグローバル変数は、ライブラリのソースコードファイルや.EX5バイナリファイルの外部にエクスポートしたりアクセスしたりすることができないため、エクスポート可能なさまざまな未決注文のステータス関数に渡して、最終的な.EX5ライブラリでアクセスできるようにします。まず、すべての未決注文データを取得する関数を作成し、GetPendingOrdersData(...)と名付けます。

GetPendingOrdersData(...)関数は、口座、特定の取引銘柄、およびEAのマジックナンバーに関連する未決注文のステータス詳細を取得し、保存します。買い逆指値、買い指値、売り逆指値、売り指値など、さまざまなタイプの未決注文の合計と数量を保存するさまざまなグローバル変数をリセットすることから始めます。このリセットの後、関数は未決注文を確認し、関連するデータを収集するためにそれらを繰り返し実行します。そして、指定された銘柄マジックナンバーに基づいて注文をフィルタリングし、一致した未決注文の合計と数量を累積します。この包括的なアプローチは、EA内の他の機能で利用可能な未決注文のステータスに関するリアルタイムのデータを確実に取得する機能です。

この関数は2つのパラメータを受け取ります。

  1. symbol (string):未決注文のデータを取得する取引銘柄を表す文字列。デフォルトはALL_SYMBOLSで、特定の銘柄が提供されない限り、すべての銘柄のデータを収集することを示します。
  2. magicNumber (ulong):EAの未決注文に割り当てられた一意のマジックナンバーを表すunsigned long integer。このパラメータはデフォルトで0に設定され、特定のマジックナンバーが指定されない限り、マジックナンバーに関係なく、すべての未決注文のデータを取得することができます。

この関数の主な目的は、グローバルステータス変数に未決注文の詳細を入力して更新することであるため、この関数は値を返しません(void)。これらの変数は、意思決定や取引戦略の参考とするため、ライブラリの他の部分からアクセスされます。

以下は、理解を深めるための詳細なコメント付きの関数コード全文です。

void GetPendingOrdersData(string symbol, ulong magicNumber)
  {
//-- Reset the account open pending orders status
   accountBuyStopOrdersTotal = 0;
   accountBuyLimitOrdersTotal = 0;

   accountSellStopOrdersTotal = 0;
   accountSellLimitOrdersTotal = 0;

   accountPendingOrdersVolumeTotal = 0.0;

   accountBuyStopOrdersVolumeTotal = 0.0;
   accountBuyLimitOrdersVolumeTotal = 0.0;

   accountSellStopOrdersVolumeTotal = 0.0;
   accountSellLimitOrdersVolumeTotal = 0.0;

//-- Reset the EA's magic open pending orders status
   magicPendingOrdersTotal = 0;

   magicBuyStopOrdersTotal = 0;
   magicBuyLimitOrdersTotal = 0;

   magicSellStopOrdersTotal = 0;
   magicSellLimitOrdersTotal = 0;

   magicPendingOrdersVolumeTotal = 0.0;

   magicBuyStopOrdersVolumeTotal = 0.0;
   magicBuyLimitOrdersVolumeTotal = 0.0;

   magicSellStopOrdersVolumeTotal = 0.0;
   magicSellLimitOrdersVolumeTotal = 0.0;

//-- Reset the symbol open pending orders status
   symbolPendingOrdersTotal = 0;

   symbolBuyStopOrdersTotal = 0;
   symbolBuyLimitOrdersTotal = 0;

   symbolSellStopOrdersTotal = 0;
   symbolSellLimitOrdersTotal = 0;

   symbolPendingOrdersVolumeTotal = 0.0;

   symbolBuyStopOrdersVolumeTotal = 0.0;
   symbolBuyLimitOrdersVolumeTotal = 0.0;

   symbolSellStopOrdersVolumeTotal = 0.0;
   symbolSellLimitOrdersVolumeTotal = 0.0;

//-- Update and save the open pending orders status with realtime data
   int totalOpenPendingOrders = OrdersTotal();
   if(totalOpenPendingOrders > 0)
     {
      //-- Scan for symbol and magic number specific pending orders and save their status
      for(int x = 0; x < totalOpenPendingOrders; x++)
        {
         //--- Get the pending orders properties
         ulong  orderTicket = OrderGetTicket(x); //-- Get ticket to select the pending order
         string selectedSymbol = OrderGetString(ORDER_SYMBOL);
         ulong orderMagicNo = OrderGetInteger(ORDER_MAGIC);

         //-- Filter pending orders by magic number
         if(magicNumber != 0 && orderMagicNo != magicNumber)
           {
            continue;
           }

         //-- Save the account pending orders status first
         accountPendingOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);

         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
           {
            //-- Account properties
            ++accountBuyStopOrdersTotal;
            accountBuyStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT)
           {
            //-- Account properties
            ++accountBuyLimitOrdersTotal;
            accountBuyLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
           {
            //-- Account properties
            ++accountSellStopOrdersTotal;
            accountSellStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }
         if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT)
           {
            //-- Account properties
            ++accountSellLimitOrdersTotal;
            accountSellLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
           }


         //-- Filter pending orders openend by EA and save their status
         if(
            OrderGetInteger(ORDER_REASON) == ORDER_REASON_EXPERT &&
            orderMagicNo == magicNumber
         )
           {
            ++magicPendingOrdersTotal;
            magicPendingOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
              {
               //-- Magic properties
               ++magicBuyStopOrdersTotal;
               magicBuyStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT)
              {
               //-- Magic properties
               ++magicBuyLimitOrdersTotal;
               magicBuyLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
              {
               //-- Magic properties
               ++magicSellStopOrdersTotal;
               magicSellStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT)
              {
               //-- Magic properties
               ++magicSellLimitOrdersTotal;
               magicSellLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
           }

         //-- Filter positions by symbol
         if(symbol == ALL_SYMBOLS || selectedSymbol == symbol)
           {
            ++symbolPendingOrdersTotal;
            symbolPendingOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
              {
               ++symbolBuyStopOrdersTotal;
               symbolBuyStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_LIMIT)
              {
               ++symbolBuyLimitOrdersTotal;
               symbolBuyLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_STOP)
              {
               ++symbolSellStopOrdersTotal;
               symbolSellStopOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
            if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_SELL_LIMIT)
              {
               ++symbolSellLimitOrdersTotal;
               symbolSellLimitOrdersVolumeTotal += OrderGetDouble(ORDER_VOLUME_CURRENT);
              }
           }
        }
     }
  }


BuyStopOrdersTotal関数

口座内の未決済の買い逆指値注文の総数を整数値で返します。

int BuyStopOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyStopOrdersTotal);
  }


BuyLimitOrdersTotal関数

口座内の未決済の買い指値注文の総数を整数値で返します。

int BuyLimitOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyLimitOrdersTotal);
  }


SellStopOrdersTotal関数

口座内の未決済の売り逆指値注文の総数を整数値で返します。

int SellStopOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellStopOrdersTotal);
  }


SellLimitOrdersTotal関数

口座内の未決済の売り指値注文の総数を整数値で返します。

int SellLimitOrdersTotal() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellLimitOrdersTotal);
  }


OrdersTotalVolume関数

口座内のすべての未決済注文の総数量/ロット/数量をdouble値で返します。

double OrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountPendingOrdersVolumeTotal);
  }


BuyStopOrdersTotalVolume関数

口座内のすべての未決済買い逆指値注文の総数量/ロット/数量をdouble値で返します。

double BuyStopOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyStopOrdersVolumeTotal);
  }


BuyLimitOrdersTotalVolume関数

口座内のすべての未決済買い指値注文の総数量/ロット/数量をdouble値で返します。

double BuyLimitOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountBuyLimitOrdersVolumeTotal);
  }


SellStopOrdersTotalVolume関数

口座内のすべての未決済売り逆指値注文の総数量/ロット/数量をdouble値で返します。

double SellStopOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellStopOrdersVolumeTotal);
  }


SellLimitOrdersTotalVolume関数

口座内のすべての未決済売り指値注文の総数量/ロット/数量をdouble値で返します。

double SellLimitOrdersTotalVolume() export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0);
   return(accountSellLimitOrdersVolumeTotal);
  }


MagicOrdersTotal関数

指定されたマジック番号の口座の未決注文の合計数を整数値で返します。

int MagicOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicPendingOrdersTotal);
  }


MagicBuyStopOrdersTotal関数

指定されたマジックナンバーの口座の、すべての未決済の買い逆指値注文の合計数を整数値で返します。

int MagicBuyStopOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyStopOrdersTotal);
  }


MagicBuyLimitOrdersTotal関数

指定されたマジックナンバーの口座の、すべての未決済買い指値注文の合計数を整数値で返します。

int MagicBuyLimitOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyLimitOrdersTotal);
  }


MagicSellStopOrdersTotal関数

指定されたマジックナンバーの口座の、すべての未決済の売り逆指値注文の合計数を整数値で返します。

int MagicSellStopOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellStopOrdersTotal);
  }


MagicSellLimitOrdersTotal関数

指定されたマジックナンバーの口座のすべての未決済売り指値注文の合計数を整数値で返します。

int MagicSellLimitOrdersTotal(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellLimitOrdersTotal);
  }


MagicOrdersTotalVolume関数

指定されたマジックナンバーの未決注文の総数量/ロット/枚数をdouble値で返します。

double MagicOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicPendingOrdersVolumeTotal);
  }


MagicBuyStopOrdersTotalVolume関数

指定されたマジックナンバーの口座の、すべての未決済の買い逆指値注文の総数量/ロット/数量をdouble値で返します。

double MagicBuyStopOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyStopOrdersVolumeTotal);
  }


MagicBuyLimitOrdersTotalVolume関数

指定されたマジックナンバーの口座のすべての未決済買い指値注文の数量/ロット/数量の合計をdouble値で返します。

double MagicBuyLimitOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicBuyLimitOrdersVolumeTotal);
  }


MagicSellStopOrdersTotalVolume関数

指定されたマジックナンバーの口座の、すべての未決済の売り逆指値注文の総数量/ロット/数量をdouble値で返します。

double MagicSellStopOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellStopOrdersVolumeTotal);
  }


MagicSellLimitOrdersTotalVolume関数

指定されたマジックナンバーの口座の全ての未決済の売り指値注文の数量/ロット/数量の合計をdouble値で返します。

double MagicSellLimitOrdersTotalVolume(ulong magicNumber) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber);
   return(magicSellLimitOrdersVolumeTotal);
  }


SymbolOrdersTotal関数

指定された銘柄とマジックナンバーの口座の未決注文の合計数を整数値で返します。

int SymbolOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolPendingOrdersTotal);
  }


SymbolBuyStopOrdersTotal関数

口座における指定された銘柄とマジックナンバーのすべての買い逆指値注文の合計数を整数値で返します。

int SymbolBuyStopOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyStopOrdersTotal);
  }


SymbolBuyLimitOrdersTotal関数

口座における指定された銘柄とマジックナンバーのすべての未決済買い指値注文の合計数を整数値で返します。

int SymbolBuyLimitOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyLimitOrdersTotal);
  }


SymbolSellStopOrdersTotal関数

口座における指定された銘柄とマジックナンバーのすべての売り逆指値注文の合計数を整数値で返します。

int SymbolSellStopOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellStopOrdersTotal);
  }


SymbolSellLimitOrdersTotal関数

指定された銘柄とマジックナンバーの口座における、すべての未決済の売り指値注文の合計数を整数値で返します。

int SymbolSellLimitOrdersTotal(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellLimitOrdersTotal);
  }


SymbolOrdersTotalVolume関数

指定された銘柄とマジックナンバーの未決注文の総数量/ロット/数量をdouble値で返します。

double SymbolOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolPendingOrdersVolumeTotal);
  }


SymbolBuyStopOrdersTotalVolume関数

指定された銘柄とマジックナンバーの口座における、すべての買い逆指値注文の総数量/ロット/数量をdouble値で返します。

double SymbolBuyStopOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyStopOrdersVolumeTotal);
  }


SymbolBuyLimitOrdersTotalVolume関数

指定された銘柄とマジックナンバーの口座における、すべての未決済の買い指値注文の総数量/ロット/数量をdouble値で返します。

double SymbolBuyLimitOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolBuyLimitOrdersVolumeTotal);
  }


SymbolSellStopOrdersTotalVolume関数

口座における指定された銘柄とマジックナンバーのすべての未決済の売り逆指値注文の総数量/ロット/数量をdouble値で返します。

double SymbolSellStopOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellStopOrdersVolumeTotal);
  }


SymbolSellLimitOrdersTotalVolume関数

指定された銘柄とマジックナンバーの口座における、すべての未決済の売り指値注文の総数量/ロット/数量をdouble値で返します。

double SymbolSellLimitOrdersTotalVolume(string symbol, ulong magicNumber) export
  {
   GetPendingOrdersData(symbol, magicNumber);
   return(symbolSellLimitOrdersVolumeTotal);
  }


AccountOrdersStatus関数

口座注文のステータスを含むフォーマット済み文字列を返します。この関数は、formatForCommentというブール値のパラメータを1つ受け取ります。formatForCommenttrueに設定されている場合、この関数はチャートウィンドウに表示するためにデータをフォーマットします。falseの場合、EAの[ログ]タブ用にデータがフォーマットされます。

string AccountOrdersStatus(bool formatForComment) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, 0); //-- Update the orders status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string accountOrdersStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| " + (string)AccountInfoInteger(ACCOUNT_LOGIN) + " - ACCOUNT ORDERS STATUS \r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)OrdersTotal() + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountPendingOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| BUY STOP ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountBuyStopOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountBuyStopOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| BUY LIMIT ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountBuyLimitOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountBuyLimitOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| SELL STOP ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountSellStopOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountSellStopOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "| SELL LIMIT ORDERS: \r\n";
   accountOrdersStatus += spacer + "|     Total Open:   " + (string)accountSellLimitOrdersTotal + "\r\n";
   accountOrdersStatus += spacer + "|     Total Volume: " + (string)accountSellLimitOrdersVolumeTotal + "\r\n";
   accountOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   accountOrdersStatus += spacer + "\r\n";
   return(accountOrdersStatus);
  }


MagicOrdersStatus関数

マジック注文の状態を示すフォーマット済みの文字列を返します。この文字列は、ログに印刷したり、チャートのコメントに表示したりできます。この関数は、対象となるマジックナンバーを指定するunsigned longmagicNumberと、フォーマットタイプを決定するboolean型のformatForCommentの2つのパラメータを受け入れます。この関数は、formatForCommentがtrueの場合はチャートウィンドウでの表示用にデータをフォーマットし、falseの場合はEAの[ログ]タブ用にデータをフォーマットします。

string MagicOrdersStatus(ulong magicNumber, bool formatForComment) export
  {
   GetPendingOrdersData(ALL_SYMBOLS, magicNumber); //-- Update the order status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string magicOrdersStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| " + (string)magicNumber + " - MAGIC ORDERS STATUS \r\n";
   magicOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicPendingOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicPendingOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| BUY STOP ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicBuyStopOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicBuyStopOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| BUY LIMIT ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicBuyLimitOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicBuyLimitOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| SELL STOP ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicSellStopOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicSellStopOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "| SELL LIMIT ORDERS: \r\n";
   magicOrdersStatus += spacer + "|     Total Open:   " + (string)magicSellLimitOrdersTotal + "\r\n";
   magicOrdersStatus += spacer + "|     Total Volume: " + (string)magicSellLimitOrdersVolumeTotal + "\r\n";
   magicOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   magicOrdersStatus += spacer + "\r\n";
   return(magicOrdersStatus);
  }


SymbolOrdersStatus関数

銘柄注文の状態を示すフォーマット済みの文字列を返します。この文字列は、ログに印刷したり、チャートのコメントに表示したりできます。string型のsymbol、マジックナンバーを指定するunsigned long型のmagicNumber0を指定するとマジックナンバーフィルタは無効になる)、書式タイプを決定するboolean型のformatForCommentの3つのパラメータを受け取ります。この関数は、formatForCommenttrueの場合はチャートウィンドウでの表示用にデータをフォーマットし、falseの場合はEAの[ログ]タブ用にデータをフォーマットします。

string SymbolOrdersStatus(string symbol, ulong magicNumber, bool formatForComment) export
  {
   GetPendingOrdersData(symbol, magicNumber); //-- Update the order status variables before we display their data
   string spacer = "";
   if(formatForComment) //-- Add some formating space for the chart comment string
     {
      spacer = "                                        ";
     }
   string symbolOrdersStatus = "\r\n" + spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| " + symbol + " - SYMBOL ORDERS STATUS \r\n";
   symbolOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolPendingOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolPendingOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| BUY STOP ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolBuyStopOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolBuyStopOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| BUY LIMIT ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolBuyLimitOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolBuyLimitOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| SELL STOP ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolSellStopOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolSellStopOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "| SELL LIMIT ORDERS: \r\n";
   symbolOrdersStatus += spacer + "|     Total Open:   " + (string)symbolSellLimitOrdersTotal + "\r\n";
   symbolOrdersStatus += spacer + "|     Total Volume: " + (string)symbolSellLimitOrdersVolumeTotal + "\r\n";
   symbolOrdersStatus += spacer + "|---------------------------------------------------------------------------\r\n";
   symbolOrdersStatus += spacer + "\r\n";
   return(symbolOrdersStatus);
  }

上記で作成した豊富なライブラリ機能は、未決注文管理EX5ライブラリを構成しています。この記事の下に、ソースコードファイルPendingOrdersManager.mq5とコンパイルされたバイナリ実行ファイルPendingOrdersManager.ex5があります。後者は簡単にインポートし、MQL5プロジェクトで使用することができます。


未決注文管理EX5ライブラリのインポートと実装方法

未決注文の管理、ステータス取得、関連情報の表示に必要な未決注文の処理、ステータスの取得、関連情報の表示に必要な機能を備えた堅牢なP未決注文管理EX5ライブラリを開発しました。これから、このライブラリをMQL5プロジェクトに正しくインポートし、利用する方法を詳しく解説します。

実装プロセスをより簡単にするため、まずは未決注文管理ライブラリ内のすべての関数とモジュールを概説します。その後、実用的なコード例を含むドキュメントセクションで詳細を説明します。これにより、PendingOrdersManager.ex5バイナリファイルに含まれるコンポーネントをユーザーが明確に理解できるようになります。


Pending Orders Manager EX5ライブラリドキュメント

ステップ1:ライブラリの実行ファイル(PositionsManager.ex5PendingOrdersManager.ex5)をコピーする

PositionManager.ex5PendingOrdersManager.ex5ファイルをMQL5/Libraries/Toolkitフォルダ、またはライブラリをインポートするソースコードファイルと同じフォルダにインストールします。これらのファイルがダウンロードされ、指定された場所にコピーされていることを確認してください。両ファイルのコピーをこの記事の末尾に添付しておきます。

ステップ2:関数プロトタイプの記述をインポートする

ソースコードのヘッダーセクションに、Pending Orders Managerライブラリimportディレクティブとその関数プロトタイプの説明を追加します。次のコードセグメントを使用して、PendingOrdersManager.ex5ライブラリからすべての関数またはモジュールを効率的にインポートします。空白のEAテンプレート(PendingOrdersManager_Imports_Template.mq5)を作成しました。プロジェクトに必要のない関数の説明は、コメントアウトしたり削除したりすることができます。 PendingOrdersManager_Imports_Template.mq5ファイルもこの記事の最後に添付されています。

//+------------------------------------------------------------------------------------------+
//-- Copy and paste the import derictives below to use the Pending Orders Manager EX5 Library
//---
//+-------------------------------------------------------------------------------------+
//| PendingOrdersManager.ex5 imports template                                           |
//+-------------------------------------------------------------------------------------+
#import "Toolkit/PendingOrdersManager.ex5" //-- Opening import directive
//-- Function descriptions for the imported function prototypes

//-- Pending Orders Execution and Modification Functions
bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenBuyStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool ModifyPendingOrderByTicket(ulong orderTicket, double newEntryPrice, int newSl, int newTp);
bool DeletePendingOrderByTicket(ulong orderTicket);
bool DeleteAllPendingOrders(string symbol, ulong magicNumber);
bool DeleteAllPendingOrders();
bool DeleteAllBuyStops(string symbol, ulong magicNumber);
bool DeleteAllBuyLimits(string symbol, ulong magicNumber);
bool DeleteAllSellStops(string symbol, ulong magicNumber);
bool DeleteAllSellLimits(string symbol, ulong magicNumber);
bool DeleteAllMagicOrders(ulong magicNumber);

//-- Pending Orders Status Monitoring Functions
int BuyStopOrdersTotal();
int BuyLimitOrdersTotal();
int SellStopOrdersTotal();
int SellLimitOrdersTotal();
double OrdersTotalVolume();
double BuyStopOrdersTotalVolume();
double BuyLimitOrdersTotalVolume();
double SellStopOrdersTotalVolume();
double SellLimitOrdersTotalVolume();

//-- Pending Orders Filtered By Magic Number Status Monitoring Functions
int MagicOrdersTotal(ulong magicNumber);
int MagicBuyStopOrdersTotal(ulong magicNumber);
int MagicBuyLimitOrdersTotal(ulong magicNumber);
int MagicSellStopOrdersTotal(ulong magicNumber);
int MagicSellLimitOrdersTotal(ulong magicNumber);
double MagicOrdersTotalVolume(ulong magicNumber);
double MagicBuyStopOrdersTotalVolume(ulong magicNumber);
double MagicBuyLimitOrdersTotalVolume(ulong magicNumber);
double MagicSellStopOrdersTotalVolume(ulong magicNumber);
double MagicSellLimitOrdersTotalVolume(ulong magicNumber);

//-- Pending Orders Filtered By Symbol and/or Magic Number Status Monitoring Functions
int SymbolOrdersTotal(string symbol, ulong magicNumber);
int SymbolBuyStopOrdersTotal(string symbol, ulong magicNumber);
int SymbolBuyLimitOrdersTotal(string symbol, ulong magicNumber);
int SymbolSellStopOrdersTotal(string symbol, ulong magicNumber);
int SymbolSellLimitOrdersTotal(string symbol, ulong magicNumber);
double SymbolOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolBuyStopOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolBuyLimitOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolSellStopOrdersTotalVolume(string symbol, ulong magicNumber);
double SymbolSellLimitOrdersTotalVolume(string symbol, ulong magicNumber);

//-- Log and Data Display Functions
string AccountOrdersStatus(bool formatForComment);
string MagicOrdersStatus(ulong magicNumber, bool formatForComment);
string SymbolOrdersStatus(string symbol, ulong magicNumber, bool formatForComment);

#import //--- Closing import directive
//+-------------------------------------------------------------------------------------+

.EX5ライブラリのプロトタイプ関数をMQL5プロジェクトまたはソースコードにインポートして、これらの関数をコードに実装して使用する方法について、以下の表に詳細なドキュメントと実用的な例を示します。

関数プロトタイプの説明 詳細 使用例
bool OpenBuyLimit(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


指定されたパラメータに一致する新規買い指値注文を出します。
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) - ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Buy Limit Order";
OpenBuyLimit(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool OpenBuyStop(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


指定されたパラメータに一致する新規買い逆指値注文を出します。
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) + ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Buy Stop Order";
OpenBuyStop(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool OpenSellLimit(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


指定されたパラメータに一致する新規売り指値注文を出します。
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) + ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Sell Limit Order";
OpenSellLimit(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool OpenSellStop(
   ulong magicNumber,
   string symbol,
   double entryPrice,
   double lotSize,
   int sl,
   int tp,
   string orderComment
);


指定されたパラメータに一致する新規売り逆指値注文を出します。
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
//---
ulong magicNo = 123;
string symbol = _Symbol;
double entryPrice = SymbolInfoDouble(
                       _Symbol, SYMBOL_ASK) - ((spread * 20) 
                       * symbolPoint
                    );
double lotSize = SymbolInfoDouble(symbol, SYMBOL_VOLUME_MIN);
int sl = spread * 50;  //-- pips
int tp = spread * 100; //-- pips
string orderComment = "Pending Orders Manager Sell Stop Order";
OpenSellStop(
   magicNumber, symbol, entryPrice, 
   lotSize, sl, tp, orderComment
);

bool ModifyPendingOrderByTicket(
   ulong orderTicket,
   double newEntryPrice,
   int newSl,
   int newTp
);

指定されたパラメータを使用して、未決注文を変更します。
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
int totalOpenOders = OrdersTotal();
for(int x = 0; x < totalOpenOders; x++)
  {
   ulong orderTicket = OrderGetTicket(x);
   if(orderTicket > 0)
     {
      //-- Modify a buy stop order
      if(OrderGetInteger(ORDER_TYPE) == ORDER_TYPE_BUY_STOP)
        {
         double newEntryPrice = OrderGetDouble(
                                   ORDER_PRICE_OPEN) + 
                                   ((spread * 40) * symbolPoint
                                );
         int newSl = 0; //-- Do not modify the stop loss level
         int newTp = 0; //-- Don not modify the take profit level
         ModifyPendingOrderByTicket(
            orderTicket, newEntryPrice, newSl, newTp
         );
         break;
        }
     }
  }

bool DeletePendingOrderByTicket(
   ulong orderTicket
);

指定されたチケット番号パラメータに基づいて、未決注文を削除します。
for(int x = 0; x < totalOpenOders; x++)
  {
   ulong orderTicket = OrderGetTicket(x);
   if(orderTicket > 0)
     {
      DeletePendingOrderByTicket(orderTicket);
      break;
     }
  }

bool DeleteAllPendingOrders(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

指定された銘柄名とマジックナンバーのパラメータに基づいて、すべての未決注文を削除します。
//Deletes all orders in the account
DeleteAllPendingOrders("", 0);

//Deletes all orders belonging to the symbol
DeleteAllPendingOrders(_Symbol, 0);

//Deletes all orders that have a magic number 101
DeleteAllPendingOrders("", 101);

//Deletes all EURUSD orders that have a magic number 101
DeleteAllPendingOrders("EURUSD", 101);

bool DeleteAllPendingOrders()

口座内の未決注文をすべて削除します。
//Deletes all orders in the account
DeleteAllPendingOrders();

bool DeleteAllBuyStops(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

指定された銘柄名とマジックナンバーのパラメータに基づいて、すべての買い逆指値注文を削除します。
//Deletes all buy stops in the account
DeleteAllBuyStops("", 0);

//Deletes all buy stops belonging to the symbol
DeleteAllBuyStops(_Symbol, 0);

//Deletes all buy stops that have a magic number 101
DeleteAllBuyStops("", 101);

//Deletes all EURUSD buy stops that have a magic number 101
DeleteAllBuyStops("EURUSD", 101);

bool DeleteAllBuyLimits(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

指定された銘柄名とマジックナンバーのパラメータに基づいて、すべての買い指値注文を削除します。
//Deletes all buy limits in the account
DeleteAllBuyLimits("", 0);

//Deletes all buy limits belonging to the symbol
DeleteAllBuyLimits(_Symbol, 0);

//Deletes all buy limits that have a magic number 101
DeleteAllBuyLimits("", 101);

//Deletes all GBPUSD buy limits that have a magic number 101
DeleteAllBuyLimits("GBPUSD", 101);

bool DeleteAllSellStops(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

指定された銘柄名とマジックナンバーのパラメータに基づいて、すべての売り逆指値注文を削除します。
//Deletes all sell stops in the account
DeleteAllSellStops("", 0);

//Deletes all sell stops belonging to the symbol
DeleteAllSellStops(_Symbol, 0);

//Deletes all sell stops that have a magic number 101
DeleteAllSellStops("", 101);

//Deletes all JPYUSD sell stops that have a magic number 101
DeleteAllSellStops("JPYUSD", 101);

bool DeleteAllSellLimits(
   string symbol = ALL_SYMBOLS,
   ulong magicNumber = 0
);

指定された銘柄名とマジックナンバーのパラメータに基づいて、すべての売り指値注文を削除します。
//Deletes all sell limits in the account
DeleteAllSellLimits("", 0);

//Deletes all sell limits belonging to the symbol
DeleteAllSellLimits(_Symbol, 0);

//Deletes all sell limits that have a magic number 101
DeleteAllSellLimits("", 101);

//Deletes all AUDJPY sell limits that have a magic number 101
DeleteAllSellLimits("AUDJPY", 101);


bool DeleteAllMagicOrders(
   ulong magicNumber
);

指定されたマジックナンバーパラメータに基づいて、すべての未決注文を削除します。
//-- Deletes all orders open in the account
DeleteAllMagicOrders("", 0);

//-- Deletes all orders that have a magic number 101
DeleteAllMagicOrders(101);

int BuyStopOrdersTotal();

未決済の買い逆指値注文の合計数を返します。
//Get the total number of open buy stops in the account
BuyStopOrdersTotal();


int BuyLimitOrdersTotal();

未決済の買い指値注文の合計数を返します。
//Get the total number of open buy limits in the account
BuyLimitOrdersTotal();


int SellStopOrdersTotal();

未決済の売り逆指値注文の合計数を返します。
//Get the total number of open sell stops in the account
SellStopOrdersTotal();


int SellLimitOrdersTotal();

未決済の売り指値注文の合計数を返します。
//Get the total number of open sell limits in the account
SellLimitOrdersTotal();


double OrdersTotalVolume();

すべての未決済注文の総数量を返します。
//Get the total volume/lot of open orders in the account
OrdersTotalVolume();


double BuyStopOrdersTotalVolume();

すべての買い逆指値注文の総数量を返します。
//Get the total volume/lot of open buy stops in the account
BuyStopOrdersTotalVolume();


double BuyLimitOrdersTotalVolume();

全ての買い指値注文の総数量を返します。
//Get the total volume/lot of open buy limits in the account
BuyLimitOrdersTotalVolume();


double SellStopOrdersTotalVolume();

すべての売り逆指値注文の総数量を返します。
//Get the total volume/lot of open sell stops in the account
SellStopOrdersTotalVolume();

double SellLimitOrdersTotalVolume();


すべての売り指値注文の総数量を返します。
//Get the total volume/lot of open sell limits in the account
SellLimitOrdersTotalVolume();

int MagicOrdersTotal(
   ulong magicNumber
);


指定されたマジックナンバーに一致する未決済注文の数を返します。
//Get the total open pending orders for magic number 101
MagicOrdersTotal(101);


int MagicBuyStopOrdersTotal(
   ulong magicNumber
);


指定されたマジックナンバーに一致する未決済の買い逆指値注文の数を返します。
//Get the total open buy stop orders for magic number 101
MagicBuyStopOrdersTotal(101);


int MagicBuyLimitOrdersTotal(
   ulong magicNumber
);


指定されたマジックナンバーに一致する未決済の買い指値注文の数を返します。
//Get the total open buy limit orders for magic number 101
MagicBuyLimitOrdersTotal(101);


int MagicSellStopOrdersTotal(
   ulong magicNumber
);


指定されたマジックナンバーに一致する売建逆指値注文の数を返します。
//Get the total open sell stop orders for magic number 101
MagicSellStopOrdersTotal(101);


int MagicSellLimitOrdersTotal(
   ulong magicNumber
);

指定されたマジックナンバーに一致する未決済の売り指値注文の数を返します。
//Get the total open sell limit orders for magic number 101
MagicSellLimitOrdersTotal(101);


double MagicOrdersTotalVolume(
   ulong magicNumber
);

指定されたマジックナンバーに一致するすべての未決済注文の総数量を返します。
//Get the total volume/lot of all open orders for magic 101
MagicOrdersTotalVolume(101);

double MagicBuyStopOrdersTotalVolume(
   ulong magicNumber
);


指定されたマジックナンバーに一致するすべての買い逆指値注文の総数量を返します。
//Get the total volume/lot of all buy stop orders for magic 101
MagicBuyStopOrdersTotalVolume(101);

double MagicBuyLimitOrdersTotalVolume(
   ulong magicNumber
);


指定されたマジックナンバーに一致するすべての未決済買い指値注文の総数量を返します。
//Get the total volume/lot of all buy limit orders for magic 101
MagicBuyLimitOrdersTotalVolume(101);

double MagicSellStopOrdersTotalVolume(
   ulong magicNumber
);


指定されたマジックナンバーに一致するすべての売り逆指値注文の総数量を返します。
//Get the total volume/lot of all sell stop orders for magic 101
MagicSellStopOrdersTotalVolume(101);

double MagicSellLimitOrdersTotalVolume(
   ulong magicNumber
);


指定されたマジックナンバーに一致するすべての未決済の売り指値注文の総数量を返します。
//Get the total volume/lot of all sell limit orders for magic 101
MagicSellLimitOrdersTotalVolume(101);

int SymbolOrdersTotal(
   string symbol,
   ulong magicNumber
);

指定された銘柄とマジックナンバーに一致する未決済注文の数を返します。
//Get the total open orders for the symbol
SymbolOrdersTotal(_Symbol, 0);

//Get the total open orders for the symbol and magic 101
SymbolOrdersTotal(_Symbol, 101);


int SymbolBuyStopOrdersTotal(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致する買いの逆指値注文の数を返します。
//Get the total buy stop orders for the symbol
SymbolBuyStopOrdersTotal(_Symbol, 0);

//Get the total buy stop orders for the symbol and magic number 101
SymbolBuyStopOrdersTotal(_Symbol, 101);


int SymbolBuyLimitOrdersTotal(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致する未決済の買い指値注文の数を返します。
//Get the total buy limit orders for the symbol
SymbolBuyLimitOrdersTotal(_Symbol, 0);

//Get the total buy limit orders for the symbol and magic number 101
SymbolBuyLimitOrdersTotal(_Symbol, 101);


int SymbolSellStopOrdersTotal(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致する売建逆指値注文の数を返します。
//Get the total sell stop orders for the symbol
SymbolSellStopOrdersTotal(_Symbol, 0);

//Get the total sell stop orders for the symbol and magic 101
SymbolSellStopOrdersTotal(_Symbol, 101);


int SymbolSellLimitOrdersTotal(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致する売り指値注文の未決済注文数を返します。
//Get the total sell limit orders for the symbol
SymbolSellLimitOrdersTotal(_Symbol, 0);

//Get the total sell limit orders for the symbol and magic 101
SymbolSellLimitOrdersTotal(_Symbol, 101);


double SymbolOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致するすべての未決済注文の総数量を返します。
//Get the total orders volume/lot for the symbol
SymbolOrdersTotalVolume(_Symbol, 0);

//Get the total orders volume/lot for the symbol and magic 101
SymbolOrdersTotalVolume(_Symbol, 101);


double SymbolBuyStopOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);

指定された銘柄とマジックナンバーに一致するすべての買い逆指値注文の総数量を返します。
//Get the total buy stops volume/lot for the symbol
SymbolBuyStopOrdersTotalVolume(_Symbol, 0);

//Get the total buy stops volume/lot for the symbol and magic 101
SymbolBuyStopOrdersTotalVolume(_Symbol, 101);

double SymbolBuyLimitOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致するすべての未決済の買い指値注文の総数量を返します。
//Get the total buy limits volume/lot for the symbol
SymbolBuyLimitOrdersTotalVolume(_Symbol, 0);

//Get the total buy limits volume/lot for symbol and magic 101
SymbolBuyLimitOrdersTotalVolume(_Symbol, 101);

double SymbolSellStopOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致するすべての売り逆指値注文の総数量を返します。
//Get the total sell stops volume/lot for symbol
SymbolSellStopOrdersTotalVolume(_Symbol, 0);

//Get the total sell stops volume/lot for symbol and magic 101
SymbolSellStopOrdersTotalVolume(_Symbol, 101);

double SymbolSellLimitOrdersTotalVolume(
   string symbol,
   ulong magicNumber
);


指定された銘柄とマジックナンバーに一致するすべての未決済の売り指値注文の総数量を返します。
//Get the total sell limits volume/lot for symbol
SymbolSellLimitOrdersTotalVolume(_Symbol, 0);

//Get the total sell limits volume/lot for symbol and magic 101
SymbolSellLimitOrdersTotalVolume(_Symbol, 101);

string AccountOrdersStatus(
   bool formatForComment
);


MetaTrader 5の銘柄チャートまたは[Experts]タブ上のすべての未決済注文の状態を文字列形式で表示します。
//Print the status of all open orders 
//formatted for the chart comments
Comment(AccountOrdersStatus(true));

//Print the status of all open orders 
//formatted for the Experts tab
Print(AccountOrdersStatus(false));

//Activate an alert with the status of all 
//open orders formatted for printing
Print(AccountOrdersStatus(false));


string MagicOrdersStatus(
   ulong magicNumber,
   bool formatForComment
);


MetaTrader 5の銘柄チャートまたは[Experts]タブに、指定されたマジックナンバーに一致するすべての未決済注文の状況を文字列形式で表示します。
//Print the status of all open orders matching 
//magic number 101 formatted for the chart comments
Comment(MagicOrdersStatus(101, true));

//Print the status of all open orders matching
//magic number 101 formatted for the Experts tab
Print(MagicOrdersStatus(101, false));

//Activate an alert with the status of all open orders
//matching magic number 101 formatted for printing
Print(MagicOrdersStatus(101, false));


 
string SymbolOrdersStatus(
   string symbol,
   ulong magicNumber,
   bool formatForComment
);

MetaTrader 5の銘柄チャートまたは[Experts]タブに、指定された銘柄とマジックナンバーに一致するすべての未決済注文の状況を文字列形式で表示します。  
//Print the status of all open orders matching
//the symbol and magic number 101 formatted for the chart comments
Comment(SymbolOrdersStatus(_Symbol, 101, true));

//Print the status of all open orders matching
//the symbol and magic number 101 formatted for the Experts tab
Print(SymbolOrdersStatus(_Symbol, 101, false));

//Activate an alert with the status of all open orders
//matching the symbol and magic number 101 formatted for printing
Print(SymbolOrdersStatus(_Symbol, 101, false));

ライブラリをインポートすれば、簡単な関数呼び出しで、未決注文ステータスデータを簡単に開いたり、変更したり、削除したり、取得したりできるようになります。これを実証するために、次のセクションでは、未決注文を管理するための実用的なグラフィカルユーザーインターフェイス(GUI)取引パネルを作成してみましょう。


未決注文パネル(GUI)の開発方法(Pending Orders Manager EX5ライブラリを使用)

このセクションでは、Pending Orders Manager EX5ライブラリを使用して、パネルに関連付けられた指定のマジックナンバーに関連付けられたすべての注文をオープン、削除、および監視する、Pending Orders Panel EA用のグラフィカルユーザーインターフェイス(GUI)を開発します。この例では、作成したEX5ライブラリを実際のMQL5アプリケーションにインポートして実装する方法を実践的に示します。

未決注文パネルは、パネルとダイアログにMQL5標準ライブラリを活用し、コードベースを最小限に抑え、効率的にします。以下は、最終的な注文待ちパネルGUIの図です。

MQL5未決注文パネル(GUI)

GUIの構築を開始するには、MetaEditor IDEのMQLウィザードを使用して新しいEAを作成し、PendingOrdersPanel.mq5という名前を付けます。Pending Orders Panel EAはPendingOrdersManager.ex5ライブラリを統合するので、最初のステップは、先に説明したように、ライブラリの関数プロトタイプの説明をインポートしてインクルードすることです。ライブラリのインポートコードを#propertyディレクティブのすぐ下に置く。ライブラリには多数の関数が含まれているため、必要な特定の関数のプロトタイプのみをインポートします。

#import "Toolkit/PendingOrdersManager.ex5" //-- Opening import directive
//-- Function descriptions for the imported function prototypes

//-- Pending Orders Execution and Modification Functions
bool OpenBuyLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenBuyStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellLimit(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
bool OpenSellStop(ulong magicNumber, string symbol, double entryPrice, double lotSize, int sl, int tp, string orderComment);
//--
int MagicOrdersTotal(ulong magicNumber);
int MagicBuyStopOrdersTotal(ulong magicNumber);
int MagicBuyLimitOrdersTotal(ulong magicNumber);
int MagicSellStopOrdersTotal(ulong magicNumber);
int MagicSellLimitOrdersTotal(ulong magicNumber);
//--
bool DeleteAllBuyStops(string symbol, ulong magicNumber);
bool DeleteAllBuyLimits(string symbol, ulong magicNumber);
bool DeleteAllSellStops(string symbol, ulong magicNumber);
bool DeleteAllSellLimits(string symbol, ulong magicNumber);
bool DeleteAllMagicOrders(ulong magicNumber);

#import //--- Closing import directive

注文のプロパティを格納するために使用するグローバル変数を作成します。

//-- Global variables
//-----------------------
ulong magicNo = 10101010;
double symbolPoint = SymbolInfoDouble(_Symbol, SYMBOL_POINT);
long symbolDigits = SymbolInfoInteger(_Symbol, SYMBOL_DIGITS);
int spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);
double volumeLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
int sl = (int)spread * 50;
int tp = (int)spread * 100;

次に、すべてのグラフィカルオブジェクトのプロパティを格納するために、いくつかの定数を定義する必要があります。これによって、注文パネルの外観を変更したい場合、一元的に値を更新したり修正したりすることが容易になります。

//-- Define some values for the main panel
#define MAIN_PANEL_NAME string("Orders Panel - Trading: " + _Symbol + " - Magic No: " + IntegerToString(magicNo))
#define MAIN_PANEL_SUBWINDOW 0
#define MAIN_PANEL_X1 350
#define MAIN_PANEL_Y1 10
#define MAIN_PANEL_WIDTH int(800 + MAIN_PANEL_X1)
#define MAIN_PANEL_X2 MAIN_PANEL_WIDTH

//-- Define the GUI objects general properties
#define GUI_OBJECTS_MARGIN 5
#define GUI_OBJECTS_HEIGHT 40//40
#define GUI_OBJECTS_WIDTH int((MAIN_PANEL_WIDTH) / 7)
#define GUI_OBJECTS_FONT_SIZE 9//10
#define GUI_OBJECTS_HEADER_FONT_SIZE GUI_OBJECTS_FONT_SIZE
//-----
#define MAIN_PANEL_HEIGHT int(((GUI_OBJECTS_HEIGHT + (GUI_OBJECTS_MARGIN * 2)) * 10) + MAIN_PANEL_Y1)
#define MAIN_PANEL_Y2 MAIN_PANEL_HEIGHT

//-- Define the GUI objects colors
#define GUI_OBJECTS_HEADING_COLOR clrNavy

#define GUI_OBJECTS_BUY_BTN_COLOR clrWhite
#define GUI_OBJECTS_BUY_BTN_BG_COLOR clrBlue
#define GUI_OBJECTS_BUY_EDIT_COLOR clrBlue
#define GUI_OBJECTS_BUY_EDIT_BG_COLOR clrAliceBlue

#define GUI_OBJECTS_SELL_BTN_COLOR clrWhite
#define GUI_OBJECTS_SELL_BTN_BG_COLOR clrCrimson
#define GUI_OBJECTS_SELL_EDIT_COLOR clrMaroon
#define GUI_OBJECTS_SELL_EDIT_BG_COLOR clrMistyRose

/*------------------------------------------------------
* Define GUI components for the heading labels ****
*-----------------------------------------------------*/
//-- Define values for the lotVolHeaderLabel
#define VOLUME_LOT_LABEL_NAME "Volume Lot Header Label"
#define VOLUME_LOT_LABEL_SUBWINDOW 0
#define VOLUME_LOT_LABEL_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define VOLUME_LOT_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define VOLUME_LOT_LABEL_TEXT "VOLUME/LOT"


//-- Define values for the openPriceHeaderLabel
#define OPEN_PRICE_LABEL_NAME "Open Price Header Label"
#define OPEN_PRICE_LABEL_SUBWINDOW 0
#define OPEN_PRICE_LABEL_X1 (int(GUI_OBJECTS_WIDTH) * 2)
#define OPEN_PRICE_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define OPEN_PRICE_LABEL_TEXT "OPENING PRICE"

//-- Define values for the slHeaderLabel
#define SL_LABEL_NAME "Sl Header Label"
#define SL_LABEL_SUBWINDOW 0
#define SL_LABEL_X1 (int(GUI_OBJECTS_WIDTH) * 3)
#define SL_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define SL_LABEL_TEXT "SL (Pips)"

//-- Define values for the tpHeaderLabel
#define TP_LABEL_NAME "Tp Header Label"
#define TP_LABEL_SUBWINDOW 0
#define TP_LABEL_X1 (int(GUI_OBJECTS_WIDTH) * 3.75)
#define TP_LABEL_Y1 int(GUI_OBJECTS_MARGIN * 2)
#define TP_LABEL_TEXT "TP (Pips)"

/*------------------------------------------------------
* Define Buy Stop Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the buyStopBtn
#define BUY_STOP_BTN_NAME "Buy Stop Button"
#define BUY_STOP_BTN_SUBWINDOW 0
#define BUY_STOP_BTN_X1 GUI_OBJECTS_MARGIN
#define BUY_STOP_BTN_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)
#define BUY_STOP_BTN_TEXT "BUY STOP"

//-- Define values for the buyStopVolumeLotEdit
#define BUY_STOP_VOLUME_LOT_EDIT_NAME "Buy Stop Volume Lot Edit"
#define BUY_STOP_VOLUME_LOT_EDIT_SUBWINDOW 0
#define BUY_STOP_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define BUY_STOP_VOLUME_LOT_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

//-- Define values for the buyStopOpenPriceEdit
#define BUY_STOP_OPEN_PRICE_EDIT_NAME "Buy Stop Open Price Edit"
#define BUY_STOP_OPEN_PRICE_EDIT_SUBWINDOW 0
#define BUY_STOP_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define BUY_STOP_OPEN_PRICE_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

//-- Define values for the buyStopSlEdit
#define BUY_STOP_SL_EDIT_NAME "Buy Stop SL Edit"
#define BUY_STOP_SL_EDIT_SUBWINDOW 0
#define BUY_STOP_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define BUY_STOP_SL_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

//-- Define values for the buyStopTpEdit
#define BUY_STOP_TP_EDIT_NAME "Buy Stop TP Edit"
#define BUY_STOP_TP_EDIT_SUBWINDOW 0
#define BUY_STOP_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define BUY_STOP_TP_EDIT_Y1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT)

/*------------------------------------------------------
* Define Sell Stop Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the sellStopBtn
#define SELL_STOP_BTN_NAME "Sell Stop Button"
#define SELL_STOP_BTN_SUBWINDOW 0
#define SELL_STOP_BTN_X1 GUI_OBJECTS_MARGIN
#define SELL_STOP_BTN_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)
#define SELL_STOP_BTN_TEXT "SELL STOP"

//-- Define values for the sellStopVolumeLotEdit
#define SELL_STOP_VOLUME_LOT_EDIT_NAME "Sell Stop Volume Lot Edit"
#define SELL_STOP_VOLUME_LOT_EDIT_SUBWINDOW 0
#define SELL_STOP_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define SELL_STOP_VOLUME_LOT_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

//-- Define values for the sellStopOpenPriceEdit
#define SELL_STOP_OPEN_PRICE_EDIT_NAME "Sell Stop Open Price Edit"
#define SELL_STOP_OPEN_PRICE_EDIT_SUBWINDOW 0
#define SELL_STOP_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define SELL_STOP_OPEN_PRICE_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

//-- Define values for the sellStopSlEdit
#define SELL_STOP_SL_EDIT_NAME "Sell Stop SL Edit"
#define SELL_STOP_SL_EDIT_SUBWINDOW 0
#define SELL_STOP_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define SELL_STOP_SL_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

//-- Define values for the sellStopTpEdit
#define SELL_STOP_TP_EDIT_NAME "Sell Stop TP Edit"
#define SELL_STOP_TP_EDIT_SUBWINDOW 0
#define SELL_STOP_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define SELL_STOP_TP_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 2)

/*------------------------------------------------------
* Define Buy Limit Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the buyLimitBtn
#define BUY_LIMIT_BTN_NAME "Buy Limit Button"
#define BUY_LIMIT_BTN_SUBWINDOW 0
#define BUY_LIMIT_BTN_X1 GUI_OBJECTS_MARGIN
#define BUY_LIMIT_BTN_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)
#define BUY_LIMIT_BTN_TEXT "BUY LIMIT"

//-- Define values for the buyLimitVolumeLotEdit
#define BUY_LIMIT_VOLUME_LOT_EDIT_NAME "Buy Limit Volume Lot Edit"
#define BUY_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW 0
#define BUY_LIMIT_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define BUY_LIMIT_VOLUME_LOT_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

//-- Define values for the buySLimitOpenPriceEdit
#define BUY_LIMIT_OPEN_PRICE_EDIT_NAME "Buy Limit Open Price Edit"
#define BUY_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW 0
#define BUY_LIMIT_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define BUY_LIMIT_OPEN_PRICE_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

//-- Define values for the buyLimitSlEdit
#define BUY_LIMIT_SL_EDIT_NAME "Buy Limit SL Edit"
#define BUY_LIMIT_SL_EDIT_SUBWINDOW 0
#define BUY_LIMIT_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define BUY_LIMIT_SL_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

//-- Define values for the buyLimitTpEdit
#define BUY_LIMIT_TP_EDIT_NAME "Buy Limit TP Edit"
#define BUY_LIMIT_TP_EDIT_SUBWINDOW 0
#define BUY_LIMIT_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define BUY_LIMIT_TP_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 3)

/*------------------------------------------------------
* Define Sell Limit Order GUI components ****
*-----------------------------------------------------*/
//-- Define values for the sellLimitBtn
#define SELL_LIMIT_BTN_NAME "Sell Limit Button"
#define SELL_LIMIT_BTN_SUBWINDOW 0
#define SELL_LIMIT_BTN_X1 GUI_OBJECTS_MARGIN
#define SELL_LIMIT_BTN_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)
#define SELL_LIMIT_BTN_TEXT "SELL LIMIT"

//-- Define values for the sellLimitVolumeLotEdit
#define SELL_LIMIT_VOLUME_LOT_EDIT_NAME "Sell Limit Volume Lot Edit"
#define SELL_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW 0
#define SELL_LIMIT_VOLUME_LOT_EDIT_X1 int(GUI_OBJECTS_MARGIN + GUI_OBJECTS_WIDTH)
#define SELL_LIMIT_VOLUME_LOT_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

//-- Define values for the sellLimitOpenPriceEdit
#define SELL_LIMIT_OPEN_PRICE_EDIT_NAME "Sell Limit Open Price Edit"
#define SELL_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW 0
#define SELL_LIMIT_OPEN_PRICE_EDIT_X1 int((GUI_OBJECTS_WIDTH) * 2)
#define SELL_LIMIT_OPEN_PRICE_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

//-- Define values for the sellLimitSlEdit
#define SELL_LIMIT_SL_EDIT_NAME "Sell Limit SL Edit"
#define SELL_LIMIT_SL_EDIT_SUBWINDOW 0
#define SELL_LIMIT_SL_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3)
#define SELL_LIMIT_SL_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

//-- Define values for the sellLimitTpEdit
#define SELL_LIMIT_TP_EDIT_NAME "Sell Limit TP Edit"
#define SELL_LIMIT_TP_EDIT_SUBWINDOW 0
#define SELL_LIMIT_TP_EDIT_X1 int(GUI_OBJECTS_WIDTH * 3.7)
#define SELL_LIMIT_TP_EDIT_Y1 int((GUI_OBJECTS_MARGIN + GUI_OBJECTS_HEIGHT) * 4)

/*------------------------------------------------------
* Define Order Status GUI components ****
*-----------------------------------------------------*/
//-- Define values for the orders status
#define STATUS_HEADER_FONT_SIZE int(GUI_OBJECTS_FONT_SIZE)// / 1.1)
#define STATUS_EDIT_FONT_SIZE int(GUI_OBJECTS_FONT_SIZE)// / 1.1)
#define STATUS_EDIT_WIDTH int((MAIN_PANEL_WIDTH / 1.485) - (GUI_OBJECTS_MARGIN * 2))
#define STATUS_EDIT_COLOR clrBlack
#define STATUS_EDIT_BG_COLOR clrLemonChiffon
#define STATUS_EDIT_BORDER_COLOR clrMidnightBlue
#define DELETE_ORDERS_BTN_COLOR clrLightYellow
#define DELETE_BUY_ORDERS_BTN_BG_COLOR clrRoyalBlue
#define DELETE_SELL_ORDERS_BTN_BG_COLOR clrCrimson
#define DELETE_ALL_ORDERS_BTN_BG_COLOR clrMediumVioletRed
#define DELETE_ORDERS_BTN_BORDER_COLOR clrBlack
#define DELETE_ORDERS_BTN_WIDTH int((STATUS_EDIT_WIDTH / 1.93) - (GUI_OBJECTS_MARGIN * 3))
#define DELETE_ORDERS_BTN_FONT_SIZE int((GUI_OBJECTS_FONT_SIZE))// / 1.05)

//-- Define values for the magicOrderStatusLabel
#define MAGIC_ORDER_STATUS_LABEL_NAME "Magic Order Status Label"
#define MAGIC_ORDER_STATUS_LABEL_SUBWINDOW 0
#define MAGIC_ORDER_STATUS_LABEL_X1 int(GUI_OBJECTS_MARGIN * 3)
#define MAGIC_ORDER_STATUS_LABEL_Y1 int((GUI_OBJECTS_HEIGHT * 6) + (GUI_OBJECTS_MARGIN * 2))
#define MAGIC_ORDER_STATUS_LABEL_TEXT string("MAGIC No: " + IntegerToString(magicNo) + " - TOTAL OPEN ORDERS: ")

//-- Define values for the magicOrdersStatusEdit
#define MAGIC_ORDER_STATUS_EDIT_NAME "Magic Order Status Edit"
#define MAGIC_ORDER_STATUS_EDIT_SUBWINDOW 0
#define MAGIC_ORDER_STATUS_EDIT_X1 int(GUI_OBJECTS_MARGIN * 2)
#define MAGIC_ORDER_STATUS_EDIT_Y1 int((MAGIC_ORDER_STATUS_LABEL_Y1) + (GUI_OBJECTS_HEIGHT / 1.7))

//-- Define values for the deleteAllMagicBuyStopsBtn
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_NAME "Delete All Magic Buy Stops Btn"
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_X1 int(GUI_OBJECTS_MARGIN * 2)
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_Y1 int((MAGIC_ORDER_STATUS_EDIT_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_BUY_STOPS_BTN_TEXT "DELETE ALL MAGIC BUY STOPS"

//-- Define values for the deleteAllMagicSellStopsBtn
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_NAME "Delete All Magic Sell Stops Btn"
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_X1 int((GUI_OBJECTS_MARGIN * 3) + DELETE_ORDERS_BTN_WIDTH)
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_Y1 int((MAGIC_ORDER_STATUS_EDIT_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_SELL_STOPS_BTN_TEXT "DELETE ALL MAGIC SELL STOPS"

//-- Define values for the deleteAllMagicBuyLimitsBtn
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_NAME "Delete All Magic Buy Limits Btn"
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_X1 int(GUI_OBJECTS_MARGIN * 2)
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1 int((DELETE_ALL_MAGIC_BUY_STOPS_BTN_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_BUY_LIMITS_BTN_TEXT "DELETE ALL MAGIC BUY LIMITS"

//-- Define values for the deleteAllMagicSellLimitsBtn
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_NAME "Delete All Magic Sell Limits Btn"
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_X1 int((GUI_OBJECTS_MARGIN * 3) + DELETE_ORDERS_BTN_WIDTH)
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_Y1 DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1//int((MAGIC_ORDER_STATUS_EDIT_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_SELL_LIMITS_BTN_TEXT "DELETE ALL MAGIC SELL LIMITS"

//-- Define values for the deleteAllMagicOrdersBtn
#define DELETE_ALL_MAGIC_ORDERS_BTN_NAME "Delete All Magic Orders Btn"
#define DELETE_ALL_MAGIC_ORDERS_BTN_SUBWINDOW 0
#define DELETE_ALL_MAGIC_ORDERS_BTN_X1 int(GUI_OBJECTS_MARGIN * 2)
#define DELETE_ALL_MAGIC_ORDERS_BTN_Y1 int((DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1) + (GUI_OBJECTS_HEIGHT + GUI_OBJECTS_MARGIN))
#define DELETE_ALL_MAGIC_ORDERS_BTN_TEXT "DELETE ALL MAGIC PENDING ORDERS"

パネルとダイアログ用のMQL5標準クラスをコードに追加または含めます。

//-- Include the MQL5 standard library for panels and dialogs
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Label.mqh>
#include <Controls\Edit.mqh>

パネルクラスとダイアログクラスがファイルに含まれ、利用できるようになったので、コード内でそれらの機能を拡張するためにオブジェクトを作成することができます。

//-- Create objects for the included standard classes
CAppDialog mainPanelWindow;

//-- Create the header label components
CLabel lotVolHeaderLabel;
CLabel openPriceHeaderLabel;
CLabel slHeaderLabel;
CLabel tpHeaderLabel;

//-- Create the buy stop GUI components
//--BuyStopBtn
CButton buyStopBtn;
//--BuyStopEdits
CEdit buyStopVolumeLotEdit;
CEdit buyStopOpenPriceEdit;
CEdit buyStopSlEdit;
CEdit buyStopTpEdit;

//-- Create the sell stop GUI components
//--SellStopBtn
CButton sellStopBtn;
//--sellStopEdits
CEdit sellStopVolumeLotEdit;
CEdit sellStopOpenPriceEdit;
CEdit sellStopSlEdit;
CEdit sellStopTpEdit;

//-- Create the buy limit GUI components
//--BuyLimitBtn
CButton buyLimitBtn;
//--BuyLimitEdits
CEdit buyLimitVolumeLotEdit;
CEdit buyLimitOpenPriceEdit;
CEdit buyLimitSlEdit;
CEdit buyLimitTpEdit;

//-- Create the sell limit GUI components
//--sellLimitBtn
CButton sellLimitBtn;
//--sellLimitEdits
CEdit sellLimitVolumeLotEdit;
CEdit sellLimitOpenPriceEdit;
CEdit sellLimitSlEdit;
CEdit sellLimitTpEdit;

//-- Create the order status GUI components
//--magic order status
CLabel magicOrderStatusLabel;
CEdit magicOrdersStatusEdit;
//--Magic orders delete buttons
CButton deleteAllMagicBuyStopsBtn;
CButton deleteAllMagicSellStopsBtn;
CButton deleteAllMagicBuyLimitsBtn;
CButton deleteAllMagicSellLimitsBtn;
CButton deleteAllMagicOrdersBtn;

注文入力価格を格納する変数と、EAが開いたすべての注文の注文ステータスを格納する文字列を作成します。

//-- Default starting entry prices for different pending orders
double buyStopEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) + ((spread * 20) * symbolPoint);
double buyLimitEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - ((spread * 20) * symbolPoint);
double sellStopEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) - ((spread * 20) * symbolPoint);
double sellLimitEntryPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK) + ((spread * 20) * symbolPoint);

//-- String values for the orders status
string magicOrderStatus;

コードの先頭セクションが完了したので、次のステップは、EAの初期化中にグラフィカルユーザーインターフェイスを生成してロードする関数を作成することです。この関数をCreateGui()と呼ぶことにします。

void CreateGui()
  {
//-- Create the orders panel
   mainPanelWindow.Create(
      0, MAIN_PANEL_NAME, MAIN_PANEL_SUBWINDOW,
      MAIN_PANEL_X1, MAIN_PANEL_Y1, MAIN_PANEL_X2, MAIN_PANEL_Y2
   );
   /*------------------------------------------------------
   * Header Labels GUI components creation ****
   *-----------------------------------------------------*/
//--Create the lot volume header label
   lotVolHeaderLabel.Create(
      0, VOLUME_LOT_LABEL_NAME, VOLUME_LOT_LABEL_SUBWINDOW,
      VOLUME_LOT_LABEL_X1,
      VOLUME_LOT_LABEL_Y1,
      GUI_OBJECTS_WIDTH,
      GUI_OBJECTS_HEIGHT
   );
   lotVolHeaderLabel.Text(VOLUME_LOT_LABEL_TEXT);
   lotVolHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   lotVolHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(lotVolHeaderLabel);

//--Create the open price header label
   openPriceHeaderLabel.Create(
      0, OPEN_PRICE_LABEL_NAME, OPEN_PRICE_LABEL_SUBWINDOW,
      OPEN_PRICE_LABEL_X1, OPEN_PRICE_LABEL_Y1,
      GUI_OBJECTS_WIDTH, GUI_OBJECTS_HEIGHT
   );
   openPriceHeaderLabel.Text(OPEN_PRICE_LABEL_TEXT);
   openPriceHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   openPriceHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(openPriceHeaderLabel);

//--Create the sl header label
   slHeaderLabel.Create(
      0, SL_LABEL_NAME, SL_LABEL_SUBWINDOW,
      SL_LABEL_X1, SL_LABEL_Y1,
      int(GUI_OBJECTS_WIDTH / 1.4), GUI_OBJECTS_HEIGHT
   );
   slHeaderLabel.Text(SL_LABEL_TEXT);
   slHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   slHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(slHeaderLabel);

//--Create the tp header label
   tpHeaderLabel.Create(
      0, TP_LABEL_NAME, TP_LABEL_SUBWINDOW,
      TP_LABEL_X1, TP_LABEL_Y1,
      int(GUI_OBJECTS_WIDTH / 1.4), GUI_OBJECTS_HEIGHT
   );
   tpHeaderLabel.Text(TP_LABEL_TEXT);
   tpHeaderLabel.Color(GUI_OBJECTS_HEADING_COLOR);
   tpHeaderLabel.FontSize(GUI_OBJECTS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(tpHeaderLabel);

   /*------------------------------------------------------
   * Buy Stop Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open buy stop button
   buyStopBtn.Create(
      0, BUY_STOP_BTN_NAME, BUY_STOP_BTN_SUBWINDOW,
      BUY_STOP_BTN_X1, BUY_STOP_BTN_Y1,
      0, 0
   );
   buyStopBtn.Text(BUY_STOP_BTN_TEXT);
   buyStopBtn.Width(GUI_OBJECTS_WIDTH);
   buyStopBtn.Height(GUI_OBJECTS_HEIGHT);
   buyStopBtn.Color(GUI_OBJECTS_BUY_BTN_COLOR);
   buyStopBtn.ColorBackground(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   buyStopBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(buyStopBtn);

//--Create the buy stop volume lot edit to get the buy stop volume/lot user input
   buyStopVolumeLotEdit.Create(
      0, BUY_STOP_VOLUME_LOT_EDIT_NAME, BUY_STOP_VOLUME_LOT_EDIT_SUBWINDOW,
      BUY_STOP_VOLUME_LOT_EDIT_X1, BUY_STOP_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   buyStopVolumeLotEdit.Text(DoubleToString(volumeLot));
   buyStopVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   buyStopVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopVolumeLotEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopVolumeLotEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopVolumeLotEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopVolumeLotEdit);

//--Create the buy stop price edit to get the buy stop opening price user input
   buyStopOpenPriceEdit.Create(
      0, BUY_STOP_OPEN_PRICE_EDIT_NAME, BUY_STOP_OPEN_PRICE_EDIT_SUBWINDOW,
      BUY_STOP_OPEN_PRICE_EDIT_X1, BUY_STOP_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   buyStopOpenPriceEdit.Text(DoubleToString(buyStopEntryPrice, int(symbolDigits)));
   buyStopOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   buyStopOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopOpenPriceEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopOpenPriceEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopOpenPriceEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopOpenPriceEdit);

//--Create the buy stop sl edit to get the buy stop sl user input
   buyStopSlEdit.Create(
      0, BUY_STOP_SL_EDIT_NAME, BUY_STOP_SL_EDIT_SUBWINDOW,
      BUY_STOP_SL_EDIT_X1, BUY_STOP_SL_EDIT_Y1,
      0, 0
   );
   buyStopSlEdit.Text(IntegerToString(sl));
   buyStopSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   buyStopSlEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopSlEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopSlEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopSlEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopSlEdit);

//--Create the buy stop tp edit to get the buy stop tp user input
   buyStopTpEdit.Create(
      0, BUY_STOP_TP_EDIT_NAME, BUY_STOP_TP_EDIT_SUBWINDOW,
      BUY_STOP_TP_EDIT_X1, BUY_STOP_TP_EDIT_Y1,
      0, 0
   );
   buyStopTpEdit.Text(IntegerToString(tp));
   buyStopTpEdit.Width(GUI_OBJECTS_WIDTH);
   buyStopTpEdit.Height(GUI_OBJECTS_HEIGHT);
   buyStopTpEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyStopTpEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyStopTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyStopTpEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyStopTpEdit);

   /*------------------------------------------------------
   * Sell Stop Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open sell stop button
   sellStopBtn.Create(
      0, SELL_STOP_BTN_NAME, SELL_STOP_BTN_SUBWINDOW,
      SELL_STOP_BTN_X1, SELL_STOP_BTN_Y1,
      0, 0
   );
   sellStopBtn.Text(SELL_STOP_BTN_TEXT);
   sellStopBtn.Width(GUI_OBJECTS_WIDTH);
   sellStopBtn.Height(GUI_OBJECTS_HEIGHT);
   sellStopBtn.Color(GUI_OBJECTS_SELL_BTN_COLOR);
   sellStopBtn.ColorBackground(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   sellStopBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(sellStopBtn);

//--Create the sell stop volume lot edit to get the sell stop volume/lot user input
   sellStopVolumeLotEdit.Create(
      0, SELL_STOP_VOLUME_LOT_EDIT_NAME, SELL_STOP_VOLUME_LOT_EDIT_SUBWINDOW,
      SELL_STOP_VOLUME_LOT_EDIT_X1, SELL_STOP_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   sellStopVolumeLotEdit.Text(DoubleToString(volumeLot));
   sellStopVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   sellStopVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopVolumeLotEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopVolumeLotEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopVolumeLotEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopVolumeLotEdit);

//--Create the sell stop price edit to get the sell stop opening price user input
   sellStopOpenPriceEdit.Create(
      0, SELL_STOP_OPEN_PRICE_EDIT_NAME, SELL_STOP_OPEN_PRICE_EDIT_SUBWINDOW,
      SELL_STOP_OPEN_PRICE_EDIT_X1, SELL_STOP_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   sellStopOpenPriceEdit.Text(DoubleToString(sellStopEntryPrice, int(symbolDigits)));
   sellStopOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   sellStopOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopOpenPriceEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopOpenPriceEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopOpenPriceEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopOpenPriceEdit);

//--Create the sell stop sl edit to get the sell stop sl user input
   sellStopSlEdit.Create(
      0, SELL_STOP_SL_EDIT_NAME, SELL_STOP_SL_EDIT_SUBWINDOW,
      SELL_STOP_SL_EDIT_X1, SELL_STOP_SL_EDIT_Y1,
      0, 0
   );
   sellStopSlEdit.Text(IntegerToString(sl));
   sellStopSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   sellStopSlEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopSlEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopSlEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopSlEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopSlEdit);

//--Create the sell stop tp edit to get the sell stop tp user input
   sellStopTpEdit.Create(
      0, SELL_STOP_TP_EDIT_NAME, SELL_STOP_TP_EDIT_SUBWINDOW,
      SELL_STOP_TP_EDIT_X1, SELL_STOP_TP_EDIT_Y1,
      0, 0
   );
   sellStopTpEdit.Text(IntegerToString(tp));
   sellStopTpEdit.Width(GUI_OBJECTS_WIDTH);
   sellStopTpEdit.Height(GUI_OBJECTS_HEIGHT);
   sellStopTpEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellStopTpEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellStopTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellStopTpEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellStopTpEdit);

   /*------------------------------------------------------
   * Buy Limit Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open buy limit button
   buyLimitBtn.Create(
      0, BUY_LIMIT_BTN_NAME, BUY_LIMIT_BTN_SUBWINDOW,
      BUY_LIMIT_BTN_X1, BUY_LIMIT_BTN_Y1,
      0, 0
   );
   buyLimitBtn.Text(BUY_LIMIT_BTN_TEXT);
   buyLimitBtn.Width(GUI_OBJECTS_WIDTH);
   buyLimitBtn.Height(GUI_OBJECTS_HEIGHT);
   buyLimitBtn.Color(GUI_OBJECTS_BUY_BTN_COLOR);
   buyLimitBtn.ColorBackground(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   buyLimitBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(buyLimitBtn);

//--Create the buy limit volume lot edit to get the buy limit volume/lot user input
   buyLimitVolumeLotEdit.Create(
      0, BUY_LIMIT_VOLUME_LOT_EDIT_NAME, BUY_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW,
      BUY_LIMIT_VOLUME_LOT_EDIT_X1, BUY_LIMIT_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   buyLimitVolumeLotEdit.Text(DoubleToString(volumeLot));
   buyLimitVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   buyLimitVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitVolumeLotEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitVolumeLotEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitVolumeLotEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitVolumeLotEdit);

//--Create the buy limit price edit to get the buy limit opening price user input
   buyLimitOpenPriceEdit.Create(
      0, BUY_LIMIT_OPEN_PRICE_EDIT_NAME, BUY_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW,
      BUY_LIMIT_OPEN_PRICE_EDIT_X1, BUY_LIMIT_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   buyLimitOpenPriceEdit.Text(DoubleToString(buyLimitEntryPrice, int(symbolDigits)));
   buyLimitOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   buyLimitOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitOpenPriceEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitOpenPriceEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitOpenPriceEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitOpenPriceEdit);

//--Create the buy limit sl edit to get the buy limit sl user input
   buyLimitSlEdit.Create(
      0, BUY_LIMIT_SL_EDIT_NAME, BUY_LIMIT_SL_EDIT_SUBWINDOW,
      BUY_LIMIT_SL_EDIT_X1, BUY_LIMIT_SL_EDIT_Y1,
      0, 0
   );
   buyLimitSlEdit.Text(IntegerToString(sl));
   buyLimitSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   buyLimitSlEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitSlEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitSlEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitSlEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitSlEdit);

//--Create the buy limit tp edit to get the buy limit tp user input
   buyLimitTpEdit.Create(
      0, BUY_LIMIT_TP_EDIT_NAME, BUY_LIMIT_TP_EDIT_SUBWINDOW,
      BUY_LIMIT_TP_EDIT_X1, BUY_LIMIT_TP_EDIT_Y1,
      0, 0
   );
   buyLimitTpEdit.Text(IntegerToString(tp));
   buyLimitTpEdit.Width(GUI_OBJECTS_WIDTH);
   buyLimitTpEdit.Height(GUI_OBJECTS_HEIGHT);
   buyLimitTpEdit.Color(GUI_OBJECTS_BUY_EDIT_COLOR);
   buyLimitTpEdit.ColorBackground(GUI_OBJECTS_BUY_EDIT_BG_COLOR);
   buyLimitTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   buyLimitTpEdit.ColorBorder(GUI_OBJECTS_BUY_BTN_BG_COLOR);
   mainPanelWindow.Add(buyLimitTpEdit);

   /*------------------------------------------------------
   * Sell Limit Order GUI components creation ****
   *-----------------------------------------------------*/
//--Create the open sell limit button
   sellLimitBtn.Create(
      0, SELL_LIMIT_BTN_NAME, SELL_LIMIT_BTN_SUBWINDOW,
      SELL_LIMIT_BTN_X1, SELL_LIMIT_BTN_Y1,
      0, 0
   );
   sellLimitBtn.Text(SELL_LIMIT_BTN_TEXT);
   sellLimitBtn.Width(GUI_OBJECTS_WIDTH);
   sellLimitBtn.Height(GUI_OBJECTS_HEIGHT);
   sellLimitBtn.Color(GUI_OBJECTS_SELL_BTN_COLOR);
   sellLimitBtn.ColorBackground(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   sellLimitBtn.FontSize(GUI_OBJECTS_FONT_SIZE);
   mainPanelWindow.Add(sellLimitBtn);

//--Create the sell limit volume lot edit to get the sell limit volume/lot user input
   sellLimitVolumeLotEdit.Create(
      0, SELL_LIMIT_VOLUME_LOT_EDIT_NAME, SELL_LIMIT_VOLUME_LOT_EDIT_SUBWINDOW,
      SELL_LIMIT_VOLUME_LOT_EDIT_X1, SELL_LIMIT_VOLUME_LOT_EDIT_Y1,
      0, 0
   );
   sellLimitVolumeLotEdit.Text(DoubleToString(volumeLot));
   sellLimitVolumeLotEdit.Width(GUI_OBJECTS_WIDTH);
   sellLimitVolumeLotEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitVolumeLotEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitVolumeLotEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitVolumeLotEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitVolumeLotEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitVolumeLotEdit);

//--Create the sell limit price edit to get the sell limit opening price user input
   sellLimitOpenPriceEdit.Create(
      0, SELL_LIMIT_OPEN_PRICE_EDIT_NAME, SELL_LIMIT_OPEN_PRICE_EDIT_SUBWINDOW,
      SELL_LIMIT_OPEN_PRICE_EDIT_X1, SELL_LIMIT_OPEN_PRICE_EDIT_Y1,
      0, 0
   );
   sellLimitOpenPriceEdit.Text(DoubleToString(sellLimitEntryPrice, int(symbolDigits)));
   sellLimitOpenPriceEdit.Width(GUI_OBJECTS_WIDTH);
   sellLimitOpenPriceEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitOpenPriceEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitOpenPriceEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitOpenPriceEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitOpenPriceEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitOpenPriceEdit);

//--Create the sell limit sl edit to get the sell limit sl user input
   sellLimitSlEdit.Create(
      0, SELL_LIMIT_SL_EDIT_NAME, SELL_LIMIT_SL_EDIT_SUBWINDOW,
      SELL_LIMIT_SL_EDIT_X1, SELL_LIMIT_SL_EDIT_Y1,
      0, 0
   );
   sellLimitSlEdit.Text(IntegerToString(sl));
   sellLimitSlEdit.Width(int(GUI_OBJECTS_WIDTH / 1.4));
   sellLimitSlEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitSlEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitSlEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitSlEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitSlEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitSlEdit);

//--Create the sell limit tp edit to get the sell limit tp user input
   sellLimitTpEdit.Create(
      0, SELL_LIMIT_TP_EDIT_NAME, SELL_LIMIT_TP_EDIT_SUBWINDOW,
      SELL_LIMIT_TP_EDIT_X1, SELL_LIMIT_TP_EDIT_Y1,
      0, 0
   );
   sellLimitTpEdit.Text(IntegerToString(tp));
   sellLimitTpEdit.Width(GUI_OBJECTS_WIDTH);
   sellLimitTpEdit.Height(GUI_OBJECTS_HEIGHT);
   sellLimitTpEdit.Color(GUI_OBJECTS_SELL_EDIT_COLOR);
   sellLimitTpEdit.ColorBackground(GUI_OBJECTS_SELL_EDIT_BG_COLOR);
   sellLimitTpEdit.FontSize(GUI_OBJECTS_FONT_SIZE);
   sellLimitTpEdit.ColorBorder(GUI_OBJECTS_SELL_BTN_BG_COLOR);
   mainPanelWindow.Add(sellLimitTpEdit);

   /*-------------------------------------------------------------
   * Status Labels and readonly edits GUI components creation ****
   *------------------------------------------------------------*/
//--Create the order magic status label
   magicOrderStatusLabel.Create(
      0, MAGIC_ORDER_STATUS_LABEL_NAME, MAGIC_ORDER_STATUS_LABEL_SUBWINDOW,
      MAGIC_ORDER_STATUS_LABEL_X1,
      MAGIC_ORDER_STATUS_LABEL_Y1,
      GUI_OBJECTS_WIDTH,
      GUI_OBJECTS_HEIGHT
   );
   magicOrderStatusLabel.Text(MAGIC_ORDER_STATUS_LABEL_TEXT + " - (Total Open Orders: " + (string(MagicOrdersTotal(magicNo))) + ")");
   magicOrderStatusLabel.Color(STATUS_EDIT_COLOR);
   magicOrderStatusLabel.FontSize(STATUS_HEADER_FONT_SIZE);
   mainPanelWindow.Add(magicOrderStatusLabel);

//--Create the magic order status edit to display the magic orders status
   magicOrdersStatusEdit.Create(
      0, MAGIC_ORDER_STATUS_EDIT_NAME, MAGIC_ORDER_STATUS_EDIT_SUBWINDOW,
      MAGIC_ORDER_STATUS_EDIT_X1, MAGIC_ORDER_STATUS_EDIT_Y1,
      0, 0
   );
   magicOrdersStatusEdit.ReadOnly(true);
   magicOrdersStatusEdit.Text(magicOrderStatus);
   magicOrdersStatusEdit.Width(STATUS_EDIT_WIDTH);
   magicOrdersStatusEdit.Height(GUI_OBJECTS_HEIGHT);
   magicOrdersStatusEdit.Color(STATUS_EDIT_COLOR);
   magicOrdersStatusEdit.ColorBackground(STATUS_EDIT_BG_COLOR);
   magicOrdersStatusEdit.FontSize(STATUS_EDIT_FONT_SIZE);
   magicOrdersStatusEdit.ColorBorder(STATUS_EDIT_BORDER_COLOR);
   mainPanelWindow.Add(magicOrdersStatusEdit);

//--Create the delete all magic buy stops button
   deleteAllMagicBuyStopsBtn.Create(
      0, DELETE_ALL_MAGIC_BUY_STOPS_BTN_NAME, DELETE_ALL_MAGIC_BUY_STOPS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_BUY_STOPS_BTN_X1, DELETE_ALL_MAGIC_BUY_STOPS_BTN_Y1,
      0, 0
   );
   deleteAllMagicBuyStopsBtn.Text(DELETE_ALL_MAGIC_BUY_STOPS_BTN_TEXT);
   deleteAllMagicBuyStopsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicBuyStopsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicBuyStopsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicBuyStopsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
   deleteAllMagicBuyStopsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicBuyStopsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicBuyStopsBtn);

//--Create the delete all magic sell stops button
   deleteAllMagicSellStopsBtn.Create(
      0, DELETE_ALL_MAGIC_SELL_STOPS_BTN_NAME, DELETE_ALL_MAGIC_SELL_STOPS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_SELL_STOPS_BTN_X1, DELETE_ALL_MAGIC_SELL_STOPS_BTN_Y1,
      0, 0
   );
   deleteAllMagicSellStopsBtn.Text(DELETE_ALL_MAGIC_SELL_STOPS_BTN_TEXT);
   deleteAllMagicSellStopsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicSellStopsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicSellStopsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicSellStopsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
   deleteAllMagicSellStopsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicSellStopsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicSellStopsBtn);

//--Create the delete all magic buy limits button
   deleteAllMagicBuyLimitsBtn.Create(
      0, DELETE_ALL_MAGIC_BUY_LIMITS_BTN_NAME, DELETE_ALL_MAGIC_BUY_LIMITS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_BUY_LIMITS_BTN_X1, DELETE_ALL_MAGIC_BUY_LIMITS_BTN_Y1,
      0, 0
   );
   deleteAllMagicBuyLimitsBtn.Text(DELETE_ALL_MAGIC_BUY_LIMITS_BTN_TEXT);
   deleteAllMagicBuyLimitsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicBuyLimitsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicBuyLimitsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicBuyLimitsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
   deleteAllMagicBuyLimitsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicBuyLimitsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicBuyLimitsBtn);

//--Create the delete all magic sell limits button
   deleteAllMagicSellLimitsBtn.Create(
      0, DELETE_ALL_MAGIC_SELL_LIMITS_BTN_NAME, DELETE_ALL_MAGIC_SELL_LIMITS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_SELL_LIMITS_BTN_X1, DELETE_ALL_MAGIC_SELL_LIMITS_BTN_Y1,
      0, 0
   );
   deleteAllMagicSellLimitsBtn.Text(DELETE_ALL_MAGIC_SELL_LIMITS_BTN_TEXT);
   deleteAllMagicSellLimitsBtn.Width(DELETE_ORDERS_BTN_WIDTH);
   deleteAllMagicSellLimitsBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicSellLimitsBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicSellLimitsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
   deleteAllMagicSellLimitsBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicSellLimitsBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicSellLimitsBtn);

//--Create the delete all magic orders button
   deleteAllMagicOrdersBtn.Create(
      0, DELETE_ALL_MAGIC_ORDERS_BTN_NAME, DELETE_ALL_MAGIC_ORDERS_BTN_SUBWINDOW,
      DELETE_ALL_MAGIC_ORDERS_BTN_X1, DELETE_ALL_MAGIC_ORDERS_BTN_Y1,
      0, 0
   );
   deleteAllMagicOrdersBtn.Text(DELETE_ALL_MAGIC_ORDERS_BTN_TEXT);
   deleteAllMagicOrdersBtn.Width(STATUS_EDIT_WIDTH);
   deleteAllMagicOrdersBtn.Height(GUI_OBJECTS_HEIGHT);
   deleteAllMagicOrdersBtn.Color(DELETE_ORDERS_BTN_COLOR);
   deleteAllMagicOrdersBtn.ColorBackground(DELETE_ALL_ORDERS_BTN_BG_COLOR);
   deleteAllMagicOrdersBtn.ColorBorder(DELETE_ORDERS_BTN_BORDER_COLOR);
   deleteAllMagicOrdersBtn.FontSize(DELETE_ORDERS_BTN_FONT_SIZE);
   mainPanelWindow.Add(deleteAllMagicOrdersBtn);

//--Call the Run() method to load the main panel window
   mainPanelWindow.Run();
  }

次に、OnChartEvent(...)関数に入力することで、ボタンが押されたりアクティブになったりしたことを検出する必要があります。この関数はすべてのユーザーインタラクションのイベントハンドラとして機能し、パネルの応答性のコアコンポーネントとなります。このセクションでは、PendingOrdersManager.ex5ライブラリからインポートされたプロトタイプ関数を呼び出し、ユーザー入力に基づいて未決注文を管理および操作できるようにします。例えば、ユーザーが新規の未決注文を出すボタンをクリックすると、対応するライブラリ関数がトリガーされ、操作が実行されます。

受注待ちパネルのユーザー体験をさらに高めるため、聴覚的フィードバックも統合する予定です。注文が成功したのか、エラーで失敗したのかなど、アクションの結果を知らせるさまざまなサウンドが再生されます。これにより、リアルタイムのフィードバックが提供され、インタラクティブな層が追加され、パネルがより直感的でユーザーフレンドリーになります。視覚的、聴覚的な合図を組み合わせることで、ユーザーは自分の行動の状況を容易に把握し、それに応じて対応することができます。

void OnChartEvent(const int id,
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)
  {
//--Detect any clicks or events performed to the orders panel window and make it moveable
   mainPanelWindow.ChartEvent(id, lparam, dparam, sparam);

//--Detect any click events on the chart
   if(id == CHARTEVENT_OBJECT_CLICK)
     {
      //--Detect when the buyStopBtn is clicked and open a new buy stop order
      if(sparam == buyStopBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Buy Stop Order with the details below: ");
         Print("Volume: ", buyStopVolumeLotEdit.Text());
         Print("Open Price: ", buyStopOpenPriceEdit.Text());
         Print("Sl (Pips): ", buyStopSlEdit.Text());
         Print("Tp (Pips): ", buyStopTpEdit.Text());
         if(
            OpenBuyStop(
               magicNo, _Symbol, StringToDouble(buyStopOpenPriceEdit.Text()),
               StringToDouble(buyStopVolumeLotEdit.Text()), (uint)StringToInteger(buyStopSlEdit.Text()),
               (uint)StringToInteger(buyStopTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the sellStopBtn is clicked and open a new sell stop order
      if(sparam == sellStopBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Sell Stop Order with the details below: ");
         Print("Volume: ", sellStopVolumeLotEdit.Text());
         Print("Open Price: ", sellStopOpenPriceEdit.Text());
         Print("Sl (Pips): ", sellStopSlEdit.Text());
         Print("Tp (Pips): ", sellStopTpEdit.Text());
         if(
            OpenSellStop(
               magicNo, _Symbol, StringToDouble(sellStopOpenPriceEdit.Text()),
               StringToDouble(sellStopVolumeLotEdit.Text()), (uint)StringToInteger(sellStopSlEdit.Text()),
               (uint)StringToInteger(sellStopTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the buyLimitBtn is clicked and open a new buy limit order
      if(sparam == buyLimitBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Buy Limit Order with the details below: ");
         Print("Volume: ", buyLimitVolumeLotEdit.Text());
         Print("Open Price: ", buyLimitOpenPriceEdit.Text());
         Print("Sl (Pips): ", buyLimitSlEdit.Text());
         Print("Tp (Pips): ", buyLimitTpEdit.Text());
         if(
            OpenBuyLimit(
               magicNo, _Symbol, StringToDouble(buyLimitOpenPriceEdit.Text()),
               StringToDouble(buyLimitVolumeLotEdit.Text()), (uint)StringToInteger(buyLimitSlEdit.Text()),
               (uint)StringToInteger(buyLimitTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the sellLimitBtn is clicked and open a new sell limit order
      if(sparam == sellLimitBtn.Name())
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Opening a new Sell Limit Order with the details below: ");
         Print("Volume: ", sellLimitVolumeLotEdit.Text());
         Print("Open Price: ", sellLimitOpenPriceEdit.Text());
         Print("Sl (Pips): ", sellLimitSlEdit.Text());
         Print("Tp (Pips): ", sellLimitTpEdit.Text());

         if(
            OpenSellLimit(
               magicNo, _Symbol, StringToDouble(sellLimitOpenPriceEdit.Text()),
               StringToDouble(sellLimitVolumeLotEdit.Text()), (uint)StringToInteger(sellLimitSlEdit.Text()),
               (uint)StringToInteger(sellLimitTpEdit.Text()), "EX5 PendingOrdersManager Panel"
            )
         )
           {
            PlaySound("ok.wav");//-- Order placed ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order failed
           }
        }

      //--Detect when the deleteAllMagicBuyStopsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicBuyStopsBtn.Name() && MagicBuyStopOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the buy stop orders with magic number: ", magicNo);
         if(DeleteAllBuyStops("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicSellStopsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicSellStopsBtn.Name() && MagicSellStopOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the sell stop orders with magic number: ", magicNo);
         if(DeleteAllSellStops("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicBuyLimitsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicBuyLimitsBtn.Name() && MagicBuyLimitOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the buy limit orders with magic number: ", magicNo);
         if(DeleteAllBuyLimits("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicSellLimitsBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicSellLimitsBtn.Name() && MagicSellLimitOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the sell limit orders with magic number: ", magicNo);
         if(DeleteAllSellLimits("", magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }

      //--Detect when the deleteAllMagicOrdersBtn is clicked and delete all the specified orders
      if(sparam == deleteAllMagicOrdersBtn.Name() && MagicOrdersTotal(magicNo) > 0)
        {
         Print(__FUNCTION__, " CHARTEVEN_OBJECT_CLICK: ", sparam);
         Print("Deleting all the open peding orders with magic number: ", magicNo);
         if(DeleteAllMagicOrders(magicNo))
           {
            PlaySound("ok.wav");//-- Orders deleted ok
           }
         else
           {
            PlaySound("alert2.wav");//-- Order deleting failed
           }
        }
     }
  }

EAがロードされるとすぐに、注文数量/ロット、エントリー価格、ストップロス(SL)、およびテイクプロフィット(TP)のフィールドに、現在のスプレッドに基づいて事前に定義された値が自動的に入力されることにお気づきでしょう。これらの値は、ユーザーに注文発注の出発点を与え、取引プロセスを合理化し、手動入力を最小限に抑えます。さらに、マジック注文ステータスの下にある注文削除ボタンは、EAに割り当てられたマジック番号に一致する未決注文または有効注文が検出されない場合、最初はグレーアウトして無効になります。EAが一致する注文を識別すると、ボタンがアクティブになり、色が変わります。

注文パネル、注文削除ボタンを無効にする

EAが割り当てられたマジックナンバーに一致する注文が出されたことを検出すると、注文削除ボタンが有効になり、色が変わって使用できることを示します。

注文パネル2 注文削除ボタンを有効にする

注文パネル すべての注文削除ボタンを有効にする

この機能を実装するには、OnTick()関数内に以下のコードを追加する必要があります。これにより、インポートされたEX5ライブラリ関数を使用して、グラフィカルユーザーインターフェイスをリアルタイムで継続的に監視および更新し、ティック受信ごとに注文のステータスと同期するようにします。

void OnTick()
  {
//---
   magicOrderStatus = " Buy Stops: " + (string(MagicBuyStopOrdersTotal(magicNo))) +
                      ", Sell Stops: " + (string(MagicSellStopOrdersTotal(magicNo))) +
                      ", Buy Limits: " + (string(MagicBuyLimitOrdersTotal(magicNo))) +
                      ", Sell Limits: " + (string(MagicSellLimitOrdersTotal(magicNo))) +
                      " ";
   magicOrderStatusLabel.Text(MAGIC_ORDER_STATUS_LABEL_TEXT + (string(MagicOrdersTotal(magicNo))));
   magicOrdersStatusEdit.Text(magicOrderStatus);

//-- Disable and change the background color of the deleteAllMagicBuyStopsBtn depending on the open orders status
   if(MagicBuyStopOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicBuyStopsBtn.Disable();
      deleteAllMagicBuyStopsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicBuyStopsBtn.Enable();
      deleteAllMagicBuyStopsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicSellStopsBtn depending on the open orders status
   if(MagicSellStopOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicSellStopsBtn.Disable();
      deleteAllMagicSellStopsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicSellStopsBtn.Enable();
      deleteAllMagicSellStopsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicBuyLimitsBtn depending on the open orders status
   if(MagicBuyLimitOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicBuyLimitsBtn.Disable();
      deleteAllMagicBuyLimitsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicBuyLimitsBtn.Enable();
      deleteAllMagicBuyLimitsBtn.ColorBackground(DELETE_BUY_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicSellLimitsBtn depending on the open orders status
   if(MagicSellLimitOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicSellLimitsBtn.Disable();
      deleteAllMagicSellLimitsBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicSellLimitsBtn.Enable();
      deleteAllMagicSellLimitsBtn.ColorBackground(DELETE_SELL_ORDERS_BTN_BG_COLOR);
     }

//-- Disable and change the background color of the deleteAllMagicOrdersBtn depending on the open orders status
   if(MagicOrdersTotal(magicNo) == 0)
     {
      deleteAllMagicOrdersBtn.Disable();
      deleteAllMagicOrdersBtn.ColorBackground(clrLightSlateGray);
     }
   else
     {
      deleteAllMagicOrdersBtn.Enable();
      deleteAllMagicOrdersBtn.ColorBackground(DELETE_ALL_ORDERS_BTN_BG_COLOR);
     }
  }

最後に、EAの終了時にすべてのリソースが適切に解放され、クリーンアップされることを確認する必要があります。これをおこなうには、OnDeinit(...)関数に以下のコードを追加します。

void OnDeinit(const int reason)
  {
//---
   //-- Delete and garbage collect the graphical user interface and other graphical objects
   mainPanelWindow.Destroy();

//-- Clear any chart comments
   Comment("");
  }

PendingOrdersPanel.mq5ファイルはこの記事の最後に添付されています。


結論

さまざまな種類の未決注文をどのように「新規作成」「変更」「削除」「並べ替え」「フィルタリング」できる、汎用性の高い未決注文管理EX5ライブラリを構築しました。このライブラリは、未決注文を柔軟かつ簡単に管理したいと考えるMQL5開発者にとって非常に便利なリソースです。簡単な関数呼び出しだけで、注文のステータスをすばやく取得したり、注文に対してアクションを実行したりすることが可能です。

ライブラリは豊富な機能を備えており、分かりやすいドキュメントや実用的な使用例も付属しています。次回の記事では、同様のアプローチで「履歴管理EX5ライブラリ」を作成し、MQL5での取引履歴や注文履歴の管理をさらに簡単にする方法を紹介します。

最後までお読みいただきありがとうございました。取引とMQL5プログラミングでの成功をお祈りしています。

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

MQL5で取引管理者パネルを作成する(第4回):ログインセキュリティ層 MQL5で取引管理者パネルを作成する(第4回):ログインセキュリティ層
悪意のある人物が取引管理者室に侵入し、世界中の何百万ものトレーダーに貴重な洞察を伝えるために使用されるコンピューターと管理パネルにアクセスしたと想像してください。このような侵入は、誤解を招くメッセージの不正送信や、意図しないアクションをトリガーするボタンのランダムクリックなど、悲惨な結果につながる可能性があります。このディスカッションでは、MQL5のセキュリティ対策と、これらの脅威から保護するために管理パネルに実装した新しいセキュリティ機能について説明します。セキュリティプロトコルを強化することで、通信チャネルを保護し、グローバルな取引コミュニティの信頼を維持することを目指しています。この記事のディスカッションでさらに詳しい情報を見つけてください。
MQL5とデータ処理パッケージの統合(第3回):データ可視化の強化 MQL5とデータ処理パッケージの統合(第3回):データ可視化の強化
この記事では、基本的なチャートの枠を超え、インタラクティブ性、データの層化、ダイナミックな要素といった機能を組み込むことで、トレーダーがトレンド、パターン、相関関係をより効果的に探求できるようにする、データ可視化の高度化について解説します。
ニュース取引が簡単に(第4回):パフォーマンス向上 ニュース取引が簡単に(第4回):パフォーマンス向上
この記事では、ストラテジーテスターでエキスパートアドバイザー(EA)のランタイムを改善する方法について掘り下げていきます。これらのニュースイベントの時間は、指定された時間内にアクセスされます。これにより、EAはボラティリティの高い環境でも低い環境でも、イベントドリブン取引を効率的に管理できます。
古典的な戦略を再構築する(第10回):AIはMACDを強化できるか? 古典的な戦略を再構築する(第10回):AIはMACDを強化できるか?
MACDインジケーターを経験的に分析し、インジケーターを含む戦略にAIを適用することで、EURUSDの予測精度が向上するかどうかをテストします。さらに、インジケーター自体が価格より予測しやすいのか、またインジケーターの値が将来の価格水準を予測できるのかも同時に評価します。これにより、AI取引戦略にMACDを統合することに投資する価値があるかどうかを判断するための情報を提供します。