RSI_EA-v1





//=============================================================================
//												RSI_EA.mq4
//												Originally by: Robert Hill
//												
//=============================================================================

#property copyright "Robert Hill"

#include <stdlib.mqh>
#include <stderror.mqh> 

#define LONG 1
#define SHORT -1
#define FLAT 0

extern bool AllowNewTrades = true;
extern int MagicCode = 5;
//+---------------------------------------------------+
//|Indicator inputs                                   |
//+---------------------------------------------------+
extern int RSI_Period = 9;
extern int RSI_LowerLevel = 30;
extern int RSI_UpperLevel = 70;
extern bool ExitAtSignal = true;
extern int    MMSet  = 45;   // Periodo da media Base


//---- Trade Management
extern bool UseTakeProfit = false;
extern double	TakeProfit			= 80;
extern double	StopLoss 			= 50;

extern string  ts ="---TrailingStop Settings---";
extern string  ts0 = "---TrailingStopLoss---";
extern string  ts1 = " 1. Trail immediately";
extern string  ts2 = " 2. Standard at input";
extern  bool UseTrailingStop = true;
extern  int		TrailingStopType 	= 2;
extern double	TrailingStop		= 25;
//+---------------------------------------------------+
//|Money Management                                   |
//+---------------------------------------------------+
extern bool UseMoneyManagement = true;   // Change to false if you want to shutdown money management controls.
extern bool BrokerIsIBFX = false;
extern string  m1="Set mini and micro to false for standard account";
extern bool AccountIsMini = true;
extern bool AccountIsMicro = false;
extern double TradeSizePercent = 2;      // Change to whatever percent of equity you wish to risk.
extern double	Lots				= 1;
double MaxLots = 100.0;

extern int Slippage = 3;
extern  int SignalCandle = 1;
double lotMM;

string  ExpertName="RSI_EA_";


int      MagicNumber;  // Magic number of the trades. must be unique to identify
string   nameEA;             // identifies the expert
int TradesInThisSymbol;
bool YesStop;
double myPoint;
int totalTries 		= 5; 
int retryDelay 		= 1000;
int OrderErr;

//=============================================================================
// expert initialization function
//=============================================================================
int init()
{
    MagicNumber = MagicCode*1000 + func_Symbol2Val(Symbol())*100 + func_TimeFrame_Const2Val(Period());
    nameEA = ExpertName + Symbol() + "_" + func_TimeFrame_Val2String(func_TimeFrame_Const2Val(Period()));
    myPoint = SetPoint();

	return(0);
}


//=============================================================================
// expert deinitialization function
//=============================================================================
int deinit()
{
	return(0);
}


//=============================================================================
//
//								CheckSignals()
//
//	Function to tell whether or not there is a trade to place.  
//
//	RETURN VALUE:
//
//		1:	If the rules are met to place a long trade
//
//		2:	If the rules are met to place a short trade
//
//		0:	If the rules are not met
//
//=============================================================================
int CheckSignals()
{
   double myRSI, myRSIp;
	
   myRSI = iRSI(Symbol(),0,RSI_Period,PRICE_CLOSE,SignalCandle);

   if (myRSI < RSI_LowerLevel) return(LONG);
   if (myRSI > RSI_UpperLevel) return(SHORT); // down

	return (FLAT); // has not changed

}

//=============================================================================
//
//								CheckExitSignals()
//
//
//=============================================================================
bool CheckExitSignals(int cmd)
{
   double myRSI, myRSIp;
	
   if (ExitAtSignal == false) return(false);
  
   myRSI = iRSI(Symbol(),0,RSI_Period,PRICE_CLOSE,SignalCandle);
   myRSIp = iRSI(Symbol(),0,RSI_Period,PRICE_CLOSE,SignalCandle+1);

   if (cmd == OP_BUY)
   {
// Check overbought and turning down
     if (myRSI > RSI_UpperLevel && myRSI < myRSIp) return(true);
   }
   if (cmd == OP_SELL)
   {
// Check oversold and turning up
     if ( myRSI < RSI_LowerLevel && myRSI > myRSIp) return(true);
   }

	return (false); // has not changed
   
}


//=============================================================================
// expert start function
//=============================================================================
int start()
{
	int total, PlaceTrade;
	
	total = CheckOpenTrades();
	if (total == 0) 
	{
	   if (AllowNewTrades == true)
	   {
        PlaceTrade = CheckSignals();
        if (PlaceTrade != FLAT) OpenTrade(PlaceTrade);
      }
   }
   else
   {
      RefreshRates();
      HandleOpenPositions();
   }
   return(0);
}

      
void OpenTrade( int signal)
{
   int res, err;
   double TPprice,STprice;
   int ticket;
   double MMB0 = iMA(NULL,0,MMSet,0,2,0,1);

   RefreshRates();
   lotMM = GetLots();
   
	if ((Close[0]>MMB0)&& signal == LONG)
	{
		res = OrderSend(Symbol(), OP_BUY, lotMM, Ask, Slippage, 0, 0, nameEA, MagicNumber, 0, Green);
		if (res > 0)
		{
			ticket = res;
			if (OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES))
			{
				Print("BUY order opened : ", OrderOpenPrice());
            TPprice = 0;
            if (TakeProfit > 0) TPprice=TakeLong(OrderOpenPrice(), TakeProfit);
            STprice = 0;
            if (StopLoss > 0)
            {
              STprice=StopLong(OrderOpenPrice(), StopLoss);
		        STprice = ValidStopLoss(OP_BUY,Bid, STprice);
		      }   
            
 // Normalize stoploss / takeprofit to the proper # of digits.
            if (Digits > 0) 
            {
              STprice = NormalizeDouble( STprice, Digits);
              TPprice = NormalizeDouble( TPprice, Digits); 
            }
		      ModifyOrder(ticket, OrderOpenPrice(), STprice, TPprice, LightGreen);
			}
		}
	}
		
	if ((Close[0]<MMB0)&& signal == SHORT)
	{
		res = OrderSend(Symbol(), OP_SELL, lotMM, Bid, Slippage, 0, 0, nameEA, MagicNumber, 0, Red);
		if (res > 0)
		{
		   ticket = res;
			if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES))
			{
				Print("SELL order opened : ", OrderOpenPrice());
            if (StopLoss != 0 || TakeProfit != 0)
	         {
               TPprice = 0;
               if (TakeProfit > 0) TPprice=TakeShort(OrderOpenPrice(),TakeProfit);
               STprice = 0;
               if (StopLoss > 0)
               {
                 STprice=StopShort(OrderOpenPrice() ,StopLoss);
		           STprice = ValidStopLoss(OP_SELL,Ask, STprice); 
		         }  
 // Normalize stoploss / takeprofit to the proper # of digits.
               if (Digits > 0) 
               {
                 STprice = NormalizeDouble( STprice, Digits);
                 TPprice = NormalizeDouble( TPprice, Digits); 
               }
		         ModifyOrder(ticket, OrderOpenPrice(), STprice, TPprice, LightGreen);
			   }
		   }
		}
	}
   if(res<0)
   {
     err = GetLastError();
     Print("OrderSend failed with error(" + err + ") " + ErrorDescription(err));
   }
}
 
	  
void HandleOpenPositions()
{
   int cnt, err, total;
	bool CloseTrade, result = false;
   
   total = OrdersTotal();
	for (cnt=0; cnt < total; cnt++)
	{
		OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES);
		
		if (OrderSymbol() != Symbol()) continue;
		if (OrderMagicNumber() != MagicNumber) continue;

		result = false;

		// Should it be closed because of a reverse signal?
		CloseTrade = CheckExitSignals(OrderType());
			// We have a long position open
		if (OrderType() == OP_BUY)
		{		  
		  if (CloseTrade == true)
		  {
			  result = OrderClose(OrderTicket(), OrderLots(), Bid, 3, Violet); 
			  if (!result)
			  {
               err = GetLastError();
               Print("OrderClose BUY failed with error(" + err + ") " + ErrorDescription(err));
					Alert("Exit of BUY FAILED.");
			  }
		  }
		}
		
		// We have a short position open
		if (OrderType() == OP_SELL)
		{				
		  if (CloseTrade == true)
		  {
			  result = OrderClose(OrderTicket(), OrderLots(), Ask, 3, Violet);
			  if (!result)
			  {
               err = GetLastError();
               Print("OrderClose SELL failed with error(" + err + ") " + ErrorDescription(err));
					Alert("Exit of SELL FAILED.");
			  }
			}
		}
		
		if (!result && UseTrailingStop)	// Handle mods to trailing stop
			HandleTrailingStop(OrderType(), OrderTicket(), OrderOpenPrice(), OrderStopLoss(), OrderTakeProfit());
	}

	return(0);
}


//=============================================================================
//
// 							HandleTrailingStop()
//
//	Type 1 moves the stoploss without delay.
//
//	Type 2 waits for price to move the amount of the trailStop
//	before moving stop loss then moves like type 1
//
//	PARAMETERS:
//
//		type:		OP_BUY or OP_SELL
//		ticket:		the ticket number
//		open_price:	the order's open price
//		cur_sl:		the order's current StopLoss value
//		cur_tp:		the order's current TakeProfit value
//
//	RETURN VALUE:
//		zero for now
//
//  Calling example 
//	HandleTrailingStop(OP_BUY,OrderTicket(),OrderOpenPrice(),OrderStopLoss(),OrderTakeProfit());
//
//=============================================================================
void HandleTrailingStop(int type, int ticket, double open_price, double cur_sl, double cur_tp)
{
	double pt, TS = 0;

	if (type == OP_BUY)
	{
		switch (TrailingStopType)
		{
			case 1: 
				pt = myPoint * StopLoss;
				if (Bid - cur_sl > pt) 
					ModifyOrder(ticket, open_price, Bid - pt, cur_tp, Aqua);
				break;
				
			case 2: 
				pt = myPoint * TrailingStop;
				if (Bid - open_price > pt && (cur_sl < Bid - pt || cur_sl == 0))
					ModifyOrder(ticket, open_price, Bid - pt, cur_tp, Aqua);
				break;

		}
	}


	if (type ==  OP_SELL)
	{
		switch (TrailingStopType)
		{
			case 1: 
				pt = myPoint * StopLoss;
				if (cur_sl - Ask > pt) 
					ModifyOrder(ticket, open_price, Ask+pt, cur_tp, Aqua);
				break;
				
			case 2: 
				pt = myPoint * TrailingStop;
				if (open_price - Ask > pt && (cur_sl > Ask + pt || cur_sl == 0))
					ModifyOrder(ticket, open_price, Ask+pt, cur_tp, Aqua);
				break;
				
		 }
	 }
}

int ModifyOrder(int ord_ticket,double op, double oSL, double oTP, color mColor)
{
    int CloseCnt, err;
    double myStop, myTake;
    
    CloseCnt=0;
    while (CloseCnt < 3)
    {
       if (OrderModify(ord_ticket,op,oSL,oTP,0,mColor))
       {
         CloseCnt = 3;
       }
       else
       {
          err=GetLastError();
          Print(CloseCnt," Error modifying order : (", err , ") " + ErrorDescription(err));
         if (err>0) CloseCnt++;
       }
    }
}

//=============================================================================
//
//								CheckOpenTrades()
//
//	RETURN VALUE:
//
//		The number of trades this EA has currently open
//
//=============================================================================
int CheckOpenTrades()
{
	int cnt;
	int NumTrades;	// Number of buy and sell trades in this symbol
	
	NumTrades = 0;
	for (cnt=OrdersTotal()-1; cnt>=0; cnt--)
	{
		OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES);
		if (OrderSymbol() != Symbol()) 
			continue;
			
		if (OrderMagicNumber() != MagicNumber)
			continue;
		
		if (OrderType() == OP_BUY)  
			NumTrades++;
			
		if (OrderType() == OP_SELL) 
			NumTrades++;
				 
	}
	return (NumTrades);
}

//+------------------------------------------------------------------+
//| Get number of lots for this trade                                |
//+------------------------------------------------------------------+
double GetLots()
{
   double lot;
   double myMaxLot = MarketInfo(Symbol(), MODE_MAXLOT);
   
   if(UseMoneyManagement == false) return(Lots);

   if (BrokerIsIBFX == true)
   {
     lot = Calc_IBFX_Money_Management();
     return(lot);
   }

   lot=NormalizeDouble((AccountEquity()*TradeSizePercent/10000)/10,2);

   
// Use at least 1 micro lot
   if (AccountIsMicro == true)
   {
      lot = MathFloor(lot*100)/100;
      if (lot < 0.01) lot = 0.01;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }

// Use at least 1 mini lot
   if(AccountIsMini == true)
   {
      lot = MathFloor(lot*10)/10;
      if (lot < 0.1) lot = 0.1;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }

   if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0;
   if (lot > MaxLots) lot = MaxLots;
   
   return(lot);
}

double Calc_IBFX_Money_Management()
{
// variables used for money management
   double lot;
   double myMaxLot = MarketInfo(Symbol(), MODE_MAXLOT);

   lot=NormalizeDouble((AccountEquity()*TradeSizePercent/10000)/10,2);
   
// Use at least 1 micro lot
   if (AccountIsMicro == true)
   {
      lot = lot * 10;
      lot = MathFloor(lot*100)/100;
      if (lot < 0.1) lot = 0.1;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }

// Use at least 1 mini lot
   if(AccountIsMini == true)
   {
      lot = lot * 10;
      lot = MathFloor(lot*10)/10;
      if (lot < 1) lot = 1;
      if (lot > myMaxLot) lot = myMaxLot;
      return(lot);
   }
   
   // Standard Account
   
   lot = MathFloor(lot);
   if (lot < 1) lot = 1;
   if (lot > myMaxLot) lot = myMaxLot;

   return(lot); 
}

double SetPoint()
{
   double mPoint;
   
   if (Digits < 4)
      mPoint = 0.01;
   else
      mPoint = 0.0001;
   
   return(mPoint);
}

double StopLong(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price-(stop*myPoint));
}

double StopShort(double price,int stop)
{
 if(stop==0)
  return(0);
 else
  return(price+(stop*myPoint));
}

double TakeLong(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price+(take*myPoint));
}

double TakeShort(double price,int take)
{
 if(take==0)
  return(0);
 else
  return(price-(take*myPoint));
}

double ValidStopLoss(int type, double price, double SL)
{

   double minstop;
   
   if (SL < 0.1) return(SL);
   
   minstop = MarketInfo(Symbol(),MODE_STOPLEVEL);
   if (type == OP_BUY)
   {
		 if((price - SL) < minstop*myPoint) SL = price - minstop*myPoint;
   }
   if (type == OP_SELL)
   {
       if((SL-price) < minstop*myPoint)  SL = price + minstop*myPoint;  
   }

   return(SL);   
}

//+------------------------------------------------------------------+
//| Time frame interval appropriation  function                      |
//+------------------------------------------------------------------+

int func_TimeFrame_Const2Val(int Constant ) {
   switch(Constant) {
      case 1:  // M1
         return(1);
      case 5:  // M5
         return(2);
      case 15:
         return(3);
      case 30:
         return(4);
      case 60:
         return(5);
      case 240:
         return(6);
      case 1440:
         return(7);
      case 10080:
         return(8);
      case 43200:
         return(9);
   }
}

//+------------------------------------------------------------------+
//| Time frame string appropriation  function                               |
//+------------------------------------------------------------------+

string func_TimeFrame_Val2String(int Value ) {
   switch(Value) {
      case 1:  // M1
         return("M1");
      case 2:  // M1
         return("M5");
      case 3:
         return("M15");
      case 4:
         return("M30");
      case 5:
         return("H1");
      case 6:
         return("H4");
      case 7:
         return("D1");
      case 8:
         return("W1");
      case 9:
         return("MN1");
   	default: 
   		return("undefined " + Value);
   }
}

int func_Symbol2Val(string symbol) {
   string mySymbol = StringSubstr(symbol,0,6);
	if(mySymbol=="AUDCAD") return(1);
	if(mySymbol=="AUDJPY") return(2);
	if(mySymbol=="AUDNZD") return(3);
	if(mySymbol=="AUDUSD") return(4);
	if(mySymbol=="CHFJPY") return(5);
	if(mySymbol=="EURAUD") return(6);
	if(mySymbol=="EURCAD") return(7);
	if(mySymbol=="EURCHF") return(8);
	if(mySymbol=="EURGBP") return(9);
	if(mySymbol=="EURJPY") return(10);
	if(mySymbol=="EURUSD") return(11);
	if(mySymbol=="GBPCHF") return(12);
	if(mySymbol=="GBPJPY") return(13);
	if(mySymbol=="GBPUSD") return(14);
	if(mySymbol=="NZDUSD") return(15);
	if(mySymbol=="USDCAD") return(16);
	if(mySymbol=="USDCHF") return(17);
	if(mySymbol=="USDJPY") return(18);
	return(19);
}







Sample





Analysis



Market Information Used:

Series array that contains close prices for each bar


Indicator Curves created:


Indicators Used:

Relative strength index
Moving average indicator


Custom Indicators Used:

Order Management characteristics:
It automatically opens orders when conditions are reached

Checks for the total of open orders
It Closes Orders by itself
It can change open orders parameters, due to possible stepping strategy

Other Features:

It issuies visual alerts to the screen

BackTest : EURUSD on H1

From 2010-04-01 to 2010-04-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-05-01 to 2010-05-31 Profit Factor:0.00 Total Net Profit:0.00

BackTest : EURUSD on H1

From 2010-06-01 to 2010-06-30 Profit Factor:0.00 Total Net Profit:0.00

BackTest : GBPUSD on H1

From 2010-01-01 to 2010-02-27 Profit Factor:0.00 Total Net Profit:0.00

Request Backtest for RSI_EA-v1


From : (yyyy/mm/dd) To: (yyyy/mm/dd)

Pair: Period: