Pending Trailing 2

Author: Copyright © 2022, Vladimir Karputov
Price Data Components
Orders Execution
Checks for the total of open ordersIt can change open orders parameters, due to possible stepping strategy
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Pending Trailing 2
ÿþ//+------------------------------------------------------------------+

//|                                           Pending Trailing 2.mq5 |

//|                              Copyright © 2022, Vladimir Karputov |

//|                      https://www.mql5.com/en/users/barabashkakvn |

//+------------------------------------------------------------------+

#property copyright "Copyright © 2022, Vladimir Karputov"

#property link      "https://www.mql5.com/en/users/barabashkakvn"

#property version   "1.006"

#property description "Trailing - in Points:"

#property description "--> (1.00055-1.00045=10 points)"

#property description "--> (91.312-91.310=2 points)"

/*

   barabashkakvn Trading engine 4.012

*/

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>

#include <Trade\AccountInfo.mqh>

#include <Trade\OrderInfo.mqh>

//---

CTrade         m_trade;                      // object of CTrade class

CSymbolInfo    m_symbol;                     // object of CSymbolInfo class

CAccountInfo   m_account;                    // object of CAccountInfo class

COrderInfo     m_order;                      // object of COrderInfo class

//+------------------------------------------------------------------+

//| Enum Bar !urrent                                                 |

//+------------------------------------------------------------------+

enum ENUM_BAR_CURRENT

  {

   bar_0=0,    // bar #0 (at every tick)

   bar_1=1,    // bar #1 (on a new bar)

  };

//+------------------------------------------------------------------+

//| Enum Symbol                                                      |

//+------------------------------------------------------------------+

enum ENUM_SYMBOL

  {

   all_symbols=0,    // Opened on any symbol

   current_symbol=1, // Opened on specified symbols

  };

//+------------------------------------------------------------------+

//| Enum Magic                                                       |

//+------------------------------------------------------------------+

enum ENUM_MAGIC

  {

   all_magics=0,     // Opened manually or by Expert Advisors

   manually_magic=1, // Opened manually

   advisors_magic=2, // Opened by advisors

  };

//--- input parameters

input group             "Trading settings"

input ENUM_TIMEFRAMES      InpWorkingPeriod        = PERIOD_CURRENT; // Working timeframe

input ENUM_BAR_CURRENT     InpTrailingBarCurrent   = bar_1;          // Trailing on ...

input uint                 InpTrailingStop         = 250;            // Trailing Stop (min distance from price to Pending order)

input uint                 InpTrailingStep         = 50;             // Trailing Step

input ENUM_SYMBOL          InpSymbols              = all_symbols;    // Symbols pending orders...

input string               InpVolumeSymbols        = "EURUSD,USDJPY";// ... for "Symbols pending orders" ("-" -> OFF)

input ENUM_MAGIC           InpMagics               = all_magics;     // Magics pending orders...

input string               InpVolumeMagics         = "200,100,45678";// ... for "Magics pending orders" ("-" -> OFF)

input group             "Pending Order Parameters"

input ushort               InpPendingExpiration    = 600;            // Pending: Expiration, in minutes ('0' -> OFF)

input uint                 InpPendingMaxSpreadUpper= 30;             // Pending: Maximum spread ... upper value ('0' -> OFF)

input uint                 InpPendingMaxSpreadLower= 12;             // Pending: Maximum spread ... lower value ('0' -> OFF)

input bool                 InpPlaceAfterDeletion   = true;           // Place pending order after deletion

input group             "Additional features"

input bool                 InpPrintLog             = true;           // Print log

input uchar                InpFreezeCoefficient    = 3;              // Coefficient (if Freeze==0 Or StopsLevels==0)

input ulong                InpMagic                = 221;            // Magic number

//---

double   m_trailing_stop            = 0.0;      // Trailing Stop                             -> double

double   m_trailing_step            = 0.0;      // Trailing Step                             -> double

double   m_pending_max_spread_upper = 0.0;      // Pending: Maximum spread ... upper value   -> double

double   m_pending_max_spread_lower = 0.0;      // Pending: Maximum spread ... lower value   -> double



datetime m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';

bool     m_init_error               = false;    // error on InInit



ulong    m_magics[];

ulong    m_tickets[];

string   m_symbols[];

//+------------------------------------------------------------------+

//| Expert initialization function                                   |

//+------------------------------------------------------------------+

int OnInit()

  {

//--- forced initialization of variables

   m_trailing_stop            = 0.0;      // Trailing Stop                             -> double

   m_trailing_step            = 0.0;      // Trailing Step                             -> double

   m_pending_max_spread_upper = 0.0;      // Pending: Maximum spread ... upper value   -> double

   m_pending_max_spread_lower = 0.0;      // Pending: Maximum spread ... lower value   -> double

//---

   m_prev_bars                = 0;        // "0" -> D'1970.01.01 00:00';

   m_init_error               = false;    // error on InInit

//---

   ArrayFree(m_magics);

   ArrayFree(m_tickets);

   ArrayFree(m_symbols);

//---

   if(InpTrailingStop!=0 && InpTrailingStep==0)

     {

      string err_text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                      ""@59;8=3 =52>7<>65=: ?0@0<5B@ \"Pending: Maximum spread ... upper value\" <= \"Pending: Maximum spread ... lower value\"!":

                      "Trailing is not possible: parameter \"Pending: Maximum spread ... upper value\" <= \"Pending: Maximum spread ... lower value\"!";

      if(MQLInfoInteger(MQL_TESTER)) // when testing, we will only output to the log about incorrect input parameters

         Print(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

      else // if the Expert Advisor is run on the chart, tell the user about the error

         Alert(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

      //---

      m_init_error=true;

      return(INIT_SUCCEEDED);

     }

   if(InpPendingMaxSpreadUpper!=0 || InpPendingMaxSpreadLower!=0)

      if(InpPendingMaxSpreadUpper<=InpPendingMaxSpreadLower)

        {

         string err_text=(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")?

                         ">=B@>;L A?@540 =52>7<>65=: ?0@0<5B@ \"Trailing Step\" @025= =C;N!":

                         "Spread control is not possible: parameter \"Trailing Step\" is zero!";

         if(MQLInfoInteger(MQL_TESTER)) // when testing, we will only output to the log about incorrect input parameters

            Print(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

         else // if the Expert Advisor is run on the chart, tell the user about the error

            Alert(__FILE__," ",__FUNCTION__,", ERROR: ",err_text);

         //---

         m_init_error=true;

         return(INIT_SUCCEEDED);

        }

//---

   ResetLastError();

   if(!m_symbol.Name(Symbol())) // sets symbol name

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");

      return(INIT_FAILED);

     }

   RefreshRates(m_symbol);

//---

   m_trade.SetExpertMagicNumber(InpMagic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(10);

//---

   string to_split= InpVolumeMagics;   // a string to split into substrings

   string sep     = ",";               // a separator as a character

   ushort u_sep;                       // the code of the separator character

   string result[];                    // an array to get strings

//--- Get the separator code

   u_sep=StringGetCharacter(sep,0);

//--- Split the string to substrings

   int k=StringSplit(to_split,u_sep,result);

//--- Show a comment

//PrintFormat("Strings obtained: %d. Used separator '%s' with the code %d",k,sep,u_sep);

//--- Now output all obtained strings

   uchar numbers_array[10]= {'0','1','2','3','4','5','6','7','8','9'};

   int size_numbers_array=ArraySize(numbers_array);

   if(k>0)

     {

      for(int i=0; i<k; i++)

        {

         //PrintFormat("result[%d]=\"%s\"",i,result[i]);

         ushort ushort_array[];         // ushort array

         StringToShortArray(result[i],ushort_array,0,-1);

         int size_ushort_array=ArraySize(ushort_array);

         bool not_a_number=true;

         for(int j=0; j<size_ushort_array-1; j++) // loop through array 'ushort_array'

           {

            not_a_number=true;

            for(int m=0; m<size_numbers_array; m++) // loop through array 'numbers_array {'0','1','2','3','4','5','6','7','8','9'}'

              {

               if(ushort_array[j]==numbers_array[m])

                 {

                  not_a_number=false;

                  break;

                 }

              }

            if(not_a_number) // if you find a letter - go to the next Magic

               break;

           }

         if(!not_a_number) // write the found Magic to the array 'm_magics'

           {

            ulong number=StringToInteger(result[i]);

            int size=ArraySize(m_magics);

            ArrayResize(m_magics,size+1);

            m_magics[size]=number;

           }

        }

     }

//---

   to_split=InpVolumeSymbols;    // a string to split into substrings

   ArrayFree(result);            // an array to get strings

//--- Split the string to substrings

   k=StringSplit(to_split,u_sep,result);

//--- Show a comment

//PrintFormat("Strings obtained: %d. Used separator '%s' with the code %d",k,sep,u_sep);

//--- Now output all obtained strings

   if(k>0)

     {

      for(int i=0; i<k; i++)

        {

         //PrintFormat("result[%d]=\"%s\"",i,result[i]);

         if(!m_symbol.Name(result[i]))

            continue;

         //---

         int size_symbols=ArraySize(m_symbols);

         ArrayResize(m_symbols,size_symbols+1);

         m_symbols[size_symbols]=result[i];

        }

     }

//---

   ArrayPrint(m_magics);

   ArrayPrint(m_symbols);

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Expert deinitialization function                                 |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//---

  }

//+------------------------------------------------------------------+

//| Expert tick function                                             |

//+------------------------------------------------------------------+

void OnTick()

  {

   if(m_init_error)

      return;

//--- check spread

   CheckSpread();

//---

   if(InpPendingExpiration>0)

     {

      for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders

         if(m_order.SelectByIndex(i)) // selects the pending order by index for further access to its properties

           {

            //--- check: does this symbol match our input parameters?

            bool bool_symbol=false;

            if(InpSymbols==all_symbols)

               bool_symbol=true;

            else

              {

               string order_symbol=m_order.Symbol();

               int size_symbols=ArraySize(m_symbols);

               for(int j=0; j<size_symbols; j++)

                 {

                  if(order_symbol==m_symbols[j])

                    {

                     bool_symbol=true;

                     break;

                    }

                 }

              }

            if(!bool_symbol)

               continue;

            //--- check: does this magic match our input parameters?

            bool bool_magic=false;

            long order_reason=-1;

            if(!m_order.InfoInteger(ORDER_REASON,order_reason))

               continue;

            if(InpMagics==manually_magic) // 'Opened manually'

              {

               if(order_reason==ORDER_REASON_EXPERT)

                  continue;

              }

            else

              {

               if(InpMagics==advisors_magic) // 'Opened by advisors'

                 {

                  if(order_reason!=ORDER_REASON_EXPERT)

                     continue;

                 }

              }

            //---

            ulong order_magic=m_order.Magic();

            int size_magics=ArraySize(m_magics);

            if(size_magics==0)

              {

               bool_magic=true;

              }

            else

              {

               for(int j=0; j<size_magics; j++)

                 {

                  if(order_magic==m_magics[j])

                    {

                     bool_magic=true;

                     break;

                    }

                 }

              }

            if(!bool_magic)

               continue;

            //---

            int size=ArraySize(m_tickets);

            bool ticket_was_found=false;

            for(int j=0; j<size; j++)

              {

               if(m_tickets[j]==m_order.Ticket())

                 {

                  ticket_was_found=true;

                  break;

                 }

              }

            if(!ticket_was_found)

              {

               datetime time_expiration=(datetime)(TimeCurrent()+(long)(InpPendingExpiration*60));

               bool result=m_trade.OrderModify(m_order.Ticket(),m_order.PriceOpen(),m_order.StopLoss(),

                                               m_order.TakeProfit(),ORDER_TIME_SPECIFIED,time_expiration);

               if(result)

                 {

                  Print("ticket ",m_order.Ticket(),", new time ",time_expiration);

                  ArrayResize(m_tickets,size+1);

                  m_tickets[size]=m_order.Ticket();

                 }

               else

                 {

                  if(m_trade.ResultRetcode()==10022)

                    {

                     ArrayResize(m_tickets,size+1);

                     m_tickets[size]=m_order.Ticket();

                    }

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify ",m_order.Ticket(),

                           " Pending -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of result: ",m_trade.ResultRetcodeDescription());

                 }

              }

           }

     }

//--- trailing at every tick

   if(InpTrailingBarCurrent==bar_0)

      Trailing();

//--- we work only at the time of the birth of new bar

   if(InpTrailingBarCurrent==bar_1)

     {

      datetime time_0=iTime(m_symbol.Name(),InpWorkingPeriod,0);

      if(time_0==m_prev_bars)

         return;

      m_prev_bars=time_0;

      if(InpTrailingBarCurrent==bar_1) // trailing only at the time of the birth of new bar

         Trailing();

     }

  }

//+------------------------------------------------------------------+

//| TradeTransaction function                                        |

//+------------------------------------------------------------------+

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//---

  }

//+------------------------------------------------------------------+

//| Refreshes the symbol quotes data                                 |

//+------------------------------------------------------------------+

bool RefreshRates(CSymbolInfo &symbol)

  {

//--- refresh rates

   if(!symbol.RefreshRates())

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: ","RefreshRates error");

      return(false);

     }

//--- protection against the return value of "zero"

   if(symbol.Ask()==0 || symbol.Bid()==0)

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.0");

      return(false);

     }

//---

   return(true);

  }

//+------------------------------------------------------------------+

//| Check Freeze and Stops levels                                    |

//+------------------------------------------------------------------+

void FreezeStopsLevels(CSymbolInfo &symbol,double &freeze,double &stops)

  {

//--- check Freeze and Stops levels

   /*

   SYMBOL_TRADE_FREEZE_LEVEL shows the distance of freezing the trade operations

      for pending orders and open positions in points

   ------------------------|--------------------|--------------------------------------------

   Type of order/position  |  Activation price  |  Check

   ------------------------|--------------------|--------------------------------------------

   Buy Limit order         |  Ask               |  Ask-OpenPrice  >= SYMBOL_TRADE_FREEZE_LEVEL

   Buy Stop order          |  Ask               |  OpenPrice-Ask  >= SYMBOL_TRADE_FREEZE_LEVEL

   Sell Limit order        |  Bid               |  OpenPrice-Bid  >= SYMBOL_TRADE_FREEZE_LEVEL

   Sell Stop order         |  Bid               |  Bid-OpenPrice  >= SYMBOL_TRADE_FREEZE_LEVEL

   Buy position            |  Bid               |  TakeProfit-Bid >= SYMBOL_TRADE_FREEZE_LEVEL

                           |                    |  Bid-StopLoss   >= SYMBOL_TRADE_FREEZE_LEVEL

   Sell position           |  Ask               |  Ask-TakeProfit >= SYMBOL_TRADE_FREEZE_LEVEL

                           |                    |  StopLoss-Ask   >= SYMBOL_TRADE_FREEZE_LEVEL

   ------------------------------------------------------------------------------------------



   SYMBOL_TRADE_STOPS_LEVEL determines the number of points for minimum indentation of the

      StopLoss and TakeProfit levels from the current closing price of the open position

   ------------------------------------------------|------------------------------------------

   Buying is done at the Ask price                 |  Selling is done at the Bid price

   ------------------------------------------------|------------------------------------------

   TakeProfit        >= Bid                        |  TakeProfit        <= Ask

   StopLoss          <= Bid                        |  StopLoss          >= Ask

   TakeProfit - Bid  >= SYMBOL_TRADE_STOPS_LEVEL   |  Ask - TakeProfit  >= SYMBOL_TRADE_STOPS_LEVEL

   Bid - StopLoss    >= SYMBOL_TRADE_STOPS_LEVEL   |  StopLoss - Ask    >= SYMBOL_TRADE_STOPS_LEVEL

   ------------------------------------------------------------------------------------------

   */

   double coeff=(double)InpFreezeCoefficient;

   if(!RefreshRates(symbol) || !symbol.Refresh())

      return;

//--- FreezeLevel -> for pending order and modification

   double freeze_level=symbol.FreezeLevel()*symbol.Point();

   if(freeze_level==0.0)

     {

      if(InpFreezeCoefficient>0)

         freeze_level=(symbol.Ask()-symbol.Bid())*coeff;

     }

   else

      freeze_level*=coeff;

//--- StopsLevel -> for TakeProfit and StopLoss

   double stop_level=symbol.StopsLevel()*symbol.Point();

   if(stop_level==0.0)

     {

      if(InpFreezeCoefficient>0)

         stop_level=(symbol.Ask()-symbol.Bid())*coeff;

     }

   else

      stop_level*=coeff;

//---

   freeze=freeze_level;

   stops=stop_level;

//---

   return;

  }

//+------------------------------------------------------------------+

//| Trailing                                                         |

//|   InpTrailingStop: min distance from price to Stop Loss          |

//+------------------------------------------------------------------+

void Trailing()

  {

   if(InpTrailingStop==0)

      return;

   double freeze=0.0,stops=0.0,max_levels=0.0;

   /*

   SYMBOL_TRADE_FREEZE_LEVEL shows the distance of freezing the trade operations

      for pending orders and open positions in points

   ------------------------|--------------------|--------------------------------------------

   Type of order/position  |  Activation price  |  Check

   ------------------------|--------------------|--------------------------------------------

   Buy Limit order         |  Ask               |  Ask-OpenPrice  >= SYMBOL_TRADE_FREEZE_LEVEL

   Buy Stop order          |  Ask               |  OpenPrice-Ask  >= SYMBOL_TRADE_FREEZE_LEVEL

   Sell Limit order        |  Bid               |  OpenPrice-Bid  >= SYMBOL_TRADE_FREEZE_LEVEL

   Sell Stop order         |  Bid               |  Bid-OpenPrice  >= SYMBOL_TRADE_FREEZE_LEVEL

   ------------------------------------------------------------------------------------------

   */

//---

   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders

      if(m_order.SelectByIndex(i)) // selects the pending order by index for further access to its properties

        {

         //--- check: does this symbol match our input parameters?

         bool bool_symbol=false;

         if(InpSymbols==all_symbols)

            bool_symbol=true;

         else

           {

            string order_symbol=m_order.Symbol();

            int size_symbols=ArraySize(m_symbols);

            for(int j=0; j<size_symbols; j++)

              {

               if(order_symbol==m_symbols[j])

                 {

                  bool_symbol=true;

                  break;

                 }

              }

           }

         if(!bool_symbol)

            continue;

         //--- check: does this magic match our input parameters?

         bool bool_magic=false;

         long order_reason=-1;

         if(!m_order.InfoInteger(ORDER_REASON,order_reason))

            continue;

         if(InpMagics==manually_magic) // 'Opened manually'

           {

            if(order_reason==ORDER_REASON_EXPERT)

               continue;

           }

         else

           {

            if(InpMagics==advisors_magic) // 'Opened by advisors'

              {

               if(order_reason!=ORDER_REASON_EXPERT)

                  continue;

              }

           }

         //---

         ulong order_magic=m_order.Magic();

         int size_magics=ArraySize(m_magics);

         if(size_magics==0)

           {

            bool_magic=true;

           }

         else

           {

            for(int j=0; j<size_magics; j++)

              {

               if(order_magic==m_magics[j])

                 {

                  bool_magic=true;

                  break;

                 }

              }

           }

         if(!bool_magic)

            continue;

         //---

         if(!SetInit(m_order.Symbol()))

            continue;

         FreezeStopsLevels(m_symbol,freeze,stops);

         max_levels=(freeze>stops)?freeze:stops;

         //---

         double price_current = m_order.PriceCurrent();

         double price_open    = m_order.PriceOpen();

         if(price_current==0.0 || price_open==0.0)

            continue;

         double stop_loss     = m_order.StopLoss();

         double take_profit   = m_order.TakeProfit();

         double ask           = m_symbol.Ask();

         double bid           = m_symbol.Bid();

         //--- check spread

         if(m_pending_max_spread_lower>0.0)

           {

            double spread=m_symbol.Ask()-m_symbol.Bid();

            if(spread>m_pending_max_spread_lower)

               continue;

           }

         //---

         if(m_order.OrderType()==ORDER_TYPE_BUY_LIMIT)

           {

            if(price_current-price_open>m_trailing_stop+m_trailing_step)

              {

               double new_price=m_symbol.NormalizePrice(price_current-m_trailing_stop);

               double new_sl=(stop_loss==0.0)?0.0:m_symbol.NormalizePrice(new_price-(price_open-stop_loss));

               double new_tp=(take_profit==0.0)?0.0:m_symbol.NormalizePrice(new_price+(take_profit-price_open));

               if(!m_trade.OrderModify(m_order.Ticket(),new_price,new_sl,new_tp,m_order.TypeTime(),m_order.TimeExpiration()))

                 {

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify BUY LIMIT ",m_order.Ticket(),

                           " Pending -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of result: ",m_trade.ResultRetcodeDescription());

                 }

              }

            continue;

           }

         if(m_order.OrderType()==ORDER_TYPE_SELL_LIMIT)

           {

            if(price_open-price_current>m_trailing_stop+m_trailing_step)

              {

               double new_price=m_symbol.NormalizePrice(price_current+m_trailing_stop);

               double new_sl=(stop_loss==0.0)?0.0:m_symbol.NormalizePrice(new_price+(stop_loss-price_open));

               double new_tp=(take_profit==0.0)?0.0:m_symbol.NormalizePrice(new_price-(price_open-take_profit));

               if(!m_trade.OrderModify(m_order.Ticket(),new_price,new_sl,new_tp,m_order.TypeTime(),m_order.TimeExpiration()))

                 {

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify SELL LIMIT ",m_order.Ticket(),

                           " Pending -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of result: ",m_trade.ResultRetcodeDescription());

                 }

              }

            continue;

           }

         if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)

           {

            if(price_open-price_current>m_trailing_stop+m_trailing_step)

              {

               double new_price=m_symbol.NormalizePrice(price_current+m_trailing_stop);

               double new_sl=(stop_loss==0.0)?0.0:m_symbol.NormalizePrice(new_price-(price_open-stop_loss));

               double new_tp=(take_profit==0.0)?0.0:m_symbol.NormalizePrice(new_price+(take_profit-price_open));

               if(!m_trade.OrderModify(m_order.Ticket(),new_price,new_sl,new_tp,m_order.TypeTime(),m_order.TimeExpiration()))

                 {

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify BUY STOP ",m_order.Ticket(),

                           " Pending -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of result: ",m_trade.ResultRetcodeDescription());

                 }

              }

            continue;

           }

         if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)

           {

            if(price_current-price_open>m_trailing_stop+m_trailing_step)

              {

               double new_price=m_symbol.NormalizePrice(price_current-m_trailing_stop);

               double new_sl=(stop_loss==0.0)?0.0:m_symbol.NormalizePrice(new_price+(stop_loss-price_open));

               double new_tp=(take_profit==0.0)?0.0:m_symbol.NormalizePrice(new_price-(price_open-take_profit));

               if(!m_trade.OrderModify(m_order.Ticket(),new_price,new_sl,new_tp,m_order.TypeTime(),m_order.TimeExpiration()))

                 {

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", ERROR: ","Modify SELL STOP ",m_order.Ticket(),

                           " Pending -> false. Result Retcode: ",m_trade.ResultRetcode(),

                           ", description of result: ",m_trade.ResultRetcodeDescription());

                 }

              }

            continue;

           }

        }

  }

//+------------------------------------------------------------------+

//| Set Init                                                         |

//+------------------------------------------------------------------+

bool SetInit(const string symbol)

  {

   if(!m_symbol.Name(symbol)) // sets symbol name

     {

      Print(__FILE__," ",__FUNCTION__,", ERROR: CSymbolInfo.Name");

      return(false);

     }

   if(!RefreshRates(m_symbol))

      return(false);

//---

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

//---

   m_trailing_stop            = InpTrailingStop             * m_symbol.Point();

   m_trailing_step            = InpTrailingStep             * m_symbol.Point();

   m_pending_max_spread_upper = InpPendingMaxSpreadUpper    * m_symbol.Point();

   m_pending_max_spread_lower = InpPendingMaxSpreadLower    * m_symbol.Point();

//---

   return(true);

  }

//+------------------------------------------------------------------+

//| Check Spread                                                     |

//+------------------------------------------------------------------+

void CheckSpread()

  {

   if(InpPendingMaxSpreadUpper==0)

      return;

   for(int i=OrdersTotal()-1; i>=0; i--) // returns the number of current orders

      if(m_order.SelectByIndex(i)) // selects the pending order by index for further access to its properties

        {

         //--- check: does this symbol match our input parameters?

         bool bool_symbol=false;

         if(InpSymbols==all_symbols)

            bool_symbol=true;

         else

           {

            string order_symbol=m_order.Symbol();

            int size_symbols=ArraySize(m_symbols);

            for(int j=0; j<size_symbols; j++)

              {

               if(order_symbol==m_symbols[j])

                 {

                  bool_symbol=true;

                  break;

                 }

              }

           }

         if(!bool_symbol)

            continue;

         //--- check: does this magic match our input parameters?

         bool bool_magic=false;

         long order_reason=-1;

         if(!m_order.InfoInteger(ORDER_REASON,order_reason))

            continue;

         if(InpMagics==manually_magic) // 'Opened manually'

           {

            if(order_reason==ORDER_REASON_EXPERT)

               continue;

           }

         else

           {

            if(InpMagics==advisors_magic) // 'Opened by advisors'

              {

               if(order_reason!=ORDER_REASON_EXPERT)

                  continue;

              }

           }

         //---

         ulong order_magic=m_order.Magic();

         int size_magics=ArraySize(m_magics);

         if(size_magics==0)

           {

            bool_magic=true;

           }

         else

           {

            for(int j=0; j<size_magics; j++)

              {

               if(order_magic==m_magics[j])

                 {

                  bool_magic=true;

                  break;

                 }

              }

           }

         if(!bool_magic)

            continue;

         //---

         if(!SetInit(m_order.Symbol()))

            continue;

         //--- check spread

         double spread=m_symbol.Ask()-m_symbol.Bid();

         if(spread>m_pending_max_spread_upper)

            if(!m_trade.OrderDelete(m_order.Ticket()))

               if(InpPrintLog)

                  Print(__FILE__," ",__FUNCTION__,", ERROR: ","CTrade.OrderDelete ",m_order.Ticket());

        }

  }

//+------------------------------------------------------------------+

Comments