Author: Copyright © 2020, Vladimir Karputov
Price Data Components
Series array that contains tick volumes of each bar
Indicators Used
Moving average indicatorIndicator of the average true rangeRelative strength index
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
Freeman 2
ÿþ//+------------------------------------------------------------------+

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

//---

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

//--- input parameters

input ushort   InpNumberMinimumLots = 1;           // The number of minimum lots (for start lot)

input uchar    InpSLFactor          = 14;          // SL Factor: Stop Loss = SL Factor * ATR

input uchar    InpTPFactor          = 2;           // TP Factor: Take Profit = TP Factor * ATR

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

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

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

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

input uchar    InpPositionsMax      = 5;           // Positions Maximum

input ushort   InpDistance          = 10;          // Distance between positions, in pips (1.00045-1.00055=1 pips)

input double   InpCoefficient       = 1.61;        // Coefficient for position locking

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

//---

input bool     InpRsiTeacher        = true;        // Use Rsi Teacher #1

input bool     InpRsiTeacher2       = true;        // Use Rsi Teacher #2

//---

input int      Inp_MA_First_ma_period     = 5;           // MA First, ATR: averaging period

input int      Inp_MA_Second_ma_period    = 9;           // MA Second: averaging period

input int      Inp_MA_Filter_ma_period    = 20;          // MA Filter: averaging period

input ENUM_MA_METHOD Inp_ma_method        = MODE_SMA;    // MA First, MA Second, MA Filter: smoothing type

input ENUM_APPLIED_PRICE Inp_applied_price= PRICE_CLOSE; // MA First, MA Second, MA Filter: type of price

//---

input int      Inp_RSI_First_ma_period    = 15;          // RSI First: averaging period

input int      Inp_RSI_Second_ma_period   = 20;          // RSI Second: averaging period

//---

input int      RSISellLevel      = 34;          // RSI Sell Level #1

input int      RSIBuyLevel       = 70;          // RSI Buy Level #1

input int      RSISellLevel2     = 34;          // RSI Sell Level 2

input int      RSIBuyLevel2      = 68;          // RSI Buy Level 2

input int      Shift             = 0;           // Signal Bar number

input bool     TrendFilter       = false;       // Trend filter

//---

input bool     InpTradeOnFriday  = true;        // Trade on Friday

input uchar    InpBeginTradeHour = 0;           // Begin trade hour

input uchar    InpEndTradeHour   = 0;           // End trade hour

//---

input bool     InpPrintLog          = false;       // Print log

input ulong    InpMagic             = 111809208;   // Magic number

//---

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

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

double   m_distance                 = 0.0;      // Distance                -> double



int      handle_iMA_First;                      // variable for storing the handle of the iMA indicator

int      handle_iMA_Second;                     // variable for storing the handle of the iMA indicator

int      handle_iMA_Filter;                     // variable for storing the handle of the iMA indicator

int      handle_iATR;                           // variable for storing the handle of the iATR indicator

int      handle_iRSI_First;                     // variable for storing the handle of the iRSI indicator

int      handle_iRSI_Second;                    // variable for storing the handle of the iRSI indicator

int      handle_iRSI_H1_14;                     // variable for storing the handle of the iRSI indicator



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



bool     m_last_OUT_buy_loss  = false;

double   m_last_IN_buy_price  = 0.0;

bool     m_last_OUT_sell_loss = false;

double   m_last_IN_sell_price = 0.0;



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

//--- the tactic is this: for positions we strictly monitor the result ***

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

//| Structure Positions                                              |

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

struct STRUCT_POSITION

  {

   ENUM_POSITION_TYPE pos_type;              // position type

   double            volume;                 // position volume (if "0.0" -> the lot is "Money management")

   bool              waiting_transaction;    // waiting transaction, "true" -> it's forbidden to trade, we expect a transaction

   ulong             waiting_order_ticket;   // waiting order ticket, ticket of the expected order

   bool              transaction_confirmed;  // transaction confirmed, "true" -> transaction confirmed

   //--- Constructor

                     STRUCT_POSITION()

     {

      pos_type                   = WRONG_VALUE;

      volume                     = 0.0;

      waiting_transaction        = false;

      waiting_order_ticket       = 0;

      transaction_confirmed      = false;

     }

  };

STRUCT_POSITION SPosition[];

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

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

//---

   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_trailing_stop         = InpTrailingStop          * m_adjusted_point;

   m_trailing_step         = InpTrailingStep          * m_adjusted_point;

   m_distance              = InpDistance              * m_adjusted_point;

//--- create handle of the indicator iMA

   handle_iMA_First=iMA(m_symbol.Name(),Period(),Inp_MA_First_ma_period,0,Inp_ma_method,Inp_applied_price);

//--- if the handle is not created

   if(handle_iMA_First==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//--- create handle of the indicator iMA

   handle_iMA_Second=iMA(m_symbol.Name(),Period(),Inp_MA_Second_ma_period,0,Inp_ma_method,Inp_applied_price);

//--- if the handle is not created

   if(handle_iMA_Second==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//--- create handle of the indicator iMA

   handle_iMA_Filter=iMA(m_symbol.Name(),PERIOD_H1,Inp_MA_Filter_ma_period,0,Inp_ma_method,Inp_applied_price);

//--- if the handle is not created

   if(handle_iMA_Filter==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//--- create handle of the indicator iATR

   handle_iATR=iATR(m_symbol.Name(),Period(),Inp_MA_First_ma_period);

//--- if the handle is not created

   if(handle_iATR==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//--- create handle of the indicator iRSI

   handle_iRSI_First=iRSI(m_symbol.Name(),Period(),Inp_RSI_First_ma_period,PRICE_CLOSE);

//--- if the handle is not created

   if(handle_iRSI_First==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//--- create handle of the indicator iRSI

   handle_iRSI_Second=iRSI(m_symbol.Name(),Period(),Inp_RSI_Second_ma_period,PRICE_CLOSE);

//--- if the handle is not created

   if(handle_iRSI_Second==INVALID_HANDLE)

     {

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

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

                  m_symbol.Name(),

                  EnumToString(Period()),

                  GetLastError());

      //--- the indicator is stopped early

      return(INIT_FAILED);

     }

//--- create handle of the indicator iRSI

   handle_iRSI_H1_14=iRSI(m_symbol.Name(),PERIOD_H1,14,PRICE_CLOSE);

//--- if the handle is not created

   if(handle_iRSI_H1_14==INVALID_HANDLE)

     {

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

      PrintFormat("Failed to create handle of the iRSI 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)

  {

//---

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

//---

   int size_need_position=ArraySize(SPosition);

   if(size_need_position>0)

     {

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

        {

         if(SPosition[i].waiting_transaction)

           {

            if(!SPosition[i].transaction_confirmed)

              {

               if(InpPrintLog)

                  Print(__FILE__," ",__FUNCTION__,", OK: ","transaction_confirmed: ",SPosition[i].transaction_confirmed);

               return;

              }

            else

               if(SPosition[i].transaction_confirmed)

                 {

                  ArrayRemove(SPosition,i,1);

                  return;

                 }

           }

         if(SPosition[i].pos_type==POSITION_TYPE_BUY)

           {

            double level;

            if(FreezeStopsLevels(level))

              {

               SPosition[i].waiting_transaction=true;

               OpenPosition(i,level);

              }

            return;

           }

         if(SPosition[i].pos_type==POSITION_TYPE_SELL)

           {

            double level;

            if(FreezeStopsLevels(level))

              {

               SPosition[i].waiting_transaction=true;

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

  {

//--- 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_entry==DEAL_ENTRY_OUT)

           {

            if(deal_type==DEAL_TYPE_BUY)

              {

               if(deal_profit<0.0)

                 {

                  m_last_OUT_buy_loss=false;

                  m_last_OUT_sell_loss=true;

                 }

               else

                  m_last_OUT_sell_loss=false;

              }

            if(deal_type==DEAL_TYPE_SELL)

              {

               if(deal_profit<0.0)

                 {

                  m_last_OUT_buy_loss=true;

                  m_last_OUT_sell_loss=false;

                 }

               else

                  m_last_OUT_buy_loss=false;

              }

           }

         if(deal_entry==DEAL_ENTRY_IN)

           {

            if(deal_type==DEAL_TYPE_BUY)

               m_last_IN_buy_price=deal_price;

            if(deal_type==DEAL_TYPE_SELL)

               m_last_IN_sell_price=deal_price;

           }

         //---

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

           {

            int size_need_position=ArraySize(SPosition);

            if(size_need_position>0)

              {

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

                 {

                  if(SPosition[i].waiting_transaction)

                     if(SPosition[i].waiting_order_ticket==deal_order)

                       {

                        Print(__FUNCTION__," Transaction confirmed");

                        SPosition[i].transaction_confirmed=true;

                        break;

                       }

                 }

              }

           }

        }

     }

  }

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

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

  }

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

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

  }

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

//| Open position                                                    |

//|   double stop_loss                                               |

//|      -> pips * m_adjusted_point (if "0.0" -> the m_stop_loss)    |

//|   double take_profit                                             |

//|      -> pips * m_adjusted_point (if "0.0" -> the m_take_profit)  |

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

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

   */

//--- buy

   if(SPosition[index].pos_type==POSITION_TYPE_BUY)

     {

      double atr_array[];

      if(InpSLFactor>0 || InpTPFactor>0)

        {

         if(!iATRGetArray(Shift,1,atr_array))

            return;

        }

      double sl=(InpSLFactor==0)?0.0:m_symbol.Ask()-atr_array[0]*(double)InpSLFactor;

      if(sl>0.0)

         if(m_symbol.Bid()-sl<level)

            sl=m_symbol.Bid()-level;

      double tp=(InpTPFactor==0)?0.0:m_symbol.Ask()+atr_array[0]*(double)InpTPFactor;

      if(tp>0.0)

         if(tp-m_symbol.Ask()<level)

            tp=m_symbol.Ask()+level;

      OpenBuy(index,sl,tp);

      return;

     }

//--- sell

   if(SPosition[index].pos_type==POSITION_TYPE_SELL)

     {

      double atr_array[];

      if(InpSLFactor>0 || InpTPFactor>0)

        {

         if(!iATRGetArray(Shift,1,atr_array))

            return;

        }

      double sl=(InpSLFactor==0)?0.0:m_symbol.Bid()+atr_array[0]*(double)InpSLFactor;

      if(sl>0.0)

         if(sl-m_symbol.Ask()<level)

            sl=m_symbol.Ask()+level;

      double tp=(InpTPFactor==0)?0.0:m_symbol.Bid()-atr_array[0]*(double)InpSLFactor;

      if(tp>0.0)

         if(m_symbol.Bid()-tp<level)

            tp=m_symbol.Bid()-level;

      OpenSell(index,sl,tp);

      return;

     }

  }

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

//| Open Buy position                                                |

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

void OpenBuy(const int index,double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);

   double long_lot=0.0;

   if(SPosition[index].volume>0.0)

      long_lot=SPosition[index].volume;

   else

     {

      ArrayRemove(SPosition,index,1);

      return;

     }

   if(m_symbol.LotsLimit()>0.0)

     {

      int      count_buys           = 0;

      double   volume_buys          = 0.0;

      double   volume_biggest_buys  = 0.0;

      int      count_sells          = 0;

      double   volume_sells         = 0.0;

      double   volume_biggest_sells = 0.0;

      CalculateAllPositions(count_buys,volume_buys,volume_biggest_buys,

                            count_sells,volume_sells,volume_biggest_sells);

      if(volume_buys+volume_sells+long_lot>m_symbol.LotsLimit())

        {

         ArrayRemove(SPosition,index,1);

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", ERROR: ","#0 Buy, Volume Buy (",DoubleToString(volume_buys,2),

                  ") + Volume Sell (",DoubleToString(volume_sells,2),

                  ") + Volume long (",DoubleToString(long_lot,2),

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

         return;

        }

     }

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

   double free_margin_check=m_account.FreeMarginCheck(m_symbol.Name(),

                            ORDER_TYPE_BUY,

                            long_lot,

                            m_symbol.Ask());

   double margin_check=m_account.MarginCheck(m_symbol.Name(),

                       ORDER_TYPE_BUY,

                       long_lot,

                       m_symbol.Ask());

   if(free_margin_check>margin_check)

     {

      if(m_trade.Buy(long_lot,m_symbol.Name(),

                     m_symbol.Ask(),sl,tp)) // CTrade::Buy -> "true"

        {

         if(m_trade.ResultDeal()==0)

           {

            if(m_trade.ResultRetcode()==10009) // trade order went to the exchange

              {

               SPosition[index].waiting_transaction=true;

               SPosition[index].waiting_order_ticket=m_trade.ResultOrder();

              }

            else

              {

               SPosition[index].waiting_transaction=false;

               if(InpPrintLog)

                  Print(__FILE__," ",__FUNCTION__,", ERROR: ","#1 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

              }

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

           }

         else

           {

            if(m_trade.ResultRetcode()==10009)

              {

               SPosition[index].waiting_transaction=true;

               SPosition[index].waiting_order_ticket=m_trade.ResultOrder();

              }

            else

              {

               SPosition[index].waiting_transaction=false;

               if(InpPrintLog)

                  Print(__FILE__," ",__FUNCTION__,", OK: ","#2 Buy -> true. Result Retcode: ",m_trade.ResultRetcode(),

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

              }

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         SPosition[index].waiting_transaction=false;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", ERROR: ","#3 Buy -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

         if(InpPrintLog)

            PrintResultTrade(m_trade,m_symbol);

        }

     }

   else

     {

      ArrayRemove(SPosition,index,1);

      if(InpPrintLog)

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

      return;

     }

//---

  }

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

//| Open Sell position                                               |

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

void OpenSell(const int index,double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);

   double short_lot=0.0;

   if(SPosition[index].volume>0.0)

      short_lot=SPosition[index].volume;

   else

     {

      ArrayRemove(SPosition,index,1);

      return;

     }

   if(m_symbol.LotsLimit()>0.0)

     {

      int      count_buys           = 0;

      double   volume_buys          = 0.0;

      double   volume_biggest_buys  = 0.0;

      int      count_sells          = 0;

      double   volume_sells         = 0.0;

      double   volume_biggest_sells = 0.0;

      CalculateAllPositions(count_buys,volume_buys,volume_biggest_buys,

                            count_sells,volume_sells,volume_biggest_sells);

      if(volume_buys+volume_sells+short_lot>m_symbol.LotsLimit())

        {

         ArrayRemove(SPosition,index,1);

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", ERROR: ","#0 Buy, Volume Buy (",DoubleToString(volume_buys,2),

                  ") + Volume Sell (",DoubleToString(volume_sells,2),

                  ") + Volume short (",DoubleToString(short_lot,2),

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

         return;

        }

     }

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

   double free_margin_check=m_account.FreeMarginCheck(m_symbol.Name(),

                            ORDER_TYPE_SELL,

                            short_lot,

                            m_symbol.Bid());

   double margin_check=m_account.MarginCheck(m_symbol.Name(),

                       ORDER_TYPE_SELL,

                       short_lot,

                       m_symbol.Bid());

   if(free_margin_check>margin_check)

     {

      if(m_trade.Sell(short_lot,m_symbol.Name(),

                      m_symbol.Bid(),sl,tp)) // CTrade::Sell -> "true"

        {

         if(m_trade.ResultDeal()==0)

           {

            if(m_trade.ResultRetcode()==10009) // trade order went to the exchange

              {

               SPosition[index].waiting_transaction=true;

               SPosition[index].waiting_order_ticket=m_trade.ResultOrder();

              }

            else

              {

               SPosition[index].waiting_transaction=false;

               if(InpPrintLog)

                  Print(__FILE__," ",__FUNCTION__,", ERROR: ","#1 Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

              }

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

           }

         else

           {

            if(m_trade.ResultRetcode()==10009)

              {

               SPosition[index].waiting_transaction=true;

               SPosition[index].waiting_order_ticket=m_trade.ResultOrder();

              }

            else

              {

               SPosition[index].waiting_transaction=false;

               if(InpPrintLog)

                  Print(__FILE__," ",__FUNCTION__,", OK: ","#2 Sell -> true. Result Retcode: ",m_trade.ResultRetcode(),

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

              }

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         SPosition[index].waiting_transaction=false;

         if(InpPrintLog)

            Print(__FILE__," ",__FUNCTION__,", ERROR: ","#3 Sell -> false. Result Retcode: ",m_trade.ResultRetcode(),

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

         if(InpPrintLog)

            PrintResultTrade(m_trade,m_symbol);

        }

     }

   else

     {

      ArrayRemove(SPosition,index,1);

      if(InpPrintLog)

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

      return;

     }

//---

  }

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

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

  }

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

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

         PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);

      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

      if(InpPrintLog)

         PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",

                     __FILE__,__FUNCTION__,count,copied,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);

                          }

                       }

              }

           }

  }

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

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

  {

   bool tradeAllow=false;

   if(!InpTradeOnFriday)

     {

      MqlDateTime STimeCurrent;

      TimeToStruct(TimeCurrent(),STimeCurrent);

      if(STimeCurrent.day_of_week==5)

         return(true);

     }

   if(InpBeginTradeHour>0 && InpEndTradeHour>0)

     {

      MqlDateTime STimeCurrent;

      TimeToStruct(TimeCurrent(),STimeCurrent);

      if(STimeCurrent.hour>=InpBeginTradeHour && STimeCurrent.hour<=InpEndTradeHour)

         tradeAllow=true;

     }

   else

     {

      tradeAllow=true;

     }

   if(!tradeAllow)

      return(true);

   int count_buys=0;

   int count_sells=0;

   CalculateAllPositions(count_buys,count_sells);

   bool SignalBuy=false;

   bool SignalSell=false;

   Signals(SignalBuy,SignalSell);

   if(!SignalBuy && !SignalSell)

      return(true);

   if(count_buys+count_sells<InpPositionsMax || InpPositionsMax==0)

     {

      double atr_array[];

      if(!iATRGetArray(Shift,1,atr_array))

         return(false);

      //--- buy signal

      if(count_buys==0)

        {

         if(SignalBuy)

           {

            int size_need_position=ArraySize(SPosition);

            ArrayResize(SPosition,size_need_position+1);

            SPosition[size_need_position].pos_type=POSITION_TYPE_BUY;

            SPosition[size_need_position].volume=InpNumberMinimumLots*m_symbol.LotsMin();

            if(InpPrintLog)

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

            return(true);

           }

        }

      else

        {

         if(SignalBuy)

           {

            if(MathAbs(m_symbol.Ask()-m_last_IN_buy_price)>m_distance)

              {

               if(m_last_OUT_buy_loss) // Lock

                 {

                  double lot_lock=LotCheck(InpNumberMinimumLots*m_symbol.LotsMin()*InpCoefficient,m_symbol);

                  if(lot_lock==0.0)

                    {

                     if(InpPrintLog)

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","Calcalate lot for lock BUY. LotCheck returned the 0.0");

                     return(true);

                    }

                  int size_need_position=ArraySize(SPosition);

                  ArrayResize(SPosition,size_need_position+1);

                  SPosition[size_need_position].pos_type=POSITION_TYPE_BUY;

                  SPosition[size_need_position].volume=lot_lock;

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", OK: ","Signal BUY (last OUT buy loss -> 'true')");

                  return(true);

                 }

               else

                 {

                  int size_need_position=ArraySize(SPosition);

                  ArrayResize(SPosition,size_need_position+1);

                  SPosition[size_need_position].pos_type=POSITION_TYPE_BUY;

                  SPosition[size_need_position].volume=InpNumberMinimumLots*m_symbol.LotsMin();

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", OK: ","Signal BUY (last OUT buy loss -> 'false')");

                  return(true);

                 }

              }

           }

        }

      //--- sell signal

      if(count_sells==0)

        {

         if(SignalSell)

           {

            int size_need_position=ArraySize(SPosition);

            ArrayResize(SPosition,size_need_position+1);

            SPosition[size_need_position].pos_type=POSITION_TYPE_SELL;

            SPosition[size_need_position].volume=InpNumberMinimumLots*m_symbol.LotsMin();

            if(InpPrintLog)

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

            return(true);

           }

        }

      else

        {

         if(SignalSell)

            if(MathAbs(m_symbol.Bid()-m_last_IN_sell_price)>m_distance)

              {

               if(m_last_OUT_sell_loss) // Lock

                 {

                  double lot_lock=LotCheck(InpNumberMinimumLots*m_symbol.LotsMin()*InpCoefficient,m_symbol);

                  if(lot_lock==0.0)

                    {

                     if(InpPrintLog)

                        Print(__FILE__," ",__FUNCTION__,", ERROR: ","Calcalate lot for lock SELL. LotCheck returned the 0.0");

                     return(true);

                    }

                  int size_need_position=ArraySize(SPosition);

                  ArrayResize(SPosition,size_need_position+1);

                  SPosition[size_need_position].pos_type=POSITION_TYPE_SELL;

                  SPosition[size_need_position].volume=lot_lock;

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", OK: ","Signal SELL (last OUT sell loss -> 'true')");

                  return(true);

                 }

               else

                 {

                  int size_need_position=ArraySize(SPosition);

                  ArrayResize(SPosition,size_need_position+1);

                  SPosition[size_need_position].pos_type=POSITION_TYPE_SELL;

                  SPosition[size_need_position].volume=InpNumberMinimumLots*m_symbol.LotsMin();

                  if(InpPrintLog)

                     Print(__FILE__," ",__FUNCTION__,", OK: ","Signal SELL (last OUT sell loss -> 'false')");

                  return(true);

                 }

              }

        }

     }

//---

   return(true);

  }

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

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

  }

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

//|                                                                  |

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

void Signals(bool &SignalBuy,bool &SignalSell)

  {

   SignalBuy=false;

   SignalSell=false;

   double MA_First[];

   if(!iMAGetArray(handle_iMA_First,0,Shift+2,MA_First))

      return;

   double MA_Second[];

   if(!iMAGetArray(handle_iMA_Second,0,Shift+2,MA_Second))

      return;

   double MA_Filter[];

   if(!iMAGetArray(handle_iMA_Filter,0,Shift+2,MA_Filter))

      return;

   double RSI_First[];

   if(!iRSIGetArray(handle_iRSI_First,0,Shift+2,RSI_First))

      return;

   double RSI_Second[];

   if(!iRSIGetArray(handle_iRSI_Second,0,Shift+2,RSI_Second))

      return;

   double RSI_H1_14[];

   if(!iRSIGetArray(handle_iRSI_H1_14,0,Shift+1,RSI_H1_14))

      return;

//--- Buy signal

   bool buy_0=((MA_Filter[Shift]>MA_Filter[Shift+1] && TrendFilter) || (!TrendFilter));

   bool buy_1=((InpRsiTeacher2 && (RSI_Second[Shift+1]<RSISellLevel2) && (RSI_Second[Shift]>RSI_Second[Shift+1]) && (RSI_H1_14[Shift]<RSIBuyLevel2) && (MA_Second[Shift]>MA_Second[Shift+1])));

   bool buy_2=((InpRsiTeacher && (RSI_First[Shift+1]<RSISellLevel) && (RSI_First[Shift]>RSI_First[Shift+1]) && (RSI_H1_14[Shift]<RSIBuyLevel) && (MA_First[Shift]>MA_First[Shift+1])));

   if((buy_0 && buy_1)|| buy_2)

     {

      SignalBuy=true;

     }

//--- Sell signal

   bool sell_0=((MA_Filter[Shift]<MA_Filter[Shift+1] && TrendFilter) || (!TrendFilter));

   bool sell_1=((InpRsiTeacher2 && (RSI_Second[Shift+1]>RSIBuyLevel2) && (RSI_Second[Shift]<RSI_Second[Shift+1]) && (RSI_H1_14[Shift]>RSISellLevel2) && (MA_Second[Shift]<MA_Second[Shift+1])));

   bool sell_2=((InpRsiTeacher && (RSI_First[Shift+1]>RSIBuyLevel) && (RSI_First[Shift]<RSI_First[Shift+1]) && (RSI_H1_14[Shift]>RSISellLevel) && (MA_First[Shift]<MA_First[Shift+1])));

   if((sell_0 && sell_1)|| sell_2)

     {

      SignalSell=true;

     }

  }

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

//| Get value of buffers for the iMA in the array                    |

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

bool iMAGetArray(const int handle_iMA,const int start_pos,const int count,double &arr_buffer[])

  {

//---

   bool result=true;

   if(!ArrayIsDynamic(arr_buffer))

     {

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

      return(false);

     }

   ArrayFree(arr_buffer);

   int       buffer_num=0;          // indicator buffer number

//--- reset error code

   ResetLastError();

//--- fill a part of the iMABuffer array with values from the indicator buffer that has 0 index

   int copied=CopyBuffer(handle_iMA,buffer_num,start_pos,count,arr_buffer);

   if(copied!=count)

     {

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

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

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

      return(false);

     }

//---

   return(result);

  }

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

//| Get value of buffers for the iRSI in the array                   |

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

bool iRSIGetArray(const int handle_iRSI,const int start_pos,const int count,double &arr_buffer[])

  {

//---

   bool result=true;

   if(!ArrayIsDynamic(arr_buffer))

     {

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

      return(false);

     }

   ArrayFree(arr_buffer);

   int       buffer_num=0;          // indicator buffer number

//--- reset error code

   ResetLastError();

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

   int copied=CopyBuffer(handle_iRSI,buffer_num,start_pos,count,arr_buffer);

   if(copied!=count)

     {

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

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

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

      return(false);

     }

//---

   return(result);

  }

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

//| Get value of buffers for the iATR in the array                   |

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

bool iATRGetArray(const int start_pos,const int count,double &arr_buffer[])

  {

   bool result=true;

   if(!ArrayIsDynamic(arr_buffer))

     {

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

      return(false);

     }

   ArrayFree(arr_buffer);

   int       buffer_num=0;          // indicator buffer number

//--- reset error code

   ResetLastError();

//--- fill a part of the iATRBuffer array with values from the indicator buffer that has 0 index

   int copied=CopyBuffer(handle_iATR,buffer_num,start_pos,count,arr_buffer);

   if(copied!=count)

     {

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

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

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

      return(false);

     }

//---

   return(result);

  }

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

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