//+------------------------------------------------------------------+
//|                                                      EMA Cut.mq4 |
//|                                                            Jasus |
//|                                                                  |
//+------------------------------------------------------------------+
#property copyright "roundrock"
#property link      ""


#include <stderror.mqh>
#include <stdlib.mqh>

extern int     base_hour		= 2;

extern int     trade_hour		= 10;


extern double     monthly_target		= 10;

extern double     stoploss_pips		= 20;

extern double     stoploss_pct		= 2.5;

extern double     min_gap_pips		= 9;


extern bool     stop_after_target		= true;


extern int    Slippage         =       3;

 color vline_base_color=Red;
 color vline_trade_color=DodgerBlue;

bool noTrade = false;

extern int    MagicNumber         =  7772811;

int orderCount=0;
int    digits=4;
double pip = 0;

int barsTotal = 0;

double initialBalance;
double monthlyTarget;

double basePrice;

string   ccy;
int      tf;
double   pnt;
 
int init()
  {
  digits=MarketInfo(Symbol(),MODE_DIGITS); 
 
  if (digits < 4)
    pip = 0.01;
  else
    pip = 0.0001;
    
  initialBalance = AccountBalance();
  double monthlyTarget = (initialBalance + initialBalance*monthly_target/100);
  Print("--- MODE_LOTSIZE "+ MarketInfo(Symbol(), MODE_LOTSIZE) + " MODE_LOTSTEP "+MarketInfo(Symbol(), MODE_LOTSTEP) + " initialBalance "+initialBalance+" monthlyTarget "+monthlyTarget);
   
   getLotSize();
  
  ccy = Symbol();
  tf  = Period();
  pnt = MarketInfo(ccy,MODE_POINT);
  digits=MarketInfo(Symbol(),MODE_DIGITS);
//---- indicators
  
   
//---- indicator buffers mapping
   
  
//---- initialization done
   return(0);
  }
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function                       |
//+------------------------------------------------------------------+
int deinit()
  {
//---- TODO: add your code here
   deleteAll();
//----
   return(0);
  }
  

void deleteAll(){
 
 Comment("");
  
      ObjectDelete("TradeComment" ); 
       ObjectDelete("TradeArrow1" );
       
        ObjectDelete("TradeArrow2" );     
      ObjectDelete("Time1" );
      ObjectDelete("Time2" ); 
      ObjectDelete("Time3" ); 
      
      for(int i=0;i<110;i++)
      ObjectDelete("TradeComment"+i );     
     
   }

  



 bool NewBar()
{
   
  
   if(Bars > barsTotal )

   {
      barsTotal = Bars;        
     
    //  Print("........ New Bar ............ "+barsTotal);   
     
      return(true);
   }
  

   return(false);
   
   
}




void CloseTrade()
{
     if(OrdersTotal()==0 && !noTrade){
      string gap = DoubleToStr(MathAbs(basePrice - iOpen(NULL,PERIOD_H1,1))/pip,0);
      Print("======== SL Hit today . GAP "+ gap);       
       writeLog(gap, -22);
    }
    
    for(int i = 0; i < OrdersTotal(); i++)
    {
      OrderSelect(i,SELECT_BY_POS,MODE_TRADES);

      if (OrderMagicNumber() == MagicNumber)
      {        
        
       // Print(" order type "+OrderType() +" ticket "+ OrderTicket());
        if (OrderType() == OP_BUY)
        {
          Comment("In full closure mode.  Closing a ", OrderSymbol(), " buy trade...");
          Print("In full closure mode.  Closing a ", OrderSymbol(), " buy trade...");
          OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_BID),5000,Blue);
          double profit = (MarketInfo(OrderSymbol(), MODE_BID) - OrderOpenPrice())/pip;
          Print("======== Pips P/L For today "+ DoubleToStr(profit,0) + "  GAP "+ DoubleToStr(MathAbs(basePrice - iOpen(NULL,PERIOD_H1,1))/pip,0));
          writeLog(DoubleToStr(MathAbs(basePrice - iOpen(NULL,PERIOD_H1,1))/pip,0), profit);
          Sleep(1000);
        }    
        else
        if (OrderType() == OP_SELL)
        {
          Comment("In full closure mode.  Closing a ", OrderSymbol(), " sell trade...");
          Print("In full closure mode.  Closing a ", OrderSymbol(), " sell trade...");
          OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(), MODE_ASK),5000,Red);
           profit = (-MarketInfo(OrderSymbol(), MODE_ASK) + OrderOpenPrice())/pip;
          Print("======== Pips P/L For today "+ DoubleToStr(profit,1) + "  GAP "+ DoubleToStr(MathAbs(basePrice - iOpen(NULL,PERIOD_H1,1))/pip,0));
          writeLog(DoubleToStr(MathAbs(basePrice - iOpen(NULL,PERIOD_H1,1))/pip,0), profit);
          Sleep(1000);
        }
      }      
      
    }
    
    
    
     
}


void writeLog(string gap, double pl){   
      
                  int h1;
                  h1 = FileOpen("OneTrade.csv", FILE_CSV | FILE_WRITE | FILE_READ, ',');
                  FileSeek(h1, 0, SEEK_END);
                 // FileWrite(h1,pc[i],TimeToStr(TimeCurrent(),TIME_DATE| TIME_SECONDS),"M5"); 
                   FileWrite(h1,TimeToStr(TimeCurrent(),TIME_DATE), gap,pl); 
                  FileClose(h1);
                  
     

}


int start()
  {
      
      int currentBarHour = TimeHour(iTime( NULL, PERIOD_H1, 0));
     
     if(stop_after_target) {
         if(!NewBar() || currentBarHour > trade_hour+1  || AccountBalance() > (initialBalance + initialBalance*monthly_target/100))
            return;
    }else {
         if(!NewBar() || currentBarHour > trade_hour+1)
            return;
    }
    
        
    if(currentBarHour==base_hour){
      basePrice =  iOpen(NULL,PERIOD_H1,0);
    }
      // draw vertical line
         
        ObjectCreate("Time1" ,OBJ_VLINE,0,Time[currentBarHour-base_hour],High[currentBarHour-base_hour]);
        ObjectSet("Time1" ,OBJPROP_COLOR,vline_base_color); // Color value to set/get object color.
       ObjectSet("Time1" ,OBJPROP_STYLE,STYLE_DOT); // Value is one of STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT constants to set/get object line style.
        ObjectSet("Time1" ,OBJPROP_WIDTH,1); // Integer value to set/get object line width. Can be from 1 to 5.
       ObjectSet("Time1" ,OBJPROP_BACK,true);
        
         ObjectCreate("Time3" ,OBJ_HLINE,0,Time[currentBarHour-base_hour],Open[currentBarHour-base_hour]);
        ObjectSet("Time3" ,OBJPROP_COLOR,vline_base_color); // Color value to set/get object color.
        ObjectSet("Time3" ,OBJPROP_STYLE,STYLE_DOT); // Value is one of STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT constants to set/get object line style.
        ObjectSet("Time3" ,OBJPROP_WIDTH,1); // Integer value to set/get object line width. Can be from 1 to 5.
        ObjectSet("Time5" ,OBJPROP_BACK,true);
      //return;
   // }    
    
    if(currentBarHour==trade_hour){
        ObjectCreate("Time2" ,OBJ_VLINE,0,Time[0],High[0]);
        ObjectSet("Time2" ,OBJPROP_COLOR,vline_trade_color); // Color value to set/get object color.
        ObjectSet("Time2" ,OBJPROP_STYLE,STYLE_DOT); // Value is one of STYLE_SOLID, STYLE_DASH, STYLE_DOT, STYLE_DASHDOT, STYLE_DASHDOTDOT constants to set/get object line style.
        ObjectSet("Time2" ,OBJPROP_WIDTH,1); // Integer value to set/get object line width. Can be from 1 to 5.
        ObjectSet("Time2" ,OBJPROP_BACK,true);
        
      placeOrder(iOpen(NULL,PERIOD_H1,0));
      return;
    }
    
    if(currentBarHour ==trade_hour+1){
      CloseTrade();
      noTrade=false;
      return;
    }
    
    
     
     
    }
      
      
      
      double getTargetPips(double lotSize){
      
       double targetDollar = AccountBalance()*monthly_target/100;
       
      // Print("targetDollar "+targetDollar);
       
       double numerator = targetDollar/(lotSize*MarketInfo(Symbol(), MODE_LOTSIZE));
      // Print(" numerator "+numerator);
        double targetPips = numerator/pip;
      // Print(" targetPips "+targetPips);
      
        return(targetPips);
      
      }
      
      
     double getLotSize(){
      
      double balance = AccountBalance();
      if(balance > initialBalance) balance = initialBalance;
      
       double risk =  (balance*stoploss_pct)/100;
       
      // Print("risk "+risk);
       
       double numerator = risk/(stoploss_pips*pip);
     //  Print("numerator "+numerator);
       
       double lotsize = numerator/MarketInfo(Symbol(), MODE_LOTSIZE);
       
    //   Print("lotsize "+lotsize);
       
       lotsize = StrToDouble(DoubleToStr(lotsize,1));
       
     //   Print("lotsize normalized "+lotsize);
       
       return(lotsize);
      
      
      
      
     }
      
     
     void placeOrder(double openPrice){
      
       double LotSize = getLotSize();
       
       bool goLong=true;
       
       if(basePrice==0) basePrice = iOpen(NULL,PERIOD_H1,(trade_hour-base_hour));
       
       
       
       if(openPrice>basePrice) goLong=false;
       
       Print("------- basePrice "+basePrice +" openPrice "+openPrice + " Gap "+ DoubleToStr(MathAbs(basePrice-openPrice)/pip,0));
       
       
       
       if(MathAbs(basePrice-openPrice)/pip < min_gap_pips){
         Print("---------- exiting, no trades today due to small gap ");
         noTrade=true;
         return(0);
       }
       
       if(goLong){
       
         double buyPrice = MarketInfo(Symbol(), MODE_ASK) ;
        
         
         double buySL =  buyPrice-(stoploss_pips*pip);
        
         double buyTP =  buyPrice + (getTargetPips(LotSize)*pip);
        
         string tradeComment= "Buy above "+DoubleToStr(buyPrice,4)+ " stop "+DoubleToStr(buySL,4) + " tp "+DoubleToStr(buyTP,4)+" Lot "+DoubleToStr(LotSize,1);
           
           Print("Placing buy  order at "+buyPrice+" with SL at "+buySL +" buyTP "+buyTP + " LotSize "+LotSize);
           
           // comments
           
           ObjectCreate("TradeComment",OBJ_LABEL,0,0,0);
            ObjectSet("TradeComment",OBJPROP_XDISTANCE,5);
            ObjectSet("TradeComment",OBJPROP_YDISTANCE,40);
            ObjectSetText("TradeComment",tradeComment,14,"Arial",DodgerBlue);
           
           // draw arrow           
                   
          ObjectCreate("TradeArrow1",OBJ_ARROW,0,iTime(ccy,tf,1),iLow(ccy,tf,1)-50*pnt);
          ObjectSet("TradeArrow1",OBJPROP_ARROWCODE,241);
          ObjectSet("TradeArrow1",OBJPROP_COLOR,DodgerBlue);
          ObjectSet("TradeArrow1",OBJPROP_WIDTH,3);
           
         
                                               
          int  ticketlong = OrderSend(Symbol(),OP_BUY,LotSize,NormalizeDouble(buyPrice, digits),
                                      Slippage,0,0,"Long OneTrade",MagicNumber,0,Blue);
                                      
          if (ticketlong < 0) {
              int check=GetLastError();
               if(check!=0) Print("Long OrderSend OP_BUY failed with error: ",ErrorDescription(check));  
              return;
          }
            Sleep(3000);  
            
            
            
          
           int ticketlong1 = OrderModify(ticketlong,OrderOpenPrice(),NormalizeDouble(buySL, digits),NormalizeDouble(buyTP, digits),0,Blue);
            Sleep(1000);
            
           // Print("ticketlong1 "+ticketlong1);
          
             if (ticketlong1 < 1) {
             // Print("Long OrderModify failed with error #",GetLastError()); 
               check=GetLastError();
              // Print("check "+check);
               if(check!=0) Print("Long OrderModify failed with error: ",ErrorDescription(check));
            }
            
           
       
       }else{
       
          double sellPrice = MarketInfo(Symbol(), MODE_BID) ;
         
         double sellSL =  sellPrice +(stoploss_pips*pip);
        
         double sellTP =  sellPrice - (getTargetPips(LotSize)*pip);
        
           
           Print("Placing sell  order at "+sellPrice+" with SL at "+sellSL +" sellTP "+sellTP + " LotSize "+LotSize);
           
             tradeComment= "Sell below "+DoubleToStr(sellPrice,4)+ " stop "+DoubleToStr(sellSL,4) + " tp "+DoubleToStr(sellTP,4)+" Lot "+DoubleToStr(LotSize,1);
         
           
            // comments
           
           ObjectCreate("TradeComment",OBJ_LABEL,0,0,0);
            ObjectSet("TradeComment",OBJPROP_XDISTANCE,5);
            ObjectSet("TradeComment",OBJPROP_YDISTANCE,40);
            ObjectSetText("TradeComment",tradeComment,14,"Arial",Red);
           
           // draw arrow           
                   
          ObjectCreate("TradeArrow2",OBJ_ARROW,0,iTime(ccy,tf,1),iHigh(ccy,tf,1)+50*pnt);
          ObjectSet("TradeArrow2",OBJPROP_ARROWCODE,242);
          ObjectSet("TradeArrow2",OBJPROP_COLOR,Red);
          ObjectSet("TradeArrow2",OBJPROP_WIDTH,3);
         
                                               
          int  ticketshort = OrderSend(Symbol(),OP_SELL,LotSize,NormalizeDouble(sellPrice, digits),
                                      Slippage,0,0,"Short OneTrade",MagicNumber,0,Red);
                                      
          if (ticketshort < 0) {
               check=GetLastError();
               if(check!=0) Print("Short OrderSend OP_SELL failed with error: ",ErrorDescription(check));  
              return;
          }
            Sleep(3000);  
            
            
            
          
           int ticketshort1 = OrderModify(ticketshort,OrderOpenPrice(),NormalizeDouble(sellSL, digits),NormalizeDouble(sellTP, digits),0,Red);
            Sleep(1000);
            
           // Print("ticketlong1 "+ticketlong1);
          
             if (ticketshort1 < 1) {
             // Print("Long OrderModify failed with error #",GetLastError()); 
               check=GetLastError();
              // Print("check "+check);
               if(check!=0) Print("Short OrderModify failed with error: ",ErrorDescription(check));
            }
       
       
       
       }
     
     
     }
  
   
   