JS Signal Baes

Author: Copyright © 2018, Vladimir Karputov
Price Data Components
Series array that contains tick volumes of each bar
Indicators Used
Commodity channel indexMoving average indicatorMACD HistogramStochastic oscillatorRelative strength index
Miscellaneous
It issuies visual alerts to the screen
0 Views
0 Downloads
0 Favorites
JS Signal Baes
ÿþ//+------------------------------------------------------------------+

//|                                               JS Signal Baes.mq5 |

//|                              Copyright © 2018, Vladimir Karputov |

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

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

#property copyright "Copyright © 2018, Vladimir Karputov"

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

#property version   "1.000"

//---

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

#include <Trade\DealInfo.mqh>

#include <Trade\OrderInfo.mqh>

#include <Expert\Money\MoneyFixedMargin.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

CDealInfo      m_deal;                       // deals object

COrderInfo     m_order;                      // pending orders object

CMoneyFixedMargin *m_money;

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

//| Enum Lor or Risk                                                 |

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

enum ENUM_LOT_OR_RISK

  {

   lot=0,   // Constant lot

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

  };

//--- input parameters

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

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

input ushort   InpTrailingStop   = 5;        // 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 IntLotOrRisk=risk;    // Money management: Lot OR Risk

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

input double   InpFreeMarginMin  = 200;      // Minimum Free Margin -> stops an EA and unloads it from a chart

//---

input int      Inp_CCI_ma_period=13;       // CCI: averaging period 

//---

input int      Inp_MA_Fast_period= 5;        // MA Fast: averaging period 

input int      Inp_MA_Slow_period= 9;        // MA Slow: averaging period 

input ENUM_MA_METHOD Inp_MA_ma_method=MODE_LWMA;// MA Fast and Slow: smoothing type 

//---

input int      Inp_MACD_fast_ema_period=8;   // MACD: period for Fast average calculation 

input int      Inp_MACD_slow_ema_period=17;  // MACD: period for Slow average calculation 

input int      Inp_MACD_signal_period=9;     // MACD: period for their difference averaging 

//---

input int      Inp_STO_Kperiod   = 5;        // Stochastic: K-period (number of bars for calculations) 

input int      Inp_STO_Dperiod   = 3;        // Stochastic: D-period (period of first smoothing) 

input int      Inp_STO_slowing   = 3;        // Stochastic: final smoothing 

//---

input int      Inp_RSI_ma_period=9;        // RSI: averaging period 

//---

input bool     InpReverse        = false;    // Reverse

input bool     InpPrintLog       = false;    // Print log

input ulong    m_magic=163170000;            // magic number

//---

ulong  m_slippage=10;                        // slippage

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

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

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

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

//---

ENUM_TIMEFRAMES array_timeframes[6]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4};

int    handles_iCCI[];                         // array for storing the handles of the iCCI indicator 

int    handles_iMA_Fast[];                   // array for storing the handles of the iMA indicators

int    handles_iMA_Slow[];                   // array for storing the handles of the iMA indicators

int    handles_iMACD[];                      // array for storing the handles of the iMACD indicators

int    handles_iStochastic[];                // array for storing the handles of the iStochastic indicators

int    handles_iRSI[];                       // array for storing the handles of the iRSI indicators

//---

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

bool   m_need_open_buy           = false;

bool   m_need_open_sell          = false;

bool   m_waiting_transaction     = false;    // "true" -> it's forbidden to trade, we expect a transaction

ulong  m_waiting_order_ticket    = 0;        // ticket of the expected order

bool   m_transaction_confirmed   = false;    // "true" -> transaction confirmed

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

//| Expert initialization function                                   |

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

int OnInit()

  {

//---

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

      return(INIT_FAILED);

   RefreshRates();

//---

   m_trade.SetExpertMagicNumber(m_magic);

   m_trade.SetMarginMode();

   m_trade.SetTypeFillingBySymbol(m_symbol.Name());

   m_trade.SetDeviationInPoints(m_slippage);

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



   ExtStopLoss       = InpStopLoss        * m_adjusted_point;

   ExtTakeProfit     = InpTakeProfit      * m_adjusted_point;

   ExtTrailingStop   = InpTrailingStop    * m_adjusted_point;

   ExtTrailingStep   = InpTrailingStep    * m_adjusted_point;

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

   string err_text="";

   if(IntLotOrRisk==lot)

     {

      if(!CheckVolumeValue(InpVolumeLorOrRisk,err_text))

        {

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

         if(MQLInfoInteger(MQL_TESTER))

           {

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

            return(INIT_FAILED);

           }

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

           {

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

            return(INIT_PARAMETERS_INCORRECT);

           }

        }

     }

   else

     {

      if(m_money!=NULL)

         delete m_money;

      m_money=new CMoneyFixedMargin;

      if(m_money!=NULL)

        {

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

            return(INIT_FAILED);

         m_money.Percent(InpVolumeLorOrRisk);

        }

      else

        {

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

         return(INIT_FAILED);

        }

     }



   if(!CreateHandlesCCIs(handles_iCCI,Inp_CCI_ma_period))

      return(INIT_FAILED);

   if(!CreateHandlesMAs(handles_iMA_Fast,Inp_MA_Fast_period,Inp_MA_ma_method))

      return(INIT_FAILED);

   if(!CreateHandlesMAs(handles_iMA_Slow,Inp_MA_Slow_period,Inp_MA_ma_method))

      return(INIT_FAILED);

   if(!CreateHandlesMACDs(handles_iMACD,Inp_MACD_fast_ema_period,Inp_MACD_slow_ema_period,Inp_MACD_signal_period))

      return(INIT_FAILED);

   if(!CreateHandlesStochastics(handles_iStochastic,Inp_STO_Kperiod,Inp_STO_Dperiod,Inp_STO_slowing))

      return(INIT_FAILED);

   if(!CreateHandlesRSIs(handles_iRSI,Inp_RSI_ma_period))

      return(INIT_FAILED);

//---

   return(INIT_SUCCEEDED);

  }

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

//| Expert deinitialization function                                 |

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

void OnDeinit(const int reason)

  {

//---

   if(m_money!=NULL)

      delete m_money;

  }

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

//| Expert tick function                                             |

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

void OnTick()

  {

//---

   if(m_waiting_transaction)

     {

      if(!m_transaction_confirmed)

        {

         Print("m_transaction_confirmed: ",m_transaction_confirmed);

         return;

        }

      else if(m_transaction_confirmed)

        {

         m_need_open_buy            = false;    // "true" -> need to open BUY

         m_need_open_sell           = false;    // "true" -> need to open SELL

         m_waiting_transaction      = false;    // "true" -> it's forbidden to trade, we expect a transaction

         m_waiting_order_ticket     = 0;        // ticket of the expected order

         m_transaction_confirmed    = false;    // "true" -> transaction confirmed

        }

     }

   if(m_need_open_buy)

     {

      double level;

      if(FreezeStopsLevels(level))

        {

         m_waiting_transaction=true;

         OpenPosition(POSITION_TYPE_BUY,level);

        }

      return;

     }

   if(m_need_open_sell)

     {

      double level;

      if(FreezeStopsLevels(level))

        {

         m_waiting_transaction=true;

         OpenPosition(POSITION_TYPE_SELL,level);

        }

      return;

     }

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

   static datetime PrevBars=0;

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

   if(time_0==PrevBars)

      return;

   PrevBars=time_0;

   if(!RefreshRates())

     {

      PrevBars=0;

      return;

     }

//---

   if(IsPositionExists())

     {

      double level;

      if(FreezeStopsLevels(level))

         Trailing(level);

     }

   else

     {

      double cci[];

      double ma_fast[],ma_slow[];

      double macd_main[],macd_signal[];

      double rsi[];

      double sto_main[];

/*      

      --------- index -------- 0 ------- 1 ------- 2 -------- 3 -------- 4 ------- 5 ----

      array_timeframes[6]={PERIOD_M1,PERIOD_M5,PERIOD_M15,PERIOD_M30,PERIOD_H1,PERIOD_H4};

*/

      int size=ArraySize(array_timeframes);

      double array[];



      ArrayResize(cci,size);

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

        {

         if(!iGetArray(handles_iCCI[i],0,0,1,array))

            return;

         cci[i]=array[0];

        }



      ArrayResize(ma_fast,size);

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

        {

         if(!iGetArray(handles_iMA_Fast[i],0,0,1,array))

            return;

         ma_fast[i]=array[0];

        }



      ArrayResize(ma_slow,size);

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

        {

         if(!iGetArray(handles_iMA_Slow[i],0,0,1,array))

            return;

         ma_slow[i]=array[0];

        }



      ArrayResize(macd_main,size);

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

        {

         if(!iGetArray(handles_iMACD[i],MAIN_LINE,0,1,array))

            return;

         macd_main[i]=array[0];

        }



      ArrayResize(macd_signal,size);

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

        {

         if(!iGetArray(handles_iMACD[i],SIGNAL_LINE,0,1,array))

            return;

         macd_signal[i]=array[0];

        }



      ArrayResize(rsi,size);

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

        {

         if(!iGetArray(handles_iRSI[i],0,0,1,array))

            return;

         rsi[i]=array[0];

        }



      ArrayResize(sto_main,size);

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

        {

         if(!iGetArray(handles_iStochastic[i],MAIN_LINE,0,1,array))

            return;

         sto_main[i]=array[0];

        }

      //---

      if(ma_fast[0]>ma_slow[0] && ma_fast[1]>ma_slow[1] && ma_fast[2]>ma_slow[2] && ma_fast[3]>ma_slow[3] && ma_fast[4]>ma_slow[4] && ma_fast[5]>ma_slow[5] && 

         rsi[0]>50 && rsi[1]>50 && rsi[2]>50 && rsi[3]>50 && rsi[4]>50 && rsi[5]>50 && 

         cci[0]>0.0 && cci[1]>0.0 && cci[2]>0.0 && cci[3]>0.0 && cci[4]>0.0 && cci[5]>0.0 && 

         sto_main[0]>40 && sto_main[1]>40 && sto_main[2]>40 && sto_main[3]>40 && sto_main[4]>40 && sto_main[5]>40 && 

         macd_main[0]>macd_signal[0] && macd_main[1]>macd_signal[1] && macd_main[2]>macd_signal[2] && macd_main[3]>macd_signal[3] && macd_main[4]>macd_signal[4] && macd_main[5]>macd_signal[5])

        {

         if(!InpReverse)

            m_need_open_buy=true;

         else

            m_need_open_sell=true;

         return;

        }

      //---

      if(ma_fast[0]<ma_slow[0] && ma_fast[1]<ma_slow[1] && ma_fast[2]<ma_slow[2] && ma_fast[3]<ma_slow[3] && ma_fast[4]<ma_slow[4] && ma_fast[5]<ma_slow[5] && 

         rsi[0]<50 && rsi[1]<50 && rsi[2]<50 && rsi[3]<50 && rsi[4]<50 && rsi[5]<50 && 

         cci[0]<0.0 && cci[1]<0.0 && cci[2]<0.0 && cci[3]<0.0 && cci[4]<0.0 && cci[5]<0.0 && 

         sto_main[0]<60 && sto_main[1]<60 && sto_main[2]<60 && sto_main[3]<60 && sto_main[4]<60 && sto_main[5]<60 && 

         macd_main[0]<macd_signal[0] && macd_main[1]<macd_signal[1] && macd_main[2]<macd_signal[2] && macd_main[3]<macd_signal[3] && macd_main[4]<macd_signal[4] && macd_main[5]<macd_signal[5])

        {

         if(!InpReverse)

            m_need_open_sell=true;

         else

            m_need_open_buy=true;

         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;

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

         if(deal_entry==DEAL_ENTRY_IN)

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

              {

               if(m_waiting_transaction)

                  if(m_waiting_order_ticket==deal_order)

                    {

                     Print(__FUNCTION__," Transaction confirmed");

                     m_transaction_confirmed=true;

                    }

              }

     }

  }

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

//| Refreshes the symbol quotes data                                 |

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

bool RefreshRates(void)

  {

//--- refresh rates

   if(!m_symbol.RefreshRates())

     {

      Print("RefreshRates error");

      return(false);

     }

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

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

      return(false);

//---

   return(true);

  }

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

//| Check the correctness of the position volume                     |

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

bool CheckVolumeValue(double volume,string &error_description)

  {

//--- minimal allowed volume for trade operations

   double min_volume=m_symbol.LotsMin();

   if(volume<min_volume)

     {

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

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

      else

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

      return(false);

     }

//--- maximal allowed volume of trade operations

   double max_volume=m_symbol.LotsMax();

   if(volume>max_volume)

     {

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

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

      else

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

      return(false);

     }

//--- get minimal step of volume changing

   double volume_step=m_symbol.LotsStep();

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

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

     {

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

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

                                        volume_step,ratio*volume_step);

      else

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

                                        volume_step,ratio*volume_step);

      return(false);

     }

   error_description="Correct volume value";

   return(true);

  }

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

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

   freeze_level*=1.1;

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

   stop_level*=1.1;



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

      return(false);



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

//---

   return(true);

  }

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

//| Open position                                                    |

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

void OpenPosition(const ENUM_POSITION_TYPE pos_type,const double level)

  {

//--- buy

   if(pos_type==POSITION_TYPE_BUY)

     {

      double price=m_symbol.Ask();



      double sl=(InpStopLoss==0)?0.0:price-ExtStopLoss;

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

         sl=price-level;



      double tp=(InpTakeProfit==0)?0.0:price+ExtTakeProfit;

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

         tp=price+level;



      OpenBuy(sl,tp);

     }

//--- sell

   if(pos_type==POSITION_TYPE_SELL)

     {

      double price=m_symbol.Bid();



      double sl=(InpStopLoss==0)?0.0:price+ExtStopLoss;

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

         sl=price+level;



      double tp=(InpTakeProfit==0)?0.0:price-ExtTakeProfit;

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

         tp=price-level;



      OpenSell(sl,tp);

     }

  }

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

//| Open Buy position                                                |

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

void OpenBuy(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double long_lot=0.0;

   if(IntLotOrRisk==risk)

     {

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

      if(InpPrintLog)

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

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

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

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

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

      if(long_lot==0.0)

        {

         m_waiting_transaction=false;

         if(InpPrintLog)

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

         return;

        }

     }

   else if(IntLotOrRisk==lot)

      long_lot=InpVolumeLorOrRisk;

   else

     {

      m_waiting_transaction=false;

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

        {

         Print("#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_SELL,long_lot,m_symbol.Bid());

   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

              {

               m_waiting_transaction=true;  // "true" -> it's forbidden to trade, we expect a transaction

               m_waiting_order_ticket=m_trade.ResultOrder();

              }

            else

               m_waiting_transaction=false;

            if(InpPrintLog)

               Print("#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)

              {

               m_waiting_transaction=true;  // "true" -> it's forbidden to trade, we expect a transaction

               m_waiting_order_ticket=m_trade.ResultOrder();

              }

            else

               m_waiting_transaction=false;

            if(InpPrintLog)

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

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

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         m_waiting_transaction=false;

         if(InpPrintLog)

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

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

         if(InpPrintLog)

            PrintResultTrade(m_trade,m_symbol);

        }

     }

   else

     {

      m_waiting_transaction=false;

      if(InpPrintLog)

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

      return;

     }

//---

  }

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

//| Open Sell position                                               |

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

void OpenSell(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double short_lot=0.0;

   if(IntLotOrRisk==risk)

     {

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

      if(InpPrintLog)

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

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

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

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

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

      if(short_lot==0.0)

        {

         m_waiting_transaction=false;

         if(InpPrintLog)

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

         return;

        }

     }

   else if(IntLotOrRisk==lot)

      short_lot=InpVolumeLorOrRisk;

   else

     {

      m_waiting_transaction=false;

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

         Print("#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

              {

               m_waiting_transaction=true;  // "true" -> it's forbidden to trade, we expect a transaction

               m_waiting_order_ticket=m_trade.ResultOrder();

              }

            else

               m_waiting_transaction=false;

            if(InpPrintLog)

               Print("#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)

              {

               m_waiting_transaction=true;  // "true" -> it's forbidden to trade, we expect a transaction

               m_waiting_order_ticket=m_trade.ResultOrder();

              }

            else

               m_waiting_transaction=false;

            if(InpPrintLog)

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

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

            if(InpPrintLog)

               PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

         m_waiting_transaction=false;

         if(InpPrintLog)

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

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

         if(InpPrintLog)

            PrintResultTrade(m_trade,m_symbol);

        }

     }

   else

     {

      m_waiting_transaction=false;

      if(InpPrintLog)

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

      return;

     }

//---

  }

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

//| Print CTrade result                                              |

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

void PrintResultTrade(CTrade &trade,CSymbolInfo &symbol)

  {

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

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

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

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

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

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

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

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

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

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

   int d=0;

  }

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

//| Get value of buffers                                             |

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

double iGetArray(const int handle,const int buffer,const int start_pos,const int count,double &arr_buffer[])

  {

   bool result=true;

   if(!ArrayIsDynamic(arr_buffer))

     {

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

      return(false);

     }

   ArrayFree(arr_buffer);

//--- reset error code 

   ResetLastError();

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

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

   if(copied!=count)

     {

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

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

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

      return(false);

     }

   return(result);

  }

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

//| Trailing                                                         |

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

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

void Trailing(const double stop_level)

  {

/*

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

           {

            if(m_position.PositionType()==POSITION_TYPE_BUY)

              {

               if(m_position.PriceCurrent()-m_position.PriceOpen()>ExtTrailingStop+ExtTrailingStep)

                  if(m_position.StopLoss()<m_position.PriceCurrent()-(ExtTrailingStop+ExtTrailingStep))

                     if(ExtTrailingStop>=stop_level)

                       {

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

                           m_symbol.NormalizePrice(m_position.PriceCurrent()-ExtTrailingStop),

                           m_position.TakeProfit()))

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

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

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

                        RefreshRates();

                        m_position.SelectByIndex(i);

                        PrintResultModify(m_trade,m_symbol,m_position);

                        continue;

                       }

              }

            else

              {

               if(m_position.PriceOpen()-m_position.PriceCurrent()>ExtTrailingStop+ExtTrailingStep)

                  if((m_position.StopLoss()>(m_position.PriceCurrent()+(ExtTrailingStop+ExtTrailingStep))) || 

                     (m_position.StopLoss()==0))

                     if(ExtTrailingStop>=stop_level)

                       {

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

                           m_symbol.NormalizePrice(m_position.PriceCurrent()+ExtTrailingStop),

                           m_position.TakeProfit()))

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

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

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

                        RefreshRates();

                        m_position.SelectByIndex(i);

                        PrintResultModify(m_trade,m_symbol,m_position);

                       }

              }



           }

  }

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

//| Print CTrade result                                              |

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

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

  {

   Print("File: ",__FILE__,", symbol: ",m_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(m_symbol.FreezeLevel(),0),", Stops Level: "+DoubleToString(m_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()));

   int d=0;

  }

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

//| Close positions                                                  |

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

void ClosePositions(const ENUM_POSITION_TYPE pos_type)

  {

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

            if(m_position.PositionType()==pos_type) // gets the position type

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

  }

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

//| Calculate all positions                                          |

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

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

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

  {

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

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

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

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

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

           {

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

              }

           }

  }

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

//| Create Handles of iCCI indicators                                |

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

bool CreateHandlesCCIs(int &array_handles[],const int ma_period)

  {

   int size=ArraySize(array_timeframes);

   ArrayFree(array_handles);

   ArrayResize(array_handles,size);

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

     {

      //--- create handle of the indicator iCCI

      int handle_iCCI=iCCI(m_symbol.Name(),array_timeframes[i],ma_period,PRICE_TYPICAL);

      //--- if the handle is not created 

      if(handle_iCCI==INVALID_HANDLE)

        {

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

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

                     m_symbol.Name(),

                     EnumToString(array_timeframes[i]),

                     GetLastError());

         //--- the indicator is stopped early 

         return(false);

        }

      array_handles[i]=handle_iCCI;

     }

//---

   return(true);

  }

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

//| Create Handles of iMA indicators                                 |

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

bool CreateHandlesMAs(int &array_handles[],const int ma_period,const ENUM_MA_METHOD ma_method)

  {

   int size=ArraySize(array_timeframes);

   ArrayFree(array_handles);

   ArrayResize(array_handles,size);

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

     {

      //--- create handle of the indicator iMA

      int handle_iMA=iMA(m_symbol.Name(),array_timeframes[i],ma_period,0,ma_method,PRICE_CLOSE);

      //--- if the handle is not created 

      if(handle_iMA==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(array_timeframes[i]),

                     GetLastError());

         //--- the indicator is stopped early 

         return(false);

        }

      array_handles[i]=handle_iMA;

     }

//---

   return(true);

  }

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

//| Create Handles of iMACD indicators                               |

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

bool CreateHandlesMACDs(int &array_handles[],const int fast_ema_period,const int slow_ema_period,const int signal_period)

  {

   int size=ArraySize(array_timeframes);

   ArrayFree(array_handles);

   ArrayResize(array_handles,size);

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

     {

      //--- create handle of the indicator iMACD

      int handle_iMACD=iMACD(m_symbol.Name(),array_timeframes[i],fast_ema_period,slow_ema_period,signal_period,PRICE_CLOSE);

      //--- if the handle is not created 

      if(handle_iMACD==INVALID_HANDLE)

        {

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

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

                     m_symbol.Name(),

                     EnumToString(array_timeframes[i]),

                     GetLastError());

         //--- the indicator is stopped early 

         return(false);

        }

      array_handles[i]=handle_iMACD;

     }

//---

   return(true);

  }

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

//| Create Handles of iStochastic indicators                         |

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

bool CreateHandlesStochastics(int &array_handles[],const int Kperiod,const int Dperiod,const int slowing)

  {

   int size=ArraySize(array_timeframes);

   ArrayFree(array_handles);

   ArrayResize(array_handles,size);

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

     {

      //--- create handle of the indicator iStochastic

      int handle_iStochastic=iStochastic(m_symbol.Name(),array_timeframes[i],Kperiod,Dperiod,slowing,MODE_SMA,STO_LOWHIGH);

      //--- if the handle is not created 

      if(handle_iStochastic==INVALID_HANDLE)

        {

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

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

                     m_symbol.Name(),

                     EnumToString(array_timeframes[i]),

                     GetLastError());

         //--- the indicator is stopped early 

         return(false);

        }

      array_handles[i]=handle_iStochastic;

     }

//---

   return(true);

  }

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

//| Create Handles of iRSI indicators                                |

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

bool CreateHandlesRSIs(int &array_handles[],const int ma_period)

  {

   int size=ArraySize(array_timeframes);

   ArrayFree(array_handles);

   ArrayResize(array_handles,size);

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

     {

      //--- create handle of the indicator iRSI

      int handle_iRSI=iRSI(m_symbol.Name(),array_timeframes[i],ma_period,PRICE_CLOSE);

      //--- if the handle is not created 

      if(handle_iRSI==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(array_timeframes[i]),

                     GetLastError());

         //--- the indicator is stopped early 

         return(false);

        }

      array_handles[i]=handle_iRSI;

     }

//---

   return(true);

  }

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

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

            return(true);

//---

   return(false);

  }

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

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