//+------------------------------------------------------------------+
//|                                  Algorithmic Input Selection.mq5 |
//|                                               Gamuchirai Ndawana |
//|                    https://www.mql5.com/en/users/gamuchiraindawa |
//+------------------------------------------------------------------+
#property copyright "Gamuchirai Ndawana"
#property link      "https://www.mql5.com/en/users/gamuchiraindawa"
#property version   "1.00"

//+------------------------------------------------------------------+
//| System constants                                                 |
//+------------------------------------------------------------------+
#define RSI_PERIOD 55
#define RSI_TIME_FRAME PERIOD_D1
#define SYSTEM_TIME_FRAME PERIOD_D1
#define RSI_PRICE  PRICE_CLOSE
#define RSI_BUFFER_SIZE 20
#define TRADING_VOLUME SymbolInfoDouble(Symbol(),SYMBOL_VOLUME_MIN)

//+------------------------------------------------------------------+
//| Load our RSI library                                             |
//+------------------------------------------------------------------+
#include <VolatilityDoctor\Indicators\RSI.mqh>
#include <Trade\Trade.mqh>

//+------------------------------------------------------------------+
//| Global variables                                                 |
//+------------------------------------------------------------------+
CTrade Trade;
RSI    rsi_55(Symbol(),RSI_TIME_FRAME,RSI_PERIOD,RSI_PRICE);
double last_value;
int    count;
int    ma_o_handler,ma_c_handler;
double ma_o[],ma_c[];
double trade_sl;

//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   setup();
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---
   IndicatorRelease(ma_c_handler);
   IndicatorRelease(ma_o_handler);
  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   update();
  }
//+------------------------------------------------------------------+

//+------------------------------------------------------------------+
//| Update our system variables                                      |
//+------------------------------------------------------------------+
void update(void)
  {
   static datetime time_stamp;
   datetime current_time = iTime(Symbol(),SYSTEM_TIME_FRAME,0);

   if(time_stamp != current_time)
     {
      time_stamp = current_time;
      CopyBuffer(ma_c_handler,0,0,1,ma_c);
      CopyBuffer(ma_o_handler,0,0,1,ma_o);

      if((count == 0) && (PositionsTotal() == 0))
        {
         rsi_55.SetIndicatorValues(RSI_BUFFER_SIZE,true);
         last_value = rsi_55.GetReadingAt(RSI_BUFFER_SIZE - 1);
         count = 1;
        }

      if(PositionsTotal() == 0)
         check_signal();

      if(PositionsTotal() > 0)
         manage_setup();
     }
  }

//+------------------------------------------------------------------+
//| Manage our open trades                                           |
//+------------------------------------------------------------------+
void manage_setup(void)
  {
   double bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   double ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);

   if(PositionSelect(Symbol()))
     {
      double current_sl = PositionGetDouble(POSITION_SL);
      double current_tp = PositionGetDouble(POSITION_TP);
      double new_sl = (current_tp > current_sl) ? (bid-trade_sl) : (ask+trade_sl);
      double new_tp = (current_tp < current_sl) ? (bid+trade_sl) : (ask-trade_sl);
      //--- Buy setup
      if((current_tp > current_sl) && (new_sl < current_sl))
         Trade.PositionModify(Symbol(),new_sl,new_tp);

      //--- Sell setup
      if((current_tp < current_sl) && (new_sl > current_sl))
         Trade.PositionModify(Symbol(),new_sl,new_tp);
     }
  }

//+------------------------------------------------------------------+
//| Setup our global variables                                       |
//+------------------------------------------------------------------+
void setup(void)
  {
   ma_c_handler = iMA(Symbol(),SYSTEM_TIME_FRAME,2,0,MODE_EMA,PRICE_CLOSE);
   ma_o_handler = iMA(Symbol(),SYSTEM_TIME_FRAME,2,0,MODE_EMA,PRICE_OPEN);
   count        = 0;
   last_value   = 0;
   trade_sl     = 1.5e-2;
  }

//+------------------------------------------------------------------+
//| Check if we have a trading setup                                 |
//+------------------------------------------------------------------+
void check_signal(void)
  {
   double current_reading = rsi_55.GetCurrentReading();
   Comment("Last Reading: ",last_value,"\nDifference in Reading: ",(last_value - current_reading));
   double bid = SymbolInfoDouble(Symbol(),SYMBOL_BID);
   double ask = SymbolInfoDouble(Symbol(),SYMBOL_ASK);
   double cp_lb = 7.17;
   double cp_ub = 10.82;

   if((((last_value - current_reading) <= -(cp_lb)) && ((last_value - current_reading) > (cp_ub)))|| ((((last_value - current_reading) > -(cp_lb))) && ((last_value - current_reading) < (cp_lb))))
     {
      if(ma_o[0] > ma_c[0])
        {
         if(PositionsTotal() == 0)
           {
            Trade.Sell(TRADING_VOLUME,Symbol(),bid,(ask+trade_sl),(ask-trade_sl));
            count = 0;
           }
        }
     }

   if(((last_value - current_reading) >= (cp_lb)) < ((last_value - current_reading) < cp_ub))
     {
      if(ma_c[0] < ma_o[0])
        {
         if(PositionsTotal() == 0)
           {
            Trade.Buy(TRADING_VOLUME,Symbol(),ask,(bid-trade_sl),(bid+trade_sl));
            count = 0;
           }
        }
     }
  }
//+------------------------------------------------------------------+

#undef RSI_BUFFER_SIZE
#undef RSI_PERIOD
#undef RSI_PRICE
#undef RSI_TIME_FRAME
#undef SYSTEM_TIME_FRAME
#undef TRADING_VOLUME
//+------------------------------------------------------------------+
