
#include <WinUser32.mqh>
#include <stderror.mqh>
#include <stdlib.mqh>

#property copyright "Risdyanto"


int ticket = 0;
double Price[2];
double buy_sl, sell_sl;
int    giSlippage;
int ticket_r3, ticket_r2, ticket_r1, ticket_s3, ticket_s2, ticket_s1 = 0;
int cmt_r3, cmt_r2, cmt_r1, cmt_s3, cmt_s2, cmt_s1 = 0;
int order_type = -1;

int ExpertID = 778899;
bool     Auto=TRUE; 
extern double StopLoss = 50.0;
extern int Trailing_Stop=35;
extern int StartTrail=35;
extern int Target_Profit = 500;
extern double LotSize = 1;
extern bool useStopLoss = true;
extern int Slippage = 1;
extern int Time_when_day_ends = 0;
extern string On_the_end_of_day = "What to do on the end of the day?";
extern bool CloseOpenOrders = false;
extern bool ClosePendingOrders = true;
extern color clOpenBuy = CLR_NONE;
extern color clSellBuy = CLR_NONE;
color ExitLongColor = CLR_NONE;
color ExitShortColor = CLR_NONE;
extern string BuyComment = "Gartley-BUY";
extern string SellComment = "Gatley-SELL";
int maxDD=0;
double NewPrice;
double fm;
double min_lot,Lot,balanc1;
 int deinit()
  {
//----
   ObjectsDeleteAll();
//----
   return(0);
  }
//----------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
int start()
  {if (Auto==true){Auto();}
//----
   int MagicNumber = MakeMagicNumber();
    double s3 = NormalizeDouble(ObjectGet("BUY", OBJPROP_PRICE1), Digits);
    double r3 = NormalizeDouble(ObjectGet("SELL", OBJPROP_PRICE1), Digits);
    
    if (AccountBalance()-AccountEquity() > maxDD) maxDD=AccountBalance()-AccountEquity();
    
   //Comment("Hour: ", Hour(), " - Time_when_day_ends: ",Time_when_day_ends);
   int iOrders=OrdersTotal()-1, i;
   if(Hour()==Time_when_day_ends) {
      Comment("End of the day, EA is relaxing and closing the trades :)");
      if (CloseOpenOrders) {
         //Comment("Deleting open orders with MagicNumber: ",MagicNumber);
         for(i=iOrders; i>=0; i--) {
            if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderMagicNumber() == MagicNumber)) {
              if((OrderType()<=OP_SELL) && GetMarketInfo()) {
                if(!OrderClose(OrderTicket(),OrderLots(),Price[1-OrderType()],giSlippage)) Alert(ErrorDescription(GetLastError()));
              }
            }
          }
      }
      if (ClosePendingOrders) {
         //Comment("Deleting pending orders with MagicNumber: ",MagicNumber);
         for(i=iOrders; i>=0; i--) {
            if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES) && (OrderMagicNumber() == MagicNumber)) {
              if(OrderType()>OP_SELL) {
                if(!OrderDelete(OrderTicket())) Alert(ErrorDescription(GetLastError()));
              }
            }
         }
      }
      return(0);
   }

if (CountShorts(MagicNumber)!= 0 && CountLongs(MagicNumber)!= 0) {      return(0);   }
 //=================================================================================================== 
   double st=Bid-50*Point;
   double bt=Bid+50*Point;
  // if(OrdersTotal()==0)
  // {
   if 
   (
   (r3>0) 
   && (Open[0]>Open[1]) &&(Open[1]>Open[2]))
   // && (Open[2]> Open[3])&&(Open[3]>Open[4]))
   if (OrderSelect(ticket_r3, SELECT_BY_TICKET, MODE_TRADES) == false) 
  // if (OrderSelect(ticket_r2, SELECT_BY_TICKET, MODE_TRADES) == false) 
     {
   //    ticket_r3 = OrderSend(Symbol(),OP_SELLLIMIT,Lot,r3,Slippage,r3+StopLoss*Point,0,SellComment,MagicNumber,0,clSellBuy);
     //  ticket_r3 = OrderSend(Symbol(),OP_BUYSTOP,LotSize,bt,Slippage,bt-StopLoss*Point,0,SellComment,MagicNumber,0,clSellBuy);
     //  ticket_r3 = OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+StopLoss*Point,0,SellComment,MagicNumber,0,clSellBuy);
     //  ticket_r3 = OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-StopLoss*Point,0,BuyComment,MagicNumber,0,clSellBuy);
         ticket_r3 = OrderSend(Symbol(),OP_SELLSTOP,LotSize,st,Slippage,st+StopLoss*Point,0,BuyComment,MagicNumber,0,clSellBuy);
      
      if (ticket_r3 || ticket_r2 < 0) 
         {Alert("Open SELL order error: ", ErrorDescription(GetLastError()));}
   }
   //}
   
   if (OrderSelect(ticket_r3, SELECT_BY_TICKET, MODE_TRADES) == true) {
      if(OrderType()==OP_SELL)
        {  
          if(Bid<OrderOpenPrice()-Point*StartTrail) 
              {                 
               if((OrderOpenPrice()-Ask)>(Point*Trailing_Stop))
                 {
                  if((OrderStopLoss()>(Ask+Point*Trailing_Stop)) || (OrderStopLoss()==0))
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Ask+Point*Trailing_Stop,OrderTakeProfit(),0,Red);
                     return(0);
                    }
                 }
              }
         }
        // if (OrdersTotal()>0&& r3 < 1)CloseAll();
        if (s3>0)CloseAll();
       
         cmt_r3=OrderCloseTime();
         if(cmt_r3>0) { // checa se a ordem foi fechada
           ticket_r3 = 0;
           cmt_r3 = 0;
         }
   }
   
//====================================================================================================================
   double rt=Ask+50*Point;
   double vt=Ask-50*Point;
   //if(OrdersTotal()==0)
   //{
   if 
   (
   (s3>0)
   && (Open[0]<Open[1]) &&(Open[1]<Open[2]))
   // && (Open[2] <Open[3])&&(Open[3]<Open[4]))
   if (OrderSelect(ticket_s3, SELECT_BY_TICKET, MODE_TRADES) == false)
  //  if (OrderSelect(ticket_s2, SELECT_BY_TICKET, MODE_TRADES) == false)
   {
    //  ticket_s3 = OrderSend(Symbol(),OP_BUYLIMIT,Lot,s3,Slippage,s3-StopLoss*Point,0,BuyComment,MagicNumber,0,clSellBuy);
     // ticket_s3 = OrderSend(Symbol(),OP_SELLSTOP,LotSize,vt,Slippage,vt+StopLoss*Point,0,BuyComment,MagicNumber,0,clSellBuy);
    //  ticket_s3 = OrderSend(Symbol(),OP_BUY,LotSize,Ask,Slippage,Ask-StopLoss*Point,0,BuyComment,MagicNumber,0,clSellBuy);
    //  ticket_s3 = OrderSend(Symbol(),OP_SELL,LotSize,Bid,Slippage,Bid+StopLoss*Point,0,SellComment,MagicNumber,0,clSellBuy);
        ticket_s3 = OrderSend(Symbol(),OP_BUYSTOP,LotSize,rt,Slippage,rt-StopLoss*Point,0,SellComment,MagicNumber,0,clSellBuy);
    
      if (ticket_s3 || ticket_s2< 0) 
      {Alert("Open BUY order error: ", ErrorDescription(GetLastError())); }
   }
   //}
   
  if (OrderSelect(ticket_s3, SELECT_BY_TICKET, MODE_TRADES) == true) {
      if(OrderType()==OP_BUY)
         {
            if(Ask>OrderOpenPrice()+Point*StartTrail) 
              {                 
               if(Bid-OrderOpenPrice()>Point*Trailing_Stop)
                 {
                  if(OrderStopLoss()<Bid-Point*Trailing_Stop)
                    {
                     OrderModify(OrderTicket(),OrderOpenPrice(),Bid-Point*Trailing_Stop,OrderTakeProfit(),0,Green);
                     return(0);
                    }
                 }
              }
         }
    //  if (OrdersTotal()>0 && s3 < 1)CloseAll();
      if (r3  >0 )CloseAll();  
          cmt_s3=OrderCloseTime();
          if(cmt_s3>0) { // checa se a ordem foi fechada
             ticket_s3 = 0;
             cmt_s3 = 0;
         }
   }
   double   point=MarketInfo(Symbol(),MODE_POINT);
   for(int w=0;w<OrdersTotal();w++) 
    {
    if (OrderSelect(w,SELECT_BY_POS,MODE_TRADES)==true)
      { 
      if(OrderType()==OP_BUYSTOP)             
        {NewPrice=OrderOpenPrice()-Trailing_Stop*point;fm=OrderModify(OrderTicket(),NewPrice,OrderStopLoss( ) -Point*Trailing_Stop,0,0,CLR_NONE);}
      if(OrderType()==OP_SELLSTOP)
        {NewPrice=OrderOpenPrice()+Trailing_Stop*point;fm=OrderModify(OrderTicket(),NewPrice,OrderStopLoss( ) +Point*Trailing_Stop,0,0,CLR_NONE);}
     
      }
    }
  // Comment("Max DrawDown: ", maxDD);
    if(getProfit()>=Target_Profit){CloseAll();}
   return(0);
  }
//+------------------------------------------------------------------+
//| Calculate concurrent Long position                               |
//+------------------------------------------------------------------+
int CountLongs(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if( OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_BUY || OrderType()==OP_BUYSTOP || OrderType()==OP_BUYLIMIT)
   count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Calculate concurrent short position                              |
//+------------------------------------------------------------------+
int CountShorts(int MagicNumber)
{
 int count=0;
 int trade;
 int trades=OrdersTotal();
 for(trade=0;trade<trades;trade++)
 {
  OrderSelect(trade,SELECT_BY_POS,MODE_TRADES);
  
  if(OrderSymbol()!=Symbol() || OrderMagicNumber() != MagicNumber )
   continue;
   
  if(OrderType()==OP_SELL || OrderType()==OP_SELLSTOP || OrderType()==OP_SELLLIMIT)
  count++;
 }//for
 return(count);
}
//+------------------------------------------------------------------+
//| Function..: GetMarketInfo                                        |
//| Returns...: bool Success.                                        |
//+------------------------------------------------------------------+
bool GetMarketInfo() {
  RefreshRates();
  Price[0]=MarketInfo(OrderSymbol(),MODE_ASK);
  Price[1]=MarketInfo(OrderSymbol(),MODE_BID);
  double dPoint=MarketInfo(OrderSymbol(),MODE_POINT);
  if(dPoint==0) return(false);
  giSlippage=(Price[0]-Price[1])/dPoint;
  return(Price[0]>0.0 && Price[1]>0.0);
}

//+------------------------------------------------------------------+
//| Make Magic Number                                                |
//+------------------------------------------------------------------+
int MakeMagicNumber()
{
   int SymbolCode  = 0;
   int PeriodCode  = 0;
   int MagicNumber = 0; 
   
   //---- Symbol Code
        if( Symbol() == "AUDCAD" || Symbol() == "AUDCADm" ) { SymbolCode = 1000; }
   else if( Symbol() == "AUDJPY" || Symbol() == "AUDJPYm" ) { SymbolCode = 2000; }
   else if( Symbol() == "AUDNZD" || Symbol() == "AUDNZDm" ) { SymbolCode = 3000; }
   else if( Symbol() == "AUDUSD" || Symbol() == "AUDUSDm" ) { SymbolCode = 4000; }
   else if( Symbol() == "CHFJPY" || Symbol() == "CHFJPYm" ) { SymbolCode = 5000; }
   else if( Symbol() == "EURAUD" || Symbol() == "EURAUDm" ) { SymbolCode = 6000; }
   else if( Symbol() == "EURCAD" || Symbol() == "EURCADm" ) { SymbolCode = 7000; }
   else if( Symbol() == "EURCHF" || Symbol() == "EURCHFm" ) { SymbolCode = 8000; }
   else if( Symbol() == "EURGBP" || Symbol() == "EURGBPm" ) { SymbolCode = 9000; }
   else if( Symbol() == "EURJPY" || Symbol() == "EURJPYm" ) { SymbolCode = 1000; }
   else if( Symbol() == "EURUSD" || Symbol() == "EURUSDm" ) { SymbolCode = 1100; }
   else if( Symbol() == "GBPCHF" || Symbol() == "GBPCHFm" ) { SymbolCode = 1200; }
   else if( Symbol() == "GBPJPY" || Symbol() == "GBPJPYm" ) { SymbolCode = 1300; }
   else if( Symbol() == "GBPUSD" || Symbol() == "GBPUSDm" ) { SymbolCode = 1400; }
   else if( Symbol() == "NZDJPY" || Symbol() == "NZDJPYm" ) { SymbolCode = 1500; }
   else if( Symbol() == "NZDUSD" || Symbol() == "NZDUSDm" ) { SymbolCode = 1600; }
   else if( Symbol() == "USDCAD" || Symbol() == "USDCADm" ) { SymbolCode = 1700; }
   else if( Symbol() == "USDCHF" || Symbol() == "USDCHFm" ) { SymbolCode = 1800; }
   else if( Symbol() == "USDJPY" || Symbol() == "USDJPYm" ) { SymbolCode = 1900; }
                     
   //---- Calculate MagicNumber
   MagicNumber = ExpertID+SymbolCode;
   return(MagicNumber);
}
/*
int DeletePending()
{int    i,Pos,Error;
  int total  = OrdersTotal();
   bool   Result;
  for (int cnt = total-1 ; cnt >= 0 ; cnt--)
  { OrderSelect(cnt,SELECT_BY_POS,MODE_TRADES);
  {Pos=OrderType();
 // if (OrderType()==OP_BUYLIMIT)   {OrderDelete(OrderTicket());}
  //if (OrderType()==OP_SELLLIMIT)  {OrderDelete(OrderTicket());}
  if((Pos==OP_BUYSTOP)||(Pos==OP_SELLSTOP)||(Pos==OP_BUYLIMIT)||(Pos==OP_SELLLIMIT))
         {Result=OrderDelete(OrderTicket(), CLR_NONE);}
   if(Result!=true) 
          { 
             Error=GetLastError(); 
             Print("LastError = ",Error); 
          }
         else Error=0;
  }}
  return(0);
}*/
//----------------------------------------------
void CloseAll()
{  RefreshRates();ObjectsDeleteAll();
   bool   Result;
   int    i,Pos,Error;
   int    Total=OrdersTotal();
   
   if(Total>0)
   {
     for(i=Total-1; i>=0; i--) 
     {
       if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES) == TRUE) 
       {
         Pos=OrderType();
         if(Pos==OP_BUY)
         {Result=OrderClose(OrderTicket(), OrderLots(), Bid, Slippage, CLR_NONE);}
         if(Pos==OP_SELL)
         {Result=OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, CLR_NONE);}
         if((Pos==OP_BUYSTOP)||(Pos==OP_SELLSTOP)||(Pos==OP_BUYLIMIT)||(Pos==OP_SELLLIMIT))
         {Result=OrderDelete(OrderTicket(), CLR_NONE);}
//-----------------------
         if(Result!=true) 
          { 
             Error=GetLastError(); 
             Print("LastError = ",Error); 
          }
         else Error=0;
//-----------------------
       }   
     }
   }
   return(0);
}
//---------------------------------------------------------------------------         
double getProfit()
{
   double Profit = 0;
   for (int TradeNumber = OrdersTotal(); TradeNumber >= 0; TradeNumber--)
   {
     if (OrderSelect(TradeNumber, SELECT_BY_POS, MODE_TRADES))
     Profit = Profit + OrderProfit() + OrderSwap()+OrderCommission();
   }
   return (Profit);
}
//---------------------------------------------------------------------------   
void Auto()
{
 min_lot=MarketInfo(Symbol(),MODE_MINLOT);
 //----- 
 balanc1= AccountEquity()/2;
 if(AccountBalance()<balanc1){Lot=0;}
 if(AccountBalance()>balanc1)    {Lot=min_lot;}
 if(AccountBalance()>balanc1*6)  {Lot=min_lot*2;}
 if(AccountBalance()>balanc1*9)  {Lot=min_lot*3;}
 if(AccountBalance()>balanc1*15)  {Lot=min_lot*4;}
 if(AccountBalance()>balanc1*30) {Lot=min_lot*5;}
 if(AccountBalance()>balanc1*15) {Lot=min_lot*2;}
 if(AccountBalance()>balanc1*18) {Lot=min_lot*2;}
} 