Tuesday 18 December 2012

StopAndReverse.mq4


//+------------------------------------------------------------------+
//|                                                       StopAndReverse.mq4 |
/* Christopher Lau  skyerlcp@yahoo.com.hk
thx Alan Strawbridge for the payment on the mqlservice on Rhythm

Many thanks to Tkimble and FxTraderPro on the ForexFactory for the simple strategy that this
EA is designed to manage.

Name: StopAndReverse    Pair: Any Pair You like.

This is a simple Stop @ Reverse system. It should be able to be used with
Daily trading

Once trade is initiated the stop loss and reversals are equal.
Example: the stop is placed at 40 PIPs and the reversal is likewise placed at 40 PIPs.
When the stop is activated, the reversal is simultaneously activated.  There is no limit on how
many reversals there can be in a day unless Max Trades variable is used

EA- Variables:

Overrule Direction: = True/False EA makes next day trade decision on the basis of the previous Days trend
(i.e.; previous day up, Place "Buy" market order, previous day down, enter "Sell" market order)
Example: Yesterdays open/close positive = LongEntry) (Yesterdays open/close negative = ShortEntry)
00:00 >< 23:55  Set it to False if you want to choose your own initial entry direction

Direction Long: =True/False  this is the manual way to either go Long or Short for your opening trade.
If using this variable Overrule Direction should be set to True

EntryTime Hour: = Entry will execute on the Open of the hour chosen. 00:00 thru 23:00

ExitTime Hour: =  00:00 thru 23:00 Exit will execute on the Open of the preceding bar from exit hour chosen
Example: exit set for 17:00 exit will execute on the open of the 18:00 bar.

Max Trades: = 0=False or 1,2,3,4 etc  Set this variable if you want to limit on how many whipsaws you want in a day or week.
EA will not take anymore trades for current day or week once variable is reached

TrailStop Once: = True/False (If set to True, Stop and Reverse order will move positive one time at
the value of the Stop loss variable)  Example: I am long at 1.2000 and I have my stop set at 1.1960 (-40)
If price was to advance to 1.2040 then my Stop & Reverse orders would move positive to 1.2000 This would be
the only positive move they would make.

Trailing Stop: = True/False (If set to True, Stop and Reverse order will move
every time price moves positive at the value of the Stop loss variable)

Stoploss: = Default 40  "Very important". It is the Value that all Stops will use.
(i.e.; TrailStop Once, Trailing Stop) It is the value that all Stop and Reverse orders are placed.

ProfitTarget: = 0=False, Default 120  If Profit Target or Time exit is not used than trade will remain
open until manually closed or when Profit Target or Time exit is initiated and executed in the future.



*/

// V.1_1   Multi Lot reverse, TimeBreak Function, calculate current pip profit and loss
//V.1_2  Break Even Point Level added  (BEP_Level)
//V 1_3  Fix EA connection resume, the EA will take the job again other than open new trade
// V 1_4  Add Start Time function, the order will start trade after definite hour
// V 1_5  Step Stop the EA will Start Trailing Stop after certain positive pip moved
//V 1_6   Adding BEPpip for specific pip protection abrove BEPLevel; adding ProfitProtect for closing the position if the current p/l drop to profit protection
//v 1_6_2 Adding fractional decimals
#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
  {//Start of Loop 1
    //if(!_Rhythm_ActivePosition(sym, magic))
    //   tempcomment=tempcomment +"Trading times" + "\n" + "Level is : " + Level + "\n";
    //else tempcomment=tempcomment +"Contain Active Position"+ "\n";
    // Check for active position
    int cnt = 0;
    int tries;
    while(!_Rhythm_ActivePosition(sym, magic) && ct &&!Lock)
    { //Start of while loop #2

      lot2=NormalizeDouble(maxlots, LotDigits);
      if(dir == OP_BUY)
         {
            if(ct)
               {
                  _Ask = MarketInfo(sym, MODE_ASK);
                  tries = 0;
                  //if(MathRound(_Ask/_Point) >= reverse)
                  if(MathRound(_Ask/_Point) >= (reverse-Slippage))   //just to easily hit the reverse provided that the stop loss is hitted
                     {
                     if (!GlobalVariableCheck("InTrade"))
                        {
                           while (tries < 3)
                              {
                                 GlobalVariableSet("InTrade", CurTime());  // set lock indicator
                                 tic = OrderSend(sym, dir, lot2, _Ask, Slippage, _sl(dir, sym, sl), _tp(dir, sym, tp),"StopAndReverse", magic, 0, Blue);
                                 GlobalVariableDel("InTrade");   // clear lock indicator
                                 initialtrade=1;
                                 if (tic<=0)
                                    {
                                       _ce();
                                       tries++;
                                    }
                                 else {
                                       Level = MathRound(MathLog((maxlots-LotInc)/vol)/MathLog(Multiplier)+1);
                                       if (Level <=0)  
                                          Level =1;
                                       else Level = Level;
                                       maxlots = vol*MathPow(Multiplier, Level)+LotInc;
                                       tries=3;
                                       }
                              }
                        }
                     }
                  else
                     break;
                  _ce();
               }
         }
       else
         {
            if(ct)
               {
                  _Bid = MarketInfo(sym, MODE_BID);
                  tries = 0;
                  //if(MathRound(_Bid/_Point) <= reverse)
                  if(MathRound(_Bid/_Point) <= (reverse+Slippage))
                     {
                     if (!GlobalVariableCheck("InTrade"))
                        {
                           while (tries < 3)
                              {
                                 GlobalVariableSet("InTrade", CurTime());  // set lock indicator
                                 tic = OrderSend(sym, dir, lot2, _Bid, Slippage, _sl(dir, sym, sl), _tp(dir, sym, tp),"StopAndReverse", magic, 0, Red);
                                 GlobalVariableDel("InTrade");   // clear lock indicator
                                 initialtrade=1;
                                 if (tic<=0)
                                    {
                                       _ce();
                                       tries++;
                                     }
                                     
                                 else {

                                       Level = MathRound(MathLog((maxlots-LotInc)/vol)/MathLog(Multiplier)+1);
                                       if (Level <=0)  
                                          Level =1;
                                       else Level = Level;  
                                       maxlots = vol*MathPow(Multiplier, Level)+LotInc;
                                       tries=3;
                                       }
                              }
                        }
                     }  
                  else
                     break;
                  _ce();
               }
         }
         /*
      Sleep(500);
      cnt++;
      if(cnt >= MAX_CNT)
        break;
        */    
      // Recalculate conditions
      ct = _Rhythm_CanTrade(sym, magic, mt,tic) && IsTradeAllowed();
      //ct = ct && _Rhythm_tt(per, EntryTimeHour, ExitTimeHour);
      if (TimeBreak)
         ct = ct && _Rhythm_tt(per, EntryTimeHour, ExitTimeHour);
      if (StartTimeFilter)
         ct = ct && ((_Rhythm_stt(EntryTimeHour, EntryTimeMinute))||(initialtrade!=0));
    } // End of While Loop #2

    // 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);
                  if (OrderMagicNumber() == magic)
                     {
                        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();
                     /*
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Blue))
                        reverse = MathRound(nsl/_Point);
                      */ //do not need reverse compare with the orignal Rhythm version
                     //else _ce();
               }
            else
               {
                  nsl = OrderClosePrice()+TrailingStopPip*_Point;
                  if(MathRound((OrderStopLoss()-_Ask)/_Point)-TrailingStopPip > 0)
                     if(!OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Red))
                        _ce();
                     /*
                     if(OrderModify(OrderTicket(), OrderOpenPrice(), nsl, OrderTakeProfit(), OrderExpiration(), Red))
                        reverse = MathRound(nsl/_Point);
                      */ //reverse pt using previous data which is different to the orignal Rhythm version
                     //else _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)
            if(OrderMagicNumber() == magic)
               {//Comment ("Trade active \n");
               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);
}

double _sl(int type, string symbol, int stoploss)
{
  if(type == OP_BUY)
    if(stoploss > 0)
      return(MarketInfo(symbol, MODE_BID)-stoploss*MarketInfo(symbol, MODE_POINT)+MarketInfo(symbol, MODE_SPREAD)*MarketInfo(symbol, MODE_POINT));
    else
      return(0.0);
  else if(type == OP_SELL)
    if(stoploss > 0)
      return(MarketInfo(symbol, MODE_ASK)+stoploss*MarketInfo(symbol, MODE_POINT)-MarketInfo(symbol, MODE_SPREAD)*MarketInfo(symbol, MODE_POINT));
    else
      return(0.0);
}

double _tp(int type, string symbol, int takeprofit)
{
  if(type == OP_BUY)
    if(takeprofit > 0)
      return(MarketInfo(symbol, MODE_BID)+takeprofit*MarketInfo(symbol, MODE_POINT)+MarketInfo(symbol, MODE_SPREAD)*MarketInfo(symbol, MODE_POINT));
    else
      return(0.0);
  else if(type == OP_SELL)
    if(takeprofit > 0)
      return(MarketInfo(symbol, MODE_ASK)-takeprofit*MarketInfo(symbol, MODE_POINT)-MarketInfo(symbol, MODE_SPREAD)*MarketInfo(symbol, MODE_POINT));
    else
      return(0.0);
}

void CloseAllTrades()
{
   int  total = OrdersTotal();
   for (int y=OrdersTotal()-1; y>=0; y--)
   {
      OrderSelect(y, SELECT_BY_POS, MODE_TRADES);
      if (OrderMagicNumber() == Magic)
      {
         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





1 comment:

  1. Hello Everyone,

    I've attached a list of the most recommended forex brokers:
    1. Most Recommended Forex Broker
    2. eToro - $50 min. deposit.

    Here is a list of money making forex tools:
    1. ForexTrendy - Recommended Odds Software.
    2. EA Builder - Custom Indicators Autotrading.
    3. Fast FX Profit - Secret Forex Strategy.

    Hopefully these lists are benificial to you...

    ReplyDelete