iRSI Pending Limit Grid

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
iRSI Pending Limit Grid
ÿþ//+------------------------------------------------------------------+

//|                                      iRSI Pending Limit Grid.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.101

*/

#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;                   // object of CPositionInfo class

CTrade         m_trade;                      // object of CTrade class

CSymbolInfo    m_symbol;                     // object of CSymbolInfo class

CAccountInfo   m_account;                    // object of CAccountInfo class

CDealInfo      m_deal;                       // object of CDealInfo class

COrderInfo     m_order;                      // object of COrderInfo class

CMoneyFixedMargin *m_money;                  // object of CMoneyFixedMargin class

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

//| Enum Lot or Risk                                                 |

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

enum ENUM_LOT_OR_RISK

  {

   lots_min=0, // Lots Min

   lot=1,      // Constant lot

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

  };

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

//| Enum Lot coefficient                                             |

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

enum ENUM_LOT_COEFF

  {

   profit=0,   // Profit

   loss=1,     // Loss

  };

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

//| Enum Take profit type                                            |

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

enum ENUM_TAKE_PROFIT

  {

   standart=0, // Standard

   none=1,     // NONE

  };

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

//| Enum Stop loss type                                              |

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

enum ENUM_STOP_LOSS

  {

   standard=0, // Standard

   breakeven=1,// Breakeven

  };

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

//| Enum Strategy type                                               |

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

enum ENUM_STRATEGY

  {

   in=0,       // IN

   out=1,      // OUT

   inside=2,   // INSIDE

  };

//--- input parameters

input ushort   InpPendingExpiration = 600;         // Pending: Expiration (in minutes, minimum 15)

input ushort   InpPendingIndent     = 5;           // Pending: Indent, in pips (1.00045-1.00055=1 pips)

input ushort   InpMaxSpread         = 12;          // Pending: Maximum spread, in points (1.00045-1.00055=10 points)

//--- Lot

input ENUM_LOT_OR_RISK InpLotOrRisk = risk;        // Money management: Lot OR Risk

input double   InpVolumeLotOrRisk   = 3.0;         // The value for "Money management"

input double   InpLotCoeff          = 1.6;         // Lot coefficient ("1.0" -> off "Lot coefficient: Type")

input ENUM_LOT_COEFF InpLotCoeffType= loss;        // Lot coefficient: Type

//--- Take Profit

input ushort   InpTakeProfit        = 65;          // Take Profit, in pips (1.00045-1.00055=1 pips)

input ENUM_TAKE_PROFIT InpTakeProfitType=standart; // Take Profit: Type

//--- Stop Loss

input ushort   InpStopLoss          = 65;          // Stop Loss, in pips (1.00045-1.00055=1 pips)

input ENUM_STOP_LOSS InpStopLossType=breakeven;    // Stop Loss: Type

input ushort   InpStopLossBreakeven = 15;          // Stop loss: Breakeven, in pips (1.00045-1.00055=1 pips)

//--- Strategy

input ENUM_STRATEGY InpStrategy     = in;          // Strategy: Type

//--- RSI Custom Smoothing 3

input uchar             InpCurrentBar        = 1;              // Current Bar

input int               Inp_RSI_Period       = 7;              // Averaging Period

input color             Inp_RSI_Color        = clrDodgerBlue;  // Color line

input int               Inp_RSI_Width        = 1;              // Width

input int               Inp_RSI_Level_Down   = 35.0;           // Value Level Down

input double            Inp_RSI_Level_Up     = 65.0;           // Value Level Up

input bool              InpUseSmoothing      = true;           // Use Smoothing

input ENUM_MA_METHOD    InpSmoothMethod      = MODE_EMA;       // Smoothing type

input int               InpSmootPeriod       = 3;              // Smoothing Period

//---

input ulong    InpDeviation         = 10;          // Deviation, in points (1.00045-1.00055=10 points)

//---

input bool     InpPrintLog          = false;       // Print log

input ulong    InpMagic             = 200;         // Magic number

//---

double m_pending_indent          = 0.0;      // Pending: Indent         -> double

double m_max_spread              = 0.0;      // Pending: Maximum spread -> double

double m_take_profit             = 0.0;      // Take Profit             -> double

double m_stop_loss               = 0.0;      // Stop Loss               -> double

double m_breakeven               = 0.0;      // Breakeven               -> double



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



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

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

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

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

//--- ***

//---    and pending orders (if the spread was verified)

//---    just shoot and zero out the arrays of structures

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

//| Structurt Pending                                                |

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

struct STRUCT_PENDING

  {

   ENUM_ORDER_TYPE   pending_type;           // pending order type

   double            volume;                 // pending order volume

   double            price;                  // pending order price

   double            stop_loss;              // pending order stop loss, in pips * m_adjusted_point (if "0.0" -> the m_stop_loss)

   double            take_profit;            // pending order take profit, in pips * m_adjusted_point (if "0.0" -> the m_take_profit)

   //--- Constructor

                     STRUCT_PENDING()

     {

      pending_type               = WRONG_VALUE;

      volume                     = 0.0;

      price                      = 0.0;

      stop_loss                  = 0.0;

      take_profit                = 0.0;

     }

  };

STRUCT_PENDING SPending[];

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

//| Expert initialization function                                   |

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

int OnInit()

  {

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

     {

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

      return(INIT_FAILED);

     }

   RefreshRates();

//---

   m_trade.SetExpertMagicNumber(InpMagic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(InpDeviation);

//--- tuning for 3 or 5 digits

   int digits_adjust=1;

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

      digits_adjust=10;

   m_adjusted_point=m_symbol.Point()*digits_adjust;



   m_pending_indent        = InpPendingIndent         * m_adjusted_point;

   m_max_spread            = InpMaxSpread             * m_symbol.Point();

   m_stop_loss             = InpStopLoss              * m_adjusted_point;

   m_take_profit           = InpTakeProfit            * m_adjusted_point;

   m_breakeven             = InpStopLossBreakeven     * m_adjusted_point;

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

   string err_text="";

   if(InpLotOrRisk==lot)

     {

      if(!CheckVolumeValue(InpVolumeLotOrRisk,err_text))

        {

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

         if(MQLInfoInteger(MQL_TESTER))

           {

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

            return(INIT_FAILED);

           }

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

           {

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

            return(INIT_PARAMETERS_INCORRECT);

           }

        }

     }

   else

      if(InpLotOrRisk==risk)

        {

         if(m_money!=NULL)

            delete m_money;

         m_money=new CMoneyFixedMargin;

         if(m_money!=NULL)

           {

            if(InpVolumeLotOrRisk<1 || InpVolumeLotOrRisk>100)

              {

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

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

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

               return(INIT_FAILED);

              }

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

              {

               Print(__FILE__," ",__FUNCTION__,", ERROR: CMoneyFixedMargin.Init");

               return(INIT_FAILED);

              }

            m_money.Percent(InpVolumeLotOrRisk);

           }

         else

           {

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

            return(INIT_FAILED);

           }

        }

//--- create handle of the indicator iCustom

   handle_iCustom=iCustom(m_symbol.Name(),Period(),"RSI Custom Smoothing 3",

                          Inp_RSI_Period,

                          Inp_RSI_Color,

                          Inp_RSI_Width,

                          Inp_RSI_Level_Down,

                          Inp_RSI_Level_Up,

                          InpUseSmoothing,

                          InpSmoothMethod,

                          InpSmootPeriod);

//--- if the handle is not created

   if(handle_iCustom==INVALID_HANDLE)

     {

      //--- tell about the failure and output the error code

      PrintFormat("Failed to create handle of the iCustom indicator for the symbol %s/%s, error code %d",

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---

   if(m_money!=NULL)

      delete m_money;

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

   int size_need_pending=ArraySize(SPending);

   if(size_need_pending>0)

     {

      if(!m_waiting_pending_order)

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

           {

            double level;

            double adjusted_point=0;

            if(FreezeStopsLevels(level))

              {

               m_waiting_pending_order=true;

               PlaceOrders(i,level);

              }

           }

      return;

     }

//---

   datetime time_current=TimeCurrent();

   if(time_current-m_last_calculate>10)

     {

      int count_buys=0;

      int count_sells=0;

      CalculateAllPositions(count_buys,count_sells);



      if(count_buys>1 || count_sells>1)

        {

         double level;

         if(FreezeStopsLevels(level))

            ModifyTakeProfit(level);

         else

            return;

         if(InpStopLossType==breakeven)

           {

            if(FreezeStopsLevels(level))

               ModifyStopLoss(level);

            else

               return;

           }

        }

      m_last_calculate=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==m_prev_bars)

      return;

   m_prev_bars=time_0;

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

   if(!RefreshRates())

     {

      m_prev_bars=0;

      return;

     }

//--- search for trading signals

   if(!SearchTradingSignals())

     {

      m_prev_bars=0;

      return;

     }

//---

  }

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

//| TradeTransaction function                                        |

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

void OnTradeTransaction(const MqlTradeTransaction &trans,

                        const MqlTradeRequest &request,

                        const MqlTradeResult &result)

  {

//--- get transaction type as enumeration value

   ENUM_TRADE_TRANSACTION_TYPE type=trans.type;

//--- if transaction is result of addition of the transaction in history

   if(type==TRADE_TRANSACTION_DEAL_ADD)

     {

      long     deal_ticket       =0;

      long     deal_order        =0;

      long     deal_time         =0;

      long     deal_time_msc     =0;

      long     deal_type         =-1;

      long     deal_entry        =-1;

      long     deal_magic        =0;

      long     deal_reason       =-1;

      long     deal_position_id  =0;

      double   deal_volume       =0.0;

      double   deal_price        =0.0;

      double   deal_commission   =0.0;

      double   deal_swap         =0.0;

      double   deal_profit       =0.0;

      string   deal_symbol       ="";

      string   deal_comment      ="";

      string   deal_external_id  ="";

      if(HistoryDealSelect(trans.deal))

        {

         deal_ticket       =HistoryDealGetInteger(trans.deal,DEAL_TICKET);

         deal_order        =HistoryDealGetInteger(trans.deal,DEAL_ORDER);

         deal_time         =HistoryDealGetInteger(trans.deal,DEAL_TIME);

         deal_time_msc     =HistoryDealGetInteger(trans.deal,DEAL_TIME_MSC);

         deal_type         =HistoryDealGetInteger(trans.deal,DEAL_TYPE);

         deal_entry        =HistoryDealGetInteger(trans.deal,DEAL_ENTRY);

         deal_magic        =HistoryDealGetInteger(trans.deal,DEAL_MAGIC);

         deal_reason       =HistoryDealGetInteger(trans.deal,DEAL_REASON);

         deal_position_id  =HistoryDealGetInteger(trans.deal,DEAL_POSITION_ID);



         deal_volume       =HistoryDealGetDouble(trans.deal,DEAL_VOLUME);

         deal_price        =HistoryDealGetDouble(trans.deal,DEAL_PRICE);

         deal_commission   =HistoryDealGetDouble(trans.deal,DEAL_COMMISSION);

         deal_swap         =HistoryDealGetDouble(trans.deal,DEAL_SWAP);

         deal_profit       =HistoryDealGetDouble(trans.deal,DEAL_PROFIT);



         deal_symbol       =HistoryDealGetString(trans.deal,DEAL_SYMBOL);

         deal_comment      =HistoryDealGetString(trans.deal,DEAL_COMMENT);

         deal_external_id  =HistoryDealGetString(trans.deal,DEAL_EXTERNAL_ID);

        }

      else

         return;

      ENUM_DEAL_ENTRY enum_deal_entry=(ENUM_DEAL_ENTRY)deal_entry;

      if(deal_symbol==m_symbol.Name() && deal_magic==InpMagic)

        {

         if(deal_type==DEAL_TYPE_BUY || deal_type==DEAL_TYPE_SELL)

           {

            if(deal_entry==DEAL_ENTRY_IN)

              {



              }

           }

        }

     }

  }

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

//| Refreshes the symbol quotes data                                 |

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

bool RefreshRates()

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      if(InpPrintLog)

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

      return(false);

     }

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

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

     {

      if(InpPrintLog)

         Print(__FILE__," ",__FUNCTION__,", ERROR: ","Ask == 0.0 OR Bid == 0.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,CSymbolInfo &symbol)

  {

//--- calculate maximum volume

   double volume=NormalizeDouble(lots,2);

   double stepvol=symbol.LotsStep();

   if(stepvol>0.0)

      volume=stepvol*MathFloor(volume/stepvol);

//---

   double minvol=symbol.LotsMin();

   if(volume<minvol)

      volume=0.0;

//---

   double maxvol=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()*m_adjusted_point;

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

//---

   return(true);

  }

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

//| Print CTrade result                                              |

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

void PrintResultTrade(CTrade &trade,CSymbolInfo &symbol)

  {

   Print(__FILE__," ",__FUNCTION__,", Symbol: ",symbol.Name()+", "+

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

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

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

         "Order ticket: "+IntegerToString(trade.ResultOrder())+", "+

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

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

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

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

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

  }

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

//| Get value of buffers                                             |

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

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

               const int count,double &arr_buffer[])

  {

   bool result=true;

   if(!ArrayIsDynamic(arr_buffer))

     {

      if(InpPrintLog)

         Print(__FILE__," ",__FUNCTION__,", ERROR: ","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(__FILE__," ",__FUNCTION__,", ERROR: ","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)

  {

   /*

      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.Bid();

             //---

             if(m_position.PositionType()==POSITION_TYPE_BUY)

               {

                if(price_current-price_open>m_trailing_stop+m_trailing_step)

                   if(stop_loss<price_current-(m_trailing_stop+m_trailing_step))

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

                        {

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

                                                    m_symbol.NormalizePrice(price_current-m_trailing_stop),

                                                    take_profit))

                            if(InpPrintLog)

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

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

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

                         if(InpPrintLog)

                           {

                            RefreshRates();

                            m_position.SelectByIndex(i);

                            PrintResultModify(m_trade,m_symbol,m_position);

                           }

                         continue;

                        }

               }

             else

               {

                if(price_open-price_current>m_trailing_stop+m_trailing_step)

                   if((stop_loss>(price_current+(m_trailing_stop+m_trailing_step))) || (stop_loss==0))

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

                        {

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

                                                    m_symbol.NormalizePrice(price_current+m_trailing_stop),

                                                    take_profit))

                            if(InpPrintLog)

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

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

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

                         if(InpPrintLog)

                           {

                            RefreshRates();

                            m_position.SelectByIndex(i);

                            PrintResultModify(m_trade,m_symbol,m_position);

                           }

                        }

               }

            }*/

  }

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

//| Modify Take Profit                                               |

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

void ModifyTakeProfit(const double stop_level)

  {

   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.Bid();

            double new_take_profit=0.0;

            //---

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(InpTakeProfitType==standart)

                 {

                  if(take_profit>0.0)

                     continue;

                  new_take_profit=(m_take_profit==0.0)?0.0:m_symbol.Ask()+m_take_profit;

                 }

               else

                 {

                  new_take_profit=0.0;

                 }

               if(!CompareDoubles(take_profit,new_take_profit,m_symbol.Digits()))

                 {

                  if((new_take_profit-bid>=stop_level || new_take_profit==0.0))

                    {

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

                                                stop_loss,

                                                m_symbol.NormalizePrice(new_take_profit)))

                        if(InpPrintLog)

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

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

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

                     if(InpPrintLog)

                       {

                        RefreshRates();

                        m_position.SelectByIndex(i);

                        PrintResultModify(m_trade,m_symbol,m_position);

                       }

                     continue;

                    }

                 }

              }

            else

              {

               if(InpTakeProfitType==standart)

                 {

                  if(take_profit>0.0)

                     continue;

                  new_take_profit=(m_take_profit==0.0)?0.0:m_symbol.Bid()-m_take_profit;

                 }

               else

                 {

                  new_take_profit=0.0;

                 }

               if(!CompareDoubles(take_profit,new_take_profit,m_symbol.Digits()))

                 {

                  if((ask-new_take_profit>=stop_level || new_take_profit==0.0))

                    {

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

                                                stop_loss,

                                                m_symbol.NormalizePrice(new_take_profit)))

                        if(InpPrintLog)

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

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

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

                     if(InpPrintLog)

                       {

                        RefreshRates();

                        m_position.SelectByIndex(i);

                        PrintResultModify(m_trade,m_symbol,m_position);

                       }

                     continue;

                    }

                 }

              }

           }

  }

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

//| Modify Stop Loss                                                 |

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

void ModifyStopLoss(const double stop_level)

  {

   if(InpStopLossType==standard)

      return;

   double net_price_buy=0.0;

   double net_price_sell=0.0;

   CalculationNetPrice(net_price_buy,net_price_sell);



   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.Bid();

            //---

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(net_price_buy==0.0)

                  continue;

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

                 {

                  if(bid-net_price_buy>=stop_level)

                    {

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

                                                m_symbol.NormalizePrice(net_price_buy),

                                                take_profit))

                        if(InpPrintLog)

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

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

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

                     if(InpPrintLog)

                       {

                        RefreshRates();

                        m_position.SelectByIndex(i);

                        PrintResultModify(m_trade,m_symbol,m_position);

                       }

                     continue;

                    }

                 }

              }

            else

              {

               if(net_price_sell==0.0)

                  continue;

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

                 {

                  if(net_price_sell-ask>=stop_level)

                    {

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

                                                m_symbol.NormalizePrice(net_price_sell),

                                                take_profit))

                        if(InpPrintLog)

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

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

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

                     if(InpPrintLog)

                       {

                        RefreshRates();

                        m_position.SelectByIndex(i);

                        PrintResultModify(m_trade,m_symbol,m_position);

                       }

                     continue;

                    }

                 }

              }

           }

  }

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

//| 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()));

  }

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

//| 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)

  {

   double rsi[];

   ArraySetAsSeries(rsi,true);

   int start_pos=0,count=InpCurrentBar+3;

//---

   if(!iGetArray(handle_iCustom,0,start_pos,count,rsi))

      return(false);



   if(InpStrategy==in)

     {

      /*

      !83=0; "BUY":

         RSI #Current Bar+1 > Value Level Down && RSI #Current Bar < Value Level Down

      !83=0; "SELL":

         RSI #Current Bar+1 < Value Level Up && RSI #Current Bar+1 > Value Level Up

      */

      int size_need_pending=ArraySize(SPending);

      if(rsi[InpCurrentBar+1]>Inp_RSI_Level_Down && rsi[InpCurrentBar]<Inp_RSI_Level_Down)

        {

         ArrayResize(SPending,size_need_pending+1);

         SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_LIMIT;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", OK: ","Signal IN BUY LIMIT");

         return(true);

        }

      if(rsi[InpCurrentBar+1]<Inp_RSI_Level_Up && rsi[InpCurrentBar]>Inp_RSI_Level_Up)

        {

         ArrayResize(SPending,size_need_pending+1);

         SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_LIMIT;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", OK: ","Signal IN SELL LIMIT");

         return(true);

        }

     }

   if(InpStrategy==out)

     {

      /*

      !83=0; "BUY":

         RSI #Current Bar+1 < Value Level Down && RSI #Current Bar > Value Level Down

      !83=0; "SELL":

         RSI #Current Bar+1 > Value Level Up && RSI #Current Bar+1 <  Value Level Up

      */

      int size_need_pending=ArraySize(SPending);

      if(rsi[InpCurrentBar+1]<Inp_RSI_Level_Down && rsi[InpCurrentBar]>Inp_RSI_Level_Down)

        {

         ArrayResize(SPending,size_need_pending+1);

         SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_LIMIT;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", OK: ","Signal OUT BUY LIMIT");

         return(true);

        }

      if(rsi[InpCurrentBar+1]>Inp_RSI_Level_Up && rsi[InpCurrentBar]<Inp_RSI_Level_Up)

        {

         ArrayResize(SPending,size_need_pending+1);

         SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_LIMIT;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", OK: ","Signal OUT SELL LIMIT");

         return(true);

        }

     }

   if(InpStrategy==inside)

     {

      /*

      !83=0; "BUY":

         RSI #Current Bar < Value Level Down

      !83=0; "SELL":

         RSI #Current Bar > Value Level Up

      */

      int size_need_pending=ArraySize(SPending);

      if(rsi[InpCurrentBar]<Inp_RSI_Level_Down)

         if(rsi[InpCurrentBar+1]<Inp_RSI_Level_Down && rsi[InpCurrentBar]>Inp_RSI_Level_Down)

           {

            ArrayResize(SPending,size_need_pending+1);

            SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_LIMIT;

            if(InpPrintLog)

               Print(__FILE__," ",__FUNCTION__,", OK: ","Signal INSIDE BUY LIMIT");

            return(true);

           }

      if(rsi[InpCurrentBar]>Inp_RSI_Level_Up)

        {

         ArrayResize(SPending,size_need_pending+1);

         SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_LIMIT;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", OK: ","Signal INSIDE SELL LIMIT");

         return(true);

        }

     }

//---

   return(true);

  }

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

//| Place Orders                                                     |

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

void PlaceOrders(const int index,const 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

   */

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

   if(spread>m_max_spread)

     {

      m_waiting_pending_order=false;

      return;

     }

//---

   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((SPending[index].pending_type==ORDER_TYPE_BUY_LIMIT && (volume_sells>0 || volume_sell_limits>0.0)) ||

      (SPending[index].pending_type==ORDER_TYPE_SELL_LIMIT && (volume_buys>0 || volume_buy_limits>0.0)))

     {

      ArrayRemove(SPending,index,1);

      m_waiting_pending_order=false;

      return;

     }

//--- buy limit

   if(SPending[index].pending_type==ORDER_TYPE_BUY_LIMIT)

     {

      SPending[index].price=m_symbol.Ask()-m_pending_indent;

      if(m_symbol.Ask()-SPending[index].price<level) // check price

         SPending[index].price=m_symbol.Ask()-level;

      SPending[index].stop_loss=(m_stop_loss==0.0)?0.0:SPending[index].price-m_stop_loss;

      SPending[index].take_profit=(m_take_profit==0.0)?0.0:SPending[index].price+m_take_profit;

      double sl=SPending[index].stop_loss;

      if(sl<=0.0) // check sl

         sl=0.0;

      else

         if(SPending[index].price-sl<level)

            sl=SPending[index].price-level;



      double tp=0.0;



      PendingOrder(index,sl,tp);

      ArrayRemove(SPending,index,1);

      m_waiting_pending_order=false;

      return;

     }

//--- sell limit

   if(SPending[index].pending_type==ORDER_TYPE_SELL_LIMIT)

     {

      SPending[index].price=m_symbol.Bid()+m_pending_indent;

      if(SPending[index].price-m_symbol.Bid()<level) // check price

         SPending[index].price=m_symbol.Bid()+level;

      SPending[index].stop_loss=(m_stop_loss==0.0)?0.0:SPending[index].price+m_stop_loss;

      SPending[index].take_profit=(m_take_profit==0.0)?0.0:SPending[index].price-m_take_profit;

      double sl=SPending[index].stop_loss;

      if(sl<=0.0) // check sl

         sl=0.0;

      else

         if(sl-SPending[index].price<level)

            sl=SPending[index].price+level;



      double tp=0.0;



      PendingOrder(index,sl,tp);

      ArrayRemove(SPending,index,1);

      m_waiting_pending_order=false;

      return;

     }

  }

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

//| Pending order                                                    |

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

bool PendingOrder(const int index,double sl,double tp)

  {

   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(SPending[index].pending_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;

   if(InpLotOrRisk==risk)

     {

      bool error=false;

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

      if(InpPrintLog)

         Print(__FILE__," ",__FUNCTION__,", OK: ","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(__FILE__," ",__FUNCTION__,", ERROR: ","CMoneyFixedMargin.CheckOpenLong returned the value of \"0.0\"");

         error=true;

        }

      //---

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

      if(InpPrintLog)

         Print(__FILE__," ",__FUNCTION__,", OK: ","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(__FILE__," ",__FUNCTION__,", ERROR: ","CMoneyFixedMargin.CheckOpenShort returned the value of \"0.0\"");

         error=true;

        }

      //---

      if(error)

         return(false);

     }

   else

      if(InpLotOrRisk==lot)

        {

         long_lot=InpVolumeLotOrRisk;

         short_lot=InpVolumeLotOrRisk;

        }

      else

         if(InpLotOrRisk==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(InpLotCoeff!=1.0)

     {

      double profit_all_positions=ProfitAllPositions();

      if((InpLotCoeffType==profit && profit_all_positions>0.0) || (InpLotCoeffType==loss && profit_all_positions<0.0))

        {

         check_lot=LotCheck(check_lot*InpLotCoeff,m_symbol);

         if(check_lot==0.0)

           {

            if(InpPrintLog)

               Print(__FILE__," ",__FUNCTION__,", ERROR: ","LotCheck returned the value of \"0.0\"");

            return(false);

           }

        }

     }

//---

   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(__FILE__," ",__FUNCTION__,", ERROR: ","#0 ,",EnumToString(SPending[index].pending_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 maximal number of allowed pending orders

   int account_limit_orders=m_account.LimitOrders();

   if(account_limit_orders>0)

     {

      int all_pending_orders=CalculateAllPendingOrders();

      /*

            there is 8,  and there will be  9 > restriction 10 -> OK

            there is 9,  and there will be 10 > restriction 10 -> OK

            there is 10, and there will be 11 > restriction 10 -> ERROR

      */

      if(all_pending_orders+1>account_limit_orders)

         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,SPending[index].price);

   if(free_margin_check>margin_check)

     {

      datetime time_expiration=TimeCurrent()+InpPendingExpiration*60;

      if(m_trade.OrderOpen(m_symbol.Name(),

                           SPending[index].pending_type,check_lot,0.0,

                           m_symbol.NormalizePrice(SPending[index].price),

                           m_symbol.NormalizePrice(sl),

                           m_symbol.NormalizePrice(tp),

                           ORDER_TIME_SPECIFIED,

                           time_expiration))

        {

         if(m_trade.ResultOrder()==0)

           {

            if(InpPrintLog)

               Print(__FILE__," ",__FUNCTION__,", ERROR: ","#1 ",EnumToString(SPending[index].pending_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(__FILE__," ",__FUNCTION__,", OK: ","#2 ",EnumToString(SPending[index].pending_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(__FILE__," ",__FUNCTION__,", ERROR: ","#3 ",EnumToString(SPending[index].pending_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(__FILE__," ",__FUNCTION__,", ERROR: 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();

           }

  }

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

//| Calculate all pending orders                                     |

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

int CalculateAllPendingOrders(void)

  {

   int count=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

         count++;

//---

   return(count);

  }

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

//| Profit all positions                                             |

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

double ProfitAllPositions(void)

  {

   double profit=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)

            profit+=m_position.Commission()+m_position.Swap()+m_position.Profit();

//---

   return(profit);

  }

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

//| Calculate all positions Buy and Sell                             |

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

void CalculateAllPositions(int &count_buys,int &count_sells)

  {

   count_buys=0;

   count_sells=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++;



            if(m_position.PositionType()==POSITION_TYPE_SELL)

               count_sells++;

           }

//---

   return;

  }

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

//| 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);

  }

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

//| 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" |

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

void CalculationNetPrice(double &net_price_buy,double &net_price_sell)

  {

   double total_price_multiply_volume_buy    = 0.0;

   double total_volume_buy                   = 0.0;

   net_price_buy                             = 0.0;



   double total_price_multiply_volume_sell   = 0.0;

   double total_volume_sell                  = 0.0;

   net_price_sell                            = 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())

        {

         if(m_position.PositionType()==POSITION_TYPE_BUY)

           {

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

            total_volume_buy+=m_position.Volume();

           }

         else

           {

            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(total_price_multiply_volume_sell!=0 && total_volume_sell!=0)

      net_price_sell=total_price_multiply_volume_sell/total_volume_sell;

//---

   return;

  }

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

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---