//+-----------------------------------------------------------------------------------+ //| Bogie-HedgeHog-v2.mq4 | //| | //| 2010.01.04 - Modified PlumCrazy code to trade HedgeHog strategy | //| from www.ForexTradersDaily.com | //+-----------------------------------------------------------------------------------+ ///Please, do not sell this EA because its FREE #property copyright "Copyright © 2010, Bogie Enterprises" // Added by Robert for better error messages #include #include // Added by Robert to check if bugs found need to use 5 digit pricing extern bool TestPoint = true; extern string INFO=" Bogie-HedgeHog-v2 "; extern int DaysOpen = 4; // EA will close all trades extern double StopLoss2 = 250; // when DaysOpen and StopLoss2 limits are exceeded. extern double step = 0.21; // Percent price change to execute trades. extern double MATrendPeriod = 2; // Daily Moving Average averaging bars. extern double MA_Mode = 0; // Choose 0=mode SMA, 1=mode EMA, 2=mode SMMA, 3=mode LWMA"; extern double MA_Price = 0; // Choose Price- 0=Close, 1=Open, 2=High, 3=Low, 4=Medium Price, 5=Typical Price extern string sb="--TRADE SETTING--"; extern double Lots = 0.01; // We start with this lots number int TakeProfit ; extern double multiply=2.0; // Factor to increase lot size from initial trade extern int MaxTrades=4; // Maximum number of orders to open extern int StopLoss = 150; // StopLoss extern int TrailingStop = 59; // Pips to trail the StopLoss extern string MM="--MOney Management--"; // (from order 2, not from first order extern string MMSwicth="if one the lots size will increase based on account size"; extern int mm=1; // if one the lots size will increase based on account size extern string riskset="risk to calculate the lots size (only if mm is enabled)"; extern int risk=10; // risk to calculate the lots size (only if mm is enabled) extern string accounttypes="0 if Normal Lots, 1 for mini lots, 2 for micro lots"; extern int AccountType=2; // 0 if Normal Lots, 1 for mini lots, 2 for micro lots extern bool BrokerIsIBFX = false; // Added by Robert to handle IBFX type lots extern bool BrokerPermitsFractionalLots = true; extern string magicnumber="--MAgic No--"; extern int MagicNumber=12345; // Magic number for the orders placed extern bool RecordData=False; // If true, record trade open time and MaxDD when using Strategy Tester extern int BacktestSpread=3; // Adjusts Market Stops from fixed backtest spread to current Demo/Live spread color ArrowsColor=Black; // color for the orders arrows bool ContinueOpening=True; int OpenOrders=0, cnt=0; int MarketOpenOrders=0; int slippage=5; double sl=0, tp=0; double BuyPrice=0, SellPrice=0; double lotsi=0, mylotsi=0; int mode=0, myOrderType=0, myOrderTypetmp=0; double LastPrice=0; int PreviousOpenOrders=0; double Profit=0; int LastTicket=0, LastType=0; double LastClosePrice=0, LastLots=0; // Added by Robert double myPoint; double myMaxLots; // Added by Robert for proper money management double myMinLots; // Added by Robert for proper money management int err; int slgap=0; int t; double PreviousClose; int nBars; double PreSellPrice, PreBuyPrice; double MaCurrent, MaPrevious; string Broker=""; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- myPoint = SetPoint(); // Added by Robert myMaxLots = MarketInfo(Symbol(), MODE_MAXLOT); // Added by Robert myMinLots = MarketInfo(Symbol(), MODE_MINLOT); // Added by Robert nBars=Bars; // Modified by Robert to save time on backtest if(_OrdersTotal()<1) { PreviousClose = iClose(NULL,PERIOD_D1,1); if (!IsTesting()) GlobalVariableSet("PreviousClose"+Symbol(),iClose(NULL,PERIOD_D1,1)); } else { if (!IsTesting()) PreviousClose = GlobalVariableGet("PreviousClose"+Symbol()); } Broker = AccountCompany(); //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- DeleteAllObjects(); //---- return(0); } //+------------------------------------------------------------------+ //| Get number of lots for this trade | //| Moved from start and code added to handle IBFX type lots | //+------------------------------------------------------------------+ double GetLots() { double lot; if(mm == 0) { lot = Lots; if (Lots < myMinLots) lot = myMinLots; if (Lots > myMaxLots) lot = myMaxLots; return(lot); } lot=NormalizeDouble(MathCeil((AccountBalance()*risk/10000))/10,2); if (BrokerIsIBFX == true) { // Use at least 1 micro lot if (AccountType==2) { lot = lot * 10; lot = MathFloor(lot*100)/100; if (lot < 0.1) lot = 0.1; if (lot > myMaxLots) lot = myMaxLots; return(lot); } // Use at least 1 mini lot if(AccountType==1) { lot = lot * 10; lot = MathFloor(lot*10)/10; if (lot < 1) lot = 1; if (lot > myMaxLots) lot = myMaxLots; return(lot); } // Standard Account if(BrokerPermitsFractionalLots == true) lot = StrToDouble(DoubleToStr(lot, 2)); else lot = MathFloor(lot); if (lot > myMaxLots) lot = myMaxLots; return(lot); } // Use at least 1 micro lot if (AccountType==2) { lot = MathFloor(lot*100)/100; if (lot < 0.01) lot = 0.01; if (lot > myMaxLots) lot = myMaxLots; return(lot); } // Use at least 1 mini lot if(AccountType==1) { lot = MathFloor(lot*10)/10; if (lot < 0.1) lot = 0.1; if (lot > myMaxLots) lot = myMaxLots; return(lot); } // Standard account if( BrokerPermitsFractionalLots == false) { if (lot >= 1.0) lot = MathFloor(lot); else lot = 1.0; } if (lot < 1.0) lot = 1.0; if (lot > myMaxLots) lot = myMaxLots; return(lot); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { CloseTrades(); //---- int cnt=0; bool result; string text=""; string version="Bogie-HedgeHog-v2"; lotsi = GetLots(); // Modified by Robert to handle IBFX type lots OpenOrders=0; MarketOpenOrders=0; for(cnt=0;cntOpenOrders) { for(cnt=OrdersTotal()-1;cnt>=0;cnt--) { if (OrderSelect(cnt, SELECT_BY_POS, MODE_TRADES)) { mode=OrderType(); if ((OrderSymbol()==Symbol() && OrderMagicNumber() == MagicNumber) ) { if (mode==OP_BUY || mode==OP_SELL) { OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),slippage,ArrowsColor); return(0); } } } } } PreviousOpenOrders=OpenOrders; if (OpenOrders>=MaxTrades) { ContinueOpening=False; } else { ContinueOpening=True; } if (LastPrice==0) { for(cnt=0;cnt=0) { if(OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES)==false) break; if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) // && Reversed==False) { //Print("Ticket ",OrderTicket()," modified."); if (OrderType()==OP_SELL) { if (myOrderTypetmp==2) { PreviousOpenOrders=OpenOrders+1; ContinueOpening=False; text = text +"\nClosing all orders because Indicator triggered another signal."; Print("Closing all orders because Indicator triggered another signal."); //return(0); } if (TrailingStop>0) { if ((OrderOpenPrice()-OrderClosePrice())>=(TrailingStop*myPoint)) { if (OrderStopLoss()>(OrderClosePrice()+TrailingStop*myPoint)) { result=OrderModify(OrderTicket(),OrderOpenPrice(),OrderClosePrice()+TrailingStop*myPoint,OrderClosePrice()-TakeProfit*myPoint-TrailingStop*myPoint,0,Purple); if(result!=TRUE) { // Added by Robert, I like a description err = GetLastError(); Print("LastError (", err, ")", ErrorDescription(err) ); } else OrderPrint(); return(0); } } } } if (OrderType()==OP_BUY) { if (myOrderTypetmp==1) { PreviousOpenOrders=OpenOrders+1; ContinueOpening=False; text = text +"\nClosing all orders because Indicator triggered another signal."; Print("Closing all orders because Indicator triggered another signal."); //return(0); } if (TrailingStop>0) { if ((OrderClosePrice()-OrderOpenPrice())>=(TrailingStop*myPoint)) { if (OrderStopLoss()<(OrderClosePrice()-TrailingStop*myPoint)) { result=OrderModify(OrderTicket(),OrderOpenPrice(),OrderClosePrice()-TrailingStop*myPoint,OrderClosePrice()+TakeProfit*myPoint+TrailingStop*myPoint,0,ArrowsColor); if(result!=TRUE) { // Added by Robert, I like a description err = GetLastError(); Print("LastError (", err, ")", ErrorDescription(err) ); } else OrderPrint(); return(0); } } } } } cnt--; } if(IsTesting() && RecordData) { if(OpenOrders==0 && t==1) { int handle; int orderOpen=OrderOpenTime(); int orderClose=TimeCurrent(); int TimeOpen=TimeCurrent()-OrderOpenTime(); handle=FileOpen("Bogie-HedgeHog-v2 data", FILE_CSV|FILE_READ|FILE_WRITE, ','); if(handle>0) { FileSeek(handle,0,SEEK_END); FileWrite(handle,TimeToStr(orderOpen),TimeToStr(orderClose),TimeOpen,slgap); FileClose(handle); } slgap=0; t=0; } if( SellGap() < slgap && OpenOrders==MaxTrades) { slgap=SellGap(); t=1; } } // ==================== COMMENT LINE =========================================== if (myOrderType==3 ) { text="No Signal"; } if (myOrderType==1 ) { text="SELL Signal"; } if (myOrderType==2 ) { text="BUY Signal"; } // Modified by Robert to save time on backtest if (IsVisualMode() || !IsTesting()) { Comment(Broker," - Server Time = ",TimeToStr(TimeCurrent(),TIME_SECONDS),"\nTrade Signal = ",text, "\nMA Previous = ",MaPrevious," MA Current = ",MaCurrent); } if (OpenOrders<1) OpenMarketOrders(); else OpenMarketOrders(); //---- return(0); } //+------------------------------------------------------------------+ void OpenMarketOrders() { // --------------------------------- // Added by Robert for Market Orders bool result; int ticket,ticket2, err,spread; double TPprice,STprice; // --------------------------------- int cnt=0; if (myOrderType==1 && ContinueOpening) { if (Bid>=LastPrice * (1 + (step/100)) || (OpenOrders<1 && !IsBarEnd())) { SellPrice=NormalizeDouble(MarketInfo(Symbol(),MODE_BID),Digits); spread=MarketInfo(Symbol(),MODE_SPREAD); LastPrice=0; if (OpenOrders!=0) { mylotsi=lotsi; for(cnt=0;cnt12) { mylotsi=NormalizeDouble(mylotsi*multiply,2); } else { mylotsi=NormalizeDouble(mylotsi*multiply,2); } } } else { mylotsi=lotsi; } // Modified by Robert to handle brokers who do not allow .01 or 100 lots // if (mylotsi>100) { mylotsi=100; } // if (mylotsi<0.01) { mylotsi=0.01; } if (mylotsi < myMinLots) mylotsi = myMinLots; if (mylotsi > myMaxLots) mylotsi = myMaxLots; ticket = OrderSend(Symbol(),OP_SELL,NormalizeDouble(mylotsi*Bid,Digits),SellPrice,slippage,0,0,"MyMEFx EA"+MagicNumber,MagicNumber,0,Red); // --------------------------------- // Added by Robert for Market Orders if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { Print("Sell order opened : ", OrderOpenPrice()); if (StopLoss != 0 || TakeProfit != 0) { TPprice = 0; if (TakeProfit > 0) { if(OpenOrders<1) { // Modified by Robert for 5 digit pricing test if (TestPoint) TPprice = PreviousClose + (spread*Point - BacktestSpread*Point); else TPprice = PreviousClose + (spread*myPoint - BacktestSpread*myPoint); PreSellPrice=SellPrice; } else {TPprice=PreSellPrice; PreSellPrice=SellPrice;} } STprice = 0; if (StopLoss > 0 && OpenOrders==MaxTrades-1) { STprice=OrderOpenPrice() + StopLoss*myPoint; STprice = ValidStopLoss(OP_SELL,Ask, STprice); } // Normalize stoploss / takeprofit to the proper # of digits. if (Digits > 0) { STprice = NormalizeDouble( STprice, Digits); TPprice = NormalizeDouble( TPprice, Digits); } result = OrderModify(ticket, OrderOpenPrice(), STprice, TPprice, 0, LightGreen); if(result!=TRUE) { // Added by Robert, I like a description err = GetLastError(); Print("Modify error (", err, ")", ErrorDescription(err) ); } } } } else { err = GetLastError(); if(err==0) { return; } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); } else //normal error { Print("Error opening Sell order (" + err + ") " + ErrorDescription(err)); } } } // --------------------------------- return(0); } // Sleep(6000); ////aku letak // RefreshRates(); } if (myOrderType==2 && ContinueOpening) { if (Ask<=LastPrice * (1 - (step/100)) || (OpenOrders<1 && !IsBarEnd())) { BuyPrice=NormalizeDouble(MarketInfo(Symbol(),MODE_ASK),Digits); LastPrice=0; if (OpenOrders!=0) { mylotsi=lotsi; for(cnt=0;cnt12) { mylotsi=NormalizeDouble(mylotsi*multiply,2); } else { mylotsi=NormalizeDouble(mylotsi*multiply,2); } } } else { mylotsi=lotsi; } // Modified by Robert to handle brokers who do not allow .01 or 100 lots // if (mylotsi>100) { mylotsi=100; } // if (mylotsi<0.01) { mylotsi=0.01; } if (mylotsi < myMinLots) mylotsi = myMinLots; if (mylotsi > myMaxLots) mylotsi = myMaxLots; ticket = OrderSend(Symbol(),OP_BUY,NormalizeDouble(mylotsi*Ask,Digits),BuyPrice,slippage,0,0,"MyMEFx EA"+MagicNumber,MagicNumber,0,Blue); // --------------------------------- // Added by Robert for Market Orders if (ticket > 0) { if (OrderSelect( ticket,SELECT_BY_TICKET, MODE_TRADES) ) { Print("BUY order opened : ", OrderOpenPrice( )); if (StopLoss != 0 || TakeProfit != 0) { TPprice = 0; if (TakeProfit > 0) { if(OpenOrders<1) { // Modified by Robert for 5 digit pricing test if (TestPoint) TPprice = PreviousClose-(spread*Point - BacktestSpread*Point); else TPprice = PreviousClose-(spread*myPoint - BacktestSpread*myPoint); PreBuyPrice=BuyPrice; } else {TPprice=PreBuyPrice; PreBuyPrice=BuyPrice;} } STprice = 0; if (StopLoss > 0 && OpenOrders==MaxTrades-1) { // Bug found by Robert // STprice = OrderOpenPrice() - StopLoss*Point; STprice = OrderOpenPrice() - StopLoss*myPoint; STprice = ValidStopLoss(OP_BUY,Bid, STprice); } // Normalize stoploss / takeprofit to the proper # of digits. if (Digits > 0) { STprice = NormalizeDouble( STprice, Digits); TPprice = NormalizeDouble( TPprice, Digits); } result = OrderModify(ticket, OrderOpenPrice(), STprice, TPprice, 0, LightGreen); if(result!=TRUE) { // Added by Robert, I like a description err = GetLastError(); Print("Modify error (", err, ")", ErrorDescription(err) ); } } } } else { err = GetLastError(); if(err==0) { return; } else { if(err==4 || err==137 ||err==146 || err==136) //Busy errors { Sleep(5000); } else //normal error { Print("Error opening BUY order (" + err + ") " + ErrorDescription(err)); } } } // --------------------------------- return(0); } } } void DeleteAllObjects() { int obj_total=ObjectsTotal(); string name; for(int i=0;i= PreviousClose *(1 + (step/100))) { MaCurrent=iMA(NULL,PERIOD_D1,MATrendPeriod,0,MA_Mode,MA_Price,1); MaPrevious=iMA(NULL,PERIOD_D1,MATrendPeriod,0,MA_Mode,MA_Price,2); if (MaCurrent < MaPrevious) myOrderType=1; } //buy order if (Ask <= PreviousClose *(1 - (step/100))) { MaCurrent=iMA(NULL,PERIOD_D1,MATrendPeriod,0,MA_Mode,MA_Price,1); MaPrevious=iMA(NULL,PERIOD_D1,MATrendPeriod,0,MA_Mode,MA_Price,2); if (MaCurrent > MaPrevious) myOrderType=2; } return(myOrderType); } // Functions added by Robert double SetPoint() { double mPoint; if (Digits < 4) mPoint = 0.01; else mPoint = 0.0001; return(mPoint); } double ValidStopLoss(int type, double price, double SL) { double minstop; double newSL; minstop = MarketInfo(Symbol(),MODE_STOPLEVEL); if (Digits == 3 || Digits == 5) minstop = minstop / 10; newSL = SL; if (type == OP_BUY) { if((price - SL) < minstop*myPoint) newSL = price - minstop*myPoint; } if (type == OP_SELL) { if((SL-price) < minstop*myPoint) newSL = price + minstop*myPoint; } newSL = NormalizeDouble(newSL,Digits); return(newSL); } int SellGap() { double value=0; for (int i=0; i= PreviousClose || (TimeCurrent()-OrderOpenTime()>(86400*DaysOpen) && OrderOpenPrice()-Close[0]>StopLoss2*myPoint)) { PreviousOpenOrders=OpenOrders+1; } } if(OrderType()==OP_SELL) { if(Ask <= PreviousClose || (TimeCurrent()-OrderOpenTime()>(86400*DaysOpen) && Close[0]-OrderOpenPrice()>StopLoss2*myPoint)) { PreviousOpenOrders=OpenOrders+1; } } } } return(0); } int _OrdersTotal() { int _total=0; for (int i=0; i