Selasa, 18 Desember 2012

StopAndReverse.mq4, Input manula SL & TP


#property copyright ""
#property link      ""
#include <stdlib.mqh>
#include <stderror.mqh>

//---- input parameters
extern bool      OverruleDirection = true;
extern bool      DirectionLong     = false;
extern bool      StartTimeFilter =false; //Set it to true to allow start trade in EntryTimeHour and EntryTimeMinutes
extern bool      TimeBreak =false;    //Set it to true to set trades on trade only in EntryTimeHour to ExitTimeHour
extern int       EntryTimeHour     = 0;
extern int       EntryTimeMinute   = 0;
extern int       ExitTimeHour      = 23; // Set it equal of lower of
extern int       MaxTrades         = 0;  // Set <= 0 to disable
extern bool    AccountIsMini = true; // Set to true if trading mini account, otherwise set to false
extern bool    threedigit=false;        //set to true if the broker house use 3 decimal digits
extern int     BEP_Level = 0;       //breakeven bail out level  Set <=0 to disable
extern double  BEPpip=0.0;          //the pip you set to break even
extern bool    ProfitProtect=false;  // ONLY set to true when the current profit pip > ProfitProtectpip
extern double  ProfitProtectpip=0.0;
extern bool      StepTrailingStop  = false;   //Set to true to eliminate takeprofit point, exit at Trailing point
extern int       StartStepPip      = 80;
extern int       TrailingStopPip   = 20;
extern bool      TrailOnceStop     = false;
extern bool      TrailingStop      = false;
extern bool       StepStop         = false;   //Using Step Stop
extern double     StepSize        =  5;
extern double     MinDistance     = 10;
extern bool       TakeProfitHold = false;   //when using StepTrailingStop/Stepstop , takeprofit determined by new stop loss if set to TRUE
extern double    Lots       = 0.1;
extern double  Multiplier = 2;      //lots progressive multiplier factor
extern double  LotInc = 0;          //Lot increment on each level
extern int       StopLoss   = 35;
extern int       TakeProfit = 120;
extern int        Slippage = 4;
extern bool      Closeimmediate = false;   //Set to true if close all the trade and halt the system

int Magic;
int LotDigits;
int tic=-1;
static int Level=1;
int initialtrade=0;
int pip;
double plpip;  //total profit and loss pip
static bool Lock = false;  //Lock the EA forever so that it won't take position again even it trigger the reverse point
static bool positivepip,stpositivepip=false;  
int init()
{
  Comment("Waiting for tick");
   if (Symbol() == "AUDCADm" || Symbol() == "AUDCAD") { Magic = 221001; }
   if (Symbol() == "AUDJPYm" || Symbol() == "AUDJPY") { Magic = 221002; }
   if (Symbol() == "AUDNZDm" || Symbol() == "AUDNZD") { Magic = 221003; }
   if (Symbol() == "AUDUSDm" || Symbol() == "AUDUSD") { Magic = 221004; }
   if (Symbol() == "CHFJPYm" || Symbol() == "CHFJPY") { Magic = 221005; }
   if (Symbol() == "EURAUDm" || Symbol() == "EURAUD") { Magic = 221006; }
   if (Symbol() == "EURCADm" || Symbol() == "EURCAD") { Magic = 221007; }
   if (Symbol() == "EURCHFm" || Symbol() == "EURCHF") { Magic = 221008; }
   if (Symbol() == "EURGBPm" || Symbol() == "EURGBP") { Magic = 221009; }
   if (Symbol() == "EURJPYm" || Symbol() == "EURJPY") { Magic = 221010; }
   if (Symbol() == "EURUSDm" || Symbol() == "EURUSD") { Magic = 221011; }
   if (Symbol() == "GBPCHFm" || Symbol() == "GBPCHF") { Magic = 221012; }
   if (Symbol() == "GBPJPYm" || Symbol() == "GBPJPY") { Magic = 221013; }
   if (Symbol() == "GBPUSDm" || Symbol() == "GBPUSD") { Magic = 221014; }
   if (Symbol() == "NZDJPYm" || Symbol() == "NZDJPY") { Magic = 221015; }
   if (Symbol() == "NZDUSDm" || Symbol() == "NZDUSD") { Magic = 221016; }
   if (Symbol() == "USDCHFm" || Symbol() == "USDCHF") { Magic = 221017; }
   if (Symbol() == "USDJPYm" || Symbol() == "USDJPY") { Magic = 221018; }
   if (Symbol() == "USDCADm" || Symbol() == "USDCAD") { Magic = 221019; }
   if (Symbol() == "XAUUSDm" || Symbol() == "XAUUSD") { Magic = 221020; }
   if (Symbol() == "XAGUSDm" || Symbol() == "XAGUSD") { Magic = 221021; }
   if (Magic == 0) { Magic = 221999; }
   LotDigits = 1;
   if (AccountIsMini) { LotDigits = 2; }
  return(0);
}

int deinit()
{
  Comment("");
  return(0);
}

int start()
{
  if(Bars<100)
  {
    Comment("Waiting for bars...");
    return(0);
  }

  return(StopAndReverse(Symbol(),Period(), Magic, Lots, Multiplier, StopLoss, TakeProfit, MaxTrades));
}

bool Visual = true;

#define MAX_CNT 120 // 1 minute

int StopAndReverse(string sym, int per, int magic, double vol, double multi, int sl, int tp, int mt)
{
  // Internals
  int _Digits = MarketInfo(sym, MODE_DIGITS);
  if(_Digits == 0) _Digits = 4;
  double _Point = MarketInfo(sym, MODE_POINT);
  if(NormalizeDouble(_Point, _Digits) == 0.0) _Point = Point;
  double _Bid = MarketInfo(sym, MODE_BID);
  double _Ask = MarketInfo(sym, MODE_ASK);
 
  static double maxlots;  
  static int dir = -1;
  static int reverse = 0;

  // Find trend (override possible and skip Sundays for Monday trend)
 
  //if ((Closeimmediate)||Lock){     //need foward test
  if (Closeimmediate) {
      reverse =0;
      dir =-1;
      tic=-1;
      maxlots=vol;
      positivepip=false;
      stpositivepip=false;
      initialtrade=0;}
  if((dir < 0)&&(!_Rhythm_ActivePosition(sym, magic))){         //if initial EA or Not Connection resume
    maxlots=vol;
    if(OverruleDirection)
      if(DirectionLong)
        dir = OP_BUY;
      else
        dir = OP_SELL;
    else
    {
      if(DayOfWeek() == 1)
        int bs = iBarShift(sym, PERIOD_D1, TimeCurrent()-72*3600);
      else
        bs = 1;
      if(iOpen(sym, PERIOD_D1, bs) < iClose(sym, PERIOD_D1, bs))
        dir = OP_BUY;
      else
        dir = OP_SELL;
    }
    if(dir == OP_BUY)
      reverse = MathRound(_Ask/_Point);
    else
      reverse = MathRound(_Bid/_Point);  
  }
 
 
  bool ct = _Rhythm_CanTrade(sym, magic, mt,tic) && IsTradeAllowed();
  bool tt = _Rhythm_tt(per, EntryTimeHour, ExitTimeHour);
  bool stt = _Rhythm_stt(EntryTimeHour, EntryTimeMinute)||(initialtrade!=0);
  double lot2;
  if (TimeBreak) ct = ct && tt;
  if (StartTimeFilter) ct = ct && stt;
  if((tt||!TimeBreak)&&(stt||!StartTimeFilter))  //Trade in define trading time slot
  {
    // Show message after ending trade
    if((!_Rhythm_ActivePosition(sym, magic))&&(!_Rhythm_CanTrade(sym, magic, mt,tic)))
    {
      for(int j=OrdersHistoryTotal()-1; j >= 0; j--)
         {
            if(OrderSelect(j, SELECT_BY_POS, MODE_HISTORY))
               {
                  if(TakeProfit > 0)
                     {
                        if((StringFind(OrderComment(), "[tp]") >= 0)&&(OrderTicket()==tic))
                           Comment("pip>=TakeProfit" + "\n");
                     }
                  if (TrailingStop||TrailOnceStop||StepTrailingStop)
                     {
                        if((StringFind(OrderComment(), "[sl]") >= 0)&&(OrderTicket()==tic))
                           Comment("Trailing/TrailOnce/StepTrailing Stop hitted" + "\n");
                     }
                  if (ProfitProtect)
                     {
                        if (OrderTicket()==tic)
                           Comment("Profit Protection met" + "\n");
                     }
               }
         }
      if ((Level>=BEP_Level)&&(BEP_Level>0))
         {
            if ((mt>0)&&(Level>=mt))
               {
                  for(int k=OrdersHistoryTotal()-1; k >= 0; k--)
                     {
                        if(OrderSelect(k, SELECT_BY_POS, MODE_HISTORY))
                           {
                              if(StopLoss > 0)
                                 if (OrderTicket()==tic)
                                    if(StringFind(OrderComment(), "[sl]") >= 0)
                                 //if((StringFind(OrderComment(), "[sl]") >= 0)&&(OrderTicket()==tic))
                                       Comment("Level >= BEP Level and Level" + Level + " >= Max Level " + mt + "System Stoplossed. \n");
                                    else Comment ("Level>=BEP_Level and Max Trade reached. Trade Stop at BEP. System will be locked, please reload the EA" + "\n");
                           }
                     }
                  //Comment ("Level>=BEP_Level and Max Trade reached. Trade Stop at BEP. System will be locked, please reload the EA" + "\n");
               }  
            else Comment ("Level>=BEP_Level  System will be locked, please reload the EA" + "\n");
         }
      else if (mt>0)
         {
            if (Level>=mt)
               if(((TrailingStop||TrailOnceStop)&&(positivepip))||((StepTrailingStop)&&(stpositivepip)))
                  Comment("Either TrailingStop/TrailOnceStop/StepTrailingStop hitted. And so do max Level reached. System Locked, please reload the EA" + "\n");
               else Comment ("Level "+ Level +" >= Max level " +mt+"  System will be locked, please reload the EA" + "\n");
         }

    }
    // Find reverse:
    if(_Rhythm_ActivePosition(sym, magic))
      {//Loop #3
       
         string sComment;
         string NL = "\n";
         reverse = MathRound(OrderStopLoss()/_Point);
     
         for (int y=OrdersTotal()-1; y>=0; y--)
            {
               OrderSelect(y, SELECT_BY_POS, MODE_TRADES);
               dir=OrderType();
               Level = MathRound(MathLog((OrderLots()-LotInc)/vol)/MathLog(Multiplier)+1);
               if (Level<=0)
                  Level = 1;
               else Level = Level;
               tic=OrderTicket();
               maxlots = vol*MathPow(Multiplier, Level)+LotInc;
       // calculate the current profit and loss pip
               if (dir== OP_BUY)
                  {
                     if (threedigit)
                        pip=(MathRound(MarketInfo(sym,MODE_BID)/MarketInfo(sym,MODE_POINT))-MathRound(OrderOpenPrice()/MarketInfo(sym,MODE_POINT)))/10;
                     else pip=MathRound(MarketInfo(sym,MODE_BID)/MarketInfo(sym,MODE_POINT))-MathRound(OrderOpenPrice()/MarketInfo(sym,MODE_POINT));
                   
                  }
               else if (dir== OP_SELL)
                  {
                     if (threedigit)
                        pip=(MathRound(OrderOpenPrice()/MarketInfo(sym,MODE_POINT))-MathRound(MarketInfo(sym,MODE_ASK)/MarketInfo(sym,MODE_POINT)))/10;
                     else pip=MathRound(OrderOpenPrice()/MarketInfo(sym,MODE_POINT))-MathRound(MarketInfo(sym,MODE_ASK)/MarketInfo(sym,MODE_POINT));
                                 
                  }    
            }
       
         if (pip>=0)
            positivepip=true;
         if (pip>=StartStepPip)
            stpositivepip=true;  
 //Set the resevse lot size and direction

               //lastsl=reverse;
         if(dir == OP_BUY)
            {
                dir = OP_SELL;
                     //Level = MathRound(MathLog((maxlots-LotInc)/vol)/MathLog(Multiplier)+1);  
                    // maxlots = NormalizeDouble(vol*MathPow(Multiplier, Level)+LotInc, LotDigits);
            }
         else
            {
                dir = OP_BUY;
                     //Level = MathRound(MathLog((maxlots-LotInc)/vol)/MathLog(Multiplier)+1);  
                     //maxlots = NormalizeDouble(vol*MathPow(Multiplier, Level)+LotInc, LotDigits);
            }
           
       
     
    //if(Visual&&_Rhythm_CanTrade(sym, magic, mt))
     
         double loss=0;
         for (int x=Level-1; x>=1;x--)
            {
               loss = loss + (NormalizeDouble(vol*MathPow(Multiplier, x-1)+LotInc, LotDigits)*StopLoss);
      //sComment = "x is " + x + NL;
      //sComment =sComment + "Normalize is " + NormalizeDouble(vol*MathPow(Multiplier, x)+LotInc, LotDigits) +NL;
      //sComment=sComment + "Loss   " + (NormalizeDouble(vol*MathPow(Multiplier, x)+LotInc, LotDigits)*StopLoss) + NL;
      //sComment=sComment + "Current Loss is :   " + loss +NL;
            }
         if (Level==1) plpip = pip *vol ;
         else {
                  plpip = pip *NormalizeDouble(vol*MathPow(Multiplier, Level-1)+LotInc, LotDigits) - loss ;
               }
         if (mt>0)
            if (Level==mt) sComment=sComment + "Last Trading Level." + NL;
               else if ((BEP_Level>0)&&(Level==BEP_Level)) sComment=sComment + "At BEP Level. "  + NL;
                  else sComment=sComment + "Trading times. Reverse at " + DoubleToStr(reverse*_Point, _Digits) + NL;
         sComment=sComment + "Level  " + Level + " Current pip " + pip + NL;
         sComment=sComment + "Total profit and loss pip " + DoubleToStr(plpip,_Digits) + NL;
    //sComment=sComment + "maxlot is " + DoubleToStr(maxlots,_Digits) + NL;
    //sComment=sComment + "AskPrice is " + DoubleToStr(MarketInfo(sym,MODE_ASK),_Digits) + NL;
    //sComment=sComment + "OpenPrice is " + DoubleToStr(OrderOpenPrice(),_Digits) + NL;
         Comment(sComment);
       
       
      }//End of Loop 3
   
  }//End of Loop 1
 
  if((!tt&&TimeBreak)||(!stt&&StartTimeFilter))
    {
      if (initialtrade==0)
         Comment("Outside of trading times ");
      //if (!tt&&TimeBreak)
      else if (!tt&&TimeBreak)
            {
               CloseAllTrades();
               Comment("Outside of trading times");
               reverse = 0;
               dir = -1;
            }      
    }
 
  if(_Rhythm_ActivePosition(sym, magic))
    {
    int z;
    // manage sl/reverse
      if(TrailingStop)
         {
            if(OrderType() == OP_BUY)
               {
                  double nsl = OrderClosePrice()-TrailingStopPip*_Point;
                  if(MathRound((_Bid-OrderStopLoss())/_Point)-TrailingStopPip > 0)
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
                        _ce();
                   
               }
            else
               {
                  nsl = OrderClosePrice()+TrailingStopPip*_Point;
                  if(MathRound((OrderStopLoss()-_Ask)/_Point)-TrailingStopPip > 0)
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Red))
                        _ce();              
               }
         }
      else if(TrailOnceStop)
         {
            nsl = OrderOpenPrice();
            if(OrderType() == OP_BUY)
               {
                  if(MathRound((_Bid-nsl)/_Point)-TrailingStopPip > 0)
                     if(MathRound((nsl-OrderStopLoss())/_Point) != 0)
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
                           _ce();
                        /*
                        if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
                           reverse = MathRound(nsl/_Point);
                        else _ce();
                        */ //reverse pt using previous data which is different to the orignal Rhythm version
               }
            else
               {
                  if(MathRound((nsl-_Ask)/_Point) - TrailingStopPip > 0)
                     if(MathRound((nsl-OrderStopLoss())/_Point) != 0)
                        if(!OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
                        _ce();
                        /*
                        if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
                           reverse = MathRound(nsl/_Point);
                        else _ce();      
                        */
               }
         }
      else if(StepTrailingStop)
         {
            if(OrderType() == OP_BUY)
               {
                  nsl = OrderClosePrice()-TrailingStopPip*_Point;
                  if(MathRound((_Bid-OrderOpenPrice())/_Point)-StartStepPip > 0)
                     if(MathRound((_Bid-OrderStopLoss())/_Point)-TrailingStopPip > 0)
                        if (TakeProfitHold)
                           OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue);
                        else OrderModify(OrderTicket(), OrderOpenPrice(), nsl, 0, OrderExpiration(), Blue);   //TakeProfit judge by trailing stop only

               }
            else
               {
                  nsl = OrderClosePrice()+TrailingStopPip*_Point;
                  if(MathRound((OrderOpenPrice()-_Ask)/_Point)-StartStepPip > 0)
                     if(MathRound((OrderStopLoss()-_Ask)/_Point)-TrailingStopPip > 0)
                        if (TakeProfitHold)
                           OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Red);
                        else OrderModify(OrderTicket(), OrderOpenPrice(), nsl, 0, OrderExpiration(), Red);   //TakeProfit judge by trailing stop only
           
               }
         }
       else if(StepStop)
         {
            if(OrderType() == OP_BUY)
               {
                  nsl = OrderStopLoss();
                  if ( Bid-OrderOpenPrice()>0)
                     {
                     for (z=1;Bid-OrderOpenPrice()>= z*StepSize*Point;z++)
                        {
                           nsl = OrderStopLoss()+ StepSize*Point;
                           if (Bid - nsl >= MinDistance*Point)
                              nsl=nsl;
                           else nsl = OrderStopLoss();
                        }
                   
                     }
                  if (TakeProfitHold)
                     OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue);  
                  else OrderModify(OrderTicket(), OrderOpenPrice(), nsl, 0, OrderExpiration(), Blue);  
               }
            else
               {
                  nsl = OrderStopLoss();
                  if (OrderOpenPrice()-Ask>0)
                     {
                     for (z=1;OrderOpenPrice()-Ask>=z*StepSize*Point;z++)
                        {
                           nsl = OrderStopLoss() - StepSize*Point;
                           if (nsl - Ask >= MinDistance*Point)
                              nsl = nsl;
                           else nsl = OrderStopLoss();
                        }
                     }
                  if (TakeProfitHold)
                     OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Red);
                  else OrderModify(OrderTicket(), OrderOpenPrice(), nsl, 0, OrderExpiration(), Red);
               }
         }
      else if (BEP_Level>0)
         {
            if (Level>=BEP_Level)
               if (plpip>BEPpip)  //Close Ticket at Break Even
                  {
                     if (OrderType() == OP_BUY)
                        OrderClose(OrderTicket(), OrderLots(),  Bid, Slippage, Blue);
                     else if(OrderType() == OP_SELL)
                           OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red);
                          else Comment("Trading error in BEP_LEVEL");
                   
                  }
         }
      else if (ProfitProtect)
         {
               if (plpip<=ProfitProtectpip)  //Close Ticket when reached Profit Protection Pip
                  {
                     if (OrderType() == OP_BUY)
                        OrderClose(OrderTicket(), OrderLots(),  Bid, Slippage, Blue);
                     else if (OrderType() == OP_SELL)
                        OrderClose(OrderTicket(), OrderLots(), Ask, Slippage, Red);
                          else Comment("Trading error in ProfitProtection");
                  }
         }        
    }
 
  return(0);
} //End of int StopAndReverse(....)

bool _Rhythm_CanTrade(string symbol, int magic, int max, int tic)
{
  //Print("Passing Order Ticker is " + tic);
  if (max>0){
    if (Level>=max){
      Lock=true;
      return (false);}
   }
 
  for(int i=OrdersHistoryTotal()-1; i >= 0; i--)
   {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
         {
            if(TakeProfit > 0)
               {
                  if((StringFind(OrderComment(), "[tp]") >= 0)&&(OrderTicket()==tic))
                     {
                        Lock=true;
                        return(false);
                     }
               }
            if(((TrailingStop||TrailOnceStop)&&(positivepip))||((StepTrailingStop)&&(stpositivepip)))
            /* If the option TrailingStop or TrailOncestop open , once have positive pip and meet stop loss point. trade Finish
               If the option StepTrailingStop open, once have positive StepTrailingPip and meet stop loss poing. trade Finish
            */
               {
                  if((StringFind(OrderComment(), "[sl]") >= 0)&&(OrderTicket()==tic))
                     {
                        Lock=true;
                        return(false);
                     }
               }
         }
   }
  /*
  if (pip>=TakeProfit){
      Lock=true;
      return(false);}
  */
  if ((Level>=BEP_Level)&&(BEP_Level>0))
         if (plpip>BEPpip) {
         Lock=true;
         return (false);}
  if (ProfitProtect)
         if (plpip<=ProfitProtectpip) {
         Lock=true;
         return (false);}
  if (Closeimmediate){
   CloseAllTrades();
   return (false);}
 if (Lock) return (false);      
  return(true);
}

bool _Rhythm_ActivePosition(string symbol, int magic)
{
  int i=0;
  for(i=0; i<OrdersTotal(); i++)
    if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)){
      //if(OrderType() <= OP_SELL)
         if(OrderSymbol() == symbol) return(true);
           
    }else
      Print("OrderSelect() error - ", ErrorDescription(GetLastError()));
  //Alert("No more Active Trade");
  return(false);
}

bool _Rhythm_tt(int period, int openh, int closeh)
{
  // Trade times
  datetime st = MathFloor(TimeCurrent()/86400)*86400 + openh*3600;
  datetime en = MathFloor(TimeCurrent()/86400)*86400 + closeh*3600+period*60;
  datetime now = TimeCurrent();
  while(st > now) st -= 86400;
  while(en > now) en -= 86400;
  if(st<en) return(false);
  return(true);
}
bool _Rhythm_stt(int openh, int openmin)
{
  // Trade times
  if ((Hour()==openh)&&(Minute()>=openmin)) return (true);
 
  return(false);
}

bool _ce()
{
  int err=GetLastError();
  if(err != ERR_NO_ERROR){
    Print("Error #", err, " ", ErrorDescription(err));
    return(true);
  }
  return(false);
}

void CloseAllTrades()
{
   int  total = OrdersTotal();
   for (int y=OrdersTotal()-1; y>=0; y--)
   {
      OrderSelect(y, SELECT_BY_POS, MODE_TRADES);
      int type = OrderType();
      bool result = false;
      int  TriesNum = 5;
      int tries=0;
      while (!result && tries < TriesNum)
      {
         RefreshRates();
         switch(type)
         {
            case OP_BUY :
               result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_BID),Slippage,Pink);
               break;
            case OP_SELL:
               result = OrderClose(OrderTicket(),OrderLots(),MarketInfo(OrderSymbol(),MODE_ASK),Slippage,Pink);            
         }          
         tries++;
      }
      if (!result) Print("Error closing order : ",ErrorDescription(GetLastError()));
   }
}
//+---- Programmed by Michal Rutka ----------------------------------+
//Amended by Christopher Lau

Tidak ada komentar:

Posting Komentar