// it is against copyright to publish this EA outside of www.stevehopwoodforex.com
#define  version "milaneseAPTM EA 2.18" //new build anOtherAllPairTradeManager 
#property strict
#property copyright "Copyright 2016, milanese"
#property link      "http://www.stevehopwoodforex.com/phpBB3/index.php"
#include <WinUser32.mqh>
#include <stdlib.mqh>
#define  NL    "\n"

#import "user32.dll"
int GetAncestor(int hWnd,int gaFlags);
int PostMessageA(int hWnd,int msg,int wParam,string IpWindow);
#import
int windowHdlFound;
bool expertsDisabeled=false;
//Error reporting
#define  slm " stop loss modification failed with error "
#define  tpm " take profit modification failed with error "
#define  ocm " order close failed with error "
#define  odm " order delete failed with error "
#define  pcm " part close failed with error ";
string          Gap,ScreenMessage;

extern string gen="---General Settings---";
extern bool    showUserDisplay=false;
extern bool    showDisplayBox=false;
extern color   displayBoxBackgroundColour=clrDimGray;
extern bool    enableCloseAllButton=true;
extern bool   NotDeletePendingOrdersWithCloseAll=false;
extern bool    showAlerts=false;
extern bool    DoNeverUseATR=false;
extern int    checkSeconds=1;
extern string genmang="---General Trade-Management Settings---";
extern string genmang1="---ManageAllOpenTrades overwrites all others---";
extern bool     ManageAllOpenTrades=false;
extern string genmang2="---Manage only By selections---";
extern bool     ManageByMagicNumber=true;
extern int      MagicNumber=7777;
extern bool     ManageByTicketNumber=false;
extern int      TicketNumber=0;
extern bool     ManageByOrderComment=false;
extern string   orderComment="";
extern bool     ManageOnlyActualSymbol=true;
extern string   gen1="----doNotManagePositionsOpenedBefore inputs----";
extern bool     doNotManagePositionsOpenedBefore=false;
extern string   gen2="----Enter in Format YYYY.MM.DD----";
extern string   doNotDate="";
extern string   gen3="----SL & TP Settings----";
extern bool     SetInitialStopLoss=false;
extern string   SLset1="---ATR true will override other settings----";
extern bool    useATRForStopLoss=true;
extern int     atrForStopLossTF=PERIOD_D1;
extern double  atrMultiplicatorForStopLoss=1;
extern int     atrPeriodForStopLoss=14;
extern double  SL=100;
extern string   SLset2="---MA as SL  Settings----";
extern string   SLset3="---this will set the MA as SL----";
extern string   SLset4="---this will disable all incompatible settings----";
extern string   SLset5="---like ATR-SL,SetBEandJump automatic----";
extern bool     useMAasSL=false;
extern int      MaTimeFrame=240;
extern int      MaPeriod = 55;
extern int      MaMethod = MODE_SMA;
extern int      MaAppliedPrice = PRICE_CLOSE;
extern int      MaShift=1;
extern bool     SetInitialTakeProfit=false;
extern string   TPSet1="---ATR true will override other settings----";
extern bool    useATRForTakeProfit=false;
extern int     atrForTakeProfitTF=PERIOD_D1;
extern double  atrMultiplicatorForTakeProfit=3.0;
extern int     atrPeriodForTakeProfit=14;
extern double  TP=150;
extern string   partSet="---PartClose inputs----";
extern bool    PartCloseEnabled=true;
extern double   PartClosePercent=10;
extern bool    PartCloseWithBE=false;
extern bool    PartCloseAsFirstTP=true;
extern bool    SetBEonPartCloseFirstTP=false;
extern string   partSet1="---ATR true will override other settings----";
extern bool    useATRForPartClosePips=true;
extern int     atrForPartClosePipsTF=PERIOD_D1;
extern double  atrMultiplicatorForPartClosePips=0.5;
extern int     atrPeriodForPartClosePips=14;
extern double  PartCloseFirstTpPips=25;
extern string   bejsSet="---BE & JS inputs----";
extern bool    Use_SetBEAndJump=true;
extern bool    MoveSLOnlyIfWin=true;
extern double  BEProfit=4;
extern double  JumpStep=15;
extern string   bejsSet1="---ATR true will override other settings----";
extern bool    useATRForSLMinDistanceToPrice=true;
extern int     atrForSLMinDistanceToPriceTF=PERIOD_D1;
extern double  atrMultiplicatorForSLMinDistanceToPriceBE=1;
extern double  atrMultiplicatorForSLMinDistanceToPriceJS=1.5;
extern int     atrPeriodForSLMinDistanceToPrice=14;
extern double  SLMinDistanceToPriceBE=45;
extern double  SLMinDistanceToPriceJS=65;
extern string   ClSets="---Close at a defined time inputs(all using BrokerTime)----";
extern string   fixTimeClSet="---Close at this time all open trades(uses BrokerTime)----";
extern bool    UseCloseAllAtDefinedTime=false;
extern int     CloseHour=21;
extern int     CloseMinute=15;
extern string   fridayClSet="---FridayClose inputs(uses BrokerTime)----";
extern bool    UseCloseFriday=false;
extern int     FridayCloseHour=21;
extern int     FridayCloseMinute=15;
extern int     mXdist = 80,
               mYdist = 14;
extern double  mBEdist = 1;               

double  SLMinDistanceToPrice=45;
double MASLMinDistanceToPrice=20;
double minDistanceSLTP=5;
int             a=0;
bool   debugTheEA=false;
bool     moveSLonlyIfInTradeDirection=true;
double          ask=0;
double          bid=0;

string         BE_Value,symbol;
int             eDigits;
bool ForceTradeClosureBasket=false;
bool   disableExpertsAfterClose=true;
string          CommentOfOrderInitial="";
double factor,adr;
bool TradeHasPartClosed=false;
int TicketNo=-1;
string           InpName="Button";            // Button name
ENUM_BASE_CORNER InpCorner=CORNER_RIGHT_UPPER;// Chart corner for anchoring
string           InpFont="Arial";             // Font
int              InpFontSize=12;              // Font size
color            InpColor=clrWhite;           // Text color
color            InpBackColor=clrRed; // Background color
color            InpBorderColor=clrAntiqueWhite;      // Border color
bool             InpState=false;              // Pressed/Released
bool             InpBack=false;               // Background object
bool             InpSelection=false;          // Highlight to move
bool             InpHidden=true;              // Hidden in the object list
long             InpZOrder=0;                 // Priority for mouse click
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit(void)
  {

   if(checkSeconds==0) checkSeconds=1;
   if(ManageAllOpenTrades==true)
     {
      ManageByMagicNumber=false;
      ManageByOrderComment=false;
      ManageByTicketNumber=false;
      ManageOnlyActualSymbol=false;
     }
   if(MoveSLOnlyIfWin==false)
     {

      PartCloseWithBE=false;
      SetBEonPartCloseFirstTP=false;
      Alert("APTM:Note BE with PartClose set to false, as you are using'MoveSLOnlyIfWin==false'");
     }
     if (useMAasSL==true){
     
     Use_SetBEAndJump=false;
     SetInitialStopLoss=false;
     useATRForStopLoss=false;
     PartCloseWithBE=false;
     
     }
   CommentOfOrderInitial=orderComment;
   if(IsDllsAllowed()==false)
     {
      Alert("APTM"+": *.dll import must be allowed!");
     }
   windowHdlFound=GetAncestor(WindowHandle(Symbol(),Period()),3);
   if(windowHdlFound<=0)
     {
      disableExpertsAfterClose=false;
      Alert("APTM"+": disableExpertsAfterClose does not work, mt4 window handle not found!");
     }
   if(!IsExpertEnabled())
     {
      Alert("APTM"+": Please enable \"Expert Advisors\" in the top toolbar of Metatrader to run this EA");
     }
   if(!IsTradeAllowed())
     {
      Alert("APTM"+": Trade is not allowed. EA cannot run. Please check \"Allow live trading\" in the \"Common\" tab of the EA properties window");
     }

   if(doNotManagePositionsOpenedBefore==true)
     {
      if(doNotDate!="")
        {
         if(showAlerts==true) Alert("APTM"+": EA will not manage orders opened before : ",doNotDate);
        }
      else doNotManagePositionsOpenedBefore=false;

     }
   while(IsConnected()==false)
     {
      Comment("APTM"+":Waiting for MT4 connection...");

      Sleep(1000);
     }//while (IsConnected()==false)

   ChartSetInteger(ChartID(),CHART_FOREGROUND,false);
   EventSetTimer(checkSeconds);
   OnTimer();
   CreateBE();

   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| expert deinitialization function                                 |
//+------------------------------------------------------------------+

void OnDeinit(const int reason)
  {
   Comment("");
   EventKillTimer();
   ObjectDelete("messageBox");
   ObjectDelete(0,InpName);
   if(showAlerts==true) Alert(__FUNCTION__,"_UninitReason = ",getUninitReasonText(_UninitReason));
  }
//+------------------------------------------------------------------+
//| expert start function                                            |
//+------------------------------------------------------------------+
void OnTick()
  {

   if(debugTheEA==true || ManageOnlyActualSymbol==true) OnTimer();
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTimer()
  {
   factor=0;
   TicketNo=-1;
   int lenght = 150;
   int height = 45;
   if(a==0)
     {
      Comment("Waiting for Initializing...");
      Sleep(2000);
      if(showUserDisplay==true)
        {
         DisplayUserFeedback();
        }
      else
        Comment("");
      a=1;

     }
   if(enableCloseAllButton)
     {

      if(ObjectFind(InpName)<0)
        {
         if(!ButtonCreate(0,InpName,0,200,80,lenght,height,InpCorner,"CloseALL!",InpFont,InpFontSize,InpColor,InpBackColor,InpBorderColor,InpState,InpBack,InpSelection,InpHidden,InpZOrder))
           {
            Print("APTM:ButtonCreate Error 34562");
           }
        }

        }else {ObjectDelete(0,InpName);
     }
   if(showUserDisplay==true)
     {
      DisplayUserFeedback();
     }

   for(int cc=OrdersTotal()-1; cc>=0; cc--)
     {

      if(!OrderSelect(cc,SELECT_BY_POS,MODE_TRADES)) continue;
      if((ManageByMagicNumber==true) && (OrderMagicNumber()!=MagicNumber)) continue;
      if((ManageByTicketNumber==true) && (OrderTicket()!=TicketNumber))continue;
      if((ManageOnlyActualSymbol==true) && (OrderSymbol()!=Symbol()))continue;
      if((ManageByOrderComment==true) && ((OrderComment()!=orderComment) || (OrderComment()!=CommentOfOrderInitial)))continue;
      if(doNotManagePositionsOpenedBefore==true)
        {
         string var1=TimeToStr(OrderOpenTime(),TIME_DATE);

         if(StrToTime(var1)<StrToTime(doNotDate)) continue;
        }
      symbol=OrderSymbol();
      eDigits=int(MarketInfo(OrderSymbol(),MODE_DIGITS));
      ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),eDigits);
      bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),eDigits);
      factor=GetPipFactor(OrderSymbol());
      TicketNo=OrderTicket();

      //now we go through the trades checking what we have to do..
      if(SetInitialStopLoss==true)
        {
         if(NormalizeDouble(OrderStopLoss(),eDigits)==0) SetInitialSL(TicketNo,factor,eDigits);
        }
      if(SetInitialTakeProfit==true)
        {
         if(NormalizeDouble(OrderTakeProfit(),eDigits)==0) SetInitialTP(TicketNo,factor,eDigits);

        }
        if (useMAasSL==true )
        {
        SetInitialMASL(TicketNo,factor,eDigits);
        }
        if(useMAasSL==true)
        {
         if(NormalizeDouble(OrderStopLoss(),eDigits)==0) SetInitialMASL(TicketNo,factor,eDigits);
        }
      if(Use_SetBEAndJump)
        {
         if(MoveSLOnlyIfWin==true)
           {
            SetBEAndJump(TicketNo,factor,eDigits);
           }
         if(MoveSLOnlyIfWin==false)
           {
            DoJS(TicketNo,factor,eDigits);
           }

        }
      if(PartCloseEnabled==true)
        {
         if(PartCloseAsFirstTP==true)
           {
            doPartCloseFirstTP(TicketNo,factor,eDigits);
           }
        }
      if(UseCloseFriday==true && DayOfWeek()==5)
        {
         CloseFriday(TicketNo,factor,eDigits);
        }
      if(UseCloseAllAtDefinedTime==true)
        {
         CloseDefinedTime(TicketNo,factor,eDigits);
        }

     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DisplayUserFeedback()
  {
   if(showUserDisplay==false)
     {
      ObjectDelete("messageBox");
      return;
     }
   if(showDisplayBox==true)
     {
      RectLabelCreate();
     }
   else ObjectDelete("messageBox");
   ScreenMessage="";
//ScreenMessage = StringConcatenate(ScreenMessage,Gap + NL);
   SM(NL);

   SM("Updates for this EA are to be found at http://www.stevehopwoodforex.com"+NL);
   SM(version);
   SM(" Copyright 2015, by milanese"+NL);
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   SM("Broker time = "+TimeToStr(TimeCurrent(),TIME_DATE|TIME_SECONDS)+" Local time = "+TimeToStr(TimeLocal(),TIME_DATE|TIME_SECONDS)+" GMT time = "+TimeToStr(TimeGMT(),TIME_DATE|TIME_SECONDS)+NL);
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   if(ManageAllOpenTrades==true)
     {
      SM("APTM will manage all open trades.."+NL);
     }
   if(ManageByMagicNumber==true)
     {
      SM("APTM will manage open trades with MagicNumber: "+IntegerToString(MagicNumber)+NL);
     }
   if(ManageByOrderComment==true)
     {
      SM("APTM will manage open trades with OrderComment: "+orderComment+NL);
     }
   if(ManageByTicketNumber==true)
     {
      SM("APTM will manage Ticket Number: "+IntegerToString(TicketNumber)+NL);
     }
   if(ManageOnlyActualSymbol==true)
     {
      SM("APTM will manage open Trades with Symbol: "+Symbol()+NL);
     }
     if (useMAasSL==true)
     {
     SM("APTM uses MA for SL"+NL);
     if(ManageOnlyActualSymbol==true)
     {
     SM("Your selected MA is at: "+DoubleToStr(MAstopValue(Symbol()),Digits)+NL);
     }
     }
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   if(DoNeverUseATR==true)
     {

      SM("All automatic calculating ATR settings are deactivated, manual inputs are used"+NL);

     }
   if(DoNeverUseATR==false)
     {

      if(useATRForStopLoss==true && SetInitialStopLoss==true)
        {
         SM("Initial-SL are calculated by ATR"+NL);

        }
      if(useATRForTakeProfit==true && SetInitialTakeProfit==true)
        {
         SM("Initial-TP are calculated by ATR"+NL);

        }
      if(useATRForSLMinDistanceToPrice==true && Use_SetBEAndJump==true)
        {
         SM("SLMinDistance is calculated by ATR"+NL);

        }
      if(useATRForPartClosePips==true && PartCloseEnabled==true && PartCloseAsFirstTP==true)
        {
         SM("PartClosePipsForFirstTP are calculated by ATR"+NL);

        }
     }
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   if(PartCloseEnabled==true && PartCloseAsFirstTP==true)
     {
      if(SetBEonPartCloseFirstTP==true)
        {
         SM("BE will set with first TP part-close"+NL);
        }
      SM("PartClose as first TP is enabled, PartClose % are: "+DoubleToString(PartClosePercent,1)+NL);

     }
   if(PartCloseEnabled==true && PartCloseWithBE==true)
     {
      SM("PartClose with setting BE is enabled, PartClose % are: "+DoubleToString(PartClosePercent,1)+NL);

     }
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   if(Use_SetBEAndJump==true && MoveSLOnlyIfWin==true)
     {

      SM("APTM will set BE and move the SL in Win"+NL);
     }
   if(Use_SetBEAndJump==true && MoveSLOnlyIfWin==false)
     {

      SM("APTM will will move SL always to SLMinDistance"+NL);
     }
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   if(doNotManagePositionsOpenedBefore==true)
     {
      SM("APTM will not manage orders opened before : "+doNotDate+NL);
     }
   if(UseCloseFriday==true)
     {
      SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
      SM("APTM will close all open Trades Friday at : "+IntegerToString(FridayCloseHour)+":"+IntegerToString(FridayCloseMinute)+" BrokerTime"+NL);
     }
   if(UseCloseAllAtDefinedTime==true)
     {
      SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
      SM("APTM will close all open Trades  at : "+IntegerToString(CloseHour)+":"+IntegerToString(CloseMinute)+" BrokerTime"+NL);
     }
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   SM("Account Equity is: "+DoubleToStr(AccountEquity(),2)+NL);
   SM("Account Profit is: "+DoubleToStr((AccountEquity()-AccountBalance()),2)+NL);
   SM("----------------------------------------------------------------------------------------------------------------------------------------------------------------"+NL);
   if(OrdersTotal()!=0)
     {
      SM("Count Active Buys="+IntegerToString(CountBuys())+NL);
      SM("Count Active Sells="+IntegerToString(CountSells())+NL);
     }
   if(OrdersTotal()==0)
     {
      SM("No Open Trades found, waiting for work!!"+NL);
     }
   Comment(ScreenMessage);

  }//void DisplayUserFeedback()
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SM(string message)
  {

   ScreenMessage=StringConcatenate(ScreenMessage,Gap,message);

  }//End void DM()
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseTotalBasket()
  {
   ForceTradeClosureBasket=false;
   bool result=false;

   if(OrdersTotal() == 0) return;

   for(int cc=OrdersTotal()-1; cc>=0; cc--)
     {

      if(!OrderSelect(cc,SELECT_BY_POS)) continue;
      if(ManageOnlyActualSymbol==true && OrderSymbol()!=Symbol()) continue;
      while(IsTradeContextBusy()) Sleep(100);
      if(OrderType() == OP_BUY || OrderType() == OP_SELL)  result = OrderClose(OrderTicket(), OrderLots(), OrderClosePrice(), 1000, CLR_NONE);
      if(OrderType() ==  OP_BUYLIMIT || OrderType() ==  OP_SELLLIMIT)  bool result_pending =OrderDelete( OrderTicket() );
      if(OrderType() ==  OP_BUYSTOP || OrderType() ==  OP_SELLSTOP)    bool result_pending =OrderDelete( OrderTicket() );
      if(result) cc++;

      //if (!result) ForceTradeClosure= true; //original, fxdaytrader

      //mod. fxdaytrader, orderclose-retry if failed with ordercloseprice(). Maybe very seldom, but it can happen, so it does not hurt to implement this:
      if(!result)
        {
         while(IsTradeContextBusy()) Sleep(100);
         RefreshRates();
         if(OrderType()==OP_BUY) result = OrderClose(OrderTicket(), OrderLots(), MarketInfo( OrderSymbol(),MODE_BID), 5000, CLR_NONE);
         if(OrderType()==OP_SELL) result = OrderClose(OrderTicket(), OrderLots(), MarketInfo( OrderSymbol(),MODE_ASK), 5000, CLR_NONE);
         if(!result) ForceTradeClosureBasket=true;
        }
      //end mod.

     }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountSells()
  {
   int nOrderCount=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS)) continue;
      if(ManageOnlyActualSymbol==true && OrderSymbol()!=Symbol()) continue;

      if(OrderType()==OP_SELL)

         nOrderCount++;
     }
   return(nOrderCount);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CountBuys()
  {
   int nOrderCount=0;
   for(int i=OrdersTotal()-1; i>=0; i--)
     {
      if(!OrderSelect(i,SELECT_BY_POS)) continue;
      if(ManageOnlyActualSymbol==true && OrderSymbol()!=Symbol()) continue;

      if(OrderType()==OP_BUY)

         nOrderCount++;
     }
   return(nOrderCount);
  }
//+-------------------
string getUninitReasonText(int reasonCode)
  {
   string text="";
//---
   switch(reasonCode)
     {
      case REASON_ACCOUNT:
         text="Account was changed";break;
      case REASON_CHARTCHANGE:
         text="Symbol or timeframe was changed";break;
      case REASON_CHARTCLOSE:
         text="Chart was closed";break;
      case REASON_PARAMETERS:
         text="Input-parameter was changed";break;
      case REASON_RECOMPILE:
         text="Program "+__FILE__+" was recompiled";break;
      case REASON_REMOVE:
         text="Program "+__FILE__+" was removed from chart";break;
      case REASON_TEMPLATE:
         text="New template was applied to chart";break;
      default:text="Another reason";
     }
//---
   return text;
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void disableEA()
  {

   if(IsExpertEnabled()==true)
     {
      if(windowHdlFound>0) PostMessageA(windowHdlFound,WM_COMMAND,33020,0);

      Sleep(3000);
      if(IsExpertEnabled()==false && expertsDisabeled==false)
        {

         Alert("EquitySL/TP"+": All EAs were disabled at "+TimeToStr(TimeLocal()));
         expertsDisabeled=true;
        }
      if(IsExpertEnabled()==true && expertsDisabeled==true)
        {

         Alert("EquitySL/TP"+" was unable to disable all EAs at "+TimeToStr(TimeLocal()));
        }
     }

  }
//+------------------------------------------------------------------+
//| getPipFactor()                                                   |
//+------------------------------------------------------------------+
int GetPipFactor(string Xsymbol)
  {

   static const string factor100[]         = {"JPY","XAG","SILVER","BRENT","WTI"};
   static const string factor10[]          = {"XAU","GOLD","SP500"};
   static const string factor1[]           = {"UK100","WS30","DAX30","NAS100","CAC40","FRA40","GER30","ITA40","EUSTX50","JPN225"};

   int xFactor=10000;       // correct xFactor for most pairs
   for(int j=0; j<ArraySize(factor100); j++)
     {
      if(StringFind(Xsymbol,factor100[j])!=-1) xFactor=100;
     }
   for(int j=0; j<ArraySize(factor10); j++)
     {
      if(StringFind(Xsymbol,factor10[j])!=-1) xFactor=10;
     }
   for(int j=0; j<ArraySize(factor1); j++)
     {
      if(StringFind(Xsymbol,factor1[j])!=-1) xFactor=1;
     }

   return (xFactor);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetInitialSL(int ticket,double Xfactor,int Xdigits)
  {
   bool modify=false;
   double NewStop=0;
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   if((OrderType()==OP_BUY))
     {

      NewStop=CalculateSLBuy(ticket,Xfactor,Xdigits);

      modify=true;

     }//if (OrderType() == OP_BUY)

   if((OrderType()==OP_SELL))
     {

      NewStop=CalculateSLSell(ticket,Xfactor,Xdigits);

      modify=true;

     }//if (OrderType() == OP_SELL)

//Send the new stop loss 
   if(modify==true)
     {
      bool result=OrderModify(TicketNo,OrderOpenPrice(),NewStop,OrderTakeProfit(),OrderExpiration(),CLR_NONE);

      if(!result && OrderType()==OP_SELL)
        {
         NewStop=NewStop+(0.1/Xfactor);
         result=OrderModify(TicketNo,OrderOpenPrice(),NewStop,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
         if(result==false)ReportError(" APTM ",slm);

        }//if (!result)
      if(!result && OrderType()==OP_BUY)
        {
         NewStop=NewStop-(0.1/Xfactor);
         result=OrderModify(TicketNo,OrderOpenPrice(),NewStop,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
         if(result==false)ReportError(" APTM ",slm);

        }//if (!result)

     }

  }//void SetInitialSL()
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetInitialTP(int ticket,double Xfactor,int Xdigits)
  {
   bool modify=false;
   double NewTP=0;
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   if((OrderType()==OP_BUY))
     {

      NewTP=CalculateTPBuy(ticket,Xfactor,Xdigits);

      modify=true;

     }//if (OrderType() == OP_BUY)

   if((OrderType()==OP_SELL))
     {

      NewTP=CalculateTPSell(ticket,Xfactor,Xdigits);

      modify=true;

     }//if (OrderType() == OP_SELL)

//Send the new stop loss 
   if(modify==true)
     {
      bool result=OrderModify(TicketNo,OrderOpenPrice(),OrderStopLoss(),NewTP,OrderExpiration(),CLR_NONE);

      if(!result && OrderType()==OP_SELL)
        {
         NewTP=NewTP-(0.1/Xfactor);
         result=OrderModify(TicketNo,OrderOpenPrice(),OrderStopLoss(),NewTP,OrderExpiration(),CLR_NONE);
         if(result==false)ReportError(" APTM ",slm);

        }//if (!result)
      if(!result && OrderType()==OP_BUY)
        {
         NewTP=NewTP+(0.1/Xfactor);
         result=OrderModify(TicketNo,OrderOpenPrice(),OrderStopLoss(),NewTP,OrderExpiration(),CLR_NONE);
         if(result==false)ReportError(" APTM ",slm);

        }//if (!result)

     }

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateSLBuy(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return(0);//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   double CalculatedBuySL=0;
   if(useATRForStopLoss==true)
     {

      adr=GetAtr(OrderSymbol(),atrForStopLossTF,atrPeriodForStopLoss,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      SL=NormalizeDouble((atrMultiplicatorForStopLoss*adr*Xfactor),0);
     }
   CalculatedBuySL=NormalizeDouble(OrderOpenPrice()-(SL/Xfactor),Xdigits);
   if(bid<CalculatedBuySL+minDistanceSLTP/Xfactor)
     {
      CalculatedBuySL=NormalizeDouble(bid-(SLMinDistanceToPrice/Xfactor),Xdigits);
     }

   return(CalculatedBuySL);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateSLSell(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false)return(0);//in case the trade closed
   ask=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),Xdigits);
   bid=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),Xdigits);
   double CalculatedSellSL=0;
   if(useATRForStopLoss==true)
     {

      adr=GetAtr(OrderSymbol(),atrForStopLossTF,atrPeriodForStopLoss,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      SL=NormalizeDouble((atrMultiplicatorForStopLoss*adr*Xfactor),0);
     }
   CalculatedSellSL=NormalizeDouble(OrderOpenPrice()+(SL/Xfactor),Xdigits);
   if(ask>CalculatedSellSL-minDistanceSLTP/Xfactor)
     {
      CalculatedSellSL=NormalizeDouble(ask+(SLMinDistanceToPrice/Xfactor),Xdigits);
     }

   return (CalculatedSellSL);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateTPBuy(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return(0);//in case the trade closed
   ask=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),Xdigits);
   bid=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),Xdigits);
   double CalculatedBuyTP=0;
   if(useATRForTakeProfit==true)
     {

      adr=GetAtr(OrderSymbol(),atrForTakeProfitTF,atrPeriodForTakeProfit,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      TP=NormalizeDouble((atrMultiplicatorForTakeProfit*adr*Xfactor),0);
     }
   CalculatedBuyTP=NormalizeDouble(OrderOpenPrice()+(TP/Xfactor),Xdigits);
   if(bid>CalculatedBuyTP-minDistanceSLTP/Xfactor)
     {
      CalculatedBuyTP=NormalizeDouble(bid+(SLMinDistanceToPrice/Xfactor),Xdigits);
     }

   return(CalculatedBuyTP);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double CalculateTPSell(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false)return(0);//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   double CalculatedSellTP=0;
   if(useATRForTakeProfit==true)
     {

      adr=GetAtr(OrderSymbol(),atrForTakeProfitTF,atrPeriodForTakeProfit,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      TP=NormalizeDouble((atrMultiplicatorForTakeProfit*adr*Xfactor),0);
     }
   CalculatedSellTP=NormalizeDouble(OrderOpenPrice()-(TP/Xfactor),Xdigits);
   if(ask<CalculatedSellTP-minDistanceSLTP/Xfactor)
     {
      CalculatedSellTP=NormalizeDouble(ask-(SLMinDistanceToPrice/Xfactor),Xdigits);
     }

   return (CalculatedSellTP);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ReportError(string function,string message)
  {

   int err=GetLastError();

   if(showAlerts==true) Alert(WindowExpertName()," ",OrderTicket(),function,message,err,": ",ErrorDescription(err));
   Print(WindowExpertName()," ",OrderTicket(),function,message,err,": ",ErrorDescription(err));

  }//void ReportError()
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetAtr(string Xsymbol,int tf,int period,int shift)
  {
//Returns the value of atr

   return(iATR(Xsymbol, tf, period, shift) );

  }//End double GetAtr()
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void SetBEAndJump(int ticket,double Xfactor,int Xdigits)
  {

   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   double NewSL=0;
   TradeHasPartClosed=false;
   bool doPartClose=false;

   if(useATRForSLMinDistanceToPrice==true)
     {

      adr=GetAtr(OrderSymbol(),atrForSLMinDistanceToPriceTF,atrPeriodForSLMinDistanceToPrice,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      SLMinDistanceToPrice=NormalizeDouble((2*adr*Xfactor),0);
      SLMinDistanceToPriceBE=NormalizeDouble((atrMultiplicatorForSLMinDistanceToPriceBE*adr*Xfactor),0);
      SLMinDistanceToPriceJS=NormalizeDouble((atrMultiplicatorForSLMinDistanceToPriceJS*adr*Xfactor),0);
     }

   if(OrderType()==OP_SELL)
     {

      doPartClose=false;
      if(OrderStopLoss()>OrderOpenPrice() || NormalizeDouble(OrderStopLoss(),Xdigits)==0)
        {

         NewSL=NormalizeDouble(OrderOpenPrice()-(BEProfit/Xfactor),Xdigits);
         SLMinDistanceToPrice=SLMinDistanceToPriceBE;
         if(PartCloseWithBE==true && PartCloseEnabled==true)
           {
            doPartClose=true;
           }
        }
      else
        {
         doPartClose=false;
         NewSL=NormalizeDouble(OrderStopLoss()-(JumpStep/Xfactor),Xdigits);
         SLMinDistanceToPrice=SLMinDistanceToPriceJS;
        }

      if((NewSL-ask)>(SLMinDistanceToPrice/Xfactor))
        {

         if(NewSL!=OrderStopLoss() && NewSL!=0)
           {

            if(showAlerts==true)Alert("APTM: SetBEAndJump :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            Print("APTM: SetBEAndJump :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            bool result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
            if(!result)
              {
               NewSL=NewSL+(1/Xfactor);
               result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
               if(result==false)ReportError(" APTM ",slm);

              }//if (!result)

            if(doPartClose==true)
              {
               PartCloseTrade(ticket);
               if(TradeHasPartClosed==true)
                 {
                  if(showAlerts==true)Alert("APTM: Ticket: ",ticket," was part closed");
                 }
               else
                 {
                  if(showAlerts==true) Alert("APTM: Partclose failed!");

                  TradeHasPartClosed=false;
                 }
              }//doPartClose
           }// if(((NewSL<OrderStopLoss()) || (OrderStopLoss()<(1/Xfactor))) && (NewSL!=0) && (NewSL>Ask+(10/Xfactor)))
        }//if((NewSL-Bid)>(SLMinDistanceToPrice/Xfactor))

     }//OP_SELL

   if(OrderType()==OP_BUY)
     {

      doPartClose=false;
      if(OrderStopLoss()<OrderOpenPrice() || NormalizeDouble(OrderStopLoss(),Xdigits)==0)
        {
         NewSL=NormalizeDouble(OrderOpenPrice()+(BEProfit/Xfactor),Xdigits);
         SLMinDistanceToPrice=SLMinDistanceToPriceBE;
         if(PartCloseWithBE==true && PartCloseEnabled==true)
           {
            doPartClose=true;
           }

        }
      else
        {
         NewSL=NormalizeDouble(OrderStopLoss()+(JumpStep/Xfactor),Xdigits);
         SLMinDistanceToPrice=SLMinDistanceToPriceJS;
         doPartClose=false;
        }
      if(bid-NewSL>(SLMinDistanceToPrice/Xfactor))
        {
         if(NewSL!=OrderStopLoss() && NewSL!=0)

           {

            Alert("APTM: SetBEAndJump :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            Print("APTM: SetBEAndJump :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));

            bool result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
            if(!result)
              {
               NewSL=NewSL-(1/Xfactor);
               result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
               if(result==false)ReportError(" APTM ",slm);

              }//if (!result)
            if(doPartClose==true)
              {
               PartCloseTrade(ticket);
               if(TradeHasPartClosed==true)
                 {
                  Alert("APTM: Ticket: ",ticket," was part closed");
                 }
               else
                 {
                  Alert("APTM: Partclose failed!");
                  TradeHasPartClosed=false;
                 }
              }//doPartClose
           }//if(((NewSL>OrderStopLoss()) || (OrderStopLoss()<(1/Xfactor))) && (NewSL!=0) && (NewSL<Bid -(10/Xfactor)))
        }//if((Bid-NewSL)>(SLMinDistanceToPrice/Xfactor))

     }//OP_BUY

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool PartCloseTrade(int ticket)
  {
//Close PartClosePercent of the initial trade.
//Return true if close succeeds, else false
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return(true);//in case the trade closed
   bool Success=false;
   double CloseLots=NormalizeLots(OrderSymbol(),OrderLots() *(PartClosePercent/100));

   RefreshRates();
   if(OrderType()==OP_BUY) Success = OrderClose(ticket, CloseLots, MarketInfo(OrderSymbol(),MODE_BID), 5000, Blue);
   if(OrderType()==OP_SELL) Success = OrderClose(ticket, CloseLots, MarketInfo(OrderSymbol(),MODE_ASK), 5000, Blue);
   if(Success) TradeHasPartClosed=true;//Warns CountOpenTrades() that the OrderTicket() is incorrect.
   if(!Success)
     {

      while(IsTradeContextBusy()) Sleep(500);
      RefreshRates();
      if(OrderType()==OP_BUY) Success = OrderClose(ticket, CloseLots, MarketInfo(OrderSymbol(),MODE_BID), 5000, Blue);
      if(OrderType()==OP_SELL) Success = OrderClose(ticket, CloseLots, MarketInfo(OrderSymbol(),MODE_ASK), 5000, Blue);
      //end mod.  
      //original:
      if(Success) TradeHasPartClosed=true;//Warns CountOpenTrades() that the OrderTicket() is incorrect.

      if(!Success)
        {

         return (false);
        }
     }//if (!Success) 

   if((ManageByTicketNumber==true) || (ManageByOrderComment==true))
     {
      string OrderNumber=StringConcatenate(ticket);
      ManageByTicketNumber=false;
      ManageByOrderComment=true;
      string OC="from #";
      orderComment=StringConcatenate(OC,OrderNumber);
     }
   return (true);

  }//bool PartCloseTrade(int ticket)
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double NormalizeLots(string Xsymbol,double lots)
  {
   if(CloseEnough(MathAbs(lots),0.0)) return(0.0); //just in case ... otherwise it may happen that after rounding 0.0 the result is >0 and we have got a problem, fxdaytrader
   double ls=MarketInfo(Xsymbol,MODE_LOTSTEP);
   lots=MathMin(MarketInfo(Xsymbol,MODE_MAXLOT),MathMax(MarketInfo(Xsymbol,MODE_MINLOT),lots)); //check if lots >= min. lots && <= max. lots, fxdaytrader
   return(MathRound(lots/ls)*ls);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool CloseEnough(double num1,double num2)
  {
/*
   This function addresses the problem of the way in which mql4 compares doubles. It often messes up the 8th
   decimal point.
   For example, if A = 1.5 and B = 1.5, then these numbers are clearly equal. Unseen by the coder, mql4 may
   actually be giving B the value of 1.50000001, and so the variable are not equal, even though they are.
   This nice little quirk explains some of the problems I have endured in the past when comparing doubles. This
   is common to a lot of program languages, so watch out for it if you program elsewhere.
   Gary (garyfritz) offered this solution, so our thanks to him.
   */

   if(num1==0 && num2==0) return(true); //0==0
   if(MathAbs(num1 - num2) / (MathAbs(num1) + MathAbs(num2)) < 0.00000001) return(true);

//Doubles are unequal
   return(false);

  }//End bool CloseEnough(double num1, double num2)
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void DoJS(int ticket,double Xfactor,int Xdigits)
  {

   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   double NewSL=0;

   if(useATRForSLMinDistanceToPrice==true)
     {

      adr=GetAtr(OrderSymbol(),atrForSLMinDistanceToPriceTF,atrPeriodForSLMinDistanceToPrice,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      SLMinDistanceToPrice=NormalizeDouble((2*adr*Xfactor),0);
      SLMinDistanceToPriceBE=NormalizeDouble((atrMultiplicatorForSLMinDistanceToPriceBE*adr*Xfactor),0);
      SLMinDistanceToPriceJS=NormalizeDouble((atrMultiplicatorForSLMinDistanceToPriceJS*adr*Xfactor),0);
     }

   if(OrderType()==OP_SELL)
     {

      NewSL=NormalizeDouble(OrderStopLoss()-(JumpStep/Xfactor),Xdigits);

      if(((NewSL-ask)>(SLMinDistanceToPriceJS/Xfactor)) && ((NewSL-ask)<((SLMinDistanceToPriceJS/Xfactor)+(5/Xfactor))))
        {

         if(NewSL<(OrderStopLoss()-(1/Xfactor)) && NewSL!=0)
           {

            if(showAlerts==true) Alert("APTM: DoJS :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            Print("APTM: DoJS :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            bool result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
            if(!result)
              {
               NewSL=NewSL+(1/Xfactor);
               result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
               if(result==false)ReportError(" APTM ",slm);

              }//if (!result)
           }
        }
     }

   if(OrderType()==OP_BUY)
     {

      NewSL=NormalizeDouble(OrderStopLoss()+(JumpStep/Xfactor),Xdigits);
      if(((bid-NewSL)>(SLMinDistanceToPriceJS/Xfactor)) && ((bid-NewSL)<((SLMinDistanceToPriceJS/Xfactor)+(5/Xfactor))))
        {
         if(NewSL>(OrderStopLoss()+(1/Xfactor)) && NewSL!=0)

           {

            if(showAlerts==true) Alert("APTM: DoJS :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            Print("APTM: DoJS :Attempting to move SL of ",OrderSymbol()," to ",DoubleToStr(NewSL,Xdigits));
            bool result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
            if(!result)
              {
               NewSL=NewSL-(1/Xfactor);
               result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
               if(result==false)ReportError(" APTM ",slm);

              }//if (!result)
           }
        }

     }

  }
//+------
void doPartCloseFirstTP(int ticket,double Xfactor,int Xdigits)
  {

   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   double NewSL=0;
   string name;

   if(useATRForPartClosePips==true)
     {

      adr=GetAtr(OrderSymbol(),atrForPartClosePipsTF,atrPeriodForPartClosePips,0);
      if(adr==0)adr=MathAbs(iHigh(OrderSymbol(),PERIOD_W1,1)-iLow(OrderSymbol(),PERIOD_W1,1));
      PartCloseFirstTpPips=NormalizeDouble((atrMultiplicatorForPartClosePips*adr*Xfactor),0);
     }

   bool doPartClose=false;

   TradeHasPartClosed=false;

   if(OrderType()==OP_SELL)
     {

      doPartClose=false;

      NewSL=NormalizeDouble((OrderOpenPrice()-(BEProfit/factor)),Xdigits);

      name=OrderComment();
      if(StringFind(name,"from #")<0)doPartClose=true;

      if((NewSL-ask)>(PartCloseFirstTpPips/Xfactor))
        {

         if(doPartClose==true)
           {
            if(SetBEonPartCloseFirstTP==true && NormalizeDouble(OrderStopLoss(),Xdigits)!=NormalizeDouble(NewSL,Xdigits))
              {
               if(showAlerts==true)Alert("APTM:SetBEonFirstTP :Attempting to move SL of ",symbol," to ",NewSL);
               Print("APTM:SetBEonFirstTP :Attempting to move SL of ",symbol," to ",NewSL);

               bool result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
               if(!result)
                 {
                  NewSL=NewSL-(1/Xfactor);
                  result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
                  if(result==false)ReportError(" APTM ",slm);

                 }//if (!result)

              }
            PartCloseTrade(ticket);
            if(TradeHasPartClosed==true)
              {
               if(showAlerts==true) Alert("APTM: Ticket: ",ticket," was part closed");
              }
            else
              {
               if(showAlerts==true) Alert("APTM: Partclose failed!");

               TradeHasPartClosed=false;
              }
           }//doPartClose

        }//if((NewSL-Bid)>(SLMinDistanceToPrice/Xfactor))

     }//OP_SELL

   if(OrderType()==OP_BUY)
     {

      doPartClose=false;

      NewSL=NormalizeDouble((OrderOpenPrice()+(BEProfit/factor)),Xdigits);

      name=OrderComment();
      if(StringFind(name,"from #")<0)doPartClose=true;

      if((bid-NewSL)>(PartCloseFirstTpPips/Xfactor))
        {
         if(SetBEonPartCloseFirstTP==true && NormalizeDouble(OrderStopLoss(),Xdigits)!=NormalizeDouble(NewSL,Xdigits))
           {
            if(showAlerts==true)Alert("APTM:SetBEonFirstTP :Attempting to move SL of ",symbol," to ",NewSL);
            Print("APTM:SetBEonFirstTP :Attempting to move SL of ",symbol," to ",NewSL);

            bool result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
            if(!result)
              {
               NewSL=NewSL+(1/Xfactor);
               result=OrderModify(ticket,OrderOpenPrice(),NewSL,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
               if(result==false)ReportError(" APTM ",slm);

              }//if (!result)

           }

         if(doPartClose==true)
           {
            PartCloseTrade(ticket);
            if(TradeHasPartClosed==true)
              {
               if(showAlerts==true) Alert("APTM: Ticket: ",ticket," was part closed");
              }
            else
              {
               if(showAlerts==true) Alert("APTM: Partclose failed!");

               TradeHasPartClosed=false;
              }
           }//doPartClose

        }//if((Bid-NewSL)>(PartCloseFirstTpPips/factor))

     }//OP_BUY

  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool RectLabelCreate()
  {
//--- reset the error value
   ResetLastError();
//--- create a rectangle label
   if(ObjectFind(0,"messageBox")>=0) return true;
   if(!ObjectCreate(0,"messageBox",OBJ_RECTANGLE_LABEL,0,0,0))
     {
      Print(__FUNCTION__,
            ": failed to create a rectangle label! Error code = ",GetLastError());
      return(false);
     }
//--- set label coordinates
   ObjectSetInteger(0,"messageBox",OBJPROP_XDISTANCE,0);
   ObjectSetInteger(0,"messageBox",OBJPROP_YDISTANCE,0);
//--- set label size
   ObjectSetInteger(0,"messageBox",OBJPROP_XSIZE,500);
   ObjectSetInteger(0,"messageBox",OBJPROP_YSIZE,440);
//--- set background color
   ObjectSetInteger(0,"messageBox",OBJPROP_BGCOLOR,displayBoxBackgroundColour);
//--- set border type
   ObjectSetInteger(0,"messageBox",OBJPROP_BORDER_TYPE,BORDER_SUNKEN);
//--- set the chart's corner, relative to which point coordinates are defined
   ObjectSetInteger(0,"messageBox",OBJPROP_CORNER,0);
//--- set flat border color (in Flat mode)
   ObjectSetInteger(0,"messageBox",OBJPROP_COLOR,Red);
//--- set flat border line style
   ObjectSetInteger(0,"messageBox",OBJPROP_STYLE,STYLE_SOLID);
//--- set flat border width
   ObjectSetInteger(0,"messageBox",OBJPROP_WIDTH,1);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(0,"messageBox",OBJPROP_BACK,false);
//--- enable (true) or disable (false) the mode of moving the label by mouse
   ObjectSetInteger(0,"messageBox",OBJPROP_SELECTABLE,true);
   ObjectSetInteger(0,"messageBox",OBJPROP_SELECTED,false);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(0,"messageBox",OBJPROP_HIDDEN,false);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(0,"messageBox",OBJPROP_ZORDER,0);
//--- successful execution
   return(true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseFriday(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   if((DayOfWeek()==5) && (TimeHour(TimeCurrent())>=FridayCloseHour) && (TimeMinute(TimeCurrent())>=FridayCloseMinute))
     {

      if(OrderType()==OP_BUY)
        {
         while(IsTradeContextBusy()) Sleep(100);
         if(showAlerts==true) Alert("APTM:CloseFriday:Attempting to close ",IntegerToString(ticket));
         Print("APTM:CloseFriday:Attempting to close ",IntegerToString(ticket));
         if(OrderClose(ticket,OrderLots(),bid,5000,clrNONE))
           {
            if(showAlerts==true)Alert("APTM:CloseFriday:Close ",IntegerToString(ticket)," Succeeded !");
            Print("APTM:CloseFriday:Close ",IntegerToString(ticket)," Succeeded !");
              } else {
            if(showAlerts==true)Alert("APTM:CloseFriday:Close ",IntegerToString(ticket)," Failed !");
            Print("APTM:CloseFriday:Close ",IntegerToString(ticket)," Failed !");
           }
        }

      if(OrderType()==OP_SELL)
        {
         while(IsTradeContextBusy()) Sleep(100);
         if(showAlerts==true)Alert("APTM:CloseFriday:Attempting to close ",IntegerToString(ticket));
         Print("APTM:CloseFriday:Attempting to close ",IntegerToString(ticket));
         if(OrderClose(ticket,OrderLots(),ask,5000,clrNONE))
           {
            if(showAlerts==true) Alert("APTM:CloseFriday:Close ",IntegerToString(ticket)," Succeeded !");
            Print("APTM:CloseFriday:Close ",IntegerToString(ticket)," Succeeded !");
              } else {
            if(showAlerts==true) Alert("APTM:CloseFriday:Close ",IntegerToString(ticket)," Failed !");
            Print("APTM:CloseFriday:Close ",IntegerToString(ticket)," Failed !");
           }
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseDefinedTime(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   if((TimeHour(TimeCurrent())==CloseHour) && (TimeMinute(TimeCurrent())==CloseMinute))
     {

      if(OrderType()==OP_BUY)
        {
         while(IsTradeContextBusy()) Sleep(100);
         if(showAlerts==true) Alert("APTM:CloseDefinedTime:Attempting to close ",IntegerToString(ticket));
         Print("APTM:CloseDefinedTime:Attempting to close ",IntegerToString(ticket));
         if(OrderClose(ticket,OrderLots(),bid,5000,clrNONE))
           {
            if(showAlerts==true)Alert("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Succeeded !");
            Print("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Succeeded !");
              } else {
            if(showAlerts==true)Alert("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Failed !");
            Print("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Failed !");
           }
        }

      if(OrderType()==OP_SELL)
        {
         while(IsTradeContextBusy()) Sleep(100);
         if(showAlerts==true)Alert("APTM:CloseDefinedTime:Attempting to close ",IntegerToString(ticket));
         Print("APTM:CloseDefinedTime:Attempting to close ",IntegerToString(ticket));
         if(OrderClose(ticket,OrderLots(),ask,5000,clrNONE))
           {
            if(showAlerts==true) Alert("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Succeeded !");
            Print("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Succeeded !");
              } else {
            if(showAlerts==true) Alert("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Failed !");
            Print("APTM:CloseDefinedTime:Close ",IntegerToString(ticket)," Failed !");
           }
        }
     }
  }
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Create the button                                                |
//+------------------------------------------------------------------+
bool ButtonCreate(const long              chart_ID=0,               // chart's ID
                  const string            name="Button",            // button name
                  const int               sub_window=0,             // subwindow index
                  const int               x=0,                      // X coordinate
                  const int               y=0,                      // Y coordinate
                  const int               width=80,                 // button width
                  const int               height=20,                // button height
                  const ENUM_BASE_CORNER  corner=CORNER_RIGHT_UPPER,// chart corner for anchoring
                  const string            text="Button",            // text
                  const string            font="Arial",             // font
                  const int               font_size=10,             // font size
                  const color             clr=clrBlack,             // text color
                  const color             back_clr=C'236,233,216',  // background color
                  const color             border_clr=clrNONE,       // border color
                  const bool              state=false,              // pressed/released
                  const bool              back=false,               // in the background
                  const bool              selection=false,          // highlight to move
                  const bool              hidden=true,              // hidden in the object list
                  const long              z_order=0)                // priority for mouse click
  {
//--- reset the error value
   ResetLastError();
//--- create the button
   if(!ObjectCreate(chart_ID,name,OBJ_BUTTON,sub_window,0,0))
     {
      Print(__FUNCTION__,
            ": failed to create the button! Error code = ",GetLastError());
      return(false);
     }
//--- set button coordinates
   ObjectSetInteger(chart_ID,name,OBJPROP_XDISTANCE,x);
   ObjectSetInteger(chart_ID,name,OBJPROP_YDISTANCE,y);
//--- set button size
   ObjectSetInteger(chart_ID,name,OBJPROP_XSIZE,width);
   ObjectSetInteger(chart_ID,name,OBJPROP_YSIZE,height);
//--- set the chart's corner, relative to which point coordinates are defined
   ObjectSetInteger(chart_ID,name,OBJPROP_CORNER,corner);
//--- set the text
   ObjectSetString(chart_ID,name,OBJPROP_TEXT,text);
//--- set text font
   ObjectSetString(chart_ID,name,OBJPROP_FONT,font);
//--- set font size
   ObjectSetInteger(chart_ID,name,OBJPROP_FONTSIZE,font_size);
//--- set text color
   ObjectSetInteger(chart_ID,name,OBJPROP_COLOR,clr);
//--- set background color
   ObjectSetInteger(chart_ID,name,OBJPROP_BGCOLOR,back_clr);
//--- set border color
   ObjectSetInteger(chart_ID,name,OBJPROP_BORDER_COLOR,border_clr);
//--- display in the foreground (false) or background (true)
   ObjectSetInteger(chart_ID,name,OBJPROP_BACK,back);
//--- enable (true) or disable (false) the mode of moving the button by mouse
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTABLE,selection);
   ObjectSetInteger(chart_ID,name,OBJPROP_SELECTED,selection);
//--- hide (true) or display (false) graphical object name in the object list
   ObjectSetInteger(chart_ID,name,OBJPROP_HIDDEN,hidden);
//--- set the priority for receiving the event of a mouse click in the chart
   ObjectSetInteger(chart_ID,name,OBJPROP_ZORDER,z_order);
//--- successful execution
   
   return(true);
  }
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // Event identifier  
                  const long& lparam,   // Event parameter of long type
                  const double& dparam, // Event parameter of double type
                  const string& sparam) // Event parameter of string type
  {
//--- the left mouse button has been pressed on the chart

//--- the mouse has been clicked on the graphic object
   if(id==CHARTEVENT_OBJECT_CLICK)
     {
      if(sparam==InpName) CloseAll();
      if(sparam == "mBE")     
        {
          ObjectSetInteger(0, "mBE", OBJPROP_BGCOLOR, clrYellow);
          Sleep(500);
          SetBE();    
          ObjectSetInteger(0, "mBE", OBJPROP_STATE, false);       
          ObjectSetInteger(0, "mBE", OBJPROP_BGCOLOR, clrRed);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAll()
  {

   bool result=false;

   if(OrdersTotal() == 0) return;
   if(showAlerts)Alert("APTM: CloseAll Button hit, starting to close all..");
   for(int cc=OrdersTotal()-1; cc>=0; cc--)
     {

      if(!OrderSelect(cc,SELECT_BY_POS)) continue;
       if(ManageOnlyActualSymbol==true && OrderSymbol()!=Symbol()) continue;
      while(IsTradeContextBusy()) Sleep(100);
      if(OrderType()==OP_BUY || OrderType()==OP_SELL) result=OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),5000,CLR_NONE);
      if(NotDeletePendingOrdersWithCloseAll==false)
        {
         if(OrderType() ==  OP_BUYLIMIT || OrderType() ==  OP_SELLLIMIT)  bool result_pending =OrderDelete( OrderTicket() );
         if(OrderType() ==  OP_BUYSTOP || OrderType() ==  OP_SELLSTOP)    bool result_pending =OrderDelete( OrderTicket() );
        }
      if(result) cc++;

      //if (!result) ForceTradeClosure= true; //original, fxdaytrader

      //mod. fxdaytrader, orderclose-retry if failed with ordercloseprice(). Maybe very seldom, but it can happen, so it does not hurt to implement this:
      if(!result)
        {
         while(IsTradeContextBusy()) Sleep(100);
         RefreshRates();
         if(OrderType()==OP_BUY) result = OrderClose(OrderTicket(), OrderLots(), MarketInfo( OrderSymbol(),MODE_BID), 5000, CLR_NONE);
         if(OrderType()==OP_SELL) result = OrderClose(OrderTicket(), OrderLots(), MarketInfo( OrderSymbol(),MODE_ASK), 5000, CLR_NONE);

        }
      //end mod.

     }//for (int cc = OrdersTotal() - 1; cc >= 0; cc--)

  }
double MAstopValue(string Xsymbol)
{
   double maValue = iMA(Xsymbol,MaTimeFrame,MaPeriod,0,MaMethod,MaAppliedPrice,MaShift);
   return(maValue);
}
double CalculateMASLSell(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false)return(0);//in case the trade closed
   ask=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),Xdigits);
   bid=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),Xdigits);
   double CalculatedSellSL=0;
   
   CalculatedSellSL=NormalizeDouble(MAstopValue(OrderSymbol()),Xdigits);
   if(ask>CalculatedSellSL-minDistanceSLTP/Xfactor)
     {
      CalculatedSellSL=NormalizeDouble(ask+(MASLMinDistanceToPrice/Xfactor),Xdigits);
       if (showAlerts==true)Alert("APTM:Ma can't be SL EmergencySL used!!");
     }

   return (CalculatedSellSL);
  }
  double CalculateMASLBuy(int ticket,double Xfactor,int Xdigits)
  {
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false)return(0);//in case the trade closed
   ask=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_ASK),Xdigits);
   bid=NormalizeDouble(MarketInfo(OrderSymbol(),MODE_BID),Xdigits);
   double CalculatedBuySL=0;
   
   CalculatedBuySL=NormalizeDouble(MAstopValue(OrderSymbol()),Xdigits);
   if(bid<CalculatedBuySL+minDistanceSLTP/Xfactor)
     {
      CalculatedBuySL=NormalizeDouble(bid-(MASLMinDistanceToPrice/Xfactor),Xdigits);
      if (showAlerts==true)Alert("APTM:Ma can't be SL EmergencySL used!!");
     }

   return (CalculatedBuySL);
  }
  void SetInitialMASL(int ticket,double Xfactor,int Xdigits)
  {
   bool modify=false;
   double NewStop=0;
   bool selectedOrder=OrderSelect(ticket,SELECT_BY_TICKET,MODE_TRADES);
   if(selectedOrder==false) return;//in case the trade closed
   ask = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_ASK),Xdigits);
   bid = NormalizeDouble(MarketInfo(OrderSymbol(), MODE_BID),Xdigits);
   factor=GetPipFactor(OrderSymbol());
   if((OrderType()==OP_BUY))
     {

      NewStop=CalculateMASLBuy(ticket,Xfactor,Xdigits);
      if ( NormalizeDouble(NewStop,Xdigits)<= NormalizeDouble((OrderStopLoss()+(5/factor)),Xdigits)) modify=false;
      else modify=true;
      if (moveSLonlyIfInTradeDirection==true && NormalizeDouble(OrderStopLoss(),Xdigits) != 0){
      if (NormalizeDouble(OrderStopLoss(),Xdigits) >= NormalizeDouble(NewStop,Xdigits) )modify=false;
      else modify=true;
      }
      

     }//if (OrderType() == OP_BUY)

   if((OrderType()==OP_SELL))
     {

      NewStop=CalculateMASLSell(ticket,Xfactor,Xdigits);

      if ( NormalizeDouble(NewStop,Xdigits)>= NormalizeDouble((OrderStopLoss()-(5/factor)),Xdigits)) modify=false;
      else modify=true;
       if (moveSLonlyIfInTradeDirection==true && NormalizeDouble(OrderStopLoss(),Xdigits) != 0){
      if (NormalizeDouble(OrderStopLoss(),Xdigits) <= NormalizeDouble(NewStop,Xdigits) )modify=false;
      else modify=true;
      }
     }//if (OrderType() == OP_SELL)

//Send the new stop loss 
   if(modify==true)
     {
      bool result=OrderModify(TicketNo,OrderOpenPrice(),NewStop,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
      if (result==true && showAlerts==true)Alert("APTM ",OrderSymbol(),": ","MA depended SL moved to: ",DoubleToString(NewStop,Xdigits));
      if(!result && OrderType()==OP_SELL)
        {
         NewStop=NewStop+(0.1/Xfactor);
         result=OrderModify(TicketNo,OrderOpenPrice(),NewStop,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
         if(result==false)ReportError(" APTM ",slm);

        }//if (!result)
      if(!result && OrderType()==OP_BUY)
        {
         NewStop=NewStop-(0.1/Xfactor);
         result=OrderModify(TicketNo,OrderOpenPrice(),NewStop,OrderTakeProfit(),OrderExpiration(),CLR_NONE);
         if(result==false)ReportError(" APTM ",slm);

        }//if (!result)

     }

  }//void SetInitialSL()
  bool NewBar(int tf)
{
   static datetime LastTime = 0;
   if (iTime(NULL, tf, 0) != LastTime)
   {
      LastTime = iTime(NULL, tf, 0);
      return (true);
   }
   else
      return (false);
}

//--------------------------------------------------------------------
void SetBE()
 {
   if(OrdersTotal() == 0) return;
   for(int m = OrdersTotal()-1; m >= 0; m--)
     {
       bool mRes = OrderSelect(m, SELECT_BY_POS, MODE_TRADES);
       int mTkt = OrderTicket();
       if((OrderType() == OP_BUY || OrderType() == OP_SELL) && OrderMagicNumber() == MagicNumber &&
           ((OrderSymbol() == Symbol() && ManageOnlyActualSymbol) || !ManageOnlyActualSymbol))
        {
          double mPF = GetPipFactor(OrderSymbol());
          double mMinStop = MarketInfo(OrderSymbol(), MODE_STOPLEVEL);
          if(OrderType() == OP_BUY && iClose(OrderSymbol(), 1, 0) > OrderOpenPrice() + (mMinStop + 1) / mPF)
            mRes = OrderModify(mTkt, OrderOpenPrice(), OrderOpenPrice() + mBEdist / mPF, 0, 0, clrNONE);
          if(OrderType() == OP_SELL && iClose(OrderSymbol(), 1, 0) < OrderOpenPrice() - (mMinStop - 1) / mPF)
            mRes = OrderModify(mTkt, OrderOpenPrice(), OrderOpenPrice() - mBEdist / mPF, 0, 0, clrNONE);

          if(mRes == false)
            Alert(OrderSymbol(), " Order Modify to BE failed");
        }
     }
       
   return;
 }
 
//--------------------------------------------------------------------
void CreateBE()
 {
               ObjectCreate("mBE", OBJ_BUTTON, 0, 0, 0); 
               ObjectSet("mBE", OBJPROP_YSIZE, 30);
               ObjectSetInteger(0, "mBE", OBJPROP_CORNER, 1);       
               ObjectSetInteger(0, "mBE", OBJPROP_XSIZE, 80);       
               ObjectSetString(0, "mBE", OBJPROP_FONT, "Times");
               ObjectSetInteger(0, "mBE", OBJPROP_BGCOLOR, clrRed);
               ObjectSetInteger(0, "mBE", OBJPROP_COLOR, clrBlack);
               ObjectSetInteger(0, "mBE", OBJPROP_FONTSIZE, 12);       
               ObjectSetString(0, "mBE", OBJPROP_TEXT, "Set to BE");
               ObjectSetInteger(0, "mBE", OBJPROP_SELECTABLE, false);       
               ObjectSetInteger(0, "mBE", OBJPROP_XDISTANCE, mXdist);       
               ObjectSetInteger(0, "mBE", OBJPROP_YDISTANCE, mYdist);       
   
 
   return;
 }
 
//--------------------------------------------------------------------
