1 (edited by footon 2020-10-24 16:27:48)

Topic: Coding Question - Dynamic ATR Stop Loss

Hi,

I don't know if someone could perhaps advise me on a MQL4 coding issue in relation to EA Studio, please. I'm 99% there through a lot of trial and error but I can't figure out the last step. Have been working on this for months to reach this point.

I have a portfolio expert with 100 strategies and I am adapting it to set the Stop Loss and Take Profit to a multiple of ATR. I have the inputs set at the beginning of the code but the values do not seem to be changing during the back tests. For example, if I set 1% risk, I get 0.05 lots traded and it's always 0.05 lots; it never changes as my balance goes up and down.

I suspect this is because I have the code in the wrong place and it's not getting updated each time it runs? If that's the case, I don't know which section to place the code it. Maybe I need to create a define a function to calculate SL/TP/ATR etc but I still dont know where to put the function.

I did try to put it in OnTick but then I have the issue it doesn't get defined at the beginning and it wont compile. Im clearly making huge coding mis-steps but am a newbie to this...

Is there a quick fix to this, otherwise it might be better to post in the MT4 forum but I wanted to check with this one first since EA Studio is where the code comes from and someone may be in a similar spot.

This might be too big an ask for the forum, but worth a try anyway!

This is my code ...

// Calculate Dynamic Lot Size //

double calculateLotSize(int StopLossPoints)
{
    // 1% risk per trade
    int risk = 1;
    
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    double minLot  = MarketInfo(Symbol(), MODE_MINLOT); 
    double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
    double tickVal = MarketInfo(Symbol(), MODE_TICKVALUE);

    double lotSize = AccountBalance() * risk / 100 / (StopLossPoints * tickVal);

    return MathMin(
        maxLot,
        MathMax(
            minLot,
            NormalizeDouble(lotSize / lotStep, 0) * lotStep // This rounds the lotSize to the nearest lotstep interval
        )
    ); 
}

#property copyright "Forex Software Ltd."
#property version   "2.4"
#property strict

static input int    Base_Magic_Number = 100;  // Base Magic Number
static input int atrPeriod = 14;
static input double atrMultipleSL = 2.5; // Stop Loss ATR Multiple
static input double atrMultipleTP = 1; // Take Profit ATR Multiple

double atr = iATR(NULL, 0, atrPeriod, 0);
int SL = (int)(atr * atrMultipleSL / Point);
int TP = (int)(atr * atrMultipleTP / Point);

double lots = calculateLotSize(SL);
double Entry_Amount = lots;

... rest of the code is unchanged except Im assigning the SL and TP in the GetEntry and GetExit signals lower down to set the right values for the trades.

Thank you,
Matthew

2 (edited by Roughey 2020-10-25 18:48:20)

Re: Coding Question - Dynamic ATR Stop Loss

Minch wrote:

Hi,

I don't know if someone could perhaps advise me on a MQL4 coding issue in relation to EA Studio, please. I'm 99% there through a lot of trial and error but I can't figure out the last step. Have been working on this for months to reach this point.

I have a portfolio expert with 100 strategies and I am adapting it to set the Stop Loss and Take Profit to a multiple of ATR. I have the inputs set at the beginning of the code but the values do not seem to be changing during the back tests. For example, if I set 1% risk, I get 0.05 lots traded and it's always 0.05 lots; it never changes as my balance goes up and down.

I suspect this is because I have the code in the wrong place and it's not getting updated each time it runs? If that's the case, I don't know which section to place the code it. Maybe I need to create a define a function to calculate SL/TP/ATR etc but I still dont know where to put the function.

I did try to put it in OnTick but then I have the issue it doesn't get defined at the beginning and it wont compile. Im clearly making huge coding mis-steps but am a newbie to this...

Is there a quick fix to this, otherwise it might be better to post in the MT4 forum but I wanted to check with this one first since EA Studio is where the code comes from and someone may be in a similar spot.

This might be too big an ask for the forum, but worth a try anyway!

This is my code ...

// Calculate Dynamic Lot Size //

double calculateLotSize(int StopLossPoints)
{
    // 1% risk per trade
    int risk = 1;
    
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    double minLot  = MarketInfo(Symbol(), MODE_MINLOT); 
    double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
    double tickVal = MarketInfo(Symbol(), MODE_TICKVALUE);

    double lotSize = AccountBalance() * risk / 100 / (StopLossPoints * tickVal);

    return MathMin(
        maxLot,
        MathMax(
            minLot,
            NormalizeDouble(lotSize / lotStep, 0) * lotStep // This rounds the lotSize to the nearest lotstep interval
        )
    ); 
}

#property copyright "Forex Software Ltd."
#property version   "2.4"
#property strict

static input int    Base_Magic_Number = 100;  // Base Magic Number
static input int atrPeriod = 14;
static input double atrMultipleSL = 2.5; // Stop Loss ATR Multiple
static input double atrMultipleTP = 1; // Take Profit ATR Multiple

double atr = iATR(NULL, 0, atrPeriod, 0);
int SL = (int)(atr * atrMultipleSL / Point);
int TP = (int)(atr * atrMultipleTP / Point);

double lots = calculateLotSize(SL);
double Entry_Amount = lots;

... rest of the code is unchanged except Im assigning the SL and TP in the GetEntry and GetExit signals lower down to set the right values for the trades.

Thank you,
Matthew

try this


//
// EA Studio Portfolio Expert Advisor
//
// Created with: Expert Advisor Studio
// Website: https://forexsb.com/expert-advisor-studio-app
//
// Copyright 2020, Forex Software Ltd.
//
// This Portfolio Expert works in MetaTrader 4.
// It opens separate positions for each strategy.
// Every position has an unique magic number,
// which corresponds to the index of the strategy.
//

#property copyright "Forex Software Ltd."
#property version   "2.4"
#property strict

enum ENUM_MM
  {
Fixed,
Risk
  };
input ENUM_MM       useMM                      = Fixed;                
static input double Fix_Lot      = 0.01; // Entry lots
static input int    Base_Magic_Number = 100;  // Base Magic Number
input  int           risk         = 1; // RIsk
static input int    atrPeriod = 14;
static input double atrMultipleSL = 2.5; // Stop Loss ATR Multiple
static input double atrMultipleTP = 1; // Take Profit ATR Multiple



#define TRADE_RETRY_COUNT 4
#define TRADE_RETRY_WAIT  100
#define OP_FLAT           -1

// Session time is set in seconds from 00:00
const int sessionSundayOpen           = 0;     // 00:00
const int sessionSundayClose          = 86400; // 24:00
const int sessionMondayThursdayOpen   = 0;     // 00:00
const int sessionMondayThursdayClose  = 86400; // 24:00
const int sessionFridayOpen           = 0;     // 00:00
const int sessionFridayClose          = 86400; // 24:00
const bool sessionIgnoreSunday        = true;
const bool sessionCloseAtSessionClose = false;
const bool sessionCloseAtFridayClose  = false;

const int    strategiesCount = 100;
const double sigma           = 0.000001;

datetime barTime;
int      digits;
double   stopLevel;
double   pip;
bool     setProtectionSeparately = false;
//---
double Entry_Amount;
int SL;
int TP;
//---

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum OrderScope
  {
   ORDER_SCOPE_UNDEFINED,
   ORDER_SCOPE_ENTRY,
   ORDER_SCOPE_EXIT
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
enum OrderDirection
  {
   ORDER_DIRECTION_NONE,
   ORDER_DIRECTION_BUY,
   ORDER_DIRECTION_SELL,
   ORDER_DIRECTION_BOTH
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct Position
  {
   int               Type;
   int               Ticket;
   int               MagicNumber;
   double            Lots;
   double            Price;
   double            StopLoss;
   double            TakeProfit;
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
struct Signal
  {
   int               MagicNumber;
   OrderScope        Scope;
   OrderDirection    Direction;
   int               StopLossPips;
   int               TakeProfitPips;
   bool              IsTrailingStop;
  };
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
// Calculate Dynamic Lot Size //

double calculateLotSize(double StopLossPoints)
{
  
    double lotStep = MarketInfo(Symbol(), MODE_LOTSTEP);
    double minLot  = MarketInfo(Symbol(), MODE_MINLOT); 
    double maxLot  = MarketInfo(Symbol(), MODE_MAXLOT);
    double tickVal = MarketInfo(Symbol(), MODE_TICKVALUE);

    double lotSize = AccountBalance() * risk / 100 / (StopLossPoints * tickVal);

    return MathMin(
        maxLot,
        MathMax(
            minLot,
            NormalizeDouble(lotSize / lotStep, 0) * lotStep // This rounds the lotSize to the nearest lotstep interval
        )
    ); 
}
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OnInit()
  {
   barTime   = Time[0];
   digits    = (int) MarketInfo(_Symbol, MODE_DIGITS);
   stopLevel = MarketInfo(_Symbol, MODE_STOPLEVEL);
   pip       = GetPipValue();

   const ENUM_INIT_RETCODE initRetcode = ValidateInit();

   return (initRetcode);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnTick()
  {
//---

      double atr = iATR(NULL, 0, atrPeriod, 0);
      SL = (int)(atr * atrMultipleSL / Point);
      TP = (int)(atr * atrMultipleTP / Point);  
//---
      
   if(IsForceSessionClose())
     {
      CloseAllPositions();
      return;
     }

   if(Time[0]>barTime)
     {
      barTime=Time[0];
      OnBar();
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnBar()
  {
   if(IsOutOfSession()) return;

   Signal signalList[];
   SetSignals(signalList);
   int signalsCount=ArraySize(signalList);

   for(int i=0;i<signalsCount;i++)
     {
      Signal signal=signalList[i];
      ManageSignal(signal);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ManageSignal(Signal &signal)
  {
   Position position=CreatePosition(signal.MagicNumber);

   if(position.Type!=OP_FLAT && signal.Scope==ORDER_SCOPE_EXIT)
     {
      if(signal.Direction==ORDER_DIRECTION_BOTH ||
         (position.Type==OP_BUY && signal.Direction==ORDER_DIRECTION_SELL) ||
         (position.Type==OP_SELL && signal.Direction==ORDER_DIRECTION_BUY))
        {
         ClosePosition(position);
        }
     }

   if(position.Type!=OP_FLAT && signal.Scope==ORDER_SCOPE_EXIT && signal.IsTrailingStop)
     {
      double trailingStop=GetTrailingStop(position,signal.StopLossPips);
      Print(trailingStop);
      ManageTrailingStop(position,trailingStop);
     }

   if(position.Type==OP_FLAT && signal.Scope==ORDER_SCOPE_ENTRY)
     {
      if(signal.Direction==ORDER_DIRECTION_BUY || signal.Direction==ORDER_DIRECTION_SELL)
        {
         OpenPosition(signal);
        }
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Position CreatePosition(const int magicNumber)
  {
   Position position;
   position.MagicNumber = magicNumber;
   position.Type        = OP_FLAT;
   position.Ticket      = 0;
   position.Lots        = 0;
   position.Price       = 0;
   position.StopLoss    = 0;
   position.TakeProfit  = 0;

   int total=OrdersTotal();
   for(int pos=total-1; pos>=0; pos--)
     {
      if(OrderSelect(pos,SELECT_BY_POS,MODE_TRADES) &&
         OrderSymbol()      == _Symbol &&
         OrderMagicNumber() == magicNumber &&
         OrderCloseTime()   == 0)
        {
         position.Type       = OrderType();
         position.Lots       = OrderLots();
         position.Ticket     = OrderTicket();
         position.Price      = OrderOpenPrice();
         position.StopLoss   = OrderStopLoss();
         position.TakeProfit = OrderTakeProfit();
         break;
        }
     }

   return (position);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Signal CreateEntrySignal(const int strategyIndex,const bool canOpenLong,const bool canOpenShort,const int stopLossPips,const int takeProfitPips, const bool isTrailingStop)
  {
   Signal signal;
   signal.MagicNumber    = GetMagicNumber(strategyIndex);
   signal.Scope          = ORDER_SCOPE_ENTRY;
   signal.Direction      = canOpenLong&&canOpenShort ? ORDER_DIRECTION_BOTH : canOpenLong ? ORDER_DIRECTION_BUY : canOpenShort ? ORDER_DIRECTION_SELL : ORDER_DIRECTION_NONE;
   signal.StopLossPips   = stopLossPips;
   signal.TakeProfitPips = takeProfitPips;
   signal.IsTrailingStop = isTrailingStop;

   return (signal);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
Signal CreateExitSignal(const int strategyIndex,const bool canCloseLong,const bool canCloseShorts,const int stopLossPips,const int takeProfitPips, const bool isTrailingStop)
  {
   Signal signal;
   signal.MagicNumber    = GetMagicNumber(strategyIndex);
   signal.Scope          = ORDER_SCOPE_EXIT;
   signal.Direction      = canCloseLong&&canCloseShorts ? ORDER_DIRECTION_BOTH : canCloseLong ? ORDER_DIRECTION_SELL : canCloseShorts ? ORDER_DIRECTION_BUY : ORDER_DIRECTION_NONE;
   signal.StopLossPips   = stopLossPips;
   signal.TakeProfitPips = takeProfitPips;
   signal.IsTrailingStop = isTrailingStop;

   return (signal);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OpenPosition(Signal &signal)
  {
   for(int attempt=0; attempt<TRADE_RETRY_COUNT; attempt++)
     {
      int    ticket     = 0;
      int    lastError  = 0;
      bool   modified   = false;
      int    command    = OrderDirectionToCommand(signal.Direction);
      double amount     = Entry_Amount;
      double stopLoss   = signal.StopLossPips>0 ? GetStopLoss(command, signal.StopLossPips) : 0;
      double takeProfit = signal.TakeProfitPips>0 ? GetTakeProfit(command, signal.TakeProfitPips) : 0;
      string comment    = IntegerToString(signal.MagicNumber);
      color  arrowColor = command==OP_BUY ? clrGreen : clrRed;

      if(IsTradeContextFree())
        {
         double price=MarketInfo(_Symbol,command==OP_BUY ? MODE_ASK : MODE_BID);
         if(useMM == Fixed)
         {
            Entry_Amount = Fix_Lot;              
         }
         if(useMM == Risk)
         {
            Entry_Amount = calculateLotSize(stopLoss);              
         }         
//---          
            Print("---------    LOT  -- ",Entry_Amount,"    ------------ ");         
         if(setProtectionSeparately)
           {
            ticket=OrderSend(_Symbol,command,amount,price,10,0,0,comment,signal.MagicNumber,0,arrowColor);
            if(ticket>0 && (signal.StopLossPips>0 || signal.TakeProfitPips>0))
               modified=OrderModify(ticket,0,stopLoss,takeProfit,0,clrBlue);
           }
         else
           {
            ticket=OrderSend(_Symbol,command,amount,price,10,stopLoss,takeProfit,comment,signal.MagicNumber,0,arrowColor);
            lastError=GetLastError();
            if(ticket<=0 && lastError==130)
              {
               ticket=OrderSend(_Symbol,command,amount,price,10,0,0,comment,signal.MagicNumber,0,arrowColor);
               if(ticket>0 && (signal.StopLossPips>0 || signal.TakeProfitPips>0))
                  modified=OrderModify(ticket,0,stopLoss,takeProfit,0,clrBlue);
               if(ticket>0 && modified)
                 {
                  setProtectionSeparately=true;
                  Print("Detected ECN type position protection.");
                 }
              }
           }
        }

      if(ticket>0) break;

      lastError=GetLastError();

      if(lastError!=135 && lastError!=136 && lastError!=137 && lastError!=138) break;

      Sleep(TRADE_RETRY_WAIT);
      Print("Open Position retry no: "+IntegerToString(attempt+2));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ClosePosition(Position &position)
  {
   for(int attempt=0; attempt<TRADE_RETRY_COUNT; attempt++)
     {
      bool closed;
      int lastError=0;

      if(IsTradeContextFree())
        {
         double price=MarketInfo(_Symbol,position.Type==OP_BUY ? MODE_BID : MODE_ASK);
         closed=OrderClose(position.Ticket,position.Lots,price,10,clrYellow);
         lastError=GetLastError();
        }

      if(closed)
        {
         position.Type       = OP_FLAT;
         position.Lots       = 0;
         position.Price      = 0;
         position.StopLoss   = 0;
         position.TakeProfit = 0;

         break;
        }

      if(lastError==4108) break;

      Sleep(TRADE_RETRY_WAIT);
      Print("Close Position retry no: "+IntegerToString(attempt+2));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ModifyPosition(Position &position)
  {
   for(int attempt=0; attempt<TRADE_RETRY_COUNT; attempt++)
     {
      bool modified;
      int lastError=0;

      if(IsTradeContextFree())
        {
         modified=OrderModify(position.Ticket,0,position.StopLoss,position.TakeProfit,0,clrBlue);
         lastError=GetLastError();
        }

      if(modified)
        {
         const int magicNumber=position.MagicNumber;
         position=CreatePosition(magicNumber);

         break;
        }

      if(lastError==4108)
         break;

      Sleep(TRADE_RETRY_WAIT);
      Print("Modify Position retry no: "+IntegerToString(attempt+2));
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void CloseAllPositions()
  {
   for(int i=0;i<strategiesCount;i++)
     {
      int magicNumber=GetMagicNumber(i);
      Position position=CreatePosition(magicNumber);

      if(position.Type==OP_BUY || position.Type==OP_SELL)
         ClosePosition(position);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetStopLoss(int command,int stopLossPips)
  {
   if(stopLossPips==0) return (0);

   double deltaPips      = MathMax(pip*stopLossPips, _Point*stopLevel);
   double referencePrice = MarketInfo(_Symbol, command==OP_BUY ? MODE_BID : MODE_ASK);
   double stopLossPoints = command==OP_BUY ? referencePrice-deltaPips : referencePrice+deltaPips;
   double finalStopLoss  = NormalizeDouble(stopLossPoints, digits);

   return (finalStopLoss);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetTakeProfit(int command,int takeProfitPips)
  {
   if(takeProfitPips==0) return (0);

   double deltaPips        = MathMax(pip*takeProfitPips, _Point*stopLevel);
   double referencePrice   = MarketInfo(_Symbol, command==OP_BUY ? MODE_BID : MODE_ASK);
   double takeProfitPoints = command==OP_BUY ? referencePrice+deltaPips : referencePrice-deltaPips;
   double finalTakeProfit  = NormalizeDouble(takeProfitPoints, digits);

   return (finalTakeProfit);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetTrailingStop(Position &position, int stopLoss)
  {
   double bid=MarketInfo(_Symbol,MODE_BID);
   double ask=MarketInfo(_Symbol,MODE_ASK);
   double stopLevelPoints=_Point*stopLevel;
   double stopLossPoints=pip*stopLoss;

   if(position.Type==OP_BUY)
     {
      double stopLossPrice=High[1]-stopLossPoints;
      if(position.StopLoss<stopLossPrice-pip)
        {
         if(stopLossPrice<bid)
           {
            if(stopLossPrice>=bid-stopLevelPoints)
               return (bid - stopLevelPoints);
            else
               return (stopLossPrice);
           }
         else
           {
            return (bid);
           }
        }
     }

   else if(position.Type==OP_SELL)
     {
      double stopLossPrice=Low[1]+stopLossPoints;
      if(position.StopLoss>stopLossPrice+pip)
        {
         if(stopLossPrice>ask)
           {
            if(stopLossPrice<=ask+stopLevelPoints)
               return (ask + stopLevelPoints);
            else
               return (stopLossPrice);
           }
         else
           {
            return (ask);
           }
        }
     }

   return (position.StopLoss);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void ManageTrailingStop(Position &position, double trailingStop)
  {
   double bid=MarketInfo(_Symbol,MODE_BID);
   double ask=MarketInfo(_Symbol,MODE_ASK);

   if(position.Type==OP_BUY && MathAbs(trailingStop-bid)<_Point)
     {
      ClosePosition(position);
     }

   else if(position.Type==OP_SELL && MathAbs(trailingStop-ask)<_Point)
     {
      ClosePosition(position);
     }

   else if(MathAbs(trailingStop-position.StopLoss)>_Point)
     {
      position.StopLoss=NormalizeDouble(trailingStop,digits);
      ModifyPosition(position);
     }
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsTradeContextFree()
  {
   if(IsTradeAllowed()) return (true);

   uint startWait=GetTickCount();
   Print("Trade context is busy! Waiting...");

   while(true)
     {
      if(IsStopped()) return (false);

      uint diff=GetTickCount()-startWait;
      if(diff>30*1000)
        {
         Print("The waiting limit exceeded!");
         return (false);
        }

      if(IsTradeAllowed())
        {
         RefreshRates();
         return (true);
        }
      Sleep(TRADE_RETRY_WAIT);
     }

   return (true);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsOutOfSession()
  {
   MqlDateTime time0; TimeToStruct(Time[0],time0);
   int weekDay           = time0.day_of_week;
   long timeFromMidnight = Time[0]%86400;
   int periodLength      = PeriodSeconds(_Period);
   bool skipTrade        = false;

   if(weekDay==0)
     {
      if(sessionIgnoreSunday) return true;
      int lastBarFix=sessionCloseAtSessionClose ? periodLength : 0;
      skipTrade=timeFromMidnight<sessionSundayOpen || timeFromMidnight+lastBarFix>sessionSundayClose;
     }
   else if(weekDay<5)
     {
      int lastBarFix=sessionCloseAtSessionClose ? periodLength : 0;
      skipTrade=timeFromMidnight<sessionMondayThursdayOpen || timeFromMidnight+lastBarFix>sessionMondayThursdayClose;
     }
   else
     {
      int lastBarFix=sessionCloseAtFridayClose || sessionCloseAtSessionClose ? periodLength : 0;
      skipTrade=timeFromMidnight<sessionFridayOpen || timeFromMidnight+lastBarFix>sessionFridayClose;
     }

   return (skipTrade);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool IsForceSessionClose()
  {
   if(!sessionCloseAtFridayClose && !sessionCloseAtSessionClose)
      return (false);

   MqlDateTime time0; TimeToStruct(Time[0],time0);
   int weekDay           = time0.day_of_week;
   long timeFromMidnight = Time[0]%86400;
   int periodLength      = PeriodSeconds(_Period);

   bool forceExit=false;
   if(weekDay==0 && sessionCloseAtSessionClose)
     {
      forceExit=timeFromMidnight+periodLength>sessionSundayClose;
     }
   else if(weekDay<5 && sessionCloseAtSessionClose)
     {
      forceExit=timeFromMidnight+periodLength>sessionMondayThursdayClose;
     }
   else if(weekDay==5)
     {
      forceExit=timeFromMidnight+periodLength>sessionFridayClose;
     }

   return (forceExit);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
datetime Time(int bar)
  {
   return Time[bar];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Open(int bar)
  {
   return Open[bar];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double High(int bar)
  {
   return High[bar];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Low(int bar)
  {
   return Low[bar];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double Close(int bar)
  {
   return Close[bar];
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
double GetPipValue()
  {
   switch((int) MarketInfo(_Symbol,MODE_DIGITS))
     {
      case  5: case  4: return (0.0001);
      case  3: case  2: return (0.01);
      case  1:          return (0.1);
     }

   return (1);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int GetMagicNumber(int strategyIndex)
  {
   int magic=1000*Base_Magic_Number+strategyIndex;
   return (magic);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int OrderDirectionToCommand(OrderDirection dir)
  {
   if(dir==ORDER_DIRECTION_BUY)  return (OP_BUY);
   if(dir==ORDER_DIRECTION_SELL) return (OP_SELL);

   return (OP_FLAT);
  }

Re: Coding Question - Dynamic ATR Stop Loss

Thank you !! I figured out it smile

Re: Coding Question - Dynamic ATR Stop Loss

does it work..i didint test it`?

Re: Coding Question - Dynamic ATR Stop Loss

I'll clarify - i didn't check the exact code you supplied, but it prompted me to start looking at the OnTick section and to read around that - which gave me the direction to follow and find the answer. I did see that section name in there but I cant figure from the code what it actually does so Im coding like a blank jigsaw puzzle and I guess trying to force bits together to see if that makes a picture or not.

I did indeed have my variables in the right place to calculate them all of once, then never again. Putting things onto the right section helped me to get the thing calculating and now my results are looking better on the strategy tester.