Super_Carry_Trade_ver2

Author: Zen_Leow
Orders Execution
Checks for the total of open ordersChecks for the total of closed ordersIt automatically opens orders when conditions are reachedIt Closes Orders by itself
Miscellaneous
Uses files from the file systemIt writes information to file
0 Views
0 Downloads
0 Favorites
Super_Carry_Trade_ver2
//+------------------------------------------------------------------+
//|                                       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);
}
//+------------------------------------------------------------------+

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---