//============================================================================= // RSI_EA.mq4 // Originally by: Robert Hill // //============================================================================= #property copyright "Robert Hill" #include #include #define LONG 1 #define SHORT -1 #define FLAT 0 extern int MagicCode = 5; //+---------------------------------------------------+ //|Indicator inputs | //+---------------------------------------------------+ extern int RSI_Period = 14; extern int RSI_UpperLevel = 53; extern int RSI_LowerLevel = 47; extern int UseRisingFallingRSI = 0; //---- Trade Management extern double TakeProfit = 0; extern double StopLoss = 0; extern int StopLossGap = 1; extern int MinStopLoss = 100; extern double Lots = 1; extern int Slippage = 3; extern int SignalCandle = 1; double lotMM; string ExpertName="RSI_DailyEA_"; 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 // //============================================================================= double GetSignal() { double myRSI, myRSIp; double cci, ccip; myRSI = iRSI(Symbol(),0,RSI_Period,PRICE_CLOSE,SignalCandle); myRSIp = iRSI(Symbol(),0,RSI_Period,PRICE_CLOSE,SignalCandle + 1); if (myRSI > RSI_UpperLevel) { if (UseRisingFallingRSI == 1) { if (myRSI > myRSIp) return(LONG); } return (LONG); } if (myRSI < RSI_LowerLevel) { if (UseRisingFallingRSI == 1) { if (myRSI < myRSIp) return(SHORT); } return(SHORT); } return (FLAT); } //============================================================================= // // CheckExitSignals() // // //============================================================================= bool CheckExitSignals(int cmd) { double myRSI, myRSIp; myRSI = iRSI(Symbol(),0,RSI_Period,PRICE_CLOSE,SignalCandle); if (cmd == OP_BUY) { if (myRSI < RSI_UpperLevel) return(true); } if (cmd == OP_SELL) { if (myRSI > RSI_LowerLevel) return(true); } return (false); // has not changed } //-- Check for Start of a new Bar bool NewBar() { static datetime dt = 0; if (Time[0] != dt) { dt = Time[0]; return(true); } return(false); } //============================================================================= // expert start function //============================================================================= int start() { int total, PlaceTrade; total = CheckOpenTrades(); if (total == 0) { if (!NewBar()) return(0); // wait until first tick after bar close to take any action; PlaceTrade = GetSignal(); if (PlaceTrade != FLAT) OpenTrade(PlaceTrade); } else { RefreshRates(); HandleOpenPositions(); } return(0); } void OpenTrade( int signal) { int res, err; double TPprice,STprice; int ticket; RefreshRates(); if (signal == LONG) { res = OrderSend(Symbol(), OP_BUY, Lots, Ask, Slippage*myPoint, 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,OrderOpenPrice(), STprice); } else { STprice = iLow(Symbol(),0,1) - StopLossGap * myPoint; if (STprice > OrderOpenPrice()) { STprice=StopLong(OrderOpenPrice(), MinStopLoss); } STprice = ValidStopLoss(OP_BUY,OrderOpenPrice(), 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 (signal == SHORT) { res = OrderSend(Symbol(), OP_SELL, Lots, Bid, Slippage*myPoint, 0, 0, nameEA, MagicNumber, 0, Red); if (res > 0) { ticket = res; if (OrderSelect(ticket, SELECT_BY_TICKET, MODE_TRADES)) { Print("SELL order opened : ", OrderOpenPrice()); TPprice = 0; if (TakeProfit > 0) TPprice=TakeShort(OrderOpenPrice(),TakeProfit); STprice = 0; if (StopLoss > 0) { STprice=StopShort(OrderOpenPrice() ,StopLoss); STprice = ValidStopLoss(OP_SELL,OrderOpenPrice(), STprice); } else { STprice=iHigh(Symbol(), 0, 1) + StopLossGap * myPoint; if (STprice < OrderOpenPrice()) { STprice=StopShort(OrderOpenPrice(), MinStopLoss); } STprice = ValidStopLoss(OP_SELL,OrderOpenPrice(), 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, Slippage * myPoint, Violet); if (!result) { err = GetLastError(); Print("OrderClose BUY failed with error(" + err + ") " + ErrorDescription(err)); } } } // We have a short position open if (OrderType() == OP_SELL) { if (CloseTrade == true) { result = OrderClose(OrderTicket(), OrderLots(), Ask, Slippage * myPoint, Violet); if (!result) { err = GetLastError(); Print("OrderClose SELL failed with error(" + err + ") " + ErrorDescription(err)); } } } } return(0); } 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); } 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); }