Pending orders Three sessions Breakeven

Author: Copyright © 2019, Vladimir Karputov
Price Data Components
Series array that contains tick volumes of each bar
Orders Execution
Checks for the total of open orders
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Pending orders Three sessions Breakeven
ÿþ//+------------------------------------------------------------------+

//|                      Pending orders Three sessions Breakeven.mq5 |

//|                              Copyright © 2019, Vladimir Karputov |

//|                                           http://wmua.ru/slesar/ |

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

#property copyright "Copyright © 2019, Vladimir Karputov"

#property link      "http://wmua.ru/slesar/"

#property version   "1.000"

/*

   barabashkakvn Trading engine 3.029

*/

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

#include <Trade\DealInfo.mqh>

#include <Trade\OrderInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

CDealInfo      m_deal;                       // deals object

COrderInfo     m_order;                      // pending orders object

CMoneyFixedMargin *m_money;

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

//| Enum Lor or Risk                                                 |

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

enum ENUM_LOT_OR_RISK

  {

   lots_min=0, // Lots Min

   lot=1,      // Constant lot

   risk=2,     // Risk in percent for a deal

  };

//--- input parameters

input ushort   InpTrailingFrequency = 10;          // Trailing, in seconds (< "10" -> only on a new bar)

input ushort   InpTrailingStop      = 25;          // Trailing Stop (min distance from price to Stop Loss, in pips

input ushort   InpTrailingStep      = 5;           // Trailing Step, in pips (1.00045-1.00055=1 pips)

//--- Session #N start time

input uchar    InpSession_1_StartTime=1;           // Session #1 start time (in hours)

input uchar    InpSession_2_StartTime=9;           // Session #2 start time (in hours)

input uchar    InpSession_3_StartTime=14;          // Session #3 start time (in hours)

//--- Session #N lifetime

input ushort   InpSession_1_LifeTime=299;          // Session #1 lifetime (in minutes, at least 15 minutes)

input ushort   InpSession_2_LifeTime=299;          // Session #2 lifetime (in minutes, at least 15 minutes)

input ushort   InpSession_3_LifeTime=299;          // Session #3 lifetime (in minutes, at least 15 minutes)

//--- Session #N indent UP 

input ushort   InpSession_1_Indent_UP=5;           // Session #1 indent UP, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_2_Indent_UP=5;           // Session #2 indent UP, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_3_Indent_UP=5;           // Session #3 indent UP, in pips (1.00045-1.00055=1 pips)

//--- Session #N indent DOWN 

input ushort   InpSession_1_Indent_DOWN=5;         // Session #1 indent DOWN, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_2_Indent_DOWN=5;         // Session #2 indent DOWN, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_3_Indent_DOWN=5;         // Session #3 indent DOWN, in pips (1.00045-1.00055=1 pips)

//--- Session #N Stop Loss

input ushort   InpSession_1_StopLoss=15;           // Session #1 Stop Loss, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_2_StopLoss=15;           // Session #2 Stop Loss, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_3_StopLoss=15;           // Session #3 Stop Loss, in pips (1.00045-1.00055=1 pips)

//--- Session #N TakeProfit

input ushort   InpSession_1_TakeProfit=0;        // Session #1 Take Profit, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_2_TakeProfit=0;        // Session #2 Take Profit, in pips (1.00045-1.00055=1 pips)

input ushort   InpSession_3_TakeProfit=0;        // Session #3 Take Profit, in pips (1.00045-1.00055=1 pips)

//--- Session #N Money management: Lot OR Risk

input ENUM_LOT_OR_RISK InpSession_1_LotOrRisk=risk;// Session #1 Money management: Lot OR Risk

input ENUM_LOT_OR_RISK InpSession_2_LotOrRisk=risk;// Session #2 Money management: Lot OR Risk

input ENUM_LOT_OR_RISK InpSession_3_LotOrRisk=risk;// Session #3 Money management: Lot OR Risk

//--- Session #N The value for "Money management"

input double   InpSession_1_VolumeLotOrRisk=3.0;   // Session #1 The value for "Money management"

input double   InpSession_2_VolumeLotOrRisk=3.0;   // Session #2 The value for "Money management"

input double   InpSession_3_VolumeLotOrRisk=3.0;  // Session #3 The value for "Money management"

//---

input bool     InpPrintLog          = false;       // Print log

input ulong    InpMagic             = 200;         // Magic number

//---

string   m_hline_name_buy        = "Buy net price";

string   m_hline_name_sell       = "Sell net price";

//---

ulong  ExtSlippage=10;              // Slippage



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

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

double ExtSession_1_Indent_UP    = 0.0;      // Session #1 indent UP    -> double

double ExtSession_2_Indent_UP    = 0.0;      // Session #2 indent UP    -> double

double ExtSession_3_Indent_UP    = 0.0;      // Session #3 indent UP    -> double

double ExtSession_1_Indent_DOWN  = 0.0;      // Session #1 indent DOWN  -> double

double ExtSession_2_Indent_DOWN  = 0.0;      // Session #2 indent DOWN  -> double

double ExtSession_3_Indent_DOWN  = 0.0;      // Session #3 indent DOWN  -> double

double ExtSession_1_StopLoss     = 0.0;      // Session #1 Stop Loss    -> double

double ExtSession_2_StopLoss     = 0.0;      // Session #2 Stop Loss    -> double

double ExtSession_3_StopLoss     = 0.0;      // Session #3 Stop Loss    -> double

double ExtSession_1_TakeProfit   = 0.0;      // Session #1 Take Profit  -> double

double ExtSession_2_TakeProfit   = 0.0;      // Session #2 Take Profit  -> double

double ExtSession_3_TakeProfit   = 0.0;      // Session #3 Take Profit  -> double



int    handle_iCustom;              // variable for storing the handle of the iCustom indicator 



double   ExtAdjustedPoint;                   // point value adjusted for 3 or 5 points

bool     ExtNeedCloseAll         = false;    //

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

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

bool     ExtWaitingPendingOrder  = false;    // waiting for a pending order

int      digits_adjust           = 1;        // 

//--- ***

//---    0 >B;>65==K5 >@45@0 (5A;8 ?@>H;0 ?@>25@:0 ?> A?@54C) 

//---    ?@>AB> 2KAB@5;8205< 8 >1=C;O5< <0AA82K AB@C:BC@

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

//| Structure Need Pending                                           |

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

struct STRUCT_NEED_PENDING

  {

   int               session;                // session

   ENUM_ORDER_TYPE   pending_type;           // pending type

   double            volume;                 // volume

   double            price;                  // price

   ulong             magic;                  // magic

   //--- Constructor 

                     STRUCT_NEED_PENDING()

     {

      session                    = -1;

      pending_type               = WRONG_VALUE;

      volume                     = 0.0;

      price                      = 0.0;

      magic                      = 0;

     }

  };

STRUCT_NEED_PENDING SNeedPending[];

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

//| Expert initialization function                                   |

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

int OnInit()

  {

//---

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

     {

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

                      ""@59;8=3 =52>7<>65=: ?0@0<5B@ \"Trailing Step\" @025= =C;N!":

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

      //--- when testing, we will only output to the log about incorrect input parameters

      if(MQLInfoInteger(MQL_TESTER))

        {

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

         return(INIT_FAILED);

        }

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

        {

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

         return(INIT_PARAMETERS_INCORRECT);

        }

     }

//---

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

      return(INIT_FAILED);

   RefreshRates();

//---

   m_trade.SetExpertMagicNumber(InpMagic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(ExtSlippage);

//--- tuning for 3 or 5 digits

   digits_adjust=1;

   if(m_symbol.Digits()==3 || m_symbol.Digits()==5)

      digits_adjust=10;

   ExtAdjustedPoint=m_symbol.Point()*digits_adjust;



   ExtTrailingStop            = InpTrailingStop          * ExtAdjustedPoint;

   ExtTrailingStep            = InpTrailingStep          * ExtAdjustedPoint;

   ExtSession_1_Indent_UP     = InpSession_1_Indent_UP   * ExtAdjustedPoint;

   ExtSession_2_Indent_UP     = InpSession_2_Indent_UP   * ExtAdjustedPoint;

   ExtSession_3_Indent_UP     = InpSession_3_Indent_UP   * ExtAdjustedPoint;

   ExtSession_1_Indent_DOWN   = InpSession_1_Indent_DOWN * ExtAdjustedPoint;

   ExtSession_2_Indent_DOWN   = InpSession_2_Indent_DOWN * ExtAdjustedPoint;

   ExtSession_3_Indent_DOWN   = InpSession_3_Indent_DOWN * ExtAdjustedPoint;

   ExtSession_1_StopLoss      = InpSession_1_StopLoss    * ExtAdjustedPoint;

   ExtSession_2_StopLoss      = InpSession_2_StopLoss    * ExtAdjustedPoint;

   ExtSession_3_StopLoss      = InpSession_3_StopLoss    * ExtAdjustedPoint;

   ExtSession_1_TakeProfit    = InpSession_1_TakeProfit  * ExtAdjustedPoint;

   ExtSession_2_TakeProfit    = InpSession_2_TakeProfit  * ExtAdjustedPoint;

   ExtSession_3_TakeProfit    = InpSession_3_TakeProfit  * ExtAdjustedPoint;

//--- 

   HLineCreate(0,m_hline_name_buy,0,0.0,clrBlue);

   HLineCreate(0,m_hline_name_sell,0,0.0,clrRed);

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---

   if(m_money!=NULL)

      delete m_money;

   HLineDelete(0,m_hline_name_buy);

   HLineDelete(0,m_hline_name_sell);

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

   if(ExtNeedCloseAll)

     {

      if(IsPositionExists())

        {

         double level;

         if(FreezeStopsLevels(level))

           {

            CloseAllPositions(level);  return;

           }

         else

            return;

        }

      else

         ExtNeedCloseAll=false;

     }

//---

   int size_need_pending=ArraySize(SNeedPending);

   if(size_need_pending>0)

     {

      if(!ExtWaitingPendingOrder)

         for(int i=size_need_pending-1;i>=0;i--)

           {

            double level;

            if(FreezeStopsLevels(level))

              {

               ExtWaitingPendingOrder=true;

               PlaceOrders(i,SNeedPending[i].session,

                           SNeedPending[i].pending_type,level,

                           SNeedPending[i].magic);

              }

           }

      return;

     }

//---

   if(InpTrailingFrequency>=10) // trailing no more than once every 10 seconds

     {

      datetime time_current=TimeCurrent();

      if(time_current-ExtLastTrailing>10)

        {

         int count_buys = 0;  double volume_buys   = 0.0;   double volume_biggest_buys = 0.0;

         int count_sells= 0;  double volume_sells  = 0.0;   double volume_biggest_sells= 0.0;

         CalculateAllPositions(count_buys,volume_buys,volume_biggest_buys,

                               count_sells,volume_sells,volume_biggest_sells);

         if(count_buys>1 || count_sells>1)

           {

            double net_price_buy=0.0;

            double net_price_sell=0.0;

            CalculationNetPrice(net_price_buy,net_price_sell);

            //---

            double level;

            if(FreezeStopsLevels(level))

               Trailing(level,net_price_buy,net_price_sell);

            else

               return;

           }

         if(count_buys==0)

            HLineMove(0,m_hline_name_buy,0.0);

         if(count_sells==0)

            HLineMove(0,m_hline_name_sell,0.0);



         ExtLastTrailing=time_current;

        }

     }

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

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

   if(time_0==ExtPrevBars)

      return;

   ExtPrevBars=time_0;

   if(InpTrailingFrequency<10) // trailing only at the time of the birth of new bar

     {

      int count_buys=0;  double volume_buys=0.0;   double volume_biggest_buys=0.0;

      int count_sells=0;  double volume_sells=0.0;   double volume_biggest_sells=0.0;

      CalculateAllPositions(count_buys,volume_buys,volume_biggest_buys,

                            count_sells,volume_sells,volume_biggest_sells);

      if(count_buys>1 || count_sells>1)

        {

         double net_price_buy=0.0;

         double net_price_sell=0.0;

         CalculationNetPrice(net_price_buy,net_price_sell);

         //---

         double level;

         if(FreezeStopsLevels(level))

            Trailing(level,net_price_buy,net_price_sell);

        }

      if(count_buys==0)

         HLineMove(0,m_hline_name_buy,0.0);

      if(count_sells==0)

         HLineMove(0,m_hline_name_sell,0.0);

     }

//--- search for trading signals only at the time of the birth of new bar

   if(!RefreshRates())

     {

      ExtPrevBars=0; return;

     }

//--- search for trading signals

   if(!SearchTradingSignals())

     {

      ExtPrevBars=0; return;

     }

//---

  }

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

//| TradeTransaction function                                        |

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

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//--- 



  }

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

//| Refreshes the symbol quotes data                                 |

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

bool RefreshRates(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      Print("RefreshRates error");

      return(false);

     }

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

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

      return(false);

//---

   return(true);

  }

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

//| Check the correctness of the position volume                     |

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

bool CheckVolumeValue(double volume,string &error_description)

  {

//--- minimal allowed volume for trade operations

   double min_volume=m_symbol.LotsMin();

   if(volume<min_volume)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< <5=LH5 <8=8<0;L=> 4>?CAB8<>3> SYMBOL_VOLUME_MIN=%.2f",min_volume);

      else

         error_description=StringFormat("Volume is less than the minimal allowed SYMBOL_VOLUME_MIN=%.2f",min_volume);

      return(false);

     }

//--- maximal allowed volume of trade operations

   double max_volume=m_symbol.LotsMax();

   if(volume>max_volume)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< 1>;LH5 <0:A8<0;L=> 4>?CAB8<>3> SYMBOL_VOLUME_MAX=%.2f",max_volume);

      else

         error_description=StringFormat("Volume is greater than the maximal allowed SYMBOL_VOLUME_MAX=%.2f",max_volume);

      return(false);

     }

//--- get minimal step of volume changing

   double volume_step=m_symbol.LotsStep();

   int ratio=(int)MathRound(volume/volume_step);

   if(MathAbs(ratio*volume_step-volume)>0.0000001)

     {

      if(TerminalInfoString(TERMINAL_LANGUAGE)=="Russian")

         error_description=StringFormat("1J5< =5 :@0B5= <8=8<0;L=><C H03C SYMBOL_VOLUME_STEP=%.2f, 1;8609H89 ?@028;L=K9 >1J5< %.2f",

                                        volume_step,ratio*volume_step);

      else

         error_description=StringFormat("Volume is not a multiple of the minimal step SYMBOL_VOLUME_STEP=%.2f, the closest correct volume is %.2f",

                                        volume_step,ratio*volume_step);

      return(false);

     }

   error_description="Correct volume value";

   return(true);

  }

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

//| Lot Check                                                        |

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

double LotCheck(double lots)

  {

//--- calculate maximum volume

   double volume=NormalizeDouble(lots,2);

   double stepvol=m_symbol.LotsStep();

   if(stepvol>0.0)

      volume=stepvol*MathFloor(volume/stepvol);

//---

   double minvol=m_symbol.LotsMin();

   if(volume<minvol)

      volume=0.0;

//---

   double maxvol=m_symbol.LotsMax();

   if(volume>maxvol)

      volume=maxvol;

   return(volume);

  }

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

//| Check Freeze and Stops levels                                    |

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

bool FreezeStopsLevels(double &level)

  {

//--- check Freeze and Stops levels

/*

   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

                           

   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

*/

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

      return(false);

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

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

   if(freeze_level==0.0)

      freeze_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;

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

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

   if(stop_level==0.0)

      stop_level=(m_symbol.Ask()-m_symbol.Bid())*3.0;



   if(freeze_level<=0.0 || stop_level<=0.0)

      return(false);



   level=(freeze_level>stop_level)?freeze_level:stop_level;



   double spread=m_symbol.Spread()*ExtAdjustedPoint;

   level=(level>spread)?level:spread;

//---

   return(true);

  }

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

//| Print CTrade result                                              |

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

void PrintResultTrade(CTrade &trade,CSymbolInfo &symbol)

  {

   Print("File: ",__FILE__,", symbol: ",symbol.Name());

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result as a string: "+trade.ResultRetcodeDescription());

   Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("Order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("Broker comment: "+trade.ResultComment());

  }

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

//| Get value of buffers                                             |

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

double iGetArray(const int handle,const int buffer,const int start_pos,

                 const int count,double &arr_buffer[])

  {

   bool result=true;

   if(!ArrayIsDynamic(arr_buffer))

     {

      Print("This a no dynamic array!");

      return(false);

     }

   ArrayFree(arr_buffer);

//--- reset error code 

   ResetLastError();

//--- fill a part of the iBands array with values from the indicator buffer

   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);

   if(copied!=count)

     {

      //--- if the copying fails, tell the error code 

      PrintFormat("Failed to copy data from the indicator, error code %d",GetLastError());

      //--- quit with zero result - it means that the indicator is considered as not calculated 

      return(false);

     }

   return(result);

  }

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

//| Trailing                                                         |

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

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

void Trailing(const double stop_level,double net_price_buy,double net_price_sell)

  {

/*

   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

*/

   if(InpTrailingStop==0)

      return;

   for(int i=PositionsTotal()-1;i>=0;i--) // returns the number of open positions

      if(m_position.SelectByIndex(i))

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)

           {

            double price_current = m_position.PriceCurrent();

            double price_open    = m_position.PriceOpen();

            double stop_loss     = m_position.StopLoss();

            double take_profit   = m_position.TakeProfit();

            double ask           = m_symbol.Ask();

            double bid           = m_symbol.Ask();

            //---

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(net_price_buy>0.0)

                  if(net_price_buy<price_current-(ExtTrailingStop+ExtTrailingStep))

                     if(ExtTrailingStop>=stop_level && (take_profit-bid>=stop_level || take_profit==0.0))

                       {

                        if(!CompareDoubles(stop_loss,net_price_buy+ExtTrailingStop,m_symbol.Digits()))

                          {

                           if(!m_trade.PositionModify(m_position.Ticket(),

                              m_symbol.NormalizePrice(net_price_buy+ExtTrailingStop),

                              take_profit))

                              Print("Modify BUY ",m_position.Ticket(),

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

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

                           RefreshRates();

                           m_position.SelectByIndex(i);

                           PrintResultModify(m_trade,m_symbol,m_position);

                           continue;

                          }

                       }

              }

            else

              {

               if(net_price_sell>0.0)

                  if((net_price_sell>(price_current+(ExtTrailingStop+ExtTrailingStep))) || (stop_loss==0))

                     if(ExtTrailingStop>=stop_level && ask-take_profit>=stop_level)

                       {

                        if(!CompareDoubles(stop_loss,net_price_sell-ExtTrailingStop,m_symbol.Digits()))

                          {

                           if(!m_trade.PositionModify(m_position.Ticket(),

                              m_symbol.NormalizePrice(net_price_sell-ExtTrailingStop),

                              take_profit))

                              Print("Modify SELL ",m_position.Ticket(),

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

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

                           RefreshRates();

                           m_position.SelectByIndex(i);

                           PrintResultModify(m_trade,m_symbol,m_position);

                          }

                       }

              }

           }

  }

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

//| Print CTrade result                                              |

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

void PrintResultModify(CTrade &trade,CSymbolInfo &symbol,CPositionInfo &position)

  {

   Print("File: ",__FILE__,", symbol: ",symbol.Name());

   Print("Code of request result: "+IntegerToString(trade.ResultRetcode()));

   Print("code of request result as a string: "+trade.ResultRetcodeDescription());

   Print("Deal ticket: "+IntegerToString(trade.ResultDeal()));

   Print("Order ticket: "+IntegerToString(trade.ResultOrder()));

   Print("Volume of deal or order: "+DoubleToString(trade.ResultVolume(),2));

   Print("Price, confirmed by broker: "+DoubleToString(trade.ResultPrice(),symbol.Digits()));

   Print("Current bid price: "+DoubleToString(symbol.Bid(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultBid(),symbol.Digits()));

   Print("Current ask price: "+DoubleToString(symbol.Ask(),symbol.Digits())+" (the requote): "+DoubleToString(trade.ResultAsk(),symbol.Digits()));

   Print("Broker comment: "+trade.ResultComment());

   Print("Freeze Level: "+DoubleToString(symbol.FreezeLevel(),0),", Stops Level: "+DoubleToString(symbol.StopsLevel(),0));

   Print("Price of position opening: "+DoubleToString(position.PriceOpen(),symbol.Digits()));

   Print("Price of position's Stop Loss: "+DoubleToString(position.StopLoss(),symbol.Digits()));

   Print("Price of position's Take Profit: "+DoubleToString(position.TakeProfit(),symbol.Digits()));

   Print("Current price by position: "+DoubleToString(position.PriceCurrent(),symbol.Digits()));

  }

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

//| Close positions                                                  |

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

void ClosePositions(const ENUM_POSITION_TYPE pos_type,const double level)

  {

/*

   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

*/

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

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)

            if(m_position.PositionType()==pos_type)

              {

               if(m_position.PositionType()==POSITION_TYPE_BUY)

                 {

                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.TakeProfit()-m_position.PriceCurrent()>=level) || m_position.TakeProfit()==0.0;

                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.PriceCurrent()-m_position.StopLoss()>=level) || m_position.StopLoss()==0.0;

                  if(take_profit_level && stop_loss_level)

                     m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol

                 }

               if(m_position.PositionType()==POSITION_TYPE_SELL)

                 {

                  bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.PriceCurrent()-m_position.TakeProfit()>=level) || m_position.TakeProfit()==0.0;

                  bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.StopLoss()-m_position.PriceCurrent()>=level) || m_position.StopLoss()==0.0;

                  if(take_profit_level && stop_loss_level)

                     m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol

                 }

              }

  }

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

//| Calculate all positions                                          |

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

void CalculateAllPositions(int &count_buys,double &volume_buys,double &volume_biggest_buys,

                           int &count_sells,double &volume_sells,double &volume_biggest_sells)

  {

   count_buys  = 0;  volume_buys   = 0.0; volume_biggest_buys  = 0.0;

   count_sells = 0;  volume_sells  = 0.0; volume_biggest_sells = 0.0;

   for(int i=PositionsTotal()-1;i>=0;i--)

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               count_buys++;

               volume_buys+=m_position.Volume();

               if(m_position.Volume()>volume_biggest_buys)

                  volume_biggest_buys=m_position.Volume();

               continue;

              }

            else if(m_position.PositionType()==POSITION_TYPE_SELL)

              {

               count_sells++;

               volume_sells+=m_position.Volume();

               if(m_position.Volume()>volume_biggest_sells)

                  volume_biggest_sells=m_position.Volume();

              }

           }

  }

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

//| Search trading signals                                           |

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

bool SearchTradingSignals(void)

  {

   MqlDateTime STimeCurrent,SStartTime,SStopTime;

   datetime time_current=TimeCurrent();

   TimeToStruct(time_current,STimeCurrent);



   SStartTime=STimeCurrent;

   SStartTime.min=0;

   SStartTime.sec=0;

   datetime start_time=StructToTime(SStartTime);



   SStopTime=STimeCurrent;

   SStopTime.min=59;

   SStopTime.sec=59;

   datetime stop_time=StructToTime(SStopTime);



   int session=-1;

   if(STimeCurrent.hour==InpSession_1_StartTime)

      session=1;

   else if(STimeCurrent.hour==InpSession_2_StartTime)

      session=2;

   if(STimeCurrent.hour==InpSession_3_StartTime)

      session=3;



   if(session==-1)

      return(true);



   int count_buy_stops   = 0;

   int count_sell_stops  = 0;

   CalculateAllPendingOrdersInTime(count_buy_stops,count_sell_stops,

                                   start_time,stop_time);

   if(count_buy_stops==0 || count_sell_stops==0)

     {

      if(count_buy_stops==0)

        {

         int size_need_pending=ArraySize(SNeedPending);

         ArrayResize(SNeedPending,size_need_pending+1);

         SNeedPending[size_need_pending].session=session;

         SNeedPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

         SNeedPending[size_need_pending].magic=InpMagic;

        }

      if(count_sell_stops==0)

        {

         int size_need_pending=ArraySize(SNeedPending);

         ArrayResize(SNeedPending,size_need_pending+1);

         SNeedPending[size_need_pending].session=session;

         SNeedPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

         SNeedPending[size_need_pending].magic=InpMagic;

        }

     }

//---

   return(true);

  }

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

//| Place Orders                                                     |

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

void PlaceOrders(const int index_in_structure,const int session,

                 const ENUM_ORDER_TYPE order_type,

                 const double level,const ulong magic)

  {

//--- check Freeze and Stops levels

/*

   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

                           

   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

*/

   if(session<0 || session>3)

      return;

   double price=0.0,inp_sl=0.0,sl=0.0,inp_tp=0.0,tp=0.0;

   datetime expiration=0;

//--- buy stop

   if(order_type==ORDER_TYPE_BUY_STOP)

     {

      if(session==1)

        {

         price=m_symbol.Ask()+ExtSession_1_Indent_UP;

         inp_sl=ExtSession_1_StopLoss;

         inp_tp=ExtSession_1_TakeProfit;

         expiration=TimeCurrent()+InpSession_1_LifeTime*60;

        }

      else if(session==2)

        {

         price=m_symbol.Ask()+ExtSession_2_Indent_UP;

         inp_sl=ExtSession_2_StopLoss;

         inp_tp=ExtSession_2_TakeProfit;

         expiration=TimeCurrent()+InpSession_2_LifeTime*60;

        }

      else if(session==3)

        {

         price=m_symbol.Ask()+ExtSession_3_Indent_UP;

         inp_sl=ExtSession_3_StopLoss;

         inp_tp=ExtSession_3_TakeProfit;

         expiration=TimeCurrent()+InpSession_3_LifeTime*60;

        }



      if(price-m_symbol.Ask()<level) // check price

         price=m_symbol.Ask()+level;



      sl=(inp_sl==0)?0.0:price-inp_sl;

      if(sl!=0.0 && inp_sl<level)// check sl

         sl=price-level;



      tp=(inp_tp==0)?0.0:price+inp_tp;

      if(tp!=0.0 && inp_tp<level) // check price

         tp=price+level;



      PendingOrder(session,ORDER_TYPE_BUY_STOP,price,expiration,sl,tp,magic);

      ArrayRemove(SNeedPending,index_in_structure,1);

      ExtWaitingPendingOrder=false;

     }

//--- sell stop

   if(order_type==ORDER_TYPE_SELL_STOP)

     {

      if(session==1)

        {

         price=m_symbol.Bid()-ExtSession_1_Indent_DOWN;

         inp_sl=ExtSession_1_StopLoss;

         inp_tp=ExtSession_1_TakeProfit;

         expiration=TimeCurrent()+InpSession_1_LifeTime*60;

        }

      else if(session==2)

        {

         price=m_symbol.Bid()-ExtSession_2_Indent_DOWN;

         inp_sl=ExtSession_2_StopLoss;

         inp_tp=ExtSession_2_TakeProfit;

         expiration=TimeCurrent()+InpSession_2_LifeTime*60;

        }

      else if(session==3)

        {

         price=m_symbol.Bid()-ExtSession_3_Indent_DOWN;

         inp_sl=ExtSession_3_StopLoss;

         inp_tp=ExtSession_3_TakeProfit;

         expiration=TimeCurrent()+InpSession_3_LifeTime*60;

        }



      if(m_symbol.Bid()-price<level) // check price

         price=m_symbol.Bid()-level;



      sl=(inp_sl==0)?0.0:price+inp_sl;

      if(sl!=0.0 && inp_sl<level) // check sl

         sl=price+level;



      tp=(inp_tp==0)?0.0:price-inp_tp;

      if(tp!=0.0 && inp_tp<level) // check tp

         tp=price-level;



      PendingOrder(session,ORDER_TYPE_SELL_STOP,price,expiration,sl,tp,magic);

      ArrayRemove(SNeedPending,index_in_structure,1);

      ExtWaitingPendingOrder=false;

     }

  }

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

//| Pending order                                                    |

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

bool PendingOrder(const int session,const ENUM_ORDER_TYPE order_type,double price,

                  const datetime expiration,

                  double sl,double tp,const ulong magic)

  {

   if(session<0 || session>3)

      return(false);

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   ENUM_ORDER_TYPE check_order_type=-1;

   switch(order_type)

     {

      case  ORDER_TYPE_BUY:

         check_order_type=ORDER_TYPE_BUY;

         break;

      case ORDER_TYPE_SELL:

         check_order_type=ORDER_TYPE_SELL;

         break;

      case ORDER_TYPE_BUY_LIMIT:

         check_order_type=ORDER_TYPE_BUY;

         break;

      case ORDER_TYPE_SELL_LIMIT:

         check_order_type=ORDER_TYPE_SELL;

         break;

      case ORDER_TYPE_BUY_STOP:

         check_order_type=ORDER_TYPE_BUY;

         break;

      case ORDER_TYPE_SELL_STOP:

         check_order_type=ORDER_TYPE_SELL;

         break;

      default:

         return(false);

         break;

     }

//---

   double long_lot=0.0;

   double short_lot=0.0;

   ENUM_LOT_OR_RISK inp_lot_or_risk=risk;

   double inp_volume_lot_or_risk=3.0;



   if(session==1)

     {

      inp_lot_or_risk=InpSession_1_LotOrRisk;

      inp_volume_lot_or_risk=InpSession_1_VolumeLotOrRisk;

     }

   else if(session==2)

     {

      inp_lot_or_risk=InpSession_2_LotOrRisk;

      inp_volume_lot_or_risk=InpSession_2_VolumeLotOrRisk;

     }

   else if(session==3)

     {

      inp_lot_or_risk=InpSession_3_LotOrRisk;

      inp_volume_lot_or_risk=InpSession_3_VolumeLotOrRisk;

     }



   if(inp_lot_or_risk==risk)

     {

      if(m_money!=NULL)

         delete m_money;

      m_money=new CMoneyFixedMargin;

      if(m_money!=NULL)

        {

         if(inp_lot_or_risk<1 || inp_lot_or_risk>100)

           {

            Print("The value for \"Money management\" (",DoubleToString(inp_lot_or_risk,2),") -> invalid parameters");

            Print("   parameter must be in the range: from 1.00 to 100.00");

            return(false);

           }

         if(!m_money.Init(GetPointer(m_symbol),Period(),m_symbol.Point()*digits_adjust))

            return(false);

         m_money.Percent(inp_volume_lot_or_risk);

        }

      else

        {

         Print(__FUNCTION__,", ERROR: Object CMoneyFixedMargin is NULL");

         return(false);

        }

      //---

      bool error=false;

      long_lot=m_money.CheckOpenLong(m_symbol.Ask(),sl);

      if(InpPrintLog)

         Print("sl=",DoubleToString(sl,m_symbol.Digits()),

               ", CheckOpenLong: ",DoubleToString(long_lot,2),

               ", Balance: ",    DoubleToString(m_account.Balance(),2),

               ", Equity: ",     DoubleToString(m_account.Equity(),2),

               ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(long_lot==0.0)

        {

         if(InpPrintLog)

            Print(__FUNCTION__,", ERROR: method CheckOpenLong returned the value of \"0.0\"");

         error=true;

        }

      //---

      short_lot=m_money.CheckOpenShort(m_symbol.Bid(),sl);

      if(InpPrintLog)

         Print("sl=",DoubleToString(sl,m_symbol.Digits()),

               ", CheckOpenLong: ",DoubleToString(short_lot,2),

               ", Balance: ",    DoubleToString(m_account.Balance(),2),

               ", Equity: ",     DoubleToString(m_account.Equity(),2),

               ", FreeMargin: ", DoubleToString(m_account.FreeMargin(),2));

      if(short_lot==0.0)

        {

         if(InpPrintLog)

            Print(__FUNCTION__,", ERROR: method CheckOpenShort returned the value of \"0.0\"");

         error=true;

        }

      //---

      if(error)

         return(false);

     }

   else if(inp_lot_or_risk==lot)

     {

      //--- check the input parameter "Lots"

      string err_text="";

      if(!CheckVolumeValue(inp_volume_lot_or_risk,err_text))

        {

         //--- when testing, we will only output to the log about incorrect input parameters

         if(MQLInfoInteger(MQL_TESTER))

           {

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

            return(false);

           }

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

           {

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

            return(false);

           }

        }

      //---

      long_lot=inp_volume_lot_or_risk;

      short_lot=inp_volume_lot_or_risk;

     }

   else if(inp_lot_or_risk==lots_min)

     {

      long_lot=m_symbol.LotsMin();

      short_lot=m_symbol.LotsMin();

     }

   else

      return(false);

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double check_price=0;

   double check_lot=0;

   if(check_order_type==ORDER_TYPE_BUY)

     {

      check_price=m_symbol.Ask();

      check_lot=long_lot;

     }

   else

     {

      check_price=m_symbol.Bid();

      check_lot=short_lot;

     }

//---

   if(m_symbol.LotsLimit()>0.0)

     {

      double volume_buys        = 0.0;   double volume_sells       = 0.0;

      double volume_buy_limits  = 0.0;   double volume_sell_limits = 0.0;

      double volume_buy_stops   = 0.0;   double volume_sell_stops  = 0.0;

      CalculateAllVolumes(volume_buys,volume_sells,

                          volume_buy_limits,volume_sell_limits,

                          volume_buy_stops,volume_sell_stops);

      if(volume_buys+volume_sells+

         volume_buy_limits+volume_sell_limits+

         volume_buy_stops+volume_sell_stops+check_lot>m_symbol.LotsLimit())

        {

         if(InpPrintLog)

            Print("#0 ,",EnumToString(order_type),", ",

                  "Volume Buy's (",DoubleToString(volume_buys,2),")",

                  "Volume Sell's (",DoubleToString(volume_sells,2),")",

                  "Volume Buy limit's (",DoubleToString(volume_buy_limits,2),")",

                  "Volume Sell limit's (",DoubleToString(volume_sell_limits,2),")",

                  "Volume Buy stops's (",DoubleToString(volume_buy_stops,2),")",

                  "Volume Sell stops's (",DoubleToString(volume_sell_stops,2),")",

                  "Check lot (",DoubleToString(check_lot,2),")",

                  " > Lots Limit (",DoubleToString(m_symbol.LotsLimit(),2),")");

         return(false);

        }

     }

//--- check volume before OrderSend to avoid "not enough money" error (CTrade)

   double free_margin_check= m_account.FreeMarginCheck(m_symbol.Name(),check_order_type,check_lot,check_price);

   double margin_check     = m_account.MarginCheck(m_symbol.Name(),check_order_type,check_lot,price);

   if(free_margin_check>margin_check)

     {

      if(m_trade.OrderOpen(m_symbol.Name(),order_type,check_lot,0.0,

         m_symbol.NormalizePrice(price),m_symbol.NormalizePrice(sl),m_symbol.NormalizePrice(tp),

         ORDER_TIME_SPECIFIED,expiration))

        {

         if(m_trade.ResultOrder()==0)

           {

            if(InpPrintLog)

               Print("#1 ",EnumToString(order_type)," -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

            return(false);

           }

         else

           {

            if(InpPrintLog)

               Print("#2 ",EnumToString(order_type)," -> true. Result Retcode: ",m_trade.ResultRetcode(),

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

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

            return(true);

           }

        }

      else

        {

         if(InpPrintLog)

            Print("#3 ",EnumToString(order_type)," -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

         if(InpPrintLog)

            PrintResultTrade(m_trade,m_symbol);

         return(false);

        }

     }

   else

     {

      if(InpPrintLog)

         Print(__FUNCTION__,", ERROR: method CAccountInfo::FreeMarginCheck returned the value ",DoubleToString(free_margin_check,2));

      return(false);

     }

//---

   return(false);

  }

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

//| Calculate all volumes                                            |

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

void CalculateAllVolumes(double &volumne_buys,double &volumne_sells,

                         double &volumne_buy_limits,double &volumne_sell_limits,

                         double &volumne_buy_stops,double &volumne_sell_stops)

  {

   volumne_buys         = 0.0;   volumne_sells        = 0.0;

   volumne_buy_limits   = 0.0;   volumne_sell_limits  = 0.0;

   volumne_buy_stops    = 0.0;   volumne_sell_stops   = 0.0;



   for(int i=PositionsTotal()-1;i>=0;i--)

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name())

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

               volumne_buys+=m_position.Volume();

            else if(m_position.PositionType()==POSITION_TYPE_SELL)

               volumne_sells+=m_position.Volume();

           }



   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

         if(m_order.Symbol()==m_symbol.Name())

           {

            if(m_order.OrderType()==ORDER_TYPE_BUY_LIMIT)

               volumne_buy_limits+=m_order.VolumeInitial();

            else if(m_order.OrderType()==ORDER_TYPE_SELL_LIMIT)

               volumne_sell_limits+=m_order.VolumeInitial();

            else if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)

               volumne_buy_stops+=m_order.VolumeInitial();

            else if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)

               volumne_sell_stops+=m_order.VolumeInitial();

           }

  }

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

//| Is position exists                                               |

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

bool IsPositionExists(void)

  {

   for(int i=PositionsTotal()-1;i>=0;i--)

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)

            return(true);

//---

   return(false);

  }

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

//| Close all positions                                              |

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

void CloseAllPositions(const double level)

  {

/*

   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

*/

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

      if(m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         if(m_position.Symbol()==m_symbol.Name() && m_position.Magic()==InpMagic)

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.TakeProfit()-m_position.PriceCurrent()>=level) || m_position.TakeProfit()==0.0;

               bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.PriceCurrent()-m_position.StopLoss()>=level) || m_position.StopLoss()==0.0;

               if(take_profit_level && stop_loss_level)

                  m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol

              }

            if(m_position.PositionType()==POSITION_TYPE_SELL)

              {

               bool take_profit_level=(m_position.TakeProfit()!=0.0 && m_position.PriceCurrent()-m_position.TakeProfit()>=level) || m_position.TakeProfit()==0.0;

               bool stop_loss_level=(m_position.StopLoss()!=0.0 && m_position.StopLoss()-m_position.PriceCurrent()>=level) || m_position.StopLoss()==0.0;

               if(take_profit_level && stop_loss_level)

                  m_trade.PositionClose(m_position.Ticket()); // close a position by the specified symbol

              }

           }

  }

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

//| Calculate all pending orders                                     |

//|   start_time <= TimeSetup && TimeSetup < stop_time               |

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

void CalculateAllPendingOrdersInTime(int &count_buy_stops,int &count_sell_stops,

                                     const datetime start_time,const datetime stop_time)

  {

   count_buy_stops   = 0;

   count_sell_stops  = 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

         if(m_order.Symbol()==m_symbol.Name() && m_order.Magic()==InpMagic)

            if(start_time<=m_order.TimeSetup() && m_order.TimeSetup()<stop_time)

              {

               if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)

                  count_buy_stops++;

               else if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)

                  count_sell_stops++;

              }

  }

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

//| Calculation Net Price                                            |

//| Formula for \"Breakeven\" is provided                            |

//|  Andrei Fandeev https://www.mql5.com/ru/users/andreifan"         |

//|  in: https://www.mql5.com/ru/forum/220911/page2#comment_6105972" |

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

double CalculationNetPrice(double &net_price_buy,double &net_price_sell)

  {

   int count_buys                            = 0;

   double total_price_multiply_volume_buy    = 0.0;

   double total_volume_buy                   = 0.0;

   net_price_buy                             = 0.0;



   int count_sells                           = 0;

   double total_price_multiply_volume_sell   = 0.0;

   double total_volume_sell                  = 0.0;

   net_price_sell                            = 0.0;



   double breakeven_price=0.0;



   int total=PositionsTotal();

   for(int i=total-1;i>=0;i--)

     {

      if(!m_position.SelectByIndex(i)) // selects the position by index for further access to its properties

         break;

      if(m_position.Symbol()==Symbol() && m_position.Magic()==InpMagic)

        {

         if(m_position.PositionType()==POSITION_TYPE_BUY)

           {

            count_buys++;

            total_price_multiply_volume_buy+=m_position.PriceOpen()*m_position.Volume();

            total_volume_buy+=m_position.Volume();

           }

         else

           {

            count_sells++;

            total_price_multiply_volume_sell+=m_position.PriceOpen()*m_position.Volume();

            total_volume_sell+=m_position.Volume();

           }

        }

     }

//---

   if(total_price_multiply_volume_buy!=0 && total_volume_buy!=0)

     {

      net_price_buy=total_price_multiply_volume_buy/total_volume_buy;

      if(count_buys>1)

         HLineMove(0,m_hline_name_buy,net_price_buy);

      else

        {

         net_price_buy=0.0;

         HLineMove(0,m_hline_name_buy,0.0);

        }

     }



   if(total_price_multiply_volume_sell!=0 && total_volume_sell!=0)

     {

      net_price_sell=total_price_multiply_volume_sell/total_volume_sell;

      if(count_sells>1)

         HLineMove(0,m_hline_name_sell,net_price_sell);

      else

        {

         net_price_sell=0.0;

         HLineMove(0,m_hline_name_sell,0.0);

        }

     }



   if(total_volume_buy-total_volume_sell!=0)

      breakeven_price=(total_price_multiply_volume_buy-total_price_multiply_volume_sell)/

                      (total_volume_buy+total_volume_sell*-1);

//---

   return(breakeven_price);

  }

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

//| Create the horizontal line                                       | 

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

bool HLineCreate(const long            chart_ID=0,        // chart's ID 

                 const string          name="HLine",      // line name 

                 const int             sub_window=0,      // subwindow index 

                 double                price=0,           // line price 

                 const color           clr=clrRed,        // line color 

                 const ENUM_LINE_STYLE style=STYLE_SOLID, // line style 

                 const int             width=1,           // line width 

                 const bool            back=false,        // in the background 

                 const bool            selection=false,   // highlight to move 

                 const bool            hidden=true,       // hidden in the object list 

                 const long            z_order=0)         // priority for mouse click 

  {

////--- if the price is not set, set it at the current Bid price level 

//   if(!price)

//      price=SymbolInfoDouble(Symbol(),SYMBOL_BID);

//--- reset the error value 

   ResetLastError();

//--- create a horizontal line 

   if(!ObjectCreate(chart_ID,name,OBJ_HLINE,sub_window,0,price))

     {

      Print(__FUNCTION__,

            ": failed to create a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- set line color 

   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);

//--- set line display style 

   ObjectSetInteger(chart_ID,name,OBJPROP_STYLE,style);

//--- set line width 

   ObjectSetInteger(chart_ID,name,OBJPROP_WIDTH,width);

//--- display in the foreground (false) or background (true) 

   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);

//--- enable (true) or disable (false) the mode of moving the line by mouse 

//--- when creating a graphical object using ObjectCreate function, the object cannot be 

//--- highlighted and moved by default. Inside this method, selection parameter 

//--- is true by default making it possible to highlight and move the object 

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);

   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);

//--- hide (true) or display (false) graphical object name in the object list 

   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);

//--- set the priority for receiving the event of a mouse click in the chart 

   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);

//--- successful execution 

   return(true);

  }

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

//| Move horizontal line                                             | 

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

bool HLineMove(const long   chart_ID=0,   // chart's ID 

               const string name="HLine", // line name 

               double       price=0)      // line price 

  {

//--- if the line price is not set, move it to the current Bid price level 

   if(!price)

      price=0.0;

//--- reset the error value 

   ResetLastError();

//--- move a horizontal line 

   if(!ObjectMove(chart_ID,name,0,0,price))

     {

      Print(__FUNCTION__,

            ": failed to move the horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

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

//| Delete a horizontal line                                         | 

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

bool HLineDelete(const long   chart_ID=0,   // chart's ID 

                 const string name="HLine") // line name 

  {

//--- reset the error value 

   ResetLastError();

//--- delete a horizontal line 

   if(!ObjectDelete(chart_ID,name))

     {

      Print(__FUNCTION__,

            ": failed to delete a horizontal line! Error code = ",GetLastError());

      return(false);

     }

//--- successful execution 

   return(true);

  }

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

//| Compare doubles                                                  |

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

bool CompareDoubles(double number1,double number2,int digits)

  {

   digits--;

   if(digits<0)

      digits=0;

   if(NormalizeDouble(number1-number2,digits)==0)

      return(true);

   else

      return(false);

  }

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

Comments