Need help with RSI indicator

Hello Guys,

I am trying to build a RSI EA using iRSI in MQL5.

My strategy is simple. It should take a buy trade if RSI is crossing above level 30 and close buy trade when RSI crossing below level 70.

But currenttly iRSI is taking trades on level 30 no matter if it is crossing level 30 from above or below.

Is there any way to solve this? Attaching my EA below

``````#include <Trade\Trade.mqh>
input int MagicNumber=10001;
input double StopLoss=0;
input double TakeProfit=0;
input int TrailingStop=0;
input double Prd =2;
input double Sell =45;
input double Sellstop =55;
input double MaximumRisk        = 0.05;    // Maximum Risk in percentage
input double DecreaseFactor     = 0;       // Descrease factor
//+------------------------------------------------------------
//+------------------------------------------------------------------+
//    expert start function
//+------------------------------------------------------------------+

ENUM_MA_METHOD MethodMigrate(int method)
{
switch(method)
{
case 0: return(MODE_SMA);
case 1: return(MODE_EMA);
case 2: return(MODE_SMMA);
case 3: return(MODE_LWMA);
default: return(MODE_SMA);
}
}

ENUM_STO_PRICE StoFieldMigrate(int field)
{
switch(field)
{
case 0: return(STO_LOWHIGH);
case 1: return(STO_CLOSECLOSE);
default: return(STO_LOWHIGH);
}
}
ENUM_APPLIED_PRICE PriceMigrate(int price)
{
switch(price)
{
case 1: return(PRICE_CLOSE);
case 2: return(PRICE_OPEN);
case 3: return(PRICE_HIGH);
case 4: return(PRICE_LOW);
case 5: return(PRICE_MEDIAN);
case 6: return(PRICE_TYPICAL);
case 7: return(PRICE_WEIGHTED);
default: return(PRICE_CLOSE);
}
}

ENUM_TIMEFRAMES TFMigrate(int tf)
{
switch(tf)
{
case 0: return(PERIOD_CURRENT);
case 1: return(PERIOD_M1);
case 5: return(PERIOD_M5);
case 15: return(PERIOD_M15);
case 30: return(PERIOD_M30);
case 60: return(PERIOD_H1);
case 240: return(PERIOD_H4);
case 1440: return(PERIOD_D1);
case 10080: return(PERIOD_W1);
case 43200: return(PERIOD_MN1);

case 2: return(PERIOD_M2);
case 3: return(PERIOD_M3);
case 4: return(PERIOD_M4);
case 6: return(PERIOD_M6);
case 10: return(PERIOD_M10);
case 12: return(PERIOD_M12);
case 16385: return(PERIOD_H1);
case 16386: return(PERIOD_H2);
case 16387: return(PERIOD_H3);
case 16388: return(PERIOD_H4);
case 16390: return(PERIOD_H6);
case 16392: return(PERIOD_H8);
case 16396: return(PERIOD_H12);
case 16408: return(PERIOD_D1);
case 32769: return(PERIOD_W1);
case 49153: return(PERIOD_MN1);
default: return(PERIOD_CURRENT);
}
}

//---
#define EMPTY -1

//+------------------------------------------------------------------+
//| Calculate optimal lot size                                       |
//+------------------------------------------------------------------+
{
double price=0.0;
double margin=0.0;
//--- select lot size
return(0.0);
return(0.0);
if(margin<=0.0)
return(0.0);

double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
if(DecreaseFactor>0)
{
//--- select history for access
HistorySelect(0,TimeCurrent());
//---
int    orders=HistoryDealsTotal();  // total history deals
int    losses=0;                    // number of losses orders without a break

for(int i=orders-1;i>=0;i--)
{
ulong ticket=HistoryDealGetTicket(i);
if(ticket==0)
{
break;
}
//--- check symbol
if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
continue;
//--- check Expert Magic number
if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MagicNumber)
continue;
//--- check profit
double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
if(profit>0.0)
break;
if(profit<0.0)
losses++;
}
//---
if(losses>1)
lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//--- normalize and check limits
double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
lot=stepvol*NormalizeDouble(lot/stepvol,0);

double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
if(lot<minvol)
lot=minvol;

double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
if(lot>maxvol)
lot=maxvol;
return(lot);
}

void OnTick()
{
// Check for New Bar
static datetime dtBarCurrent   = WRONG_VALUE;
datetime dtBarPrevious  = dtBarCurrent;
dtBarCurrent   = (datetime) SeriesInfoInteger( _Symbol, _Period, SERIES_LASTBAR_DATE );

bool     boolNewBarFlag = ( dtBarCurrent != dtBarPrevious );

if( boolNewBarFlag ) {

double Bid=SymbolInfoDouble(_Symbol,SYMBOL_BID);

double MyPoint=_Point;
if(_Digits==3 || _Digits==5) MyPoint=_Point*10;
double TheStopLoss=0;
double TheTakeProfit=0;
if( TotalOrdersCount()==0 )
{

{

return;
}

if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)<Sell)) // Here is your open Sell rule
{
return;
}

}

int posTotal=PositionsTotal();
for(int posIndex=posTotal-1;posIndex>=0;posIndex--)
{
ulong ticket=PositionGetTicket(posIndex);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC)==MagicNumber)
{
{
{
break;
}

if(TrailingStop>0)
{
if(SymbolInfoDouble(_Symbol,SYMBOL_BID)-PositionGetDouble(POSITION_PRICE_OPEN)>MyPoint*TrailingStop)
{
if(PositionGetDouble(POSITION_SL)<SymbolInfoDouble(_Symbol,SYMBOL_BID)-MyPoint*TrailingStop)
{
return;
}
}
}
}

if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)>Sellstop)) // here is your close sell rule
{
break;
}
if(TrailingStop>0)
{
{
{
return;
}
}
}
}
}
}
return;
}
}

int TotalOrdersCount()
{
int result=0;
int posTotal=PositionsTotal();
for(int posIndex=posTotal-1;posIndex>=0;posIndex--)
{
ulong ticket=PositionGetTicket(posIndex);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC)==MagicNumber) result++;
}
return (result);
}

int Hour()
{
MqlDateTime tm;
TimeCurrent(tm);
return(tm.hour);
}
int Minute()
{
MqlDateTime tm;
TimeCurrent(tm);
return(tm.min);
}

double CopyBufferMQL4(int handle,int index,int shift)
{
double buf[];
switch(index)
{
case 0: if(CopyBuffer(handle,0,shift,1,buf)>0)
return(buf[0]); break;
case 1: if(CopyBuffer(handle,1,shift,1,buf)>0)
return(buf[0]); break;
case 2: if(CopyBuffer(handle,2,shift,1,buf)>0)
return(buf[0]); break;
case 3: if(CopyBuffer(handle,3,shift,1,buf)>0)
return(buf[0]); break;
case 4: if(CopyBuffer(handle,4,shift,1,buf)>0)
return(buf[0]); break;
default: break;
}
return(EMPTY_VALUE);
}

double iRSIMQL4(string symbol,
int tf,
int period,
int price,
int shift)
{
ENUM_TIMEFRAMES timeframe=TFMigrate(tf);
ENUM_APPLIED_PRICE applied_price=PriceMigrate(price);
int handle=iRSI(symbol,timeframe,period,applied_price);
if(handle<0)
{
return(-1);
}
else
return(CopyBufferMQL4(handle,0,shift));
}``````
1 Like

Hi, your rule is â€śIf RSI for previous bar is > 30 then BUYâ€ť
To capture only cross you need to have TWO conditions:

• RSI for bar -1 > 30
• RSI for bar -2 < 30

So basically for Daily timeframe, on Monday it needs to be below 30, on Tuesday above 30 to have a cross. Similarily you need to identify the cross for upper part of RSI.

(btw your code looks not bad, but itâ€™s very long for such simple strategy. Think about closing reusable functions in MQH files, such as opening trades, setting break even, trailing stops, calculating position size to risk etc.)

2 Likes

RSI is not regarded as being an effective indicator, according to No Nonsense Forex testing analysis. He said what it is useful for is to just have a 50 line to confirm trend. Above 50 for bullish, and below for bearish.

The trouble with the standard settings is that trades can stay for days, even weeks being overbought or oversold.

2 Likes

The question here is not if RSI is effective or not. It was a coding issue to be resolved.

What does it mean, that RSI is not effective? Buying on 30 cross down is not effective? or buying on 30 cross up? Or maybe even selling on 30 cross down? Is it not effective for any potential risk/reward ratio and regardless of target TP/SL size?

Beginners are reading this forum and such general opinion may close some doors for them. I would encourage anyone to test and experiment with RSI and decide on their own. Instead of â€śRSI is not effective indicatorâ€ť I would say â€śbuying when RSI on default settings go into oversold without any other factors may not be profitable strategy in strong downtrendâ€ť.

2 Likes

Maybe you should read my post again. It stated what the No Nonsense FX guy said on Youtube when he tested out this indicator, as he does with dozens of others.He is a reliable source of information, and his take was as I stated.

I use RSI 50 as a trend signal, but itâ€™s not an indicator Iâ€™d use for changing gear, as price action is by far the best probability movement.

As for the coding issue, there are better indicators to spend your time with.

1 Like

Did you code this yourself? Iâ€™m no expert but these bits of code seem to contradict your description.

`````` if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)<Sell)) // Here is your open Sell rule
{
return;
}
``````

and

``````   if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)>Sellstop)) // here is your close sell rule
{
break;
``````

Plus the weird bit that stands out is that it looks like an attempted conversion of an MQL4 to 5 code? The syntax is in the form of MQL4 and not MQL5. Also not sure how declaring the MAs, Stoch and Timeframes are supposed to help either.

Iâ€™m not an expert but the codes looks very messy and doesnâ€™t appear to fulfill the described function. Iâ€™d code one from scratch if I were you and get rid of redundant lines of code and avoid conversion errors (try compiling the code). Probably the best place to try is the MQL5 forum.

No Nonsense Forex guy as in Victor Patrick? Heâ€™s got a very poor testing methodology. He bashes indicators and the RSI in particular when heâ€™s using it standalone. No textbook recommends using oscillators standalone so not sure what heâ€™s trying to prove.

If I remember the RSI video he cites (from about 2 years ago) he makes two alarming claims:

1. Thereâ€™s no overselling/overbuying in forex: Donâ€™t see how this is relevant if he understands the RSI formula
2. Itâ€™s outdated since it came out in 1978: The ATR he uses in his system was developed in the same year by the same guy. Donâ€™t know why he chooses to point how supposedly outdated this is in this instance only.

Hopefully Iâ€™m not misremembering things, but I completely unsubbed from him and anything he has to say after I saw him butchering the use of the Ichomoku Kinko Hyo. Garbage explanation on his part.

Yeah, I guess weâ€™re not all perfect. The argument against these indicators, apart from lagging is that overbought and sold positions can last days, if not weeks. Thatâ€™s not much use, is it?

It is quite factual that overbought and oversold indicators are losing strategies long term. Unless, of course theyâ€™re confirmation to an otherwise probable trade based on price action movement.

As for Ichimoku, which I use, more to prevent me for making an unsuitable trade. It has stood the test of time, and used as intended - in a trending market - is a better than 50% indicator. As an aside to that, IMO, in todayâ€™s covid environment the only true probability is price action and timing.

Come on guys, wake up to yourselvesâ€¦ You sound like a New Mothers Clubâ€¦

The only way to get these standard Indicators to be profitable is by applying outside the box thinkingâ€¦

GBPJPY 4 Hour Chart (Current) Not cherry-picked!!

Simple 4 Hour Chart with RSI 4 Period appliedâ€¦ High of 75 Lowâ€¦ of 25 to apply some smoothing.

Cross below the 25 is a Sellâ€¦ Cross above the 75 is a Buyâ€¦ A cross in the opposite direction reverses the tradeâ€¦ And Bingoâ€¦ You have a viable RSI Strategy on the 4 Hour timeframe that has gained 1076 pips over the last 30 daysâ€¦ It wonâ€™t win every trade, but it will lose small and win largeâ€¦

Even a new trader using 1:100 margin account and 0.05 lot positions should have added 660 whatevers to his/hers accountâ€¦

Donâ€™t want to use the GBPJPYâ€¦ No problem, just layout the template and toggle through your favorite pairs until you find one that gives clean trading opportunitiesâ€¦ Tweak the settings if it is requiredâ€¦

I have laid it all out so even Stevie Wonder wonâ€™t trip over itâ€¦

|

A few more examplesâ€¦

EURUSD 4 Hour - 204 pips / 138 Buttons in 30 days of tradingâ€¦

AUDUSD 4 Hour - 529 pips / 358 Buttons in 30 days of tradingâ€¦

2 Likes

I think it works in your examples due to the fact that the market is ranging at present (medium term). Do you agree?

@meza, Bitcoin is one of the most volatile instruments to trade in the markets todayâ€¦ (See Below)

Bitcoin 4 Hour (Current) Chart with the same strategy appliedâ€¦ Manually back testing each Instrument across the previous 30/60/90 day period will display the slight tweaks required I explained in the original postâ€¦

Period is now 3, High is now 80â€¦ Low is now 20 which sharpens the Indicator for use on this volatile cryptoâ€¦ Gains 132,000 pips - Loses 4,000 pips = 128,000 across a 30 day periodâ€¦

A strategy like this should require 15-30 mins per dayâ€¦

It can be applied to the 15 min (Current) Chart only change erquired was to extend the Period to 4â€¦

Using exactly the same entry and exit criteria as displayed in the original post a disciplined trader should have gained 43,800 pips and lost 1,800 pips = 42,000 pip gain across a 3 day periodâ€¦

No Take Profits or Stop Losses (OMG!) have been used in any of these displayed strategies, Price Action and the Indicator alone allows you to implement such a simple strategyâ€¦ Trial on a DEMO!!

1 Like

So, I take it you close your position when it crosses in the opposite direction. That means you need to be in front of your screen virtually all day.
Unless you can set it up as an EA.
Have you tried to modify it so it could work as an EOD strategy?

@meza, You might want to sit there all dayâ€¦ OR you could just download a FREE RSI Alert Indicator for MT4 or MT5 (See Below) from MQL5 Website and apply the strategy to your chosen pairâ€¦

Set it up to send you an email or Notification to your mobileâ€¦ You have a few hours to enter and exit each trade on the 4 hour time frameâ€¦

Itâ€™s pretty simple to test if you put some real thought into itâ€¦

@meza I used to trade a very similar strategy a few years backâ€¦ If you search through my posts back in 2017 - 2019 you will see itâ€™s not the first time I have posted this trading strategyâ€¦ You will find trades posted live over a couple of weeksâ€¦

Only stopped at the time because a few of the â€śself appointed BP expertsâ€ť got their panties all in a bunchâ€¦ Would make for some interesting reading if you can be bothered to dig for itâ€¦

I have a couple of sharper strategies which I trade these daysâ€¦ That wonâ€™t see the light of day in BPâ€¦

Edit: You were here in 2008!.. nearly 10 years before meâ€¦ You might have seen it in your travelsâ€¦

2 Likes

I like the simplicity and will demo it.
Thanks for sharing.

1 Like

interesting range of opinions, here, on how to use the RSI

1 Like

This strategy of mine was working with RSI filtered with ADX.
->https://www.darwinex.com/darwin/KVL
It worked pretty well for 2 years.
99% of strategies fail
99% of srategies with RSI or other oscillators fail
99% of strategies with movng averages fail
99% of strategies with candlestick patterns AKA â€śprice actionâ€ť fail.

Iâ€™m no expert but apparently folks use other levels as well after studying and understanding the nuances of the RSI. Hereâ€™s an excerpt from this book that gives some insight:

The RSI portion concludes with this para:

@darthdimsky, good article that shows that what I have posted is not rocket science. Many traders before me have used similar concepts in their attempt to make the RSI profitableâ€¦.

To offset the RSI values concurrent with the longer term trend is a characteristic that I had noticed when back testing, but never applied. So many thanks @darthdimsky for highlighting that text. It is something that I and other readers of your post can add to back testing this strategy.

There is many other Oscillators that can be applied in the same way? Itâ€™s really just converting the RSI to give it stochastic behaviour.

CCI, DPO, Trix, Williams%R etc. Virtually any bound indicator that displays the extremes (not strengths) of price action.

2 Likes