Author: Copyright © 2012, Yury V. Reshetov
Price Data Components
Series array that contains tick volumes of each bar
Indicators Used
Relative strength index
Miscellaneous
It issuies visual alerts to the screenIt sends emails
10 Views
0 Downloads
0 Favorites
RNN
ÿþ//+------------------------------------------------------------------+

//|                                 RNN(barabashkakvn's edition).mq5 |

//|                               Copyright © 2012, Yury V. Reshetov |

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

#property copyright "Copyright © 2012, Yury V. Reshetov"

#property version   "1.000"

//---

#include <Trade\PositionInfo.mqh>

#include <Trade\Trade.mqh>

#include <Trade\SymbolInfo.mqh>  

#include <Trade\AccountInfo.mqh>

CPositionInfo  m_position;                   // trade position object

CTrade         m_trade;                      // trading object

CSymbolInfo    m_symbol;                     // symbol info object

CAccountInfo   m_account;                    // account info wrapper

//--- input parameters

input double      InpLots  = 1.0;   // Lots

input ushort      InpSLTP  = 100;   // Stop Loss and TakeProfit (in pips)

input int         x0       = 6;     // x0: Setting from 0 to 100 in increments of 1

input int         x1       = 96;    // x1: Setting from 0 to 100 in increments of 1

input int         x2       = 90;    // x2: Setting from 0 to 100 in increments of 1

input int         x3       = 35;    // x3: Setting from 0 to 100 in increments of 1

input int         x4       = 64;    // x4: Setting from 0 to 100 in increments of 1

input int         x5       = 83;    // x5: Setting from 0 to 100 in increments of 1

input int         x6       = 66;    // x6: Setting from 0 to 100 in increments of 1 

input int         x7       = 50;    // x7: Setting from 0 to 100 in increments of 1

//---

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

input ENUM_APPLIED_PRICE   Inp_RSI_applied_price= PRICE_OPEN;  // RSI: type of price

//---

input ulong    m_magic=345727040;// magic number

//---

ulong  m_slippage=10;               // slippage

double ExtSLTP=0.0;

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

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

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

//| Expert initialization function                                   |

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

int OnInit()

  {

//---

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

      return(INIT_FAILED);

   RefreshRates();

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

   string err_text="";

   if(!CheckVolumeValue(InpLots,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);

        }

     }

//---

   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;



   ExtSLTP=InpSLTP*m_adjusted_point;

//--- create handle of the indicator iRSI

   handle_iRSI=iRSI(m_symbol.Name(),Period(),Inp_RSI_ma_period,Inp_RSI_applied_price);

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

  {

//--- 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 there are open positions - exit

   if(IsPositionExists())

      return;

//--- calculate the trading signal

   double sp=TradesSingal();



   double stoploss=0.0;

   double takeprofit=0.0;



   string s="";

   int ticket=-1;



   if(sp<0.0)

     {

      double sl=(InpSLTP==0)?0.0:m_symbol.Ask()-ExtSLTP;

      if(sl>=m_symbol.Bid()) // incident: the position isn't opened yet, and has to be already closed

        {

         PrevBars=0;

         return;

        }

      double tp=(InpSLTP==0)?0.0:m_symbol.Ask()+ExtSLTP;

      OpenBuy(sl,tp);

     }

   else

     {

      double sl=(InpSLTP==0)?0.0:m_symbol.Bid()+ExtSLTP;

      if(sl<=m_symbol.Ask()) // incident: the position isn't opened yet, and has to be already closed

        {

         PrevBars=0;

         return;

        }

      double tp=(InpSLTP==0)?0.0:m_symbol.Bid()-ExtSLTP;

      OpenSell(sl,tp);

     }

//---

  }

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

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

              {

               string s="Open Buy position of "+m_symbol.Name();

               SendMail(s,s);

              }

            else if(deal_type==DEAL_TYPE_SELL)

              {

               string s="Open Sell position of "+m_symbol.Name();

               SendMail(s,s);

              }

           }

     }

  }

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

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

  }

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

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

  }

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

//| Converts probability into a trading signal                       |

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

double TradesSingal()

  {

//--- read indicator volume

   double a1=0.0,a2=0.0,a3=0.0;

   GetRSI(a1,a2,a3);

//--- calculate the probability of a trading signal for a short position.

   double result=GetProbability(a1,a2,a3);



   string s=m_symbol.Name()+", Probability for Short (Sell) position: "+DoubleToString(result,4);



   if(result>0.5)

     {

      Print(s);

     }

   else

     {

      double r=1.0-result;

      Print(s);

      s=m_symbol.Name()+", Probability for Long (Buy) position: "+DoubleToString(r,4);

     }



   SendMail(s,s);

//-- linear sigmoid translates values from 0 to 1 into values from -1 to +1

   result=result*2.0-1.0;

   Print("Result = ",result);

//---

   return(result);

  }

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

//|                                                                  |

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

void GetRSI(double &a1,double &a2,double &a3)

  {

   a1=0.0;

   a2=0.0;

   a3=0.0;



   double rsi_array[];

   ArraySetAsSeries(rsi_array,true);

   int buffer=0,start_pos=0,count=Inp_RSI_ma_period*2+1;



   if(!iGetArray(handle_iRSI,buffer,start_pos,count,rsi_array))

      return;



   a1=rsi_array[0]/100.0;

   a2=rsi_array[Inp_RSI_ma_period]/100.0;

   a3=rsi_array[Inp_RSI_ma_period*2]/100.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);

  }

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

//| Calculation of the probability of a trading signal               | 

//|  for a short position                                            |

//| p1, p2, p3 - signals of TA indicators or oscillators             |

//|  in the range from 0 to 1                                        |

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

double GetProbability(double p1,double p2,double p3)

  {

   double y0 = x0;

   double y1 = x1;

   double y2 = x2;

   double y3 = x3;

   double y4 = x4;

   double y5 = x5;

   double y6 = x6;

   double y7 = x7;



   double pn1 = 1.0 - p1;

   double pn2 = 1.0 - p2;

   double pn3 = 1.0 - p3;

//--- calculation of probability in percent

   double probability=

                      pn1 *(pn2 *(pn3*y0+

                      p3*y1)+

                      p2 *(pn3*y2+

                      p3*y3))+

                      p1 *(pn2 *(pn3*y4+

                      p3*y5)+

                      p2 *(pn3*y6+

                      p3*y7));

                      //--- percent into probabilities

                      probability=probability/100.0;

//---

   return (probability);

  }

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

//| Open Buy position                                                |

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

void OpenBuy(double sl,double tp)

  {

   sl=m_symbol.NormalizePrice(sl);

   tp=m_symbol.NormalizePrice(tp);



   double long_lot=InpLots;

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

   if(free_margin_check>0.0)

     {

      if(m_trade.Buy(long_lot,m_symbol.Name(),m_symbol.Ask(),sl,tp))

        {

         if(m_trade.ResultDeal()==0)

           {

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

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

            PrintResultTrade(m_trade,m_symbol);

           }

         else

           {

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

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

            PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

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

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

         PrintResultTrade(m_trade,m_symbol);

        }

     }

   else

     {

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

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

   if(free_margin_check>0.0)

     {

      if(m_trade.Sell(short_lot,NULL,m_symbol.Bid(),sl,tp))

        {

         if(m_trade.ResultDeal()==0)

           {

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

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

            PrintResultTrade(m_trade,m_symbol);

           }

         else

           {

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

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

            PrintResultTrade(m_trade,m_symbol);

           }

        }

      else

        {

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

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

         PrintResultTrade(m_trade,m_symbol);

        }

     }

   else

     {

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

  }

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

Comments