//+-----------------------------+ //|Shashi RSI-R2 from Shell_20b | //+-----------------------------+ #property copyright "Ron Thompson" #property link "http://www.ForexMT4.com/" // This EA is NEVER to be SOLD individually // This EA is NEVER to be INCLUDED as part of a collection that is SOLD // user input extern bool WithTrend = false ; extern string Pairs = "AUDJPY,AUDNZD,AUDUSD,CHFJPY,EURAUD,EURCAD,EURCHF,EURGBP,EURJPY,EURUSD,GBPCHF,GBPJPY,GBPUSD,NZDJPY,NZDUSD,USDCAD,USDCHF,USDJPY" ; extern double Lots = 0.2 ; extern double ProfitMade = 130 ; extern double LossLimit = 100 ; extern double BreakEven = 0 ; extern double TrailStop = 0 ; extern bool KillLogging = true ; // MULTI Pair handling // hard coded to use current symbol() for testing string Pairz[100]; static bool TradeAllowed[100]; static datetime bartime[100]; int ptrPMAX; int ptrPairz=0; string mySymbol; double bid; double ask; // Trade control double myPoint; // support for 3/5 decimal places int Slippage=2; // how many pips of slippage can you tolorate int loopcount; // count of order attempts int maxloop=20; // maximum number of attempts to handle errors int LL2SL=50; // LossLimit to StopLoss server spread int MagicNumber = 142538004; // allows multiple experts to trade on same account string TradeComment = "_ShashiM1d.txt"; // where to log information // Statistics int maxOrders; // statistic for maximum numbers or orders open at one time // used for verbose error logging #include <stdlib.mqh> //+-------------+ //| Custom init | //|-------------+ // Called ONCE when EA is added to chart or recompiled int init() { int OPS=0; int i; int cnt; // trades turned on only if there is NO open order // MULTIPLE order systems may need to change this for (i=0; i<100; i++) { mySymbol=Pairz[i]; OPS=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) OPS++; } if(OPS==0) TradeAllowed[i]=true; else TradeAllowed[i]=false; }//for // Split the user string into an array int ipair=0; int pcomma=0; int comma=0; //clear the array for (i=0; i<100; i++) { Pairz[i]=""; } while (true) { // if backtesting then set array to current symbol only if(IsTesting()) { Pairz[0]=Symbol(); ptrPMAX=1; break; } // if nothing in the extern that we can use // then set array to current symbol only if(StringLen(Pairs)<6) { Pairz[0]=Symbol(); ptrPMAX=1; break; } //save the old comma pcomma=comma; // find the next comma comma=StringFind(Pairs, ",", pcomma+1); // Gather trailing pair (no comma following last pair) // then leave (accounts for one pair on line) if(comma<0) { Pairz[ipair]=StringSubstr(Pairs, pcomma+1, comma-pcomma); ptrPMAX=ipair; Print(ipair+" "+Pairz[ipair]); break; } // store the pair into an array if(ipair==0) Pairz[ipair]=StringSubstr(Pairs, pcomma, comma-pcomma); if(ipair >0) Pairz[ipair]=StringSubstr(Pairs, pcomma+1, comma-pcomma-1); Print(ipair+" "+Pairz[ipair]); // increment pointer for next elemant ipair++; if(ipair>100) break; } Comment(" "); logwrite(TradeComment,"Init Complete"); } //+----------------+ //| Custom DE-init | //+----------------+ // Called ONCE when EA is removed from chart int deinit() { // always indicate deinit statistics logwrite(TradeComment,"MAX number of orders "+maxOrders); Comment(" "); logwrite(TradeComment,"DE-Init Complete"); } //+-----------+ //| Main | //+-----------+ // Called EACH TICK and each Bar[] int start() { // The following MUST be done before anything else // step through each pair, once a tick ptrPairz++; if(ptrPairz>=ptrPMAX) ptrPairz=0; mySymbol=Pairz[ptrPairz]; Comment("Now trading -"+mySymbol+"- at position "+ptrPairz ); // get normalized Point based on Broker decimal places // every tick, since we may be using multi-pairs myPoint = SetPoint(); // end 'MUST' int cnt=0; int gle=0; int ticket=0; int OrdersPerSymbol=0; // stoploss and takeprofit and close control double SL=0; double TP=0; double CurrentProfit=0; double CurrentBasket=0; // direction control bool BUYme=false; bool SELLme=false; double MaCurrent; double MaPrevious; //safety counter int loopcount=0; OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) OrdersPerSymbol++; } // keep some statistics if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol; //uncomment for MULTIPLE trades per bar //if(OrdersPerSymbol==0) TradeAllowed[ptrPairz]=true; // bar counting if(bartime[ptrPairz]!=iTime(mySymbol, PERIOD_D1, 0) ) { bartime[ptrPairz]=iTime(mySymbol, PERIOD_D1, 0) ; //uncomment for SINGLE trade per bar if(OrdersPerSymbol==0) TradeAllowed[ptrPairz]=true; //+-----------------------------+ //| Code here will execute once | //| at the OPEN of a NEW BAR | //| | //| NOTE: use 'tf1' for any | //| indicator or iCustom | //| timeframe parameter | //+-----------------------------+ double RSI1=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,1); double RSI2=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,2); double RSI3=iRSI(mySymbol,PERIOD_D1,2,MODE_CLOSE,3); if(WithTrend==false && RSI3<50 && RSI2<RSI3 && RSI1<RSI2) BUYme=true; if(WithTrend==false && RSI3>50 && RSI2>RSI3 && RSI1>RSI2) SELLme=true; if(WithTrend==true && RSI1<50 && RSI2<RSI3 && RSI1<RSI2) SELLme=true; if(WithTrend==true && RSI1>50 && RSI2>RSI3 && RSI1>RSI2) BUYme=true; //+------------+ //| End Insert | //+------------+ } //+-----------------------------+ //| Insert your indicator here | //| And set either BUYme or | //| SELLme true to place orders | //| | //| NOTE: use 'tf1' for any | //| indicator or iCustom | //| timeframe parameter | //+-----------------------------+ //+------------+ //| End Insert | //+------------+ //ENTRY LONG (buy, Ask) if( TradeAllowed[ptrPairz] && BUYme) { OpenBuy(); } //ENTRY SHORT (sell, Bid) if( TradeAllowed[ptrPairz] && SELLme) { OpenSell(); } // // Order Management // //Basket profit // Basket profit or loss - count the profit/loss // from this EA & Symbol()& magicnumber only // calculation can be done in PIPS or DOLLARS CurrentBasket=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber) { // add up pips //if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( Close[0]-OrderOpenPrice() ); //if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( (Close[0]-OrderOpenPrice()) * (-1) ); //add up dollars if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( OrderProfit() ); if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( OrderProfit() ); } } for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==mySymbol && OrderMagicNumber()==MagicNumber ) { if(OrderType()==OP_BUY) { bid=MarketInfo(mySymbol,MODE_BID); CurrentProfit=(bid-OrderOpenPrice()) ; // // Modify for break even //======================= // // OrderStopLoss will be equal to OrderOpenPrice if this event happens // thus it will only ever get executed one time per ticket if( BreakEven>0 ) { if (CurrentProfit >= BreakEven*myPoint && OrderOpenPrice()>OrderStopLoss()) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); SL=OrderOpenPrice()+(ask-bid); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY BUY BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY BUY BE Bid="+Bid+" error="+gle+" "+ErrorDescription(gle)); } } } // // check for trailing stop //========================= // // This starts trailing after 'TrailStop' pips of profit if( TrailStop>0 && iClose(mySymbol,PERIOD_D1,0)>OrderOpenPrice()+(TrailStop*myPoint) ) { bid=MarketInfo(mySymbol,MODE_BID); if( OrderStopLoss() < bid-(TrailStop*myPoint) ) { SL=bid-(TrailStop*myPoint); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY BUY TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY BUY TS Bid="+bid+" error="+gle+" "+ErrorDescription(gle)+" "); } } } // Did we make a profit //====================== if(ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint)) { CloseBuy("PROFIT"); } // Did we take a loss //==================== if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint)) { CloseBuy("LOSS"); } } // if BUY if(OrderType()==OP_SELL) { ask=MarketInfo(mySymbol,MODE_ASK); CurrentProfit=(OrderOpenPrice()-ask); //logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/myPoint+" CurrentBasket="+CurrentBasket/myPoint); // // Modify for break even //======================= // // OrderStopLoss will be equal to OrderOpenPrice if this event happens // thus it will only ever get executed one time per ticket if( BreakEven>0 ) { if (CurrentProfit >= BreakEven*myPoint && OrderOpenPrice()<OrderStopLoss()) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); SL=OrderOpenPrice()-(ask-bid); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP, Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY SELL BE Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY SELL BE Ask="+ask+" error="+gle+" "+ErrorDescription(gle)); } } } // // check for trailing stop //========================= // // This starts trailing after 'TrailStop' pips of profit if( TrailStop>0 && iClose(mySymbol,PERIOD_D1,0)<OrderOpenPrice()-(TrailStop*myPoint) ) { ask=MarketInfo(mySymbol,MODE_ASK); if( OrderStopLoss() > ask+(TrailStop*myPoint) ) { SL=ask+(TrailStop*myPoint); TP=OrderTakeProfit(); OrderModify(OrderTicket(),OrderOpenPrice(),SL,TP,0,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"MODIFY SELL TS Ticket="+OrderTicket()+" SL="+SL+" TP="+TP); } else { logwrite(TradeComment,"-----ERROR----- MODIFY SELL TS Ask="+ask+" error="+gle+" "+ErrorDescription(gle)); } } } // Did we make a profit //====================== if( ProfitMade>0 && CurrentProfit>=(ProfitMade*myPoint) ) { CloseSell("PROFIT"); } // Did we take a loss //==================== if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*myPoint) ) { CloseSell("LOSS"); } } //if SELL } // if(OrderSymbol) } // for } // start() // log data to a file name passed in // print everything regardless of log setting void logwrite (string filename, string mydata) { int myhandle; string gregorian=TimeToStr(CurTime(),TIME_DATE|TIME_SECONDS); Print(" "+mySymbol+" "+mydata+" "+gregorian); // don't log anything if testing or if user doesn't want it if(IsTesting()) return(0); if(KillLogging) return(0); myhandle=FileOpen(mySymbol+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";"); if(myhandle>0) { FileSeek(myhandle,0,SEEK_END); FileWrite(myhandle, " "+mySymbol+" "+mydata+" "+gregorian); FileClose(myhandle); } } //ENTRY LONG (buy, Ask) void OpenBuy() { int gle=0; int ticket=0; double SL=0; double TP=0; int loopcount; // PLACE order is independent of MODIFY order. // This is mandatory for ECNs and acceptable for retail brokers loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); // place order - NO TP OR SL ticket=OrderSend(mySymbol,OP_BUY,Lots,ask,Slippage,0,0,TradeComment,MagicNumber,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"BUY PLACED Ticket="+ticket+" Ask="+ask+" Lots="+Lots); TradeAllowed[ptrPairz]=false; break; } else { logwrite(TradeComment,"-----ERROR----- Placing BUY order: Lots="+Lots+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); // give up after loopcount tries loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on placing BUY order"); return(gle); } } }//while - place order // modify the order for users TP & SL loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); // don't set TP and SL both to zero, they're already there if(LossLimit==0 && ProfitMade==0) break; if(LossLimit ==0) SL=0; if(ProfitMade ==0) TP=0; if(LossLimit >0) SL=ask-((LossLimit+LL2SL)*myPoint ); if(ProfitMade >0) TP=ask+((ProfitMade+LL2SL)*myPoint ); OrderModify(ticket,OrderOpenPrice(),SL,TP,0,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"BUY OPENMOD Ticket="+ticket+" Ask="+ask+" Lots="+Lots+" SL="+SL+" TP="+TP); break; } else { logwrite(TradeComment,"-----ERROR----- Modifying BUY order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on modifying BUY order"); return(gle); } } }//while - modify order }//BUYme //ENTRY SHORT (sell, Bid) void OpenSell() { int gle=0; int ticket=0; double SL=0; double TP=0; int loopcount; // PLACE order is independent of MODIFY order. // This is mandatory for ECNs and acceptable for retail brokers loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); ticket=OrderSend(mySymbol,OP_SELL,Lots,bid,Slippage,0,0,TradeComment,MagicNumber,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"SELL PLACED Ticket="+ticket+" Bid="+bid+" Lots="+Lots); TradeAllowed[ptrPairz]=false; break; } else { logwrite(TradeComment,"-----ERROR----- placing SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order"); return(gle); } } }//while // modify the order for users TP & SL loopcount=0; while(true) { bid=MarketInfo(mySymbol,MODE_BID); ask=MarketInfo(mySymbol,MODE_ASK); // don't set TP and SL both to zero, they're already there if(LossLimit==0 && ProfitMade==0) break; if(LossLimit ==0) SL=0; if(ProfitMade ==0) TP=0; if(LossLimit >0) SL=bid+((LossLimit+LL2SL)*myPoint ); if(ProfitMade >0) TP=bid-((ProfitMade+LL2SL)*myPoint ); OrderModify(ticket,OrderOpenPrice(),SL,TP,0,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"SELL OPENMOD Ticket="+ticket+" Bid="+bid+" Lots="+Lots+" SL="+SL+" TP="+TP); break; } else { logwrite(TradeComment,"-----ERROR----- modifying SELL order: Lots="+Lots+" SL="+SL+" TP="+TP+" Bid="+bid+" Ask="+ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on placing SELL order"); return(gle); } } }//while }//SELLme void CloseBuy (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; string bTK=" Ticket="+OrderTicket(); string bSL=" SL="+OrderStopLoss(); string bTP=" TP="+OrderTakeProfit(); string bPM; string bLL; string bER; bPM=" PM="+ProfitMade; bLL=" LL="+LossLimit; while(true) { bid=MarketInfo(mySymbol,MODE_BID); OrderClose(OrderTicket(),OrderLots(),bid,Slippage,White); gle=GetLastError(); bER=" error="+gle+" "+ErrorDescription(gle); if(gle==0) { logwrite(TradeComment,"CLOSE BUY "+myInfo+ bTK + bSL + bTP + bPM + bLL); break; } else { logwrite(TradeComment,"-----ERROR----- CLOSE BUY "+myInfo+ bER +" Bid="+bid+ bTK + bSL + bTP + bPM + bLL); RefreshRates(); Sleep(500); } loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on closing BUY order"); return(gle); } }//while } void CloseSell (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; string sTK=" Ticket="+OrderTicket(); string sSL=" SL="+OrderStopLoss(); string sTP=" TP="+OrderTakeProfit(); string sPM; string sLL; string sER; sPM=" PM="+ProfitMade; sLL=" LL="+LossLimit; while(true) { ask=MarketInfo(mySymbol,MODE_ASK); OrderClose(OrderTicket(),OrderLots(),ask,Slippage,Red); gle=GetLastError(); sER=" error="+gle+" "+ErrorDescription(gle); if(gle==0) { logwrite(TradeComment,"CLOSE SELL "+myInfo + sTK + sSL + sTP + sPM + sLL); break; } else { logwrite(TradeComment,"-----ERROR----- CLOSE SELL "+myInfo+ sER +" Ask="+ask+ sTK + sSL + sTP + sPM + sLL); RefreshRates(); Sleep(500); } loopcount++; if(loopcount>maxloop) { logwrite(TradeComment,"-----ERROR----- Giving up on closing SELL order"); return(gle); } }//while } // Function to correct the value of Point // for brokers that add an extra digit to price // Courtesy of Robert Hill double SetPoint() { double mPoint; int digits=MarketInfo(mySymbol,MODE_DIGITS); if (digits < 4) { mPoint = 0.01; } else { mPoint = 0.0001; } return(mPoint); }
Sample
Analysis
Market Information Used:
Series array that contains close prices for each bar
Indicator Curves created:
Indicators Used:
Relative strength index
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It can change open orders parameters, due to possible stepping strategy
It automatically opens orders when conditions are reached
It Closes Orders by itself
Other Features:
Uses files from the file system
It writes information to file