//+-------------------------------------------------------------------+ //| 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=-6; // 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); }
Sample
Analysis
Market Information Used:
Series array that contains the highest prices of each bar
Series array that contains the lowest prices of each bar
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
It automatically opens orders when conditions are reached
Checks for the total of open orders
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 issuies visual alerts to the screen
It writes information to file