Having trouble coding Stochastic RSI EA - need help with iCustom()

 

I have tried to understand how iCustom works, but I guess I'm just not getting it. I'm trying to build a simple Stochastic RSI EA. I have tried using both of these indicators:

Free download of the 'Stochastic RSI' indicator by 'GODZILLA' for MetaTrader 5 in the MQL5 Code Base, 2011.11.25

Free download of the 'SVE Stochastic RSI' indicator by 'mladen' for MetaTrader 5 in the MQL5 Code Base, 2019.01.26

In both cases, it seems like I'm just getting the loop counter back, not the Stochastic RSI values.

Here's the work in progress (no exit signals yet, trying to get the entry signal working first):

#property strict

input int                RSILength = 8;
input int                StocLength = 8;
input int                WMALength = 8;
input int                Shift = 0;
input double             Overbought = 70.0;        // Overbought level
input double             Oversold = 30.0;          // Oversold level
input double             LotSize = 0.1;            // Order size in lots
input int                ATRPeriod = 14;           // ATR period
input double             ATRMultiplier = 2.0;      // ATR multiplier for SL
input int                MagicNumber = 123456;     // Magic number

MqlRates rates[];
datetime last_bar_time;

int OnInit()
  {
   ArraySetAsSeries(rates, true);
   return(INIT_SUCCEEDED);
  }

void OnTick()
  {
  datetime current_bar_time = iTime(Symbol(), 0, 0);
  if(current_bar_time == last_bar_time) return;
  last_bar_time = current_bar_time;
   
   MqlTick last_tick;
   SymbolInfoTick(Symbol(), last_tick);
   double Ask = last_tick.ask;
   double Bid = last_tick.bid;

   double StochRSI = iCustom(Symbol(), Period(), "stochasticrsi", RSILength, StocLength, WMALength, Shift, 0);
   double StochRSI_prev = iCustom(Symbol(), Period(), "stochasticrsi", RSILength, StocLength, WMALength, Shift, 1);
   double ATR = iATR(Symbol(), 0, ATRPeriod);
   if(StochRSI == EMPTY_VALUE || StochRSI_prev == EMPTY_VALUE || ATR == EMPTY_VALUE)
      return;

   double stopLossLong = NormalizeDouble(Bid - ATR * ATRMultiplier, _Digits);
   double stopLossShort = NormalizeDouble(Ask + ATR * ATRMultiplier, _Digits);

   int totalOrders = PositionsTotal();

   PrintFormat("StochRSI: %f, StochRSI_prev: %f, ATR: %f, stopLossLong: %f, stopLossShort: %f",
              StochRSI, StochRSI_prev, ATR, stopLossLong, stopLossShort);
   PrintFormat("totalOrders: %d", totalOrders);

   //--- If there are open orders, check for exit signals
   if(totalOrders > 0)
   {
      // Add exit logic here
   }

   MqlTradeRequest request;
   MqlTradeResult result;

   ZeroMemory(request);

   request.magic = MagicNumber;
   request.deviation = 10;
   request.volume = LotSize;

   //--- Long position entry
   if(StochRSI > Oversold && StochRSI_prev <= Oversold)
     {
      request.action = TRADE_ACTION_DEAL;
      request.price = Ask;
      request.sl = stopLossLong;
      request.tp = 0;
      request.type = ORDER_TYPE_BUY;
      request.symbol = Symbol();

      OrderSend(request, result);
     }

   //--- Short position entry
   if(StochRSI < Overbought && StochRSI_prev >= Overbought)
     {
      request.action = TRADE_ACTION_DEAL;
      request.price = Bid;
      request.sl = stopLossShort;
      request.tp = 0;
      request.type = ORDER_TYPE_SELL;
      request.symbol = Symbol();

      OrderSend(request, result);
     }
  }

Like I said, I'm just not getting it. In my programming background, the "return" value of a function is the output you're looking for, but in this case, it just seems to be the loop value from the indicator. How do I get the values from the iCustom into a buffer/array so I can look at past values?

BTW, it's pretty amazing that as common as Stochastic RSI is, I can't find one single example of source code anywhere on the internet of an EA built around it. It would be a great service to the community for someone to post even a simple single indicator example in CodeBase.

Stochastic RSI
Stochastic RSI
  • www.mql5.com
Stochastic RSI is a standard Stochastic oscillator, the values of which are calculated not from a price series but from RSI technical indicator values.
 
Scott Allen: I have tried to understand how iCustom works, but I guess I'm just not getting it.
void OnTick()
  {
 ⋮
   double StochRSI = iCustom(Symbol(), Period(), "stochasticrsi", RSILength, StocLength, WMALength, Shift, 0);
   double StochRSI_prev = iCustom(Symbol(), Period(), "stochasticrsi", RSILength, StocLength, WMALength, Shift, 1);
   double ATR = iATR(Symbol(), 0, ATRPeriod);

Perhaps you should read the manual, especially the examples.
   How To Ask Questions The Smart Way. (2004)
      How To Interpret Answers.
         RTFM and STFW: How To Tell You've Seriously Screwed Up.

They all (including iCustom) return a handle (an int). You get that in OnInit. In OnTick/OnCalculate (after the indicator has updated its buffers), you use the handle, shift and count to get the data.
          Technical Indicators - Reference on algorithmic/automated trading language for MetaTrader 5
          Timeseries and Indicators Access / CopyBuffer - Reference on algorithmic/automated trading language for MetaTrader 5
          How to start with MQL5 - General - MQL5 programming forum - Page 3 #22 (2020)
          How to start with MQL5 - MetaTrader 5 - General - MQL5 programming forum - Page 7 #61 (2020)
          MQL5 for Newbies: Guide to Using Technical Indicators in Expert Advisors - MQL5 Articles (2010)
          How to call indicators in MQL5 - MQL5 Articles (2010)