//+--------+ //|Shell_15 //+--------+ #property copyright "Ron Thompson" #property link "http://www.lightpatch.com/forex" // 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 // "12345678901234567890123456789012345678901"; //extern string MinFreeMarginPct_is = "percent of freemargin necessary to trade "; extern double MinFreeMarginPct = 25.0; //extern string ProfitMade_is = "PIPS PROFIT you want to make per trade "; extern double ProfitMade = 8; //extern string BasketProfit_is = "close all orders if this $ profit "; extern double BasketProfit = 14.5; //extern string LossLimit_is = "PIPS LOSS you can afford per trade "; extern double LossLimit = 35; //extern string BasketLoss_is = "close all orders if this $ loss "; extern double BasketLoss = 0; //extern string BreakEven_is = "set StopLoss to OpenPrice at this profit "; extern double BreakEven = 0; //extern string TrailStop_is = "Trail OrderPrice starting from 1st tick "; extern double TrailStop = 0; //extern string Lots_is1 = "How many lots or partial lots per trade "; extern double Lots = 0.1; //extern string LotIncrease_is = "grow Lots based on account balance "; extern bool LotIncrease = true ; //extern string LotResolution_is = "for LotIncrease: 0=FullLot 1=0.1 2=0.01 "; extern int LotResolution = 1 ; //extern string TradeEveryBar_is = "One trade for EVERY bar that qualifies "; extern bool TradeEveryBar = false; //extern string TradeOnFriday_is = "trade Friday news (8:00-9:00 GMT) or not "; extern bool TradeNewsFriday = true ; //extern string KillLogging_is = "Turn on or off ALL logging "; extern bool KillLogging = true ; // non-external flag settings int Slippage=2; // how many pips of slippage can you tolorate // naming and numbering int MagicNumber = 142537; // allows multiple experts to trade on same account string TradeComment = "_shell15.txt"; // where to log information double StartingBalance=0; // lot size control if LotIncrease == true int LL2SL=10; // LossLimit to StopLoss server spread int maxloop=50; // no more than 50 tries/25 seconds to close an order // Bar handling datetime bartime=0; // used to determine when a bar has moved int bartick=0; // number of times bars have moved // Lot calculations double lotsi; // used in doubling calculations // Trade control bool TradeAllowed=true; // used to manage trades string SST[200]; // Start-Stop Time array used to manage time avoidance // Min/Max tracking and tick logging 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() { // Even numbered elements are STOP times // Odd numbered elements are START times // // THESE ARE IN SERVER-SIDE TIME!!!!!! // (usually GMT, your broker may vary) // SST[0] ="2006.11.07 13:15:00"; SST[1] ="2006.11.07 15:15:00"; if(MinFreeMarginPct==0) MinFreeMarginPct=1; if(LotIncrease) { //StartingBalance=AccountBalance()/Lots; StartingBalance=10000; logwrite(TradeComment,"LotIncrease ACTIVE Balance="+AccountBalance()+" StartingBalance="+StartingBalance+" Lots="+NormalizeDouble(AccountBalance()/StartingBalance,LotResolution)); } else { logwrite(TradeComment,"LotIncrease NOT ACTIVE Account balance="+AccountBalance()+" Lots="+Lots); } logwrite(TradeComment,"Init Complete"); Comment(" "); } //+----------------+ //| Custom DE-init | //+----------------+ // Called ONCE when EA is removed from chart int deinit() { // always indicate deinit statistics logwrite(TradeComment,"MAX number of orders "+maxOrders); logwrite(TradeComment,"DE-Init Complete"); Comment(" "); } //+-----------+ //| Main | //+-----------+ // Called EACH TICK and each Bar[] int start() { 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; //safety counter int loopcount=0; // bar counting if(bartime!=Time[0]) { bartime=Time[0]; bartick++; if(TradeEveryBar) TradeAllowed=true; logwrite(TradeComment,"New Bar at"); } // Lot increasement based on AccountBalance if(LotIncrease) { Lots=NormalizeDouble(AccountBalance()/StartingBalance,LotResolution); if( Lots>MarketInfo(Symbol(), MODE_MAXLOT) ) Lots=MarketInfo(Symbol(), MODE_MAXLOT); } OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) { OrdersPerSymbol++; } } if(OrdersPerSymbol==0) { TradeAllowed=true; } // keep some statistics if(OrdersPerSymbol>maxOrders) maxOrders=OrdersPerSymbol; //+-----------------------------+ //| Insert your indicator here | //| And set either BUYme or | //| SELLme true to place orders | //+-----------------------------+ SELLme=true; //+------------+ //| End Insert | //+------------+ // Trades may be turned off if the init() section // has dates and times defined to avoid trading // (for things such as NFP and other news times bool TradesOff=false; datetime gstart; datetime gstop; for(cnt=0; cnt<ArraySize(SST); cnt=cnt+2) { gstart=StrToTime(SST[cnt]); gstop =StrToTime(SST[cnt+1]); if(Time[0]>=gstart && Time[0]<=gstop) { Print( Time[0],CurTime() ); TradesOff=true; } } //ENTRY LONG (buy, Ask) if( TradeAllowed && BUYme && !TradesOff) { loopcount=0; while(true) { if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) ) { logwrite(TradeComment,"Your BUY equity is too low to trade"); break; } if(LossLimit ==0) SL=0; else SL=Ask-((LossLimit+LL2SL)*Point ); if(ProfitMade==0) TP=0; else TP=Ask+((ProfitMade+LL2SL)*Point ); ticket=OrderSend(Symbol(),OP_BUY,Lots,Ask,Slippage,SL,TP,TradeComment,MagicNumber,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment," "); logwrite(TradeComment,"BUY Ticket="+ticket+" Ask="+Ask+" Lots="+Lots+" SL="+SL+" TP="+TP); TradeAllowed=false; bartick=0; break; } else { logwrite(TradeComment,"-----ERROR----- opening BUY order: Lots="+Lots+" AcctBal="+AccountBalance()+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) break; } }//while }//BUYme //ENTRY SHORT (sell, Bid) if( TradeAllowed && SELLme && !TradesOff) { loopcount=0; while(true) { if( AccountFreeMargin()< (AccountBalance()*(MinFreeMarginPct/100)) ) { logwrite(TradeComment,"Your SELL equity is too low to trade"); break; } if(LossLimit ==0) SL=0; else SL=Bid+((LossLimit+LL2SL)*Point ); if(ProfitMade==0) TP=0; else TP=Bid-((ProfitMade+LL2SL)*Point ); ticket=OrderSend(Symbol(),OP_SELL,Lots,Bid,Slippage,SL,TP,TradeComment,MagicNumber,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment," "); logwrite(TradeComment,"SELL Ticket="+ticket+" Bid="+Bid+" Lots="+Lots+" SL="+SL+" TP="+TP); TradeAllowed=false; bartick=0; break; } else { logwrite(TradeComment,"-----ERROR----- opening SELL order: Lots="+Lots+" AcctBal="+AccountBalance()+" SL="+SL+" TP="+TP+" Bid="+Bid+" Ask="+Ask+" ticket="+ticket+" Err="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); loopcount++; if(loopcount>maxloop) break; } }//while }//SELLme //Basket profit or loss CurrentBasket=AccountEquity()-AccountBalance(); if( BasketProfit>0 && CurrentBasket>=BasketProfit ) CloseEverything(); if( BasketLoss >0 && CurrentBasket<=(BasketLoss*(-1)) ) CloseEverything(); // // Order Management // for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber ) { if(OrderType()==OP_BUY) { CurrentProfit=(Bid-OrderOpenPrice()) ; //logwrite(TradeComment,"BUY CurrentProfit="+CurrentProfit/Point+" CurrentBasket="+CurrentBasket/Point); // // 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*Point && OrderOpenPrice()>OrderStopLoss()) { 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 //========================= // if( OrderProfit()>0 && TrailStop>0 ) { if( OrderStopLoss() < Bid-(TrailStop*Point) ) { SL=Bid-(TrailStop*Point); 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*Point)) CloseBuy("PROFIT"); // Did we take a loss //==================== if(LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point)) CloseBuy("LOSS"); } // if BUY if(OrderType()==OP_SELL) { CurrentProfit=(OrderOpenPrice()-Ask); //logwrite(TradeComment,"SELL CurrentProfit="+CurrentProfit/Point+" CurrentBasket="+CurrentBasket/Point); // // 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*Point && OrderOpenPrice()<OrderStopLoss()) { 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 //========================= // if( OrderProfit()>0 && TrailStop>0) { if( OrderStopLoss() > Ask+(TrailStop*Point) ) { SL=Ask+(TrailStop*Point); 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*Point) ) CloseSell("PROFIT"); // Did we take a loss //==================== if( LossLimit>0 && CurrentProfit<=(LossLimit*(-1)*Point) ) 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); if(KillLogging) 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); } } void CloseBuy (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; while(true) { OrderClose(OrderTicket(),OrderLots(),Bid,Slippage,White); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"CLOSE BUY "+myInfo+" Ticket="+OrderTicket()+" SL="+OrderStopLoss()+" TP="+OrderTakeProfit()+" PM="+ProfitMade+" LL="+LossLimit); break; } else { logwrite(TradeComment,"-----ERROR----- CLOSE BUY PROFIT Bid="+Bid+" error="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); } OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) break; } loopcount++; if(loopcount>maxloop) break; }//while } void CloseSell (string myInfo) { int gle; int cnt; int OrdersPerSymbol; int loopcount=0; while(true) { OrderClose(OrderTicket(),OrderLots(),Ask,Slippage,Red); gle=GetLastError(); if(gle==0) { logwrite(TradeComment,"CLOSE SELL "+myInfo+" Ticket="+OrderTicket()+" SL="+OrderStopLoss()+" TP="+OrderTakeProfit()+" PM="+ProfitMade+" LL="+LossLimit); break; } else { logwrite(TradeComment,"-----ERROR----- CLOSE SELL PROFIT Ask="+Ask+" error="+gle+" "+ErrorDescription(gle)); RefreshRates(); Sleep(500); } OrdersPerSymbol=0; for(cnt=OrdersTotal();cnt>=0;cnt--) { OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES); if( OrderSymbol()==Symbol() && OrderMagicNumber()==MagicNumber) break; } loopcount++; if(loopcount>maxloop) break; }//while } double LSMA(int myLPeriod, int myShift ) { int myI; double myLengthvar; double myTmp; double mySum=0; for(myI = myLPeriod; myI >= 1 ; myI--) { myLengthvar = myLPeriod + 1; myLengthvar /= 3; myTmp = 0; myTmp = ( myI - myLengthvar)*Open[myLPeriod-myI+myShift]; mySum+=myTmp; } return( mySum*6/(myLPeriod*(myLPeriod+1)) ); }
Sample
Analysis
Market Information Used:
Series array that contains open time of each bar
Series array that contains open prices of each bar
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
It automatically opens orders when conditions are reached
It can change open orders parameters, due to possible stepping strategy
It Closes Orders by itself
Other Features:
Uses files from the file system
It writes information to file