Multi-timeframe trading and one buy/one sell per period

Created at 09 Mar 2022, 13:15
How’s your experience with the cTrader Platform?
Your feedback is crucial to cTrader's development. Please take a few seconds to share your opinion and help us improve your trading experience. Thanks!
WM

wmclennan77

Joined 29.06.2021

Multi-timeframe trading and one buy/one sell per period
09 Mar 2022, 13:15


Hi, I am building a basic EA to test multi-timeframe trading, and I am having some trouble in that bot does not create any trades.

The bot needs to buy when Bull Price > Previous Period High (Bull Price = Price + Safety in Pips)
And sell when Bear Price < Previous Period Low open sell (Bear Price = Price - Safety in Pips)

Additionally, one of each (buy or sell) is allowed per trading day.

 

Here I have attached the code I am having problems with:

 

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AFFS : Robot
    {
        [Parameter("Name", DefaultValue = "AFFS")]
        public string _name { get; set; }

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double _starttime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 18.0)]
        public double _stoptime { get; set; }

        [Parameter("Max Lots", DefaultValue = 100.0, MinValue = 0.01, MaxValue = 1000.0)]
        public double _maxlots { get; set; }

        [Parameter("Starting Risk (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _startingrisk { get; set; }

        [Parameter("Risk Step (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _riskstep { get; set; }

        [Parameter("Take Profit", DefaultValue = 5.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _takeprofit { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _stoploss { get; set; }

        [Parameter("Safety (Pips)", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _safety { get; set; }

        [Parameter("High/Low Timeframe", DefaultValue = "Daily")]
        public TimeFrame _hltf { get; set; }

        private Bars _hlbars;
        private double _bullprice, _bearprice, _previoushigh, _previouslow, _maxunits, _activerisk;
        private bool _todaybuy, _todaysell;

        protected override void OnStart()
        {
            _hlbars = MarketData.GetBars(_hltf);
        }

        protected override void OnBar()
        {
            var _currenthours = Server.Time.TimeOfDay.TotalHours;
            bool _tradetime = _starttime < _stoptime ? _currenthours > _starttime && _currenthours < _stoptime : _currenthours < _stoptime || _currenthours > _starttime;

            _activerisk = GetRisk();
            var _volume = GetVolume();
            _maxunits = Symbol.QuantityToVolumeInUnits(_maxlots);
            if (_volume > _maxunits)
            {
                _volume = _maxunits;
            }
            _previoushigh = _hlbars.HighPrices.Last(1);
            _previouslow = _hlbars.LowPrices.Last(1);
            _bullprice = Symbol.Ask + (_safety / Symbol.PipValue);
            _bearprice = Symbol.Bid - (_safety / Symbol.PipValue);

            if (_tradetime && !_todaybuy)
            {
                if (_bullprice > _previoushigh)
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaybuy = true;
                }
            }
            if (!_tradetime && _todaybuy)
            {
                _todaybuy = false;
            }

            if (_tradetime && !_todaysell)
            {
                if (_bearprice < _previouslow)
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaysell = true;
                }
            }
            if (!_tradetime && _todaysell)
            {
                _todaysell = false;
            }
        }

        private double GetRisk()
        {
            double _result = 0.0;
            double _maxrisk = 10.0;
            var _lastposition = History.FindLast(_name);
            bool _win = _lastposition.NetProfit > 0.0 ? true : false;
            if (_win && _activerisk < _maxrisk)
            {
                _result = _activerisk + _riskstep;
            }
            else if (!_win)
            {
                _result = _startingrisk;
            }
            return _result;
        }

        private double GetVolume()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;

            double baseNumber = Account.Balance;

            double sizeInLots = Math.Round((baseNumber * _activerisk / 100) / (_stoploss * costPerPip), 2);

            var result = Symbol.QuantityToVolumeInUnits(sizeInLots);

            if (result > Symbol.VolumeInUnitsMax)
            {
                result = Symbol.VolumeInUnitsMax;
            }
            else if (result < Symbol.VolumeInUnitsMin)
            {
                result = Symbol.VolumeInUnitsMin;
            }
            else if (result % Symbol.VolumeInUnitsStep != 0)
            {
                result = result - (result % Symbol.VolumeInUnitsStep);
            }

            return result;
        }
    }
}

 


@wmclennan77
Replies

amusleh
10 Mar 2022, 10:16

Hi,

Try this:

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AFFS : Robot
    {
        [Parameter("Name", DefaultValue = "AFFS")]
        public string _name { get; set; }

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double _starttime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 18.0)]
        public double _stoptime { get; set; }

        [Parameter("Max Lots", DefaultValue = 100.0, MinValue = 0.01, MaxValue = 1000.0)]
        public double _maxlots { get; set; }

        [Parameter("Starting Risk (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _startingrisk { get; set; }

        [Parameter("Risk Step (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _riskstep { get; set; }

        [Parameter("Take Profit", DefaultValue = 5.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _takeprofit { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _stoploss { get; set; }

        [Parameter("Safety (Pips)", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _safety { get; set; }

        [Parameter("High/Low Timeframe", DefaultValue = "Daily")]
        public TimeFrame _hltf { get; set; }

        private Bars _hlbars;
        private double _bullprice, _bearprice, _previoushigh, _previouslow, _maxunits, _activerisk;
        private bool _todaybuy, _todaysell;

        protected override void OnStart()
        {
            _hlbars = MarketData.GetBars(_hltf);

            _safety *= Symbol.PipSize;
        }

        protected override void OnBar()
        {
            var _currenthours = Server.Time.TimeOfDay.TotalHours;
            bool _tradetime = _starttime < _stoptime ? _currenthours > _starttime && _currenthours < _stoptime : _currenthours < _stoptime || _currenthours > _starttime;

            _activerisk = GetRisk();
            var _volume = GetVolume();
            _maxunits = Symbol.QuantityToVolumeInUnits(_maxlots);
            if (_volume > _maxunits)
            {
                _volume = _maxunits;
            }
            _previoushigh = _hlbars.HighPrices.Last(1);
            _previouslow = _hlbars.LowPrices.Last(1);
            _bullprice = Symbol.Ask + _safety;
            _bearprice = Symbol.Bid - _safety;

            if (_tradetime && !_todaybuy)
            {
                if (_bullprice > _previoushigh)
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaybuy = true;
                }
            }
            if (!_tradetime && _todaybuy)
            {
                _todaybuy = false;
            }

            if (_tradetime && !_todaysell)
            {
                if (_bearprice < _previouslow)
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaysell = true;
                }
            }
            if (!_tradetime && _todaysell)
            {
                _todaysell = false;
            }
        }

        private double GetRisk()
        {
            double _result = 0.0;
            double _maxrisk = 10.0;
            var _lastposition = History.FindLast(_name);
            bool _win = _lastposition != null && _lastposition.NetProfit > 0.0 ? true : false;
            if (_win && _activerisk < _maxrisk)
            {
                _result = _activerisk + _riskstep;
            }
            else if (!_win)
            {
                _result = _startingrisk;
            }
            return _result;
        }

        private double GetVolume()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;

            double baseNumber = Account.Balance;

            double sizeInLots = Math.Round((baseNumber * _activerisk / 100) / (_stoploss * costPerPip), 2);

            var result = Symbol.QuantityToVolumeInUnits(sizeInLots);

            if (result > Symbol.VolumeInUnitsMax)
            {
                result = Symbol.VolumeInUnitsMax;
            }
            else if (result < Symbol.VolumeInUnitsMin)
            {
                result = Symbol.VolumeInUnitsMin;
            }
            else if (result % Symbol.VolumeInUnitsStep != 0)
            {
                result = result - (result % Symbol.VolumeInUnitsStep);
            }

            return result;
        }
    }
}

 


@amusleh

wmclennan77
10 Mar 2022, 13:25

RE:

amusleh said:

Hi,

Try this:

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AFFS : Robot
    {
        [Parameter("Name", DefaultValue = "AFFS")]
        public string _name { get; set; }

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double _starttime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 18.0)]
        public double _stoptime { get; set; }

        [Parameter("Max Lots", DefaultValue = 100.0, MinValue = 0.01, MaxValue = 1000.0)]
        public double _maxlots { get; set; }

        [Parameter("Starting Risk (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _startingrisk { get; set; }

        [Parameter("Risk Step (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _riskstep { get; set; }

        [Parameter("Take Profit", DefaultValue = 5.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _takeprofit { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _stoploss { get; set; }

        [Parameter("Safety (Pips)", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _safety { get; set; }

        [Parameter("High/Low Timeframe", DefaultValue = "Daily")]
        public TimeFrame _hltf { get; set; }

        private Bars _hlbars;
        private double _bullprice, _bearprice, _previoushigh, _previouslow, _maxunits, _activerisk;
        private bool _todaybuy, _todaysell;

        protected override void OnStart()
        {
            _hlbars = MarketData.GetBars(_hltf);

            _safety *= Symbol.PipSize;
        }

        protected override void OnBar()
        {
            var _currenthours = Server.Time.TimeOfDay.TotalHours;
            bool _tradetime = _starttime < _stoptime ? _currenthours > _starttime && _currenthours < _stoptime : _currenthours < _stoptime || _currenthours > _starttime;

            _activerisk = GetRisk();
            var _volume = GetVolume();
            _maxunits = Symbol.QuantityToVolumeInUnits(_maxlots);
            if (_volume > _maxunits)
            {
                _volume = _maxunits;
            }
            _previoushigh = _hlbars.HighPrices.Last(1);
            _previouslow = _hlbars.LowPrices.Last(1);
            _bullprice = Symbol.Ask + _safety;
            _bearprice = Symbol.Bid - _safety;

            if (_tradetime && !_todaybuy)
            {
                if (_bullprice > _previoushigh)
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaybuy = true;
                }
            }
            if (!_tradetime && _todaybuy)
            {
                _todaybuy = false;
            }

            if (_tradetime && !_todaysell)
            {
                if (_bearprice < _previouslow)
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaysell = true;
                }
            }
            if (!_tradetime && _todaysell)
            {
                _todaysell = false;
            }
        }

        private double GetRisk()
        {
            double _result = 0.0;
            double _maxrisk = 10.0;
            var _lastposition = History.FindLast(_name);
            bool _win = _lastposition != null && _lastposition.NetProfit > 0.0 ? true : false;
            if (_win && _activerisk < _maxrisk)
            {
                _result = _activerisk + _riskstep;
            }
            else if (!_win)
            {
                _result = _startingrisk;
            }
            return _result;
        }

        private double GetVolume()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;

            double baseNumber = Account.Balance;

            double sizeInLots = Math.Round((baseNumber * _activerisk / 100) / (_stoploss * costPerPip), 2);

            var result = Symbol.QuantityToVolumeInUnits(sizeInLots);

            if (result > Symbol.VolumeInUnitsMax)
            {
                result = Symbol.VolumeInUnitsMax;
            }
            else if (result < Symbol.VolumeInUnitsMin)
            {
                result = Symbol.VolumeInUnitsMin;
            }
            else if (result % Symbol.VolumeInUnitsStep != 0)
            {
                result = result - (result % Symbol.VolumeInUnitsStep);
            }

            return result;
        }
    }
}

 

Hi amusleh,

Thanks, works perfectly!


@wmclennan77

wmclennan77
11 Mar 2022, 11:42

RE:

amusleh said:

Hi,

Try this:

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AFFS : Robot
    {
        [Parameter("Name", DefaultValue = "AFFS")]
        public string _name { get; set; }

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double _starttime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 18.0)]
        public double _stoptime { get; set; }

        [Parameter("Max Lots", DefaultValue = 100.0, MinValue = 0.01, MaxValue = 1000.0)]
        public double _maxlots { get; set; }

        [Parameter("Starting Risk (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _startingrisk { get; set; }

        [Parameter("Risk Step (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _riskstep { get; set; }

        [Parameter("Take Profit", DefaultValue = 5.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _takeprofit { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _stoploss { get; set; }

        [Parameter("Safety (Pips)", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _safety { get; set; }

        [Parameter("High/Low Timeframe", DefaultValue = "Daily")]
        public TimeFrame _hltf { get; set; }

        private Bars _hlbars;
        private double _bullprice, _bearprice, _previoushigh, _previouslow, _maxunits, _activerisk;
        private bool _todaybuy, _todaysell;

        protected override void OnStart()
        {
            _hlbars = MarketData.GetBars(_hltf);

            _safety *= Symbol.PipSize;
        }

        protected override void OnBar()
        {
            var _currenthours = Server.Time.TimeOfDay.TotalHours;
            bool _tradetime = _starttime < _stoptime ? _currenthours > _starttime && _currenthours < _stoptime : _currenthours < _stoptime || _currenthours > _starttime;

            _activerisk = GetRisk();
            var _volume = GetVolume();
            _maxunits = Symbol.QuantityToVolumeInUnits(_maxlots);
            if (_volume > _maxunits)
            {
                _volume = _maxunits;
            }
            _previoushigh = _hlbars.HighPrices.Last(1);
            _previouslow = _hlbars.LowPrices.Last(1);
            _bullprice = Symbol.Ask + _safety;
            _bearprice = Symbol.Bid - _safety;

            if (_tradetime && !_todaybuy)
            {
                if (_bullprice > _previoushigh)
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaybuy = true;
                }
            }
            if (!_tradetime && _todaybuy)
            {
                _todaybuy = false;
            }

            if (_tradetime && !_todaysell)
            {
                if (_bearprice < _previouslow)
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaysell = true;
                }
            }
            if (!_tradetime && _todaysell)
            {
                _todaysell = false;
            }
        }

        private double GetRisk()
        {
            double _result = 0.0;
            double _maxrisk = 10.0;
            var _lastposition = History.FindLast(_name);
            bool _win = _lastposition != null && _lastposition.NetProfit > 0.0 ? true : false;
            if (_win && _activerisk < _maxrisk)
            {
                _result = _activerisk + _riskstep;
            }
            else if (!_win)
            {
                _result = _startingrisk;
            }
            return _result;
        }

        private double GetVolume()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;

            double baseNumber = Account.Balance;

            double sizeInLots = Math.Round((baseNumber * _activerisk / 100) / (_stoploss * costPerPip), 2);

            var result = Symbol.QuantityToVolumeInUnits(sizeInLots);

            if (result > Symbol.VolumeInUnitsMax)
            {
                result = Symbol.VolumeInUnitsMax;
            }
            else if (result < Symbol.VolumeInUnitsMin)
            {
                result = Symbol.VolumeInUnitsMin;
            }
            else if (result % Symbol.VolumeInUnitsStep != 0)
            {
                result = result - (result % Symbol.VolumeInUnitsStep);
            }

            return result;
        }
    }
}

 

Hi amusleh,

I have one more issue if you can help me.

In the bot above, is there any way to check in the OnStart if:
In the _hlbars period,  the one entry for the day has already happened? If so, the bot cannot trade until the next period.

 

For example, if HL is set to daily and I start the bot at 2 PM and today's entry happened at 1 PM, I don't want the bot to trade until the next day.

What is happening now is when I initialize the bot, the logic sees that the current price is higher than the previous high, and makes a buy immediately. This is wrong since the ideal entry has passed.

Any help would be greatly appreciated, thanks.


@wmclennan77

amusleh
14 Mar 2022, 08:58

Hi,

You can use the loaded Bars BarOpened event instead of Bot OnBar method, ex:

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class AFFS : Robot
    {
        [Parameter("Name", DefaultValue = "AFFS")]
        public string _name { get; set; }

        [Parameter("Start Hour", DefaultValue = 6.0)]
        public double _starttime { get; set; }

        [Parameter("Stop Hour", DefaultValue = 18.0)]
        public double _stoptime { get; set; }

        [Parameter("Max Lots", DefaultValue = 100.0, MinValue = 0.01, MaxValue = 1000.0)]
        public double _maxlots { get; set; }

        [Parameter("Starting Risk (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _startingrisk { get; set; }

        [Parameter("Risk Step (%)", DefaultValue = 1.0, MinValue = 0.01, MaxValue = 100.0)]
        public double _riskstep { get; set; }

        [Parameter("Take Profit", DefaultValue = 5.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _takeprofit { get; set; }

        [Parameter("Stop Loss", DefaultValue = 10.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _stoploss { get; set; }

        [Parameter("Safety (Pips)", DefaultValue = 3.0, MinValue = 0.1, MaxValue = 100.0)]
        public double _safety { get; set; }

        [Parameter("High/Low Timeframe", DefaultValue = "Daily")]
        public TimeFrame _hltf { get; set; }

        private Bars _hlbars;
        private double _bullprice, _bearprice, _previoushigh, _previouslow, _maxunits, _activerisk;
        private bool _todaybuy, _todaysell;

        protected override void OnStart()
        {
            _hlbars = MarketData.GetBars(_hltf);

            _hlbars.BarOpened += _hlbars_BarOpened;
            _safety *= Symbol.PipSize;
        }

        private void _hlbars_BarOpened(BarOpenedEventArgs obj)
        {
            var _currenthours = Server.Time.TimeOfDay.TotalHours;
            bool _tradetime = _starttime < _stoptime ? _currenthours > _starttime && _currenthours < _stoptime : _currenthours < _stoptime || _currenthours > _starttime;

            _activerisk = GetRisk();
            var _volume = GetVolume();
            _maxunits = Symbol.QuantityToVolumeInUnits(_maxlots);
            if (_volume > _maxunits)
            {
                _volume = _maxunits;
            }
            _previoushigh = _hlbars.HighPrices.Last(1);
            _previouslow = _hlbars.LowPrices.Last(1);
            _bullprice = Symbol.Ask + _safety;
            _bearprice = Symbol.Bid - _safety;

            if (_tradetime && !_todaybuy)
            {
                if (_bullprice > _previoushigh)
                {
                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaybuy = true;
                }
            }
            if (!_tradetime && _todaybuy)
            {
                _todaybuy = false;
            }

            if (_tradetime && !_todaysell)
            {
                if (_bearprice < _previouslow)
                {
                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, _volume, _name, _stoploss, _takeprofit);
                    _todaysell = true;
                }
            }
            if (!_tradetime && _todaysell)
            {
                _todaysell = false;
            }
        }

        private double GetRisk()
        {
            double _result = 0.0;
            double _maxrisk = 10.0;
            var _lastposition = History.FindLast(_name);
            bool _win = _lastposition != null && _lastposition.NetProfit > 0.0 ? true : false;
            if (_win && _activerisk < _maxrisk)
            {
                _result = _activerisk + _riskstep;
            }
            else if (!_win)
            {
                _result = _startingrisk;
            }
            return _result;
        }

        private double GetVolume()
        {
            double costPerPip = (double)((int)(Symbol.PipValue * 10000000)) / 100;

            double baseNumber = Account.Balance;

            double sizeInLots = Math.Round((baseNumber * _activerisk / 100) / (_stoploss * costPerPip), 2);

            var result = Symbol.QuantityToVolumeInUnits(sizeInLots);

            if (result > Symbol.VolumeInUnitsMax)
            {
                result = Symbol.VolumeInUnitsMax;
            }
            else if (result < Symbol.VolumeInUnitsMin)
            {
                result = Symbol.VolumeInUnitsMin;
            }
            else if (result % Symbol.VolumeInUnitsStep != 0)
            {
                result = result - (result % Symbol.VolumeInUnitsStep);
            }

            return result;
        }
    }
}

This way the execution logic will be executed only once per bar based on your selected time frame.


@amusleh