//+---------------------+ //| Every Bar CCI | //+---------------------+ #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 int TM_CCI = 95; extern bool CloseOnChange=true; extern double Lots = 0.1; // how many lots to trade at a time extern double ProfitMade = 0; // how much money do you expect to make extern double LossLimit = 0; // how much loss can you tolorate extern bool BasketAsPips = true; extern int BasketProfit = 0; // if equity reaches this level, close trades extern int BasketLoss = 0; // if equity reaches this negative level, close trades extern double BasketTrail = 0; int Slippage = 2; // how many pips of slippage can you tolorate // naming and numbering int MagicNumber = 201003302201; // allows multiple experts to trade on same account string TradeComment = "EBTM7a"; double myPoint; // Bar handling datetime bartime = 0; // used to determine when a bar has moved //basket trail double btrail; // Trade control bool TradeAllowed = true; // used to manage trades int maxloop = 5; // used for verbose error logging #include #include //+-------------+ //| Custom init | //|-------------+ // Called ONCE when EA is added to chart or recompiled int init() { myPoint=SetPoint(); Print("Init happened ", CurTime()); Comment(" "); } //+----------------+ //| Custom DE-init | //+----------------+ // Called ONCE when EA is removed from chart int deinit() { Print("DE-Init happened ",CurTime()); Comment(" "); } //+-----------+ //| Main | //+-----------+ // Called EACH TICK int start() { int cnt = 0; int gle = 0; // stoploss and takeprofit and close control double SL = 0; double TP = 0; double CurrentProfit = 0; double CurrentBasket = 0; double thisCCI; double lastCCI; // direction control bool BUYme = false; bool SELLme = false; // open of new bar if(bartime != Time[0]) { bartime = Time[0]; // allow a new trade on each new bar TradeAllowed = true; if (CloseOnChange) { // close everything if direction changes and CloseOnChange is true thisCCI = iCCI(Symbol(), 0, TM_CCI, PRICE_TYPICAL, 1); lastCCI = iCCI(Symbol(), 0, TM_CCI, PRICE_TYPICAL, 2); if ( thisCCI >= 0 && lastCCI < 0 ) CloseEverything(); if ( thisCCI <= 0 && lastCCI > 0 ) CloseEverything(); } }//bartime //+-----------------------------+ //| Insert your indicator here | //| And set either BUYme or | //| SELLme true to place orders | //+-----------------------------+ thisCCI = iCCI(Symbol(), 0, TM_CCI, PRICE_TYPICAL, 1); lastCCI = iCCI(Symbol(), 0, TM_CCI, PRICE_TYPICAL, 2); if (thisCCI >= 0 && TradeAllowed) OpenBuy(); if (thisCCI <= 0 && TradeAllowed) OpenSell(); //+------------+ //| End Insert | //+------------+ //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()==Symbol() && OrderMagicNumber()==MagicNumber && BasketAsPips) { // add up pips (This will be in pips something like 0.0098 if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( Ask-OrderOpenPrice() ); if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( OrderOpenPrice()-Bid ); } if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber && !BasketAsPips) { //add up dollars if(OrderType()==OP_BUY ) CurrentBasket=CurrentBasket+( OrderProfit() ); if(OrderType()==OP_SELL ) CurrentBasket=CurrentBasket+( OrderProfit() ); } } //scale pips up to integers is AsPips if(BasketAsPips) CurrentBasket=CurrentBasket/myPoint; if( BasketProfit>0 && CurrentBasket>=BasketProfit ) { CloseEverything(); btrail=0; } if( BasketLoss >0 && CurrentBasket<=BasketLoss * (-1) ) { CloseEverything(); btrail=0; } //basket trailing stop //calculate trail if(BasketTrail>0 && CurrentBasket>BasketTrail) { if(CurrentBasket>btrail) { btrail=CurrentBasket; } } //close on retrace if(btrail>0 && CurrentBasket<(btrail-BasketTrail)) { CloseEverything(); btrail=0; } // CLOSE order if profit target made for(cnt = 0; cnt < OrdersTotal(); cnt++) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { if(OrderType() == OP_BUY) { CurrentProfit = Bid - OrderOpenPrice(); // did we make our desired BUY profit if( ProfitMade > 0 && CurrentProfit >= (ProfitMade*myPoint) ) CloseBuy("PROFIT"); // or did we hit the BUY LossLimit if( LossLimit > 0 && CurrentProfit <= ((LossLimit*(-1))*myPoint) ) CloseBuy("LOSS"); } // if BUY if(OrderType()==OP_SELL) { CurrentProfit = OrderOpenPrice() - Ask; // did we make our desired SELL profit? if( ProfitMade > 0 && CurrentProfit >= (ProfitMade*myPoint) ) CloseSell("PROFIT"); // or did we hit the SELL LossLimit if( LossLimit > 0 && CurrentProfit <= ((LossLimit*(-1))*myPoint) ) CloseSell("LOSS"); } //if SELL } // if(OrderSymbol) } // for } // start() //+-----------------+ //| CloseEverything | //+-----------------+ // Closes all OPEN and PENDING orders int CloseEverything() { int i; for(i=OrdersTotal();i>=0;i--) { OrderSelect(i, SELECT_BY_POS); if(OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) { if(OrderType()==OP_BUY) CloseBuy ("BASKET"); if(OrderType()==OP_SELL) CloseSell("BASKET"); if(OrderType()==OP_BUYLIMIT) OrderDelete( OrderTicket() ); if(OrderType()==OP_SELLLIMIT) OrderDelete( OrderTicket() ); if(OrderType()==OP_BUYSTOP) OrderDelete( OrderTicket() ); if(OrderType()==OP_SELLSTOP) OrderDelete( OrderTicket() ); } Sleep(1000); } //for } // closeeverything // 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(mydata+" "+gregorian); // don't log anything if testing or if user doesn't want it if(IsTesting()) return(0); myhandle=FileOpen(Symbol()+"_"+filename, FILE_CSV|FILE_WRITE|FILE_READ, ";"); if(myhandle>0) { FileSeek(myhandle,0,SEEK_END); FileWrite(myhandle, 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) { // place order - NO TP OR SL ticket=OrderSend(Symbol(),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=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) { // 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)*myPoint ); if(ProfitMade >0) TP=Ask+((ProfitMade)*myPoint ); OrderModify(ticket,OrderOpenPrice(),SL,TP,0,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"BUY MODIFIED 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) { ticket=OrderSend(Symbol(),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=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) { // 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)*myPoint ); if(ProfitMade >0) TP=Bid-((ProfitMade)*myPoint ); OrderModify(ticket,OrderOpenPrice(),SL,TP,0,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"SELL MODIFIED 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) { 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 SELL 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) { 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; if (Digits < 4) mPoint = 0.01; else mPoint = 0.0001; return(mPoint); }