//+------------------------------------------------------------------+ //| Super_Carry_Trade_ver2.mq4 | //| Zen_Leow | //| | //+------------------------------------------------------------------+ #property copyright "Zen_Leow" #property link "" #include <stdlib.mqh> #include <stderror.mqh> extern int EA_MAGIC_NUM = 511112; extern int StartHour = 19; extern int LadderHeight = 400; extern int CarryBuffer = 200; extern double Slippage = 3.0; extern int TakeProfit = 10; extern int CustomSpread = 9; extern int StopLoss = 0; extern bool MoneyManagement = true; extern double RiskPercent = 0.5; extern double Lots = 0.1; extern double MaxLots = 15.0; extern double MinLots = 0.01; string msg = ""; double CurrentAveragePrice = 0; bool AveragingStarted = false; //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { if( (Symbol()=="EURJPY") || (Symbol()=="EURJPYm") || (Symbol()=="USDJPY") || (Symbol()=="USDJPYm") || (Symbol()=="CHFJPY") || (Symbol()=="CHFJPYm") || (Symbol()=="AUDJPY") || (Symbol()=="AUDJPYm") || (Symbol()=="CADJPY") || (Symbol()=="CADJPYm") || (Symbol()=="NZDJPY") || (Symbol()=="NZDJPYm") || (Symbol()=="GBPJPY") || (Symbol()=="GBPJPYm") || (Symbol()=="SGDJPY") || (Symbol()=="SGDJPYm") ) //---- GetCurrentAveragePrice(); WriteComment(); CheckForAveraging(); //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } void CheckForAveraging() { int total = OrdersTotal(); if (total > 0) { for(int cnt=0;cnt<total;cnt++) { if(OrderSelect(cnt,SELECT_BY_POS)) { if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && (OrderComment()=="SuperCarry_Buy_START "+EA_MAGIC_NUM+" Averager")) { AveragingStarted = true; } } } } else { AveragingStarted = false; } } void WriteComment() { int CurrentHour = TimeHour(TimeCurrent()); msg = ""; msg = msg + "Current Average Position Price: "+CurrentAveragePrice; if (CurrentHour == StartHour) { msg = msg + "\nEA at Work!"; } else { msg = msg + "\nEA sleeping..."; } if (AveragingStarted) { msg = msg + "\nAveraging Started"; } else { msg = msg + "\nNo Averaging... yet."; } Comment(msg); } double GetPositionSize() { double PositionSize = 0; if (MoneyManagement) { PositionSize = ((AccountEquity()/100) * RiskPercent) / (MarketInfo(Symbol(),MODE_LOTSIZE) / AccountLeverage()); } else { PositionSize = Lots; } PositionSize = NormalizeDouble(PositionSize,2); if (PositionSize < MinLots) { PositionSize = MinLots; } if (PositionSize > MaxLots) { PositionSize = MaxLots; } return (PositionSize); } double GetCurrentAveragePrice() { double PositionSizeTotal = 0; double AveragePrice = 0; int total = OrdersTotal(); if (total > 0) { for(int cnt=0;cnt<total;cnt++) { if(OrderSelect(cnt,SELECT_BY_POS)) { if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && (OrderType()==OP_BUY)) { PositionSizeTotal = PositionSizeTotal + OrderLots(); AveragePrice = AveragePrice + (OrderOpenPrice() * OrderLots()); } } } AveragePrice = AveragePrice / PositionSizeTotal; NormalizeDouble(AveragePrice, Digits); CurrentAveragePrice = AveragePrice; } CurrentAveragePrice = AveragePrice; return (AveragePrice); } double GetLowestOfLastLadder(double CurrentPrice) { double LowestPrice = 999999; int total = OrdersTotal(); if (total > 0) { for(int cnt=0;cnt<total;cnt++) { if(OrderSelect(cnt,SELECT_BY_POS)) { if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && (OrderType()==OP_BUY)) { if (OrderOpenPrice() < LowestPrice) { LowestPrice = OrderOpenPrice(); } } } } NormalizeDouble(LowestPrice, Digits); } if (LowestPrice != 999999) { return (LowestPrice); } else { return (CurrentPrice + (LadderHeight * Point)); } } void PlaceLadderTrades(double StartPrice, double EndPrice) { //double EndPrice = StartPrice + (LadderHeight * Point); StartPrice = StartPrice + (TakeProfit * Point) + (CustomSpread * Point); double currentTP = StartPrice + (TakeProfit * Point); NormalizeDouble(EndPrice,Digits); NormalizeDouble(currentTP,Digits); NormalizeDouble(StartPrice,Digits); while (currentTP < EndPrice) { SendOrders (OP_BUYSTOP, GetPositionSize(), StartPrice, Slippage, 0, currentTP, "SuperCarry_Buy", 0); // if this order doesn't open due to whatever factors, forget it and move on. StartPrice = currentTP + (CustomSpread * Point); currentTP = StartPrice + (TakeProfit * Point); NormalizeDouble(currentTP,Digits); NormalizeDouble(StartPrice,Digits); } } bool DecideToOpenTrade(int tradeType, int tradeType2) { int total = OrdersTotal(); if (total > 0) { for(int cnt=0;cnt<total;cnt++) { if(OrderSelect(cnt,SELECT_BY_POS)) { if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && ((OrderType()==tradeType) || (OrderType()==tradeType2))) { if (Time[0] <= OrderOpenTime()) // don't open a new position if we're still on the same candle { return (false); } } } } } // in case trades has already opened and closed within the candle int histotal = OrdersHistoryTotal(); if (histotal > 0) { for(cnt=0;cnt<histotal;cnt++) { if(OrderSelect(cnt,SELECT_BY_POS,MODE_HISTORY)) { if(OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && ((OrderType()==tradeType) || (OrderType()==tradeType2))) { if (Time[0] <= OrderOpenTime()) // don't open a new position if we're still on the same candle { return (false); } } } } } return (true); } bool SendOrders (int PositionType, double LotSize, double PriceToOpen, double Slippage, double SL_Price, double TP_Price, string comments, datetime ExpirationTime) { int ticket, errorType; if (PositionType == OP_BUY) { Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Order: "+Symbol()+", "+PositionType+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green"); ticket=OrderSend(Symbol(),PositionType,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Green); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { Print("BUY order opened : ",OrderOpenPrice()); msg = ticket + ": Buy position opened on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds(); WriteToLogFile(msg); return (true); } } else { errorType = GetLastError(); Print("Error opening BUY order : ", ErrorDescription(errorType)); msg = "CANNOT open BUY position on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds(); WriteToLogFile(msg); return (false); } } if (PositionType == OP_BUYSTOP) { Print("Bid: "+Bid+" Ask: "+Ask+" | Opening Buy Stop Order: "+Symbol()+", "+PositionType+", "+LotSize+", "+PriceToOpen+", "+Slippage+", "+SL_Price+", "+TP_Price+", "+comments+", "+EA_MAGIC_NUM+", "+ExpirationTime+", Green"); ticket=OrderSend(Symbol(),PositionType,LotSize,PriceToOpen,Slippage,SL_Price,TP_Price,comments,EA_MAGIC_NUM,ExpirationTime,Green); if(ticket>0) { if(OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES)) { Print("BUY order opened : ",OrderOpenPrice()); msg = ticket + ": Buy position opened on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds(); WriteToLogFile(msg); return (true); } } else { errorType = GetLastError(); Print("Error opening BUY order : ", ErrorDescription(errorType)); msg = "CANNOT open BUY position on "+Symbol()+" at "+ Day()+"/"+Month()+"/"+Year()+" - "+Hour()+":"+Minute()+":"+Seconds(); WriteToLogFile(msg); return (false); } } return (false); } void CloseAllOrders() { int total = OrdersTotal()-1; int positionType; if (total > 0) { for(int cnt=total;cnt>=0;cnt--) { if(OrderSelect(cnt,SELECT_BY_POS)) { if (OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && OrderType()==OP_BUY) { if (!OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),3)) { OrderError(); } } if (OrderSymbol()==Symbol() && OrderMagicNumber() == EA_MAGIC_NUM && OrderType()==OP_BUYSTOP) // pending orders { if (!OrderDelete(OrderTicket())) { OrderError(); } } } } } } void OrderError() { int iError=GetLastError(); Print("Order:",OrderTicket()," GetLastError()=",iError," ",ErrorDescription(iError)); } void WriteToLogFile(string input) { string filename = "SuperCarryTrade-"+Symbol()+"-"+Day()+"-"+Month()+"-"+Year()+".log"; int handle = FileOpen(filename,FILE_READ|FILE_WRITE); if (handle>1) { FileSeek(handle, 0, SEEK_END); // go to end of file FileWrite(handle, input); FileClose(handle); } } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //---- GetCurrentAveragePrice(); CheckForAveraging(); WriteComment(); int CurrentHour = TimeHour(TimeCurrent()); if (CurrentHour == StartHour) { if(DecideToOpenTrade(OP_BUY,OP_BUYSTOP)) { double PriceToOpen = 0; double LadderEndPrice = 0; if(CurrentAveragePrice != 0 && Bid > CurrentAveragePrice && AveragingStarted) // Finally you can clear your orders!!! { CloseAllOrders(); } GetCurrentAveragePrice(); if(CurrentAveragePrice == 0) // Start a brand new ladder { PriceToOpen = Ask; if (SendOrders(OP_BUY, GetPositionSize(), PriceToOpen, Slippage, 0, PriceToOpen + (TakeProfit*Point), "SuperCarry_Buy_START "+EA_MAGIC_NUM, 0)) { LadderEndPrice = PriceToOpen + (LadderHeight * Point); PlaceLadderTrades(PriceToOpen, LadderEndPrice); } } if(CurrentAveragePrice != 0 && Bid < (CurrentAveragePrice - (CarryBuffer * Point))) // Start the averaging ladder { PriceToOpen = Ask; if (SendOrders(OP_BUY, GetPositionSize(), PriceToOpen, Slippage, 0, 0, "SuperCarry_Buy_START "+EA_MAGIC_NUM+" Averager", 0)) { LadderEndPrice = GetLowestOfLastLadder(PriceToOpen); PlaceLadderTrades(PriceToOpen, LadderEndPrice); } } } } //---- return(0); } //+------------------------------------------------------------------+
Sample
Analysis
Market Information Used:
Series array that contains open time of each bar
Indicator Curves created:
Indicators Used:
Custom Indicators Used:
Order Management characteristics:
Checks for the total of open orders
Checks for the total of closed orders
It automatically opens orders when conditions are reached
It Closes Orders by itself
Other Features:
Uses files from the file system
It writes information to file