New Day New Pending Order 2

Author: Copyright © 2020, 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
New Day New Pending Order 2
ÿþ//+------------------------------------------------------------------+

//|                                  New Day New Pending Order 2.mq5 |

//|                              Copyright © 2020, Vladimir Karputov |

//|                     https://www.mql5.com/ru/market/product/43516 |

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

#property copyright "Copyright © 2020, Vladimir Karputov"

#property link      "https://www.mql5.com/ru/market/product/43516"

#property version   "2.001"

/*

   barabashkakvn Trading engine 3.112

*/

#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 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

  };

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

//| Enum Type Trade                                                  |

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

enum ENUM_TYPE_TRADE

  {

   buy_stop=0,             // Only Buy stop

   sell_stop=1,            // Only Sell stop

   buy_stop_sell_stop=2,   // Buy stop and Sell stop

  };

//--- input parameters

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

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

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

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

input ushort   InpTrailingStop      = 0;           // 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)

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

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

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

//---

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

//--- Monday

input datetime InpMonday_1                   = D'1980.07.19 10:00:00';  // Monday time 1 (use only HH::MM) (00::00 -> off)

input datetime InpMonday_2                   = D'1980.07.19 15:00:00';  // Monday time 2 (use only HH::MM) (00::00 -> off)

input datetime InpMonday_3                   = D'1980.07.19 18:00:00';  // Monday time 3 (use only HH::MM) (00::00 -> off)

input ushort   InpMondayPendingExpiration    = 600;                     // Monday expiration (in minutes, minimum 15)

input ushort   InpMondayPendingIndent        = 5;                       // Monday indent, in pips (1.00045-1.00055=1 pips)

input ENUM_TYPE_TRADE InpMondayTypeTrade     = buy_stop_sell_stop;      // Monday Type Trade

//--- Tuesday

input datetime InpTuesday_1                  = D'1980.07.19 10:00:00';  // Tuesday time 1 (use only HH::MM) (00::00 -> off)

input datetime InpTuesday_2                  = D'1980.07.19 15:00:00';  // Tuesday time 2 (use only HH::MM) (00::00 -> off)

input datetime InpTuesday_3                  = D'1980.07.19 18:00:00';  // Tuesday time 3 (use only HH::MM) (00::00 -> off)

input ushort   InpTuesdayPendingExpiration   = 600;                     // Tuesday expiration (in minutes, minimum 15)

input ushort   InpTuesdayPendingIndent       = 5;                       // Tuesday indent, in pips (1.00045-1.00055=1 pips)

input ENUM_TYPE_TRADE InpTuesdayTypeTrade    = buy_stop_sell_stop;      // Tuesday Type Trade

//--- Wednesday

input datetime InpWednesday_1                = D'1980.07.19 10:00:00';  // Wednesday time 1 (use only HH::MM) (00::00 -> off)

input datetime InpWednesday_2                = D'1980.07.19 15:00:00';  // Wednesday time 2 (use only HH::MM) (00::00 -> off)

input datetime InpWednesday_3                = D'1980.07.19 18:00:00';  // Wednesday time 3 (use only HH::MM) (00::00 -> off)

input ushort   InpWednesdayPendingExpiration = 600;                     // Wednesday expiration (in minutes, minimum 15)

input ushort   InpWednesdayPendingIndent     = 5;                       // Wednesday indent, in pips (1.00045-1.00055=1 pips)

input ENUM_TYPE_TRADE InpWednesdayTypeTrade  = buy_stop_sell_stop;      // Wednesday Type Trade

//--- Thursday

input datetime InpThursday_1                 = D'1980.07.19 10:00:00';  // Thursday time 1 (use only HH::MM) (00::00 -> off)

input datetime InpThursday_2                 = D'1980.07.19 15:00:00';  // Thursday time 2 (use only HH::MM) (00::00 -> off)

input datetime InpThursday_3                 = D'1980.07.19 18:00:00';  // Thursday time 3 (use only HH::MM) (00::00 -> off)

input ushort   InpThursdayPendingExpiration  = 600;                     // Thursday expiration (in minutes, minimum 15)

input ushort   InpThursdayPendingIndent      = 5;                       // Thursday indent, in pips (1.00045-1.00055=1 pips)

input ENUM_TYPE_TRADE InpThursdayTypeTrade   = buy_stop_sell_stop;      // Thursday Type Trade

//--- Thursday

input datetime InpFriday_1                   = D'1980.07.19 10:00:00';  // Friday time 1 (use only HH::MM) (00::00 -> off)

input datetime InpFriday_2                   = D'1980.07.19 15:00:00';  // Friday time 2 (use only HH::MM) (00::00 -> off)

input datetime InpFriday_3                   = D'1980.07.19 18:00:00';  // Friday time 3 (use only HH::MM) (00::00 -> off)

input ushort   InpFridayPendingExpiration    = 600;                     // Friday expiration (in minutes, minimum 15)

input ushort   InpFridayPendingIndent        = 5;                       // Friday indent, in pips (1.00045-1.00055=1 pips)

input ENUM_TYPE_TRADE InpFridayTypeTrade     = buy_stop_sell_stop;      // Friday Type Trade

//---

input bool     InpPrintLog          = false;       // Print log

input ulong    InpMagic             = 71655419;    // Magic number

//---

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

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

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

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

double   m_monday_indent            = 0.0;      // Monday indent           -> double

double   m_tuesday_indent           = 0.0;      // Tuesday indent          -> double

double   m_wednesday_indent         = 0.0;      // Wednesday indent        -> double

double   m_thursday_indent          = 0.0;      // Thursday indent         -> double

double   m_friday_indent            = 0.0;      // Friday indent           -> double



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



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

bool     m_need_close_all           = false;    // close all positions

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

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

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

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

bool     m_need_delete_all          = false;    // delete all pending orders

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

//--- Monday

long m_monday_1     = 0;

long m_monday_2     = 0;

long m_monday_3     = 0;

//--- Tuesday

long m_tuesday_1    = 0;

long m_tuesday_2    = 0;

long m_tuesday_3    = 0;

//--- Wednesday

long m_wednesday_1  = 0;

long m_wednesday_2  = 0;

long m_wednesday_3  = 0;

//--- Thursday

long m_thursday_1   = 0;

long m_thursday_2   = 0;

long m_thursday_3   = 0;

//--- Thursday

long m_friday_1     = 0;

long m_friday_2     = 0;

long m_friday_3     = 0;

//--- ***

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

   double            indent;                 // pending indent, in pips * m_adjusted_point

   long              expiration;             // expiration (extra time)

   //--- Constructor

                     STRUCT_PENDING()

     {

      pending_type               = WRONG_VALUE;

      volume                     = 0.0;

      price                      = 0.0;

      stop_loss                  = 0.0;

      take_profit                = 0.0;

      indent                     = 0.0;

      expiration                 = 0;

     }

  };

STRUCT_PENDING SPending[];

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

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

        }

     }

//---

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

     {

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

      return(INIT_FAILED);

     }

   RefreshRates();

//---

   if(InpMondayPendingExpiration || InpTuesdayPendingExpiration || InpWednesdayPendingExpiration ||

      InpThursdayPendingExpiration || InpFridayPendingExpiration)

     {

      int exp_type=(int)SYMBOL_EXPIRATION_SPECIFIED;

      int expiration=(int)m_symbol.TradeTimeFlags();

      if((expiration&exp_type)!=exp_type)

        {

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

                         "0 A8<2>;5 "+m_symbol.Name()+" =5;L7O 7040BL !@>: 8AB5G5=8O 4;O >B;>65==>3> >@45@0!":

                         "On the symbol "+m_symbol.Name()+" you can not set the expiration date for a pending order!";

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

           }

        }

     }

//---

   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_stop_loss             = InpStopLoss              * m_adjusted_point;

   m_take_profit           = InpTakeProfit            * m_adjusted_point;

   m_trailing_stop         = InpTrailingStop          * m_adjusted_point;

   m_trailing_step         = InpTrailingStep          * m_adjusted_point;

   m_monday_indent         = InpMondayPendingIndent   * m_adjusted_point;

   m_tuesday_indent        = InpTuesdayPendingIndent  * m_adjusted_point;

   m_wednesday_indent      = InpWednesdayPendingIndent* m_adjusted_point;

   m_thursday_indent       = InpThursdayPendingIndent * m_adjusted_point;

   m_friday_indent         = InpFridayPendingIndent   * m_adjusted_point;

   m_max_spread            = InpMaxSpread             * m_symbol.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);

           }

        }

//---

   MqlDateTime STime;

//--- Monday

   TimeToStruct(InpMonday_1,STime);

   m_monday_1=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpMonday_2,STime);

   m_monday_2=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpMonday_3,STime);

   m_monday_3=STime.hour*60*60+STime.min*60;

//--- Tuesday

   TimeToStruct(InpTuesday_1,STime);

   m_tuesday_1=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpTuesday_2,STime);

   m_tuesday_2=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpTuesday_3,STime);

   m_tuesday_3=STime.hour*60*60+STime.min*60;

//--- Wednesday

   TimeToStruct(InpWednesday_1,STime);

   m_wednesday_1=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpWednesday_2,STime);

   m_wednesday_2=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpWednesday_3,STime);

   m_wednesday_3=STime.hour*60*60+STime.min*60;

//--- Thursday

   TimeToStruct(InpThursday_1,STime);

   m_thursday_1=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpThursday_2,STime);

   m_thursday_2=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpThursday_3,STime);

   m_thursday_3=STime.hour*60*60+STime.min*60;

//--- Friday

   TimeToStruct(InpFriday_1,STime);

   m_friday_1=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpFriday_2,STime);

   m_friday_2=STime.hour*60*60+STime.min*60;

   TimeToStruct(InpFriday_3,STime);

   m_friday_3=STime.hour*60*60+STime.min*60;

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---

   if(m_money!=NULL)

      delete m_money;

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

   if(m_need_close_all)

     {

      if(IsPositionExists())

        {

         double level;

         if(FreezeStopsLevels(level))

           {

            CloseAllPositions(level);

            return;

           }

         else

            return;

        }

      else

         m_need_close_all=false;

     }

//---

   if(m_need_delete_all)

     {

      if(IsPendingOrdersExists())

        {

         double level;

         if(FreezeStopsLevels(level))

           {

            DeleteAllPendingOrders(level);

            return;

           }

         else

            return;

        }

      else

         m_need_delete_all=false;

     }

//---

   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;

     }

//---

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

     {

      datetime time_current=TimeCurrent();

      if(time_current-m_last_trailing>10)

        {

         double level;

         if(FreezeStopsLevels(level))

            Trailing(level);

         else

            return;

         m_last_trailing=time_current;

        }

     }

   if(InpSignalsFrequency>=10) // search for trading signals no more than once every 10 seconds

     {

      datetime time_current=TimeCurrent();

      if(time_current-m_last_signal>10)

        {

         //--- search for trading signals

         if(!RefreshRates())

           {

            m_prev_bars=0;

            return;

           }

         if(!SearchTradingSignals())

           {

            m_prev_bars=0;

            return;

           }

         m_last_signal=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;

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

     {

      double level;

      if(FreezeStopsLevels(level))

         Trailing(level);

     }

   if(InpSignalsFrequency<10) // 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)

  {

//---



  }

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

//| 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_symbol.Point()*3.0;

   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())+", "+

         "Order retcode external: "+IntegerToString(trade.ResultRetcodeExternal())+", "+

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

  }

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

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

                          }

                       }

              }

           }

  }

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

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

                     if(!m_trade.PositionClose(m_position.Ticket())) // close a position by the specified m_symbol

                        if(InpPrintLog)

                           Print(__FILE__," ",__FUNCTION__,", ERROR: ","CTrade.PositionClose ",m_position.Ticket());

                 }

               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(!m_trade.PositionClose(m_position.Ticket())) // close a position by the specified m_symbol

                     if(InpPrintLog)

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","CTrade.PositionClose ",m_position.Ticket());

                 }

              }

  }

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

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

           {

            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;

   TimeToStruct(TimeCurrent(),STimeCurrent);

   long time_current=STimeCurrent.hour*60*60+STimeCurrent.min*60+STimeCurrent.sec;

   switch(STimeCurrent.day_of_week)

     {

      case  1: // Monday

         if(m_monday_1==0 && m_monday_2==0 && m_monday_3==0)

            return(true);

         //--- Monday time 1

         if(m_monday_1!=0 && (time_current>=m_monday_1 && time_current<m_monday_1+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==1 && (time_last_setup>=m_monday_1 && time_last_setup<m_monday_1+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpMondayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_monday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_monday_indent;

               if(InpMondayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpMondayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpMondayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpMondayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_monday_indent;

               if(InpMondayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpMondayPendingExpiration*60);

              }

            return(true);

           }

         //--- Monday time 2

         if(m_monday_2!=0 && (time_current>=m_monday_2 && time_current<m_monday_2+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==1 && (time_last_setup>=m_monday_2 && time_last_setup<m_monday_2+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpMondayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_monday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_monday_indent;

               if(InpMondayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpMondayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpMondayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpMondayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_monday_indent;

               if(InpMondayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpMondayPendingExpiration*60);

              }

            return(true);

           }

         //--- Monday time 3

         if(m_monday_3!=0 && (time_current>=m_monday_3 && time_current<m_monday_3+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==1 && (time_last_setup>=m_monday_3 && time_last_setup<m_monday_3+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpMondayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_monday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_monday_indent;

               if(InpMondayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpMondayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpMondayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpMondayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_monday_indent;

               if(InpMondayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpMondayPendingExpiration*60);

              }

            return(true);

           }



         break;

      case  2: // Tuesday

         if(m_tuesday_1==0 && m_tuesday_2==0 && m_tuesday_3==0)

            return(true);

         //--- Tuesday time 1

         if(m_tuesday_1!=0 && (time_current>=m_tuesday_1 && time_current<m_tuesday_1+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==1 && (time_last_setup>=m_tuesday_1 && time_last_setup<m_tuesday_1+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpTuesdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_tuesday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_tuesday_indent;

               if(InpTuesdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpTuesdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpTuesdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpTuesdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_tuesday_indent;

               if(InpTuesdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpTuesdayPendingExpiration*60);

              }

            return(true);

           }

         //--- Tuesday time 2

         if(m_tuesday_2!=0 && (time_current>=m_tuesday_2 && time_current<m_tuesday_2+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==2 && (time_last_setup>=m_tuesday_2 && time_last_setup<m_tuesday_2+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpTuesdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_tuesday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_tuesday_indent;

               if(InpTuesdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpTuesdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpTuesdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpTuesdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_tuesday_indent;

               if(InpTuesdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpTuesdayPendingExpiration*60);

              }

            return(true);

           }

         //--- Tuesday time 3

         if(m_tuesday_3!=0 && (time_current>=m_tuesday_3 && time_current<m_tuesday_3+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==2 && (time_last_setup>=m_tuesday_3 && time_last_setup<m_tuesday_3+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpTuesdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_tuesday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_tuesday_indent;

               if(InpTuesdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpTuesdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpTuesdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpTuesdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_tuesday_indent;

               if(InpTuesdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpTuesdayPendingExpiration*60);

              }

            return(true);

           }



         break;

      case  3: // Wednesday

         if(m_wednesday_1==0 && m_wednesday_2==0 && m_wednesday_3==0)

            return(true);

         //--- Wednesday time 1

         if(m_wednesday_1!=0 && (time_current>=m_wednesday_1 && time_current<m_wednesday_1+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==3 && (time_last_setup>=m_wednesday_1 && time_last_setup<m_wednesday_1+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpWednesdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_wednesday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_wednesday_indent;

               if(InpWednesdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpWednesdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpWednesdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpWednesdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_wednesday_indent;

               if(InpWednesdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpWednesdayPendingExpiration*60);

              }

            return(true);

           }

         //--- Wednesday time 2

         if(m_wednesday_2!=0 && (time_current>=m_wednesday_2 && time_current<m_wednesday_2+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==3 && (time_last_setup>=m_wednesday_2 && time_last_setup<m_wednesday_2+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpWednesdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_wednesday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_wednesday_indent;

               if(InpWednesdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpWednesdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpWednesdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpWednesdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_wednesday_indent;

               if(InpWednesdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpWednesdayPendingExpiration*60);

              }

            return(true);

           }

         //--- Wednesday time 3

         if(m_wednesday_3!=0 && (time_current>=m_wednesday_3 && time_current<m_wednesday_3+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==3 && (time_last_setup>=m_wednesday_3 && time_last_setup<m_wednesday_3+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpWednesdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_wednesday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_wednesday_indent;

               if(InpWednesdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpWednesdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpWednesdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpWednesdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_wednesday_indent;

               if(InpWednesdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpWednesdayPendingExpiration*60);

              }

            return(true);

           }



         break;

      case  4: // Thursday

         if(m_thursday_1==0 && m_thursday_2==0 && m_thursday_3==0)

            return(true);

         //--- Thursday time 1

         if(m_thursday_1!=0 && (time_current>=m_thursday_1 && time_current<m_thursday_1+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==4 && (time_last_setup>=m_thursday_1 && time_last_setup<m_thursday_1+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpThursdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_thursday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_thursday_indent;

               if(InpThursdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpThursdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpThursdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpThursdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_thursday_indent;

               if(InpThursdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpThursdayPendingExpiration*60);

              }

            return(true);

           }

         //--- Thursday time 2

         if(m_thursday_2!=0 && (time_current>=m_thursday_2 && time_current<m_thursday_2+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==4 && (time_last_setup>=m_thursday_2 && time_last_setup<m_thursday_2+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpThursdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_thursday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_thursday_indent;

               if(InpThursdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpThursdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpThursdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpThursdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_thursday_indent;

               if(InpThursdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpThursdayPendingExpiration*60);

              }

            return(true);

           }

         //--- Thursday time 3

         if(m_thursday_3!=0 && (time_current>=m_thursday_3 && time_current<m_thursday_3+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==4 && (time_last_setup>=m_thursday_3 && time_last_setup<m_thursday_3+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpThursdayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_thursday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_thursday_indent;

               if(InpThursdayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpThursdayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpThursdayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpThursdayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_thursday_indent;

               if(InpThursdayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpThursdayPendingExpiration*60);

              }

            return(true);

           }



         break;

      default: // Friday

         if(m_friday_1==0 && m_friday_2==0 && m_friday_3==0)

            return(true);

         //--- Friday time 1

         if(m_friday_1!=0 && (time_current>=m_friday_1 && time_current<m_friday_1+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==5 && (time_last_setup>=m_friday_1 && time_last_setup<m_friday_1+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpFridayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_friday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_friday_indent;

               if(InpFridayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpFridayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpFridayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpFridayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_friday_indent;

               if(InpFridayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpFridayPendingExpiration*60);

              }

            return(true);

           }

         //--- Friday time 2

         if(m_friday_2!=0 && (time_current>=m_friday_2 && time_current<m_friday_2+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==5 && (time_last_setup>=m_friday_2 && time_last_setup<m_friday_2+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpFridayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_friday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_friday_indent;

               if(InpFridayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpFridayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpFridayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpFridayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_friday_indent;

               if(InpFridayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpFridayPendingExpiration*60);

              }

            return(true);

           }

         //--- Friday time 3

         if(m_friday_3!=0 && (time_current>=m_friday_3 && time_current<m_friday_3+60))

           {

            datetime last_setup=LastPendingOrderTimeSetup();

            MqlDateTime SLastSetup;

            TimeToStruct(last_setup,SLastSetup);

            long time_last_setup=SLastSetup.hour*60*60+SLastSetup.min*60+SLastSetup.sec;

            if(SLastSetup.day_of_week==5 && (time_last_setup>=m_friday_3 && time_last_setup<m_friday_3+60))

               return(true);

            m_need_delete_all=true;

            int size_need_pending=ArraySize(SPending);

            if(InpFridayTypeTrade==buy_stop_sell_stop)

              {

               ArrayResize(SPending,size_need_pending+2);

               SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               SPending[size_need_pending].indent=m_friday_indent;

               SPending[size_need_pending+1].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending+1].indent=m_friday_indent;

               if(InpFridayPendingExpiration>0)

                 {

                  SPending[size_need_pending].expiration=(long)(InpFridayPendingExpiration*60);

                  SPending[size_need_pending+1].expiration=(long)(InpFridayPendingExpiration*60);

                 }

              }

            else

              {

               ArrayResize(SPending,size_need_pending+1);

               if(InpFridayTypeTrade==buy_stop)

                  SPending[size_need_pending].pending_type=ORDER_TYPE_BUY_STOP;

               else

                  SPending[size_need_pending].pending_type=ORDER_TYPE_SELL_STOP;

               SPending[size_need_pending].indent=m_friday_indent;

               if(InpFridayPendingExpiration>0)

                  SPending[size_need_pending].expiration=(long)(InpFridayPendingExpiration*60);

              }

            return(true);

           }

         break;

     }

//---

   return(true);

  }

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

//| Delete all pending orders                                        |

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

void DeleteAllPendingOrders(const double level)

  {

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

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

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

           {

            if(m_order.OrderType()==ORDER_TYPE_BUY_LIMIT)

              {

               if(m_symbol.Ask()-m_order.PriceOpen()>=level)

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

                     if(InpPrintLog)

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

               continue;

              }

            if(m_order.OrderType()==ORDER_TYPE_BUY_STOP)

              {

               if(m_order.PriceOpen()-m_symbol.Ask()>=level)

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

                     if(InpPrintLog)

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

               continue;

              }

            if(m_order.OrderType()==ORDER_TYPE_SELL_LIMIT)

              {

               if(m_order.PriceOpen()-m_symbol.Bid()>=level)

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

                     if(InpPrintLog)

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

               continue;

              }

            if(m_order.OrderType()==ORDER_TYPE_SELL_STOP)

              {

               if(m_symbol.Bid()-m_order.PriceOpen()>=level)

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

                     if(InpPrintLog)

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

               continue;

              }

           }

  }

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

//| Is pending orders exists                                         |

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

bool IsPendingOrdersExists(void)

  {

   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)

            return(true);

//---

   return(false);

  }

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

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

      if(InpPrintLog)

         Print(__FILE__," ",__FUNCTION__,

               ", ERROR: ","Spread Ask-Bid (",DoubleToString(spread,m_symbol.Digits()),")",

               " > Maximum spread (",DoubleToString(m_max_spread,m_symbol.Digits()),")");

      return;

     }

//--- buy stop

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

     {

      if(SPending[index].price==0.0)

         SPending[index].price=m_symbol.Ask()+SPending[index].indent;

      if(SPending[index].price-m_symbol.Ask()<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=SPending[index].take_profit;

      if(tp<=0.0) // check tp

         tp=0.0;

      else

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

            tp=SPending[index].price+level;



      PendingOrder(index,sl,tp);

      ArrayRemove(SPending,index,1);

      m_waiting_pending_order=false;

      return;

     }

//--- sell stop

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

     {

      if(SPending[index].price==0.0)

         SPending[index].price=m_symbol.Bid()-SPending[index].indent;

      if(m_symbol.Bid()-SPending[index].price<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=SPending[index].take_profit;

      if(tp<=0.0) // check tp

         tp=0.0;

      else

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

            tp=SPending[index].price-level;



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

     {

      bool result=false;

      if(SPending[index].expiration>0)

        {

         datetime time_expiration=TimeCurrent()+(datetime)SPending[index].expiration;

         result=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);

        }

      else

        {

         result=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));

        }



      if(result)

        {

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

           }

  }

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

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

                  if(!m_trade.PositionClose(m_position.Ticket())) // close a position by the specified m_symbol

                     if(InpPrintLog)

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","CTrade.PositionClose ",m_position.Ticket());

              }

            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)

                  if(!m_trade.PositionClose(m_position.Ticket())) // close a position by the specified m_symbol

                     if(InpPrintLog)

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","CTrade.PositionClose ",m_position.Ticket());

              }

           }

  }

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

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

  }

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

//| Last Pending Order Time Setup                                    |

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

datetime LastPendingOrderTimeSetup(void)

  {

   datetime last_time=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(m_order.TimeSetup()>last_time)

               last_time=m_order.TimeSetup();

//---

   return(last_time);

  }

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

Comments