//+-------------------------------------------------------------------+ //| GaoXing Daily Breakout v1.3.1.mq4 | //| Copyright © 2006, BaasHarm | //| http://www.goldenmoneytree.com | //| Version: 1.3.1 | //| Version Date: 7-feb-2007 | //| Last change by: BaasHarm | //+-------------------------------------------------------------------+ #property copyright "Copyright © 2006, BaasHarm" //-- Feel free to correct, add or modify as you please. //-- But if you do: //-- * Mark and identify changes. //-- * Update "Version", "Version Date" and "Last changed by" at the top. //-- * Send a copy to baasharm@zeelandnet.nl //-- Record of changes: //-- * 17-nov 2006: BaasHarm, EA created // * 19-nov-2006: BaasHarm, changed MM to deal with dynamic stop loss // * 22-nov-2006: BaasHarm, changed Trailing Stop // * 30-nov-2006: BaasHarm, added GetTicketNr() function // added ChannelFilter // * 2-dec-2006: BaasHarm, fixed Trailstop bug // added 2nd MM option // added UseCloseOrdersTime // * 16-dec-2006: BaasHarm, added Export2CSV() // * 21-dec-2006: BaasHarm, fixed Order placement bug, when order is closed within 1 hour of TFstop // BaasHarm, modified BuyStop & BuyPrice to include spread. // modified Placeorder() to correct for spread. // BaasHarm, changed EA_comment // BaasHarm, checked MoveStop2BE() for spread and SL placement. // * 23-dec-2006 BaasHarm, modified GetTicketNr() to include history scan // * 1-jan-2007 BaasHarm, modified GetTicketNr() to include SL/TP closed tickets // modified order entry conditions to place orders at min. 10 pip upto 4 hours after TFStop // modified Results2CSV() to include open/close price // * 30-jan-2007 BaasHarm, fixed bug in Trail() // * 5-feb-2007 BaasHarm, modified Result2CSV() to include swap and changed layout // extern int Breakout=5; // Pip distance between high/low and buy/sell order extern int Stop=70; extern int Stop2BE=40; // Pips in profit to move stop to breakeven extern int ProfitTarget=120; extern int TrailStop=0; // Pips to trail; if > 0 trails price when Profit Target is reached extern int ChannelFilter=0; // If > 0, breakout channel (time frame high-low) exceeds channel filter, no orders will be placed for the referenced timeframe extern int UseMM=0; // > 0 turns Money Management on // 1 uses fixed dollar risk as percentage of balance per trade // 2 uses fixed pipvalue as percentage of balance per trade extern double MMRisk=2; // Money Management risk per trade in percent extern double LotSize=0.1; // Lotsize with UseMM = 0 extern double LotFactor=1; // LotSize multiplication factor after loss trade. Only with UseMM 1 & 2 extern bool UseCloseOrdersTime=True; // True closes all positions and deletes all orders at CloseOrdersTime extern int CloseOrdersTime=0; // CET Time to close positions and delete all orders. On friday, orders are closed at 22:45 CET if not closed before that time extern bool Export2CSV=False; // True saves daily pips and profit to CSV File extern string FileName="GaoXing"; // Filename for export file extern int ServerTimeZone=2; // Server's time zone, 0 = London Time, 1 = London Time + 1, etc. // Use 2 for FXDD, 1WorldFX // 0 for IBFX // 1 for MIGFX extern int MagicNumber=321; extern int TF1Start=6; // Start timeframe 1 in hours CET extern int TF1Stop=10; // End timeframe 1 in hours CET extern bool UseTF2=True; // True enables 2nd timeframe extern int TF2Start=10; // Start timeframe 2 in hours CET extern int TF2Stop=14; // End timeframe 2 in hours CET //internal variables string EA_Comment=""; string demo=""; int CETHour=0; double LowTF1=0; double LowTF2=0; double HighTF1=0; double HighTF2=0; double SellPrice=0; double BuyPrice=0; double SellStop=0; double BuyStop=0; int SellTicketTF1=0; int SellTicketTF2=0; int BuyTicketTF1=0; int BuyTicketTF2=0; int Handle=0; int p=0; int ExpireOrders=4; double Spread=0; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { Print(" Copyright © 2006, BaasHarm"); Print(" baasharm@zeelandnet.nl"); if (Export2CSV == True) { FileName = FileName + Symbol() + ".CSV"; Handle = FileOpen(FileName,FILE_CSV|FILE_READ,","); if (Handle > 0) { return (0); } else { Handle = FileOpen(FileName,FILE_CSV|FILE_WRITE,","); if(Handle < 1) { Alert("Error writing file: ",GetLastError()); } else { FileWrite(Handle, "GaoXing Daily Breakout v1.3.1"); FileWrite(Handle, "Account Nr:", AccountNumber()); if (IsDemo() == True) { demo = "Demo Account"; } else { demo = "Live Account"; } FileWrite(Handle, demo); FileWrite(Handle, "Account name:", AccountName()); FileWrite(Handle, "Company: ", CompanyName()); FileWrite(Handle, "Server: ", ServerAddress()); FileWrite(Handle, "Account Currency: ",AccountCurrency()); FileWrite(Handle, " "); FileWrite(Handle, "Ticket", "Comment", "Open Time","Type","Lots", "Symbol", "Open Price", "Close Time", "Close Price", "Profit", "Pips", "Balance"); FileClose(Handle); } } } return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { CETHour = TimeHour(CurTime()) - ServerTimeZone + 1; // Calculate CET if (CETHour < 0) { CETHour = CETHour + 24; } if (CETHour > 23) { CETHour = CETHour - 24; } LowTF1 = GetBreakout(0,TF1Start,TF1Stop); HighTF1 = GetBreakout(1,TF1Start,TF1Stop); LowTF2 = GetBreakout(0,TF2Start,TF2Stop); HighTF2 = GetBreakout(1,TF2Start,TF2Stop); Spread=Ask-Bid; Comment("Server Time: ",TimeToStr(CurTime( )),"; CET hour: ",CETHour, "\n"," ",TF1Start,":00-",TF1Stop,":00 CET: Low: ",LowTF1,", High: ",HighTF1, "\n"," ",TF2Start,":00-",TF2Stop,":00 CET: Low: ",LowTF2,", High: ",HighTF2); GetTicketNr(); if (CETHour >= TF1Stop && CETHour - TF1Stop < ExpireOrders) // Place orders for timeframe 1 within 4 hours after TF1Stop { if ((ChannelFilter == 0)||(ChannelFilter > 0 && (HighTF1 - LowTF1) <= ChannelFilter * Point)) { EA_Comment = "GaoXing DB TF1"; p=0; SellPrice = LowTF1 - Breakout * Point; BuyPrice = HighTF1 + Breakout * Point + Spread; SellStop = SellPrice + Stop * Point; // Place stops at breakout channel if (SellStop > BuyPrice) { SellStop = BuyPrice; } BuyStop = BuyPrice - Stop * Point; if (BuyStop < SellPrice) { BuyStop = SellPrice; } if (SellTicketTF1 == 0) { if (Bid - SellPrice > 10 * Point) // Place sell order when current price is 10 pips above breakout { SellTicketTF1 = PlaceOrder(OP_SELLSTOP,SellPrice,SellStop); } if (SellPrice >= Bid) // Open short when channel is broken { SellTicketTF1 = PlaceOrder(OP_SELL,Bid,SellStop); } } if (BuyTicketTF1 == 0) { if (BuyPrice - Ask > 10 * Point) // Place buy order when current price is 10 pips above breakout { BuyTicketTF1 = PlaceOrder(OP_BUYSTOP,BuyPrice,BuyStop); } if (BuyPrice <= Ask) // Open long when channel is broken { BuyTicketTF1 = PlaceOrder(OP_BUY,Ask,BuyStop); } } } } if (CETHour >= TF2Stop && CETHour - TF2Stop < ExpireOrders && UseTF2==True) // Place orders for timeframe 2 within 4 hours after TF2Stop { if ((ChannelFilter == 0)||(ChannelFilter > 0 && (HighTF2 - LowTF2) <= ChannelFilter * Point)) { EA_Comment = "GaoXing DB TF2"; SellPrice = LowTF2 - Breakout * Point; BuyPrice = HighTF2 + Breakout * Point + Spread; SellStop = SellPrice + Stop * Point; // Place stops at breakout channel if (SellStop > BuyPrice) { SellStop = BuyPrice; } BuyStop = BuyPrice - Stop * Point; if (BuyStop < SellPrice) { BuyStop = SellPrice; } if (SellTicketTF2 == 0) { if (Bid - SellPrice > 10 * Point) // Place sell order when current price is 20 pips above breakout { SellTicketTF2 = PlaceOrder(OP_SELLSTOP,SellPrice,SellStop); } if (SellPrice >= Bid) // Open short when channel is broken { SellTicketTF2 = PlaceOrder(OP_SELL,Bid,SellStop); } } if (BuyTicketTF2 == 0) { if (BuyPrice - Ask > 10 * Point) // Place buy order when current price is 20 pips above breakout { BuyTicketTF2 = PlaceOrder(OP_BUYSTOP,BuyPrice, BuyStop); } if (BuyPrice <= Ask) // Open long when channel is broken { BuyTicketTF2 = PlaceOrder(OP_BUY,Ask, BuyStop); } } } } MoveStop2BE(SellTicketTF1); MoveStop2BE(BuyTicketTF1); MoveStop2BE(SellTicketTF2); MoveStop2BE(BuyTicketTF2); if (TrailStop > 0) // Trial opened tickets { Trail(SellTicketTF1); Trail(BuyTicketTF1); Trail(SellTicketTF2); Trail(BuyTicketTF2); } if (CETHour == CloseOrdersTime) // Close postions { CloseAllOrders(); if (Export2CSV == True && p!=1) { Results2CSV(); p=1; } } if ( TimeDayOfWeek(CurTime()) == 5 && TimeHour(CurTime()) == 22 && TimeMinute(CurTime()) >= 45) // Close friday position 15 min before weekend close { CloseAllOrders(); if (Export2CSV == True && p!=1) { Results2CSV(); p=1; } } return(0); } double GetBreakout (int HighLow, int CET1, int CET2) // Gets High or low price for referenced period in CET, HighLow = 0 is for low, HighLow = 1 is for high { double CurrBO=0; double BO=0; if(CETHour >= CET2) { for (int i = 1; i < (CET2-CET1 + 1); i++) { if (HighLow == 1) { CurrBO = iHigh(Symbol(),PERIOD_H1,CETHour-CET2 + i); if (CurrBO > BO ) { BO = CurrBO; } } if (HighLow == 0) { CurrBO = iLow(Symbol(),PERIOD_H1,CETHour - CET2 + i); if (BO == 0) { BO = CurrBO; } if (CurrBO < BO) { BO = CurrBO; } } } } return(BO); } double GetLotSize(int SL) // Calculates lotsize using Money Management { double Lot=0; double MinLotSize=0; double MaxLotSize=0; double LotStep=0; MinLotSize = MarketInfo(Symbol(),MODE_MINLOT); MaxLotSize = MarketInfo(Symbol(),MODE_MAXLOT); LotStep = MarketInfo(Symbol(),MODE_LOTSTEP); if (UseMM == 0) { Lot = LotSize; } if (UseMM == 1) { Lot = NormalizeDouble(AccountBalance() * MMRisk * 0.01 / (SL * MarketInfo(Symbol(),MODE_TICKVALUE)),2); } if (UseMM == 2) { Lot = NormalizeDouble(AccountBalance() * MMRisk * 0.01 / AccountLeverage(),2); } Lot = NormalizeDouble(Lot/LotStep,0) * LotStep; if(Lot < MinLotSize) { Lot = MinLotSize; } if(Lot > MaxLotSize) { Lot = MaxLotSize; } return(Lot); } int PlaceOrder(int Order, double Price, double StopLoss) // Places order, opens positions and returns ticket nr { int Ticket = 0; double TakeProfit=0; LotSize = GetLotSize(MathAbs(Price - StopLoss)/Point - Spread/Point); if (Order == OP_SELLSTOP) { if (TrailStop > 0) { TakeProfit = 0; } else { TakeProfit = Price - (ProfitTarget * Point); } if (IsTradeAllowed() == True) { Ticket=OrderSend(Symbol(),OP_SELLSTOP,LotSize,Price,0,StopLoss,TakeProfit,EA_Comment,MagicNumber,0,CLR_NONE); if (Ticket <= 0) { Print("Error opening Sellstop: ", GetLastError()); } } } if (Order == OP_BUYSTOP) { if (TrailStop > 0) { TakeProfit = 0; } else { TakeProfit = Price + ProfitTarget * Point; } if (IsTradeAllowed() == True) { Ticket=OrderSend(Symbol(),OP_BUYSTOP,LotSize,Price,0,StopLoss,TakeProfit,EA_Comment,MagicNumber,0,CLR_NONE); if (Ticket < 0) { Print("Error opening Buystop: ", GetLastError()); } } } if (Order == OP_SELL) { if (TrailStop > 0) { TakeProfit = 0; } else { TakeProfit = Price - (ProfitTarget * Point); } if (IsTradeAllowed() == True) { Ticket=OrderSend(Symbol(),OP_SELL,LotSize,Price,0,StopLoss,TakeProfit,EA_Comment,MagicNumber,0,CLR_NONE); if (Ticket <= 0) { Print("Error opening Sell Order: ", GetLastError()); } } } if (Order == OP_BUY) { if (TrailStop > 0) { TakeProfit = 0; } else { TakeProfit = Price + ProfitTarget * Point; } if (IsTradeAllowed() == True) { Ticket=OrderSend(Symbol(),OP_BUY,LotSize,Price,0,StopLoss,TakeProfit,EA_Comment,MagicNumber,0,CLR_NONE); if (Ticket < 0) { Print("Error opening Buy Order: ", GetLastError()); } } } return(Ticket); } void GetTicketNr() { SellTicketTF1=0; SellTicketTF2=0; BuyTicketTF1=0; BuyTicketTF2=0; for (int i=OrdersTotal()-1 ; i>=0 ; i--) //Scan trades { OrderSelect(i, SELECT_BY_POS,MODE_TRADES); if (OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP) { if (OrderComment()=="GaoXing DB TF1") { BuyTicketTF1 = OrderTicket(); } if (OrderComment()=="GaoXing DB TF2") { BuyTicketTF2 = OrderTicket(); } } if (OrderType() == OP_SELL || OrderType() == OP_SELLSTOP) { if (OrderComment()=="GaoXing DB TF1") { SellTicketTF1 = OrderTicket(); } if (OrderComment()=="GaoXing DB TF2") { SellTicketTF2 = OrderTicket(); } } } } for (i=HistoryTotal()-1 ; i>=0 ; i--) //Scan history { OrderSelect(i, SELECT_BY_POS,MODE_HISTORY); if(TimeDayOfYear(CurTime()) == TimeDayOfYear(OrderOpenTime()) && TimeYear(CurTime())== TimeYear(OrderOpenTime())) { if (OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_BUY || OrderType() == OP_BUYSTOP) { if (OrderComment()=="GaoXing DB TF1" || OrderComment()=="GaoXing DB TF1[sl]" || OrderComment()=="GaoXing DB TF1[tp]") { if(TimeHour(OrderOpenTime()) - ServerTimeZone + 1 >= TF1Stop) { BuyTicketTF1 = OrderTicket(); } } if (OrderComment()=="GaoXing DB TF2" || OrderComment()=="GaoXing DB TF2[sl]" || OrderComment()=="GaoXing DB TF2[tp]") { if(TimeHour(OrderOpenTime()) - ServerTimeZone + 1 >= TF2Stop) { BuyTicketTF2 = OrderTicket(); } } } if (OrderType() == OP_SELL || OrderType() == OP_SELLSTOP) { if (OrderComment()=="GaoXing DB TF1" || OrderComment()=="GaoXing DB TF1[sl]" || OrderComment()=="GaoXing DB TF1[tp]") { if(TimeHour(OrderOpenTime()) - ServerTimeZone + 1 >= TF1Stop) { SellTicketTF1 = OrderTicket(); } } if (OrderComment()=="GaoXing DB TF2" || OrderComment()=="GaoXing DB TF2[sl]" || OrderComment()=="GaoXing DB TF2[tp]") { if(TimeHour(OrderOpenTime()) - ServerTimeZone + 1 >= TF2Stop) { SellTicketTF2 = OrderTicket(); } } } } } } } void MoveStop2BE(int Ticket) // Moves stop to breakeven { OrderSelect(Ticket,SELECT_BY_TICKET); if (OrderType() == OP_BUY && OrderMagicNumber() == MagicNumber && OrderCloseTime()==0) { if (Bid - OrderOpenPrice() >= Stop2BE * Point && OrderStopLoss() < OrderOpenPrice()) { OrderModify(Ticket,0,OrderOpenPrice(),OrderTakeProfit(),0,CLR_NONE); if (GetLastError() > 0) { Print("Error move stop to breakeven: ", GetLastError()); } } } if (OrderType() == OP_SELL && OrderMagicNumber() == MagicNumber && OrderCloseTime()==0) { if (OrderOpenPrice() - Ask >= Stop2BE * Point && OrderStopLoss() > OrderOpenPrice()) { OrderModify(Ticket,0,OrderOpenPrice(),OrderTakeProfit(),0,CLR_NONE); if (GetLastError() > 0) { Print("Error move stop to breakeven: ", GetLastError()); } } } } void Trail(int Ticket) // Trails specified ticket { OrderSelect(Ticket,SELECT_BY_TICKET); if (OrderType() == OP_BUY && OrderMagicNumber() == MagicNumber && OrderCloseTime()==0) { if ((Bid - OrderOpenPrice() >= ProfitTarget * Point && OrderOpenPrice() == OrderStopLoss()) || (OrderStopLoss() >= OrderOpenPrice())) { if (Bid - TrailStop * Point > OrderStopLoss()) { OrderModify(Ticket,0,Bid - TrailStop * Point,0,0,CLR_NONE); } } } if (OrderType() == OP_SELL && OrderMagicNumber() == MagicNumber && OrderCloseTime()==0) { if ((OrderOpenPrice() - Ask >= ProfitTarget * Point && OrderOpenPrice() == OrderStopLoss()) || (OrderStopLoss() <= OrderOpenPrice())) { if (Ask + TrailStop * Point < OrderStopLoss() || OrderStopLoss() == 0) { OrderModify(Ticket,0, Ask + TrailStop * Point,0,0,CLR_NONE); } } } } void CloseAllOrders() // Closes all open and pending orders { int Orders = OrdersTotal(); for (int i=Orders-1 ; i>=0 ; i--) { OrderSelect(i, SELECT_BY_POS); if (OrderSymbol() == Symbol()&& OrderMagicNumber() == MagicNumber) { if (OrderType() == OP_BUY && UseCloseOrdersTime == True) { OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_BID), 3, CLR_NONE); } if (OrderType() == OP_SELL && UseCloseOrdersTime == True) { OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_ASK), 3, CLR_NONE); } if (OrderType() == OP_BUYSTOP) { OrderDelete(OrderTicket()); } if (OrderType() == OP_SELLSTOP) { OrderDelete(OrderTicket()); } } } } void Results2CSV() { int Orders = HistoryTotal(); double Profit=0; int Pips=0; for (int i=Orders-1 ; i>=0 ; i--) { OrderSelect(i,SELECT_BY_POS,MODE_HISTORY); if (OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber) { if(CurTime() - OrderCloseTime() < (24 - TF1Stop) * 60 * 60) { if (OrderType() == OP_BUY) { Profit = Profit + OrderProfit()+ OrderSwap(); Pips = Pips + (OrderClosePrice() - OrderOpenPrice())/Point; Handle = FileOpen(FileName,FILE_CSV|FILE_WRITE|FILE_READ,","); if (Handle < 1) { Alert("Error writing to file."); } FileSeek(Handle, 0, SEEK_END); FileWrite(Handle, OrderTicket(), OrderComment(),TimeToStr(OrderOpenTime()), "Buy", OrderLots(), OrderSymbol(), OrderOpenPrice(),TimeToStr(OrderCloseTime()), OrderClosePrice(), OrderProfit() + OrderSwap(), (OrderClosePrice() - OrderOpenPrice())/Point); FileClose(Handle); } if (OrderType() == OP_SELL) { Profit = Profit + OrderProfit()+ OrderSwap(); Pips = Pips + (OrderOpenPrice() - OrderClosePrice())/Point; Handle = FileOpen(FileName,FILE_CSV|FILE_WRITE|FILE_READ,","); if (Handle < 1) { Alert("Error writing to file."); } FileSeek(Handle, 0, SEEK_END); FileWrite(Handle, OrderTicket(), OrderComment(),TimeToStr(OrderOpenTime()), "Sell", OrderLots(), OrderSymbol(), OrderOpenPrice(),TimeToStr(OrderCloseTime()), OrderClosePrice(), OrderProfit() + OrderSwap(), (OrderOpenPrice() - OrderClosePrice())/Point); FileClose(Handle); } } } } Handle = FileOpen(FileName,FILE_CSV|FILE_WRITE|FILE_READ,","); if (Handle < 1) { Alert("Error writing to file."); } FileSeek(Handle, 0, SEEK_END); FileWrite(Handle, " ", "Daily Result: ", " ", " ", " ", " ", " ", " ", " ", Profit, Pips, AccountBalance()); FileClose(Handle); }