Every pending order cancelled immediately after being placed - Error Code: 10013 [Invalid Request]

 

I am trying to figure out why every pending order is being cancelled right away after placing it successfully in the market. The error message the EA is returning is the following: "Error Code: 10013 [Invalid Request]"


Here is the log where you can see the messages from the server:

RQ 0 17:21:02.223 Trades '1520355161': sell stop 1 XAUUSD at 2450.69 sl: 2475.20 tp: 2401.68

EF 0 17:21:02.366 Trades '1520355161': accepted sell stop 1 XAUUSD at 2450.69 sl: 2475.20 tp: 2401.68

GF 0 17:21:02.371 Trades '1520355161': order #31994308 sell stop 1 / 1 XAUUSD at 2450.69 done in 148.542 ms

OQ 0 17:21:02.435 Trades '1520355161': cancel order #31994308 sell stop 1 XAUUSD at 2450.69 sl: 2475.20 tp: 2401.68

PR 0 17:21:02.488 Trades '1520355161': accepted cancel order #31994308 sell stop 1 XAUUSD at 2450.69 sl: 2475.20 tp: 2401.68

ML 0 17:21:02.490 Trades '1520355161': cancel #31994308 sell stop 1 XAUUSD at market done in 54.933 ms


Here is the code:

//+------------------------------------------------------------------+
//|                                        London range breakout.mq5 |
//|                                  Copyright 2024, MetaQuotes Ltd. |
//|                                             https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2024, MetaQuotes Ltd."
#property link      "https://www.mql5.com"
#property version   "1.00"

#include <trade/trade.mqh>

//+------------------------------------------------------------------+
//| Parámetros de entrada                                            |
//+------------------------------------------------------------------+

input group "Trade Settings"
input ENUM_TIMEFRAMES v_TimeFrame = PERIOD_H1; //Timeframe to execute the strategy
input double i_Risk           = 1.0; //Balance Risk % per operation
input double i_StopLossPerc   = 1.0; //Stop Loss % from the entry price
input double i_TakeProfitPerc = 2.0; //Take profit % from the entry price

input group "Trading days"
input bool   i_Monday    = true; //Enable trading on Monday
input bool   i_Tuesday   = true; //Enable trading on Tuesday
input bool   i_Wednesday = true; //Enable trading on Wednesday
input bool   i_Thursday  = true; //Enable trading on Thursday
input bool   i_Friday    = true; //Enable trading on Friday

input group "General Settings"
input bool i_SwingTrading  = true; //Enable swing trading
input bool i_ClosePendingOrders = true; //Close pending orders at EOD

input group "Trailing Stop Settings"
input bool   i_TrailingStop         = true; //Trailing Stop
input double i_TraillingTriggerPerc = 0.5; //Profit % from which you want to modify the stop loss
input double i_TraillingPerc        = 0.5; //Stop Loss (%) from the current price

input group "Partial Close Settings"
input bool   i_PartialClose       = false; //Take partials
input double i_PartialClosePerc   = 0.5; //Profit % where to partially close the order
input double i_PartialCloseFactor = 0.25; //Lot % to close

//+------------------------------------------------------------------+
//| Variables globales                                               |
//+------------------------------------------------------------------+
double v_LondonOpenPrice,
       v_LondonClosePrice,
       v_LondonHighestPrice,
       v_LondonLowestPrice,
       v_EntryPrice;

ulong v_OrderTicket;

int const c_MagicNumber = 35273184;

bool v_tradeOpenedToday = false;

MqlDateTime v_lastTradeDate,
            v_currentDate;

//+------------------------------------------------------------------+
//| Clases                                                           |
//+------------------------------------------------------------------+
CTrade v_Trade;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit() {
   v_Trade.SetExpertMagicNumber(35273184);
   v_tradeOpenedToday = false;
   return(INIT_SUCCEEDED);
}

//+------------------------------------------------------------------+
//| Expert trade transaction function                                |
//+------------------------------------------------------------------+
void OnTradeTransaction(const MqlTradeTransaction& trans,
                        const MqlTradeRequest& request,
                        const MqlTradeResult& result) {

   if(result.retcode == TRADE_RETCODE_INVALID) {
      Print(__FUNCTION__, "Invalid request in symbol ", _Symbol, ". Error: ", result.retcode);
   }
}
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick() {

   TimeToStruct(TimeGMT(), v_currentDate);
   if (AccountInfoInteger(ACCOUNT_TRADE_ALLOWED) &&
         AccountInfoInteger(ACCOUNT_TRADE_EXPERT)) {

//Verificar si comenzó un nuevo día
      if(v_currentDate.day_of_year != v_lastTradeDate.day_of_year) {
         v_tradeOpenedToday = false;
         //Al finalizar el día, cerrar órdenes colocadas que aún no
         //hayan sido abiertas
         closeOrder();
      }
//Si no se abrieron trades en el día actual
      if(v_tradeOpenedToday == false) {
         //Analizar condiciones para establecer una orden
         checkTradeConditions(v_currentDate);
      }
      if(i_TrailingStop || i_PartialClose) {
         //Modificar órdenes abiertas
         modifyOrder();
      }
   }  else {
      Print("Trading not allowed");
   }
}

//+------------------------------------------------------------------+
//| Analizar condiciones para establecer una orden                   |
//+------------------------------------------------------------------+
void checkTradeConditions(MqlDateTime & p_currentDate) {

   string lv_day = "";

   if((p_currentDate.day_of_week == 1 && i_Monday == true) ||
         (p_currentDate.day_of_week == 2 && i_Tuesday == true) ||
         (p_currentDate.day_of_week == 3 && i_Wednesday == true) ||
         (p_currentDate.day_of_week == 4 && i_Thursday == true) ||
         (p_currentDate.day_of_week == 5 && i_Friday == true)) {

      if(p_currentDate.day_of_week == 0) lv_day = "Sunday";
      if(p_currentDate.day_of_week == 1) lv_day = "Monday";
      if(p_currentDate.day_of_week == 2) lv_day = "Tuesday";
      if(p_currentDate.day_of_week == 3) lv_day = "Wednesday";
      if(p_currentDate.day_of_week == 4) lv_day = "Thursday";
      if(p_currentDate.day_of_week == 5) lv_day = "Friday";
      if(p_currentDate.day_of_week == 6) lv_day = "Saturday";

      //London session hours
      //5am - 10am (GMT)
      //6am - 11am (LN Time) (UTC + 1) DST
      //5am - 10am (LN Time) (UTC-0)
      int lv_LondonOpen  = 05,
          lv_LondonClose = 10;

      //Si ya finalizó la London Session
      if(p_currentDate.hour > lv_LondonClose) {
         if(v_LondonLowestPrice  == NULL &&
               v_LondonHighestPrice == NULL ) {

            MqlDateTime lv_MqlDate = p_currentDate;
            lv_MqlDate.min = 0;
            lv_MqlDate.sec = 0;

            for(int i = lv_LondonOpen; i <= lv_LondonClose; i++) {
               lv_MqlDate.hour = i;
               //Obtener precios de interés de la sesión de Londres
               getLondonPrices(lv_MqlDate);
            }
         }

         MqlTick lv_currentTick;
         SymbolInfoTick(_Symbol, lv_currentTick);

         //Si el precio se encuentra debajo del London Highest Price
         if(lv_currentTick.ask < v_LondonHighestPrice) {
            sendOrder(ORDER_TYPE_BUY_STOP);
         }
         //Si el precio se encuentra encima del London Lowest Price
         if(lv_currentTick.bid > v_LondonLowestPrice) {
            sendOrder(ORDER_TYPE_SELL_STOP);
         }
      }
   }
}
//+------------------------------------------------------------------+
//| Obtener niveles de precios de London Session                     |
//+------------------------------------------------------------------+
void getLondonPrices(MqlDateTime & p_CurrentDate) {
   datetime lv_DateTime = StructToTime(p_CurrentDate);
   switch(p_CurrentDate.hour) {
   //Obtener el precio de apertura de Londres
   case 05:
      v_LondonOpenPrice    = iOpen(_Symbol, v_TimeFrame, iBarShift(_Symbol, v_TimeFrame, lv_DateTime));
      v_LondonOpenPrice    = NormalizeDouble(v_LondonOpenPrice, _Digits);
      v_LondonHighestPrice = iHigh(_Symbol, v_TimeFrame, iBarShift(_Symbol, v_TimeFrame, lv_DateTime));
      v_LondonLowestPrice  = iLow(_Symbol, v_TimeFrame, iBarShift(_Symbol, v_TimeFrame, lv_DateTime));
      v_LondonHighestPrice = NormalizeDouble(v_LondonHighestPrice, _Digits);
      v_LondonLowestPrice = NormalizeDouble(v_LondonLowestPrice, _Digits);
      break;
   case 06:
   case 07:
   case 08:
      getSessionHighLow(v_LondonLowestPrice, v_LondonHighestPrice, lv_DateTime);
      break;
   case 09:
      v_LondonClosePrice = iClose(_Symbol, v_TimeFrame, iBarShift(_Symbol, v_TimeFrame, lv_DateTime));
      getSessionHighLow(v_LondonLowestPrice, v_LondonHighestPrice, lv_DateTime);
      break;
   }
}
//+------------------------------------------------------------------+
//| Modificar órdenes abiertas                                       |
//+------------------------------------------------------------------+
void modifyOrder() {

   for(int i = 0; i < PositionsTotal(); i++) {

      ulong lv_positionTicket = PositionGetTicket(i);

      if(PositionGetSymbol(POSITION_SYMBOL) != _Symbol)
         continue;

      if(PositionGetInteger(POSITION_MAGIC) != c_MagicNumber)
         continue;

      double lv_BidPrice = SymbolInfoDouble(_Symbol, SYMBOL_BID);
      lv_BidPrice = NormalizeDouble(lv_BidPrice, _Digits);

      double lv_AskPrice = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
      lv_AskPrice = NormalizeDouble(lv_AskPrice, _Digits);

      double lv_positionOpenPrice = PositionGetDouble(POSITION_PRICE_OPEN);
      lv_positionOpenPrice = NormalizeDouble(lv_positionOpenPrice, _Digits);

      double lv_PositionStopLoss = PositionGetDouble(POSITION_SL);
      lv_PositionStopLoss = NormalizeDouble(lv_PositionStopLoss, _Digits);

      double lv_PositionTakeProfit = PositionGetDouble(POSITION_TP);
      lv_PositionTakeProfit = NormalizeDouble(lv_PositionTakeProfit, _Digits);

      double lv_PositionVolume = PositionGetDouble(POSITION_VOLUME);
      lv_PositionVolume = NormalizeDouble(lv_PositionVolume, _Digits);

      double lv_VolMin = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
      lv_VolMin = NormalizeDouble(lv_VolMin, _Digits);

      double lv_VolMax = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
      lv_VolMax = NormalizeDouble(lv_VolMax, _Digits);

      int lv_StopLevel = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
      int lv_Spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);

      //Si es una orden de compra
      if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY) {

         if(i_TrailingStop) {

            double lv_trailingTrigger = lv_positionOpenPrice + (lv_positionOpenPrice * i_TraillingTriggerPerc / 100);
            lv_trailingTrigger = NormalizeDouble(lv_trailingTrigger, _Digits);

            if(lv_BidPrice >= lv_trailingTrigger) {

               //Calculo el nuevo Stop Loss en base a un porcentaje (parámetro) de la
               //diferencia entre el Bid Price y el precio de apertura de la orden
               double lv_StopLoss = lv_BidPrice - (lv_BidPrice * i_TraillingPerc / 100);
               lv_StopLoss = NormalizeDouble(lv_StopLoss, _Digits);

               if(lv_StopLoss > lv_PositionStopLoss && (lv_BidPrice - lv_StopLoss >= (lv_StopLevel + lv_Spread) * _Point)) {
                  v_Trade.PositionModify(lv_positionTicket, lv_StopLoss, lv_PositionTakeProfit);
               } else {
                  Print(__FUNCTION__, " > Trailing Stop error. Cannot modify SL (Invalid SL Price)");
               }
            }
         }

         if(i_PartialClose) {

            double lv_pClose = lv_positionOpenPrice + ((lv_PositionTakeProfit - lv_positionOpenPrice) * i_PartialClosePerc / 100);
            lv_pClose = NormalizeDouble(lv_pClose, _Digits);

            if(lv_BidPrice >= lv_pClose) {

               double lv_LotSize = calcLotSize(ORDER_TYPE_BUY_STOP, lv_PositionStopLoss, lv_positionOpenPrice, i_Risk);

               if(lv_PositionVolume == lv_LotSize) {

                  double lv_LotsToClose = lv_PositionVolume * i_PartialCloseFactor / 100;

                  if (lv_LotsToClose < lv_VolMin) {
                     lv_LotsToClose = lv_VolMin;
                  } else if (lv_LotsToClose > lv_VolMax) {
                     lv_LotsToClose = lv_VolMax;
                  }

                  v_Trade.PositionClosePartial(lv_positionTicket, lv_LotsToClose);

               }
            }
         }

      } else if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL) {

         if(i_TrailingStop) {

            double lv_trailingTrigger = lv_positionOpenPrice - (lv_positionOpenPrice * i_TraillingTriggerPerc / 100);
            lv_trailingTrigger = NormalizeDouble(lv_trailingTrigger, _Digits);

            if(lv_AskPrice <= lv_trailingTrigger) {

               //Calculo el nuevo Stop Loss en base a un porcentaje (parámetro) de la
               //diferencia entre el precio de apertura de la orden y el Ask Price
               double lv_StopLoss = lv_AskPrice + (lv_AskPrice * i_TraillingPerc / 100);
               lv_StopLoss = NormalizeDouble(lv_StopLoss, _Digits);

               if((lv_StopLoss < lv_PositionStopLoss || lv_PositionStopLoss == 0) && (lv_StopLoss - lv_AskPrice >= (lv_StopLevel + lv_Spread) * _Point)) {
                  v_Trade.PositionModify(lv_positionTicket, lv_StopLoss, lv_PositionTakeProfit);
               } else {
                  Print(__FUNCTION__, " > Trailing Stop error. Cannot modify SL (Invalid SL Price)");
               }

            }
         }

         if(i_PartialClose) {

            double lv_pClose = lv_positionOpenPrice - (lv_positionOpenPrice * i_PartialClosePerc / 100);
            lv_pClose = NormalizeDouble(lv_pClose, _Digits);

            if(lv_AskPrice <= lv_pClose) {

               double lv_LotSize = calcLotSize(ORDER_TYPE_SELL_STOP, lv_PositionStopLoss, lv_positionOpenPrice, i_Risk);

               if(lv_PositionVolume == lv_LotSize) {

                  double lv_LotsToClose = lv_PositionVolume * i_PartialCloseFactor / 100;

                  if (lv_LotsToClose < lv_VolMin) {
                     lv_LotsToClose = lv_VolMin;
                  } else if (lv_LotsToClose > lv_VolMax) {
                     lv_LotsToClose = lv_VolMax;
                  }

                  v_Trade.PositionClosePartial(lv_positionTicket, lv_LotsToClose);

               }

            }
         }
      }
   }
}
//+------------------------------------------------------------------+
//| Cerrar órdenes y posiciones abiertas al final del NY PM Session|
//+------------------------------------------------------------------+
void closeOrder() {
//Cerrar posiciones abiertas
   if(i_SwingTrading == false) {
      if(PositionsTotal() > 0) {
         for(int i = PositionsTotal() - 1; i >= 0; i--) {
            ulong lv_positionTicket = PositionGetTicket(i);
            if(PositionGetSymbol(POSITION_SYMBOL) == _Symbol &&
                  PositionGetInteger(POSITION_MAGIC) == c_MagicNumber) {
               v_Trade.PositionClose(lv_positionTicket);
            }
         }
      }
   }
   if(i_ClosePendingOrders) {
      //Eliminar órdenes pendientes
      if(OrdersTotal() > 0) {
         for(int i = OrdersTotal() - 1; i >= 0; i--) {
            ulong lv_orderTicket = OrderGetTicket(i);
            if(OrderGetInteger(ORDER_MAGIC) == c_MagicNumber) {
               v_Trade.OrderDelete(lv_orderTicket);
            }
         }
      }
   }

   v_LondonClosePrice    = NULL;
   v_LondonOpenPrice     = NULL;
   v_LondonHighestPrice  = NULL;
   v_LondonLowestPrice   = NULL;
   v_EntryPrice          = NULL;
}

//+------------------------------------------------------------------+
//| Obtener máximo y mínimo de la sesión                             |
//+------------------------------------------------------------------+
void getSessionHighLow(double & p_SessionLow, double & p_SessionHigh,
                       datetime & p_DateTime) {
   double lv_high = iHigh(_Symbol, v_TimeFrame, iBarShift(_Symbol, v_TimeFrame, p_DateTime));
   double lv_low = iLow(_Symbol, v_TimeFrame, iBarShift(_Symbol, v_TimeFrame, p_DateTime));
   if(lv_high * _Point > p_SessionHigh * _Point || p_SessionHigh == NULL) {
      p_SessionHigh = lv_high;
      p_SessionHigh = NormalizeDouble(p_SessionHigh, _Digits);
   }
   if(lv_low * _Point < p_SessionLow * _Point || p_SessionLow == NULL) {
      p_SessionLow = lv_low;
      p_SessionLow = NormalizeDouble(p_SessionLow, _Digits);
   }
}
//+------------------------------------------------------------------+
//| Enviar orden al mercado                                          |
//+------------------------------------------------------------------+
void sendOrder(ENUM_ORDER_TYPE p_OrderType) {

   if(p_OrderType == ORDER_TYPE_BUY_STOP) {

      v_EntryPrice = v_LondonHighestPrice;
      v_EntryPrice = NormalizeDouble(v_EntryPrice, _Digits);

      double lv_StopLoss = v_EntryPrice - ((v_EntryPrice * i_StopLossPerc) / 100),
             lv_TakeProfit = v_EntryPrice + ((v_EntryPrice * i_TakeProfitPerc) / 100),
             //Calcular el tamaño del lote en base al balance
             lv_lots = 1;
      lv_lots = NormalizeDouble(lv_lots, 2);

      lv_TakeProfit = NormalizeDouble(lv_TakeProfit, _Digits);
      lv_StopLoss = NormalizeDouble(lv_StopLoss, _Digits);

      if(checksForStopOrders(ORDER_TYPE_BUY_STOP, lv_TakeProfit, lv_StopLoss, lv_lots)) {
         bool lv_result = v_Trade.BuyStop(lv_lots, v_EntryPrice, _Symbol, lv_StopLoss, lv_TakeProfit, ORDER_TIME_GTC);
         if(lv_result) {
            MqlTradeResult lv_OrderResult;
            v_Trade.Result(lv_OrderResult);
            if(lv_OrderResult.retcode == TRADE_RETCODE_DONE) {
               v_OrderTicket = lv_OrderResult.order;
               TimeToStruct(TimeGMT(), v_lastTradeDate);
               v_tradeOpenedToday = true;
         } else {
            Print(__FUNCTION__, " | Error: ", v_Trade.ResultRetcodeDescription(), ". | Code: ", v_Trade.ResultRetcode(), " | Price: ", v_EntryPrice, " | SL: ", lv_StopLoss, " | TP: ", lv_TakeProfit, " | Volume: ", lv_lots);
         }
      }
   } else if(p_OrderType == ORDER_TYPE_SELL_STOP) {

      v_EntryPrice = v_LondonLowestPrice;
      v_EntryPrice = NormalizeDouble(v_EntryPrice, _Digits);

      double lv_StopLoss = v_EntryPrice + ((v_EntryPrice * i_StopLossPerc) / 100),
             lv_TakeProfit = v_EntryPrice - ((v_EntryPrice * i_TakeProfitPerc) / 100),
             //Calcular el tamaño del lote en base al balance
             lv_lots = 1;
      
      lv_TakeProfit = NormalizeDouble(lv_TakeProfit, _Digits);
      lv_StopLoss = NormalizeDouble(lv_StopLoss, _Digits);
      lv_lots = NormalizeDouble(lv_lots, _Digits);

      if(checksForStopOrders(ORDER_TYPE_SELL_STOP, lv_TakeProfit, lv_StopLoss, lv_lots)) {
         bool lv_result = v_Trade.SellStop(lv_lots, v_EntryPrice, Symbol(), lv_StopLoss, lv_TakeProfit, ORDER_TIME_GTC);
         if(lv_result) {
            MqlTradeResult lv_OrderResult;
            v_Trade.Result(lv_OrderResult);
            if(lv_OrderResult.retcode == TRADE_RETCODE_DONE) {
               v_OrderTicket = lv_OrderResult.order;
               TimeToStruct(TimeGMT(), v_lastTradeDate);
               v_tradeOpenedToday = true;
         } else {
            Print(__FUNCTION__, " | Error: ", v_Trade.ResultRetcodeDescription(), ". | Code: ", v_Trade.ResultRetcode(), " | Price: ", v_EntryPrice, " | SL: ", lv_StopLoss, " | TP: ", lv_TakeProfit, " | Volume: ", lv_lots);
         }
      }
   }
}
//+------------------------------------------------------------------+
//| Verificaciones para órdenes stop                                 |
//+------------------------------------------------------------------+
bool checksForStopOrders(ENUM_ORDER_TYPE p_OrderType,
                         double p_TP,
                         double p_SL,
                         double p_lots) {

   double lv_bid = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_BID), _Digits);
   double lv_ask = NormalizeDouble(SymbolInfoDouble(_Symbol, SYMBOL_ASK), _Digits);
   int lv_freezeLevel = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_FREEZE_LEVEL);
   double lv_margin;
   int lv_StopLevel = (int)SymbolInfoInteger(_Symbol, SYMBOL_TRADE_STOPS_LEVEL);
   int lv_Spread = (int)SymbolInfoInteger(_Symbol, SYMBOL_SPREAD);

//Controles para órdenes Buy Stop
   if(p_OrderType == ORDER_TYPE_BUY_STOP) {
      if(v_EntryPrice != lv_ask && v_EntryPrice - lv_ask < (lv_StopLevel + lv_Spread) * _Point) {
         Print(__FUNCTION__, " > Cannot place Buy Stop Order (Invalid Order Price)");
         return false;
      }
      if(v_EntryPrice - lv_ask < lv_freezeLevel) {
         Print(__FUNCTION__, " > Cannot place Buy Stop Order (Price within Freeze Level)");
         return false;
      }
      if(p_SL > 0 && v_EntryPrice - p_SL < (lv_StopLevel + lv_Spread) * _Point) {
         Print(__FUNCTION__, " > Cannot place Buy Stop Order (Invalid SL Price)");
         return false;
      }
      if(p_TP > 0 && p_TP - v_EntryPrice < (lv_StopLevel + lv_Spread) * _Point) {
         Print(__FUNCTION__, " > Cannot place Buy Stop Order (Invalid TP Price)");
         return false;
      }
      if(OrderCalcMargin(ORDER_TYPE_BUY_STOP, _Symbol, p_lots, v_EntryPrice, lv_margin) &&
            lv_margin > AccountInfoDouble(ACCOUNT_MARGIN_FREE)) {
         Print(__FUNCTION__, " > Cannot place Buy Stop Order (Not enough margin)");
         return false;
      }

      return true;

//Controles para órdenes Sell Stop
   } else { //if(PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL_STOP) {
      if(v_EntryPrice != lv_bid && lv_bid - v_EntryPrice < (lv_StopLevel + lv_Spread) * _Point) {
         Print(__FUNCTION__, " > Cannot place Sell Stop Order (Invalid Order Price)");
         return false;
      }
      if(lv_bid - v_EntryPrice < lv_freezeLevel) {
         Print(__FUNCTION__, " > Cannot place Buy Stop Order (Price within Freeze Level)");
         return false;
      }
      if(p_SL > 0 && p_SL - v_EntryPrice < (lv_StopLevel + lv_Spread) * _Point) {
         Print(__FUNCTION__, " > Cannot place Sell Stop Order (Invalid SL Price)");
         return false;
      }
      if(p_TP > 0 && v_EntryPrice - p_TP < (lv_StopLevel + lv_Spread) * _Point) {
         Print(__FUNCTION__, " > Cannot place Sell Stop Order (Invalid TP Price)");
         return false;
      }
      if(OrderCalcMargin(ORDER_TYPE_SELL_STOP, _Symbol, p_lots, v_EntryPrice, lv_margin) &&
            lv_margin > AccountInfoDouble(ACCOUNT_MARGIN_FREE)) {
         Print(__FUNCTION__, " > Cannot place Sell Stop Order (Not enough margin)");
         return false;
      }
      return true;
   }
}
////+------------------------------------------------------------------+