//+------------------------------------------------------------------+ //| | //| RSI-R2.mq4 - Ver 1.0 @ 03/22/2007 by Bluto | //| | //| Changes by Robert Hill | //| 4/3/2007 added input for RSI_Period | //| Modified code for MagicNumber calculation | //| Added function to set value for RSI_Period | //| Set value of AssignRSI to false during optimization | //| Use optimized value in function AssignRSI_Period | //| Set value of AssignRSI to true when running live | //| 4/5/2007 Fixed bug that caused no more trades after a stoploss | //| added 2 variable to hold pSar values to reduce calls | //| Added GetLots as a function using MM code from start | //+------------------------------------------------------------------+ #property copyright "Bluto" #property link "None" // This makes code easier to read #define AUDCAD 1 #define AUDJPY 2 #define AUDNZD 3 #define AUDUSD 4 #define CHFJPY 5 #define EURAUD 6 #define EURCAD 7 #define EURCHF 8 #define EURGBP 9 #define EURJPY 10 #define EURUSD 11 #define GBPCHF 12 #define GBPJPY 13 #define GBPUSD 14 #define NZDJPY 15 #define NZDUSD 16 #define USDCAD 17 #define USDCHF 18 #define USDJPY 19 #define UNEXPECTED 999 extern double LotSize=10; extern int Slippage=3; extern double StopLoss=0; extern double TakeProfit=700; extern double RiskPercent=2.0; extern bool UseMoneyMgmt=false; extern int RSI_Period = 2; // input value to be optimized extern bool AssignRSI = false; // Set to true for live trading extern double RSI_Overbought_Value = 75.0; extern double RSI_Oversold_Value = 25.0; int MagicNumber=0; int ticket; int OpenBuyOrders=0; int OpenSellOrders=0; int BuyCount=0,SellCount=0; int i; bool Buy_Mode=false, Sell_Mode=false; int myRSI_Period = 2; // Used by RSI indicator call double RSI_Day_1=0, RSI_Day_2=0, RSI_Day_3=0, SMA200_Day3=0; double pSar1 = 0; double pSar2 = 0; double MM_MinLotSize=0; double MM_MaxLotSize=0; double MM_LotStep=0; double MM_Decimals=0; double MM_OrderLotSize=0; int MM_AcctLeverage=0; int MM_CurrencyLotSize=0; int init() { /* if (Symbol()=="AUDCADm" || Symbol()=="AUDCAD") {MagicNumber=200001;} if (Symbol()=="AUDJPYm" || Symbol()=="AUDJPY") {MagicNumber=200002;} if (Symbol()=="AUDNZDm" || Symbol()=="AUDNZD") {MagicNumber=200003;} if (Symbol()=="AUDUSDm" || Symbol()=="AUDUSD") {MagicNumber=200004;} if (Symbol()=="CHFJPYm" || Symbol()=="CHFJPY") {MagicNumber=200005;} if (Symbol()=="EURAUDm" || Symbol()=="EURAUD") {MagicNumber=200006;} if (Symbol()=="EURCADm" || Symbol()=="EURCAD") {MagicNumber=200007;} if (Symbol()=="EURCHFm" || Symbol()=="EURCHF") {MagicNumber=200008;} if (Symbol()=="EURGBPm" || Symbol()=="EURGBP") {MagicNumber=200009;} if (Symbol()=="EURJPYm" || Symbol()=="EURJPY") {MagicNumber=200010;} if (Symbol()=="EURUSDm" || Symbol()=="EURUSD") {MagicNumber=200011;} if (Symbol()=="GBPCHFm" || Symbol()=="GBPCHF") {MagicNumber=200012;} if (Symbol()=="GBPJPYm" || Symbol()=="GBPJPY") {MagicNumber=200013;} if (Symbol()=="GBPUSDm" || Symbol()=="GBPUSD") {MagicNumber=200014;} if (Symbol()=="NZDJPYm" || Symbol()=="NZDJPY") {MagicNumber=200015;} if (Symbol()=="NZDUSDm" || Symbol()=="NZDUSD") {MagicNumber=200016;} if (Symbol()=="USDCHFm" || Symbol()=="USDCHF") {MagicNumber=200017;} if (Symbol()=="USDJPYm" || Symbol()=="USDJPY") {MagicNumber=200018;} if (Symbol()=="USDCADm" || Symbol()=="USDCAD") {MagicNumber=200019;} if (MagicNumber==0) {MagicNumber = 200999;} */ MagicNumber = func_Symbol2Val(Symbol()) + 200000; if (AssignRSI) myRSI_Period = AssignRSI_Period(Symbol()); else myRSI_Period = RSI_Period; return(0); } 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=="NZDJPY") return(15); if(mySymbol=="NZDUSD") return(16); if(mySymbol=="USDCAD") return(17); if(mySymbol=="USDCHF") return(18); if(mySymbol=="USDJPY") return(19); Comment("unexpected Symbol"); return(999); } int AssignRSI_Period(string symbol) { int RSI = 0; int which = func_Symbol2Val(symbol); switch (which) { case AUDCAD : RSI = 2; break; case AUDJPY : RSI = 2; break; case AUDNZD : RSI = 2; break; case AUDUSD : RSI = 2; break; case CHFJPY : RSI = 2; break; case EURAUD : RSI = 2; break; case EURCAD : RSI = 2; break; case EURCHF : RSI = 2; break; case EURGBP : RSI = 2; break; case EURJPY : RSI = 4; // Optimized value break; case EURUSD : RSI = 2; break; case GBPCHF : RSI = 2; break; case GBPJPY : RSI = 2; break; case GBPUSD : RSI = 2; break; case NZDJPY : RSI = 2; break; case NZDUSD : RSI = 2; break; case USDCAD : RSI = 2; break; case USDCHF : RSI = 2; break; case USDJPY : RSI = 2; break; case UNEXPECTED : RSI = 2; } if (RSI == 0) RSI = 2; return (RSI); } int deinit() { return(0); } int start() { MM_OrderLotSize = GetLots(); SMA200_Day3 = iMA(NULL,PERIOD_D1,200, 0, MODE_SMA, PRICE_CLOSE, 1); RSI_Day_1 = iRSI(NULL, PERIOD_D1, myRSI_Period, PRICE_CLOSE, 3); RSI_Day_2 = iRSI(NULL, PERIOD_D1, myRSI_Period, PRICE_CLOSE, 2); RSI_Day_3 = iRSI(NULL, PERIOD_D1, myRSI_Period, PRICE_CLOSE, 1); if (RSI_Day_1 < 65 && RSI_Day_2 < RSI_Day_1 && RSI_Day_3 < RSI_Day_2 && Close[1] > SMA200_Day3) { Buy_Mode=true; } else { Buy_Mode=false; } if (RSI_Day_1 > 35 && RSI_Day_2 > RSI_Day_1 && RSI_Day_3 > RSI_Day_2 && Close[1] < SMA200_Day3) { Sell_Mode=true; } else { Sell_Mode=false; } // Check to make sure no trade was stopped out OpenBuyOrders = CheckOpenPositions(OP_BUY); OpenSellOrders = CheckOpenPositions(OP_SELL); if (OpenBuyOrders == 1 && iRSI(NULL, PERIOD_D1, myRSI_Period, PRICE_CLOSE, 1) > RSI_Overbought_Value) { CloseLongs(MagicNumber); OpenBuyOrders = 0; BuyCount=0; } if (OpenSellOrders == 1 && iRSI(NULL, PERIOD_D1, myRSI_Period, PRICE_CLOSE, 1) < RSI_Oversold_Value) { CloseShorts(MagicNumber); OpenSellOrders = 0; SellCount=0; } //----- Count number of existing open buy & sell orders; update trailing stops. OpenBuyOrders=0; OpenSellOrders=0; // Bug fix for trades that are stopped out BuyCount = 0; SellCount = 0; // Manage Paraolic SAR // Added pSar1 and pSar2 for faster backtesting pSar1 = iSAR(NULL,0,0.02,0.2,1); pSar2 = iSAR(NULL,0,0.02,0.2,2); for (i = 0; i <= OrdersTotal(); i++) { OrderSelect(i,SELECT_BY_POS,MODE_TRADES); if ((OrderSymbol() == Symbol()) && (OrderMagicNumber() == MagicNumber)) { if (OrderType() == OP_BUY) { // Bug fix for trades that are stopped out OpenBuyOrders++;BuyCount++; if ( (pSar1> OrderStopLoss()) && (Bid > pSar1) && (OrderOpenPrice() < pSar1) && (pSar1 > pSar2)) { OrderModify(OrderTicket(),OrderOpenPrice(),pSar1,OrderTakeProfit(),0,Blue); Print("Order # ",OrderTicket()," updated at ",Hour(),":",Minute(),":",Seconds()); return(0); } } if (OrderType() == OP_SELL) { // Bug fix for trades that are stopped out OpenSellOrders++;SellCount++; if ((pSar1 < OrderStopLoss()) && (Ask < pSar1) && (OrderOpenPrice() > pSar1) && (pSar1 < pSar2)) { OrderModify(OrderTicket(),OrderOpenPrice(),pSar1,OrderTakeProfit(),0,Blue); Print("Order # ",OrderTicket()," updated at ",Hour(),":",Minute(),":",Seconds()); return(0); } } } } //----- Generic order handler. //----- If we have a new buy signal, close existing sell orders; if we have a new sell signal, close existing buy orders; reset order counters. //----- Next, create new buy or sell order. if (Buy_Mode==true && BuyCount==0) { if(OpenSellOrders > 0) { CloseShorts(MagicNumber); OpenSellOrders = 0; } SellCount=0; if(OpenBuyOrders == 0) { ticket = OpenPendingOrder(OP_BUY,MM_OrderLotSize,Ask,Slippage,Bid,StopLoss,TakeProfit,"RSI-R2",MagicNumber,0,Lime); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } else { OpenBuyOrders++; BuyCount++; } } } if (Sell_Mode==true && SellCount==0) { if(OpenBuyOrders > 0) { CloseLongs(MagicNumber); OpenBuyOrders = 0; } BuyCount=0; if (OpenSellOrders == 0) { ticket = OpenPendingOrder(OP_SELL,MM_OrderLotSize,Bid,Slippage,Ask,StopLoss,TakeProfit,"RSI-R2",MagicNumber,0,HotPink); if(ticket<0) { Print("OrderSend failed with error #",GetLastError()); return(0); } else { OpenSellOrders++; SellCount++; } } } return(0); } double GetLots() { double OrderLotSize; //----- Money Management & Lot Sizing Stuff. MM_AcctLeverage = AccountLeverage(); MM_MinLotSize = MarketInfo(Symbol(),MODE_MINLOT); MM_MaxLotSize = MarketInfo(Symbol(),MODE_MAXLOT); MM_LotStep = MarketInfo(Symbol(),MODE_LOTSTEP); MM_CurrencyLotSize = MarketInfo(Symbol(),MODE_LOTSIZE); if(MM_LotStep == 0.01) {MM_Decimals = 2;} if(MM_LotStep == 0.1) {MM_Decimals = 1;} if (UseMoneyMgmt == true) { OrderLotSize = AccountEquity() * (RiskPercent * 0.01) / (MM_CurrencyLotSize / MM_AcctLeverage); OrderLotSize = StrToDouble(DoubleToStr(OrderLotSize,MM_Decimals)); } else { OrderLotSize = LotSize; } if (OrderLotSize < MM_MinLotSize) {OrderLotSize = MM_MinLotSize;} if (OrderLotSize > MM_MaxLotSize) {OrderLotSize = MM_MaxLotSize;} return(OrderLotSize); } //+------------------------------------------------------------------+ //| Check Open Position Controls | //+------------------------------------------------------------------+ int CheckOpenPositions(int cmd) { int cnt, total; int NumTrades; NumTrades = 0; total=OrdersTotal(); for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { OrderSelect (cnt, SELECT_BY_POS, MODE_TRADES); if ( OrderSymbol() != Symbol()) continue; if ( OrderMagicNumber() != MagicNumber) continue; if(OrderType() == cmd ) NumTrades++; } return (NumTrades); } //----- Order Processing Functions void CloseLongs(int MagicNumber) { int trade; for(trade=OrdersTotal()-1;trade>=0;trade--) { if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber) continue; if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber) if(OrderType()==OP_BUY) OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,Blue); }//for } void CloseShorts(int MagicNumber) { int trade; for(trade=OrdersTotal()-1;trade>=0;trade--) { if(OrderSelect(trade,SELECT_BY_POS,MODE_TRADES)==false) continue; if(OrderSymbol()!=Symbol()||OrderMagicNumber()!=MagicNumber) continue; if(OrderSymbol()==Symbol()&&OrderMagicNumber()==MagicNumber) if(OrderType()==OP_SELL) OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red); }//for } int OpenPendingOrder(int pType,double pLots,double pLevel,int sp, double pr, int sl, int tp,string pComment,int pMagic,datetime pExpiration,color pColor) { int ticket=0; int err=0; int c = 0; int NumberOfTries = 10; switch (pType) { case OP_BUY: for(c = 0 ; c < NumberOfTries ; c++) { RefreshRates(); ticket=OrderSend(Symbol(),OP_BUY,pLots,Ask,sp,StopLong(Bid,sl),TakeLong(Bid,tp),pComment,pMagic,pExpiration,pColor); if (ticket > 0) break; err=GetLastError(); if(err==0) { break; } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); continue; } else //normal error { Print("Error Code= ", err); break; } } } break; case OP_SELL: for(c = 0 ; c < NumberOfTries ; c++) { RefreshRates(); ticket=OrderSend(Symbol(),OP_SELL,pLots,Bid,sp,StopShort(Ask,sl),TakeShort(Ask,tp),pComment,pMagic,pExpiration,pColor); if (ticket > 0) break; err=GetLastError(); if(err==0) { break; } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); continue; } else //normal error { Print("Error Code= ", err); break; } } } break; } return(ticket); } double StopLong(double price,int stop) { if(stop==0) return(0); else return(price-(stop*Point)); } double StopShort(double price,int stop) { if(stop==0) return(0); else return(price+(stop*Point)); } double TakeLong(double price,int take) { if(take==0) return(0); else return(price+(take*Point)); } double TakeShort(double price,int take) { if(take==0) return(0); else return(price-(take*Point)); }