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 Buyy =55;
input double Buyystop =45;
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 TradeSizeOptimized(void)
{
double price=0.0;
double margin=0.0;
//--- select lot size
if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
return(0.0);
if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
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)
{
Print("HistoryDealGetTicket failed, no trade history");
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 trading volume
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 ) {
CTrade trade;
trade.SetExpertMagicNumber(MagicNumber);
double Ask=SymbolInfoDouble(_Symbol,SYMBOL_ASK);
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 )
{
if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)>Buyy)) // Here is your open buy rule
{
if(StopLoss>0) TheStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-StopLoss*MyPoint;
if(TakeProfit>0) TheTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+TakeProfit*MyPoint;
trade.PositionOpen(_Symbol,ORDER_TYPE_BUY,TradeSizeOptimized(),SymbolInfoDouble(_Symbol,SYMBOL_ASK),TheStopLoss,TheTakeProfit);
return;
}
if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)<Sell)) // Here is your open Sell rule
{
if(StopLoss>0) TheStopLoss=SymbolInfoDouble(_Symbol,SYMBOL_ASK)+StopLoss*MyPoint;
if(TakeProfit>0) TheTakeProfit=SymbolInfoDouble(_Symbol,SYMBOL_ASK)-TakeProfit*MyPoint;
trade.PositionOpen(_Symbol,ORDER_TYPE_SELL,TradeSizeOptimized(),SymbolInfoDouble(_Symbol,SYMBOL_BID),TheStopLoss,TheTakeProfit);
return;
}
}
int posTotal=PositionsTotal();
for(int posIndex=posTotal-1;posIndex>=0;posIndex--)
{
ulong ticket=PositionGetTicket(posIndex);
if(PositionSelectByTicket(ticket) && PositionGetInteger(POSITION_MAGIC)==MagicNumber)
{
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
{
if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)<Buyystop)) //here is your close buy rule
{
trade.PositionClose(ticket);
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)
{
trade.PositionModify(ticket,SymbolInfoDouble(_Symbol,SYMBOL_BID)-MyPoint*TrailingStop,PositionGetDouble(POSITION_TP));
return;
}
}
}
}
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
{
if((iRSIMQL4(NULL,0,Prd,PRICE_CLOSE,00)>Sellstop)) // here is your close sell rule
{
trade.PositionClose(ticket);
break;
}
if(TrailingStop>0)
{
if(PositionGetDouble(POSITION_PRICE_OPEN)-SymbolInfoDouble(_Symbol,SYMBOL_ASK)>MyPoint*TrailingStop)
{
if(PositionGetDouble(POSITION_SL)>SymbolInfoDouble(_Symbol,SYMBOL_ASK)+MyPoint*TrailingStop)
{
trade.PositionModify(ticket,SymbolInfoDouble(_Symbol,SYMBOL_ASK)+MyPoint*TrailingStop,PositionGetDouble(POSITION_TP));
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));
}