Variable is displayed differently in the indicator and in the robot

Created at 03 Mar 2021, 15:35
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!
TR

travkinsm1

Joined 05.04.2018

Variable is displayed differently in the indicator and in the robot
03 Mar 2021, 15:35


Hello! When testing the indicator, I noticed that one of the variables (_isLong) is displayed differently in the indicator and in the robot. If you do not pay attention to the different processing of ticks by the robot and the indicator, you can verify this by analyzing 2 log files. Tell me, please, what could be the matter? (For testing, you need to change the paths to the files)

using System;
using System.Linq;
using System.Windows;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;


namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class MycBot : Robot
    {
        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }


        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter("Timeframe1", DefaultValue = "Ticks10")]
        public TimeFrame TF { get; set; }

        [Parameter("Загрузить Баров", DefaultValue = 30000)]
        public int BarCount_set { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }

        [Parameter("Запись в файл", DefaultValue = true)]
        public bool FileWrite { get; set; }
        [Parameter("Запись торговли в файл", DefaultValue = true)]
        public bool FileWrite2 { get; set; }

        private Bars Bars2;
        public StreamWriter file;
        public int LoadHistory_for_ind = 3000;


        protected override void OnStart()
        {
            while (Bars.Count < BarCount_set)
            {
                var loadedCount = Bars.LoadMoreHistory();
                Print("Loaded {0} bars", loadedCount);
                Print("Total bars {0}", Bars.Count);
                if (loadedCount == 0)
                    break;
            }
            Print("Finished, total bars {0}", Bars.Count);
            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            while (Bars2.Count < (BarCount_set / 10))
            {
                var loadedCount = Bars2.LoadMoreHistory();
                if (loadedCount == 0)
                    break;
            }
            Print("Finished, total bars {0}", Bars2.Count);
            file = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long2.txt", false);
            file.WriteLine("Begin");
            file.Flush();
            file.Close();
        }
        protected override void OnTick()
        {
            bool dirInd = Indicators.GetIndicator<ATR_Stops_time_MarketData_History>(TF, MaType, 10, 4, UseHighAndLow, LoadHistory_for_ind, LoadIndHist)._isLong;
            file = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long2.txt", true);
            file.WriteLine("Bot " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + dirInd);
            file.Flush();
            file.Close();
        }
    }
}
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Indicators
{
    [Indicator("ATR Trailing Stop", AutoRescale = false, IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class ATR_Stops_time_MarketData_History : Indicator
    {

        [Parameter("Timeframe", DefaultValue = 0.0)]
        public TimeFrame TF { get; set; }

        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Parameter("Period", DefaultValue = 10, MinValue = 2, MaxValue = 50000)]
        public int Period { get; set; }

        [Parameter("Weight", DefaultValue = 4.0, MinValue = 0.1, MaxValue = 400.0)]
        public double Weight { get; set; }

        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter(DefaultValue = 16000)]
        public int LoadHistory_for_ind { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }


        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        private ATRMTF_time_History _atr;
        public bool _isLong;

        private MarketSeries _marketSeries;

        private Bars Bars2;
        public StreamWriter file3;

        protected override void Initialize()
        {
            Print("Start");

            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            Print("{0} bar on the chart. Loading 2.000.000 bars", Bars2.Count);
            if (LoadIndHist == true)
            {
                while (Bars2.Count < LoadHistory_for_ind)
                {
                    var loadedCount = Bars2.LoadMoreHistory();
                    if (loadedCount == 0)
                        break;
                }
                Print("Finished, total bars {0}", Bars2.Count);
            }
            Print("1");
            this._marketSeries = MarketData.GetSeries(MarketData.GetSymbol(Symbol.Name), TF);

        }


        public override void Calculate(int index)
        {
            var currentAtr = Weight * _atr.Result[index];

            if (double.IsNaN(currentAtr))
                return;

if (double.IsNaN(Result[index - 1]) && !double.IsNaN(_atr.Result[index - 1]))
            {
                var previousATR = Weight * _atr.Result[index - 1];

                _isLong = MarketSeries.Close.IsRising();

                var previous = UseHighAndLow ? (_isLong ? this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])] : this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])]) : this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])];

                Result[index] = _isLong ? previous - previousATR : previous + previousATR;
            }
            else
            {
                var current = this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

                if (_isLong)
                {
                    if (current >= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Max(Result[index - 1], current - currentAtr);
                    }
                    else
                    {
                        _isLong = false;
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current + currentAtr;
                    }
                }
                else
                {
                    if (current <= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Min(Result[index - 1], current + currentAtr);
                    }
                    else
                    {
                        _isLong = true;
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current - currentAtr;
                    }
                }
            }
            file3 = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long.txt", true);
            file3.WriteLine("Indicator " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + Period + " " + Weight + " " + _isLong);
            file3.Flush();
            file3.Close();

        }
    }
}

 


@travkinsm1
Replies

travkinsm1
03 Mar 2021, 15:36

I forgot to say that I launch the robot on the 1 tick timeframe, and the indicator on 10 ticks. The timeframe parameter in the indicator is also 10 ticks


@travkinsm1

amusleh
04 Mar 2021, 09:55

RE:

travkinsm1 said:

Hello! When testing the indicator, I noticed that one of the variables (_isLong) is displayed differently in the indicator and in the robot. If you do not pay attention to the different processing of ticks by the robot and the indicator, you can verify this by analyzing 2 log files. Tell me, please, what could be the matter? (For testing, you need to change the paths to the files)

using System;
using System.Linq;
using System.Windows;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;


namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class MycBot : Robot
    {
        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }


        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter("Timeframe1", DefaultValue = "Ticks10")]
        public TimeFrame TF { get; set; }

        [Parameter("Загрузить Баров", DefaultValue = 30000)]
        public int BarCount_set { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }

        [Parameter("Запись в файл", DefaultValue = true)]
        public bool FileWrite { get; set; }
        [Parameter("Запись торговли в файл", DefaultValue = true)]
        public bool FileWrite2 { get; set; }

        private Bars Bars2;
        public StreamWriter file;
        public int LoadHistory_for_ind = 3000;


        protected override void OnStart()
        {
            while (Bars.Count < BarCount_set)
            {
                var loadedCount = Bars.LoadMoreHistory();
                Print("Loaded {0} bars", loadedCount);
                Print("Total bars {0}", Bars.Count);
                if (loadedCount == 0)
                    break;
            }
            Print("Finished, total bars {0}", Bars.Count);
            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            while (Bars2.Count < (BarCount_set / 10))
            {
                var loadedCount = Bars2.LoadMoreHistory();
                if (loadedCount == 0)
                    break;
            }
            Print("Finished, total bars {0}", Bars2.Count);
            file = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long2.txt", false);
            file.WriteLine("Begin");
            file.Flush();
            file.Close();
        }
        protected override void OnTick()
        {
            bool dirInd = Indicators.GetIndicator<ATR_Stops_time_MarketData_History>(TF, MaType, 10, 4, UseHighAndLow, LoadHistory_for_ind, LoadIndHist)._isLong;
            file = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long2.txt", true);
            file.WriteLine("Bot " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + dirInd);
            file.Flush();
            file.Close();
        }
    }
}
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Indicators
{
    [Indicator("ATR Trailing Stop", AutoRescale = false, IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class ATR_Stops_time_MarketData_History : Indicator
    {

        [Parameter("Timeframe", DefaultValue = 0.0)]
        public TimeFrame TF { get; set; }

        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Parameter("Period", DefaultValue = 10, MinValue = 2, MaxValue = 50000)]
        public int Period { get; set; }

        [Parameter("Weight", DefaultValue = 4.0, MinValue = 0.1, MaxValue = 400.0)]
        public double Weight { get; set; }

        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter(DefaultValue = 16000)]
        public int LoadHistory_for_ind { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }


        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        private ATRMTF_time_History _atr;
        public bool _isLong;

        private MarketSeries _marketSeries;

        private Bars Bars2;
        public StreamWriter file3;

        protected override void Initialize()
        {
            Print("Start");

            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            Print("{0} bar on the chart. Loading 2.000.000 bars", Bars2.Count);
            if (LoadIndHist == true)
            {
                while (Bars2.Count < LoadHistory_for_ind)
                {
                    var loadedCount = Bars2.LoadMoreHistory();
                    if (loadedCount == 0)
                        break;
                }
                Print("Finished, total bars {0}", Bars2.Count);
            }
            Print("1");
            this._marketSeries = MarketData.GetSeries(MarketData.GetSymbol(Symbol.Name), TF);

        }


        public override void Calculate(int index)
        {
            var currentAtr = Weight * _atr.Result[index];

            if (double.IsNaN(currentAtr))
                return;

if (double.IsNaN(Result[index - 1]) && !double.IsNaN(_atr.Result[index - 1]))
            {
                var previousATR = Weight * _atr.Result[index - 1];

                _isLong = MarketSeries.Close.IsRising();

                var previous = UseHighAndLow ? (_isLong ? this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])] : this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])]) : this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])];

                Result[index] = _isLong ? previous - previousATR : previous + previousATR;
            }
            else
            {
                var current = this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

                if (_isLong)
                {
                    if (current >= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Max(Result[index - 1], current - currentAtr);
                    }
                    else
                    {
                        _isLong = false;
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current + currentAtr;
                    }
                }
                else
                {
                    if (current <= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Min(Result[index - 1], current + currentAtr);
                    }
                    else
                    {
                        _isLong = true;
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current - currentAtr;
                    }
                }
            }
            file3 = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long.txt", true);
            file3.WriteLine("Indicator " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + Period + " " + Weight + " " + _isLong);
            file3.Flush();
            file3.Close();

        }
    }
}

 

Inside your cBot OnTick method: 

            bool dirInd = Indicators.GetIndicator<ATR_Stops_time_MarketData_History>(TF, MaType, 10, 4, UseHighAndLow, LoadHistory_for_ind, LoadIndHist)._isLong;

You should not do this, you have to initialize a custom indicator on your cBot OnStart method not inside OnTick method.

And don't use properties/fields of your custom indicator, instead try to use IndicatorDataSeries, you can't get the actual value of properties/fields inside your cBot.


@amusleh

travkinsm1
04 Mar 2021, 16:22 ( Updated at: 04 Mar 2021, 16:27 )

RE: RE:

 

Perhaps this is because I am using an array of indicators, but when I corrected the code as follows, nothing changed.

using System;
using System.Linq;
using System.Windows;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;


namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class MycBot : Robot
    {
        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { getset; }


        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { getset; }

        [Parameter("Timeframe1", DefaultValue = "Ticks10")]
        public TimeFrame TF { getset; }

        [Parameter("Загрузить Баров", DefaultValue = 30000)]
        public int BarCount_set { getset; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { getset; }

        private Int32 weightCount = 3;
        private double weightMin = 2, weightStep = 1;
        private Int32 perCount = 3;
        private Int32 perMin = 10, perStep = 5;
        private Int32 arPeriod, arWeight;

        private ATR_Stops_time_MarketData_History[,] stop_ind;

        private Bars Bars2;
        private StreamWriter file;
        private int LoadHistory_for_ind = 3000;
        private int period;
        private double weight;
        private bool dirInd;

        protected override void OnStart()
        {
            while (Bars.Count < BarCount_set)
            {
                var loadedCount = Bars.LoadMoreHistory();
                Print("Loaded {0} bars", loadedCount);
                Print("Total bars {0}", Bars.Count);
                if (loadedCount == 0)
                    break;
            }
            Print("Finished, total bars {0}", Bars.Count);
            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            while (Bars2.Count < (BarCount_set / 10))
            {
                var loadedCount = Bars2.LoadMoreHistory();
                if (loadedCount == 0)
                    break;
            }
            stop_ind = new ATR_Stops_time_MarketData_History[perCount, weightCount];
            for (int z2 = 0; z2 < perCount; z2++)
                for (int z3 = 0; z3 < weightCount; z3++)
                {
                    int Per = perMin + perStep * z3;
                    double Weight = weightMin + weightStep * z2;
                    stop_ind[z2, z3] = Indicators.GetIndicator<ATR_Stops_time_MarketData_History>(TF, MaType, Per, Weight, UseHighAndLow, LoadHistory_for_ind, LoadIndHist);
                }
            Print("Finished, total bars {0}", Bars2.Count);
            file = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long2.txt"false);
            file.WriteLine("Begin");
            file.Flush();
            file.Close();
            Calc();
            Timer.Start(120);
        }
        protected override void OnTimer()
        {
            Calc();
        }
        protected void Calc()
        {
            var rand = new Random();
            arPeriod = rand.Next(0, perCount - 1);
            period = perMin + arPeriod * perStep;
            arWeight = rand.Next(0, weightCount - 1);
            weight = weightMin + arWeight * weightStep;
            Print("weight=" + weight + " period=" + period);
        }
        protected override void OnTick()
        {
            if (stop_ind[arWeight, arPeriod]._myIsLong.LastValue == 1)
                dirInd = true;
            else
                dirInd = false;
            file = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long2.txt"true);
            file.WriteLine("Bot " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + weight + " " + period + " " + dirInd);
            file.Flush();
            file.Close();
            Print("Bot " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + weight + " " + period + " " + dirInd);
        }
    }
}
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Indicators
{
    [Indicator("ATR Trailing Stop", AutoRescale = false, IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class ATR_Stops_time_MarketData_History : Indicator
    {

        [Parameter("Timeframe", DefaultValue = 0.0)]
        public TimeFrame TF { get; set; }

        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Parameter("Period", DefaultValue = 10, MinValue = 2, MaxValue = 50000)]
        public int Period { get; set; }

        [Parameter("Weight", DefaultValue = 4.0, MinValue = 0.1, MaxValue = 400.0)]
        public double Weight { get; set; }

        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter(DefaultValue = 16000)]
        public int LoadHistory_for_ind { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }


        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }
        [Output("My")]
        public IndicatorDataSeries _myIsLong { get; set; }
        private ATRMTF_time_History _atr;
        public bool _isLong;


        private MarketSeries _marketSeries;

        //private AverageTrueRange_Cust_lag[,] stop_ind = new ATRStops[perCount, weightCount];
        private Bars Bars2;
        public StreamWriter file3;

        protected override void Initialize()
        {
            Print("Start");

            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            // Print("2");
            Print("{0} bar on the chart. Loading 2.000.000 bars", Bars2.Count);
            //Print("3");
            if (LoadIndHist == true)
            {
                while (Bars2.Count < LoadHistory_for_ind)
                {
                    //  Print("3");
                    var loadedCount = Bars2.LoadMoreHistory();
                    //Print("3");
                    //Print("Loaded {0} bars", loadedCount);
                    //Print("Total bars {0}", Bars2.Count);
                    if (loadedCount == 0)
                        break;
                }
                Print("Finished, total bars {0}", Bars2.Count);
            }
            /*file3 = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long.txt", false);
            file3.WriteLine("Indicator Begin");
            file3.Flush();
            file3.Close();
            */
            Print("1");
            // Result = CreateDataSeries();
            //ATR = CreateDataSeries();
            // _marketSeries = MarketData.GetSeries(TF);
            _atr = Indicators.GetIndicator<ATRMTF_time_History>(Period, TF, LoadHistory_for_ind, LoadIndHist);
            // _atr = Indicators.AverageTrueRange(Period, MaType);
            ////Print("_marketSeries : {0}", _marketSeries);
            ////Print("_atr : {0}", _atr);
            this._marketSeries = MarketData.GetSeries(MarketData.GetSymbol(Symbol.Name), TF);

            //else
            //Print("Не загружено {0} баров", BarCount_set);
        }


        public override void Calculate(int index)
        {

            ////Print(index, " ", _atr.Result[index]);

            var currentAtr = Weight * _atr.Result[index];

            if (double.IsNaN(currentAtr))
                return;
            /* Print("_marketSeries.Close {0}", this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])]);
            Print("_marketSeries.High {0}", this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])]);
            Print("_marketSeries.Low {0}", this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])]);
            */
            //Print("MarketData..close..IsRising: {0}", MarketData.GetBars(TF, Symbol.Name).ClosePrices.IsRising());
                        /*
            Print("MarketData..close[index] {0}", MarketData.GetBars(TF, Symbol.Name).ClosePrices[index]);
            Print("MarketData..LastValue: {0}", MarketData.GetBars(TF, Symbol.Name).ClosePrices.LastValue);
            Print("MarketData..Last: {0}", MarketData.GetBars(TF, Symbol.Name).ClosePrices.Count);
*/

if (double.IsNaN(Result[index - 1]) && !double.IsNaN(_atr.Result[index - 1]))
            {
                var previousATR = Weight * _atr.Result[index - 1];

                _isLong = MarketSeries.Close.IsRising();

                var previous = UseHighAndLow ? (_isLong ? this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])] : this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])]) : this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])];

                Result[index] = _isLong ? previous - previousATR : previous + previousATR;
            }
            else
            {
                var current = this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

                if (_isLong)
                {
                    if (current >= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Max(Result[index - 1], current - currentAtr);
                    }
                    else
                    {
                        _isLong = false;
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current + currentAtr;
                    }
                }
                else
                {
                    if (current <= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Min(Result[index - 1], current + currentAtr);
                    }
                    else
                    {
                        _isLong = true;
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current - currentAtr;
                    }
                }
            }
            if (_isLong)
                _myIsLong[index] = 1;
            else
                _myIsLong[index] = -1;
        }
    }
    /*file3 = new StreamWriter("C:\\Users\\travk_000\\Documents\\bot1.3_is_long.txt", true);
            file3.WriteLine("Indicator " + Bars.OpenPrices.LastValue + " " + Bars.OpenTimes.LastValue + " " + Period + " " + Weight + " " + _isLong);
            file3.Flush();
            file3.Close();*/

}

naturally in my original code weight and period are not random


@travkinsm1

travkinsm1
08 Mar 2021, 18:06

Re3:

members of the forum, and first of all amusleh, have any thoughts about my problem?


@travkinsm1

amusleh
09 Mar 2021, 12:33

RE: Re3:

travkinsm1 said:

members of the forum, and first of all amusleh, have any thoughts about my problem?

I tried to compile your code but the "ATRMTF_time_History" indicator is missing, please decrease the amount of your code and post it again so I will be able to find the issue.

Right now I don't see any specific issue on your cBot code, but your indicator might be the problem.

Regarding getting different values, it can be because cBot loads different data, not the same amount of data that indicator uses, your indicator is a multi time frame indicator and it references another multi time frame indicator, which can cause this mismatch.

I recommend you if its possible move your indicator code to your cBot, that will decrease the complexity and you will have direct access to code so you will not much easier what goes wrong.

Try to use the indicator on a small sample cBot, see if you can replicate the issue, if you were able then post that small sample cBot here and I will be able to identify the issue faster


@amusleh

travkinsm1
10 Mar 2021, 13:54

Re4:

 Thanks for the answer. I think that in order to localize the error, you don't need to parse the entire code. Look, there is a _isLong variable in the indicator. It returns true if the indicator is at the bottom, and false if the indicator is at the top. And, according to my observations, there is no error here. To make sure of this, it is enough to insert into line 163

Print("Indicator" + Bars.OpenPrices.LastValue + "" + Bars.OpenTimes.LastValue + "" + Period + "" + Weight + "" + _isLong);

Lines 159 through 162 bind _isLong to _myIsLong. In the bot, _myIsLong is bound to dirInd in OnTick, and often is sent to Print() a different value.

As for the time error, it seems to me that this is unlikely to be, because _myIsLong receives LastValue. And I send the ATRMTF_time_History indicator.

Sorry for not thinking about it right away

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class ATRMTF_time_History : Indicator
    {
        [Parameter("Period", DefaultValue = 30)]
        public int Period { get; set; }

        [Parameter("Timeframe", DefaultValue = 0.0)]
        public TimeFrame TF { get; set; }

        [Parameter(DefaultValue = 200)]
        public int LoadHistory_for_ind { get; set; }
        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        private AverageTrueRange atr;
        private MarketSeries series;
        private Bars Bars3;
        public int loaded = 0;
        protected override void Initialize()
        {
            if (LoadIndHist)
            {
                if (loaded == 0)
                {
                    Print("Start");
                    Bars3 = MarketData.GetBars(TF, Symbol.Name);
                    // Print("2");
                    Print("{0} bar on the chart. Loading 2.000.000 bars", Bars3.Count);
                    //Print("3");

                    while (Bars3.Count < LoadHistory_for_ind)
                    {
                        //  Print("3");
                        var loadedCount = Bars3.LoadMoreHistory();
                        //Print("3");
                        //Print("Loaded {0} bars", loadedCount);
                        //Print("Total bars {0}", Bars2.Count);
                        if (loadedCount == 0)
                            break;
                    }
                    Print("Finished, total bars {0}", Bars3.Count);

                    Print("2");
                    loaded = 1;
                }
            }

            series = MarketData.GetSeries(TF);
            atr = Indicators.AverageTrueRange(series, Period, MovingAverageType.Exponential);
        }

        public override void Calculate(int index)
        {
            var index1 = series.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index]);
            // Print(index1, " ", Result[index - 1], " ", atr.Result[index1]);
            if (Result[index - 1] != atr.Result[index1])
                Result[index] = atr.Result[index1];
            else
                Result[index] = Result[index - 1];
            // (int)Math.Round(minJamp * Symbol.PipSize / Math.Pow(0.1, Symbol.Digits));
        }
    }
}
//ATRMTF_time_History

 


@travkinsm1

amusleh
11 Mar 2021, 13:57

Please try this new indicator code on your cBot:

using cAlgo.API;
using cAlgo.API.Internals;
using System;
using System.IO;

namespace cAlgo.Indicators
{
    [Indicator("ATR Trailing Stop", AutoRescale = false, IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.FileSystem)]
    public class ATR_Stops_time_MarketData_History : Indicator
    {
        [Parameter("Timeframe", DefaultValue = 0.0)]
        public TimeFrame TF { get; set; }

        [Parameter("MA Method", DefaultValue = MovingAverageType.Simple)]
        public MovingAverageType MaType { get; set; }

        [Parameter("Period", DefaultValue = 10, MinValue = 2, MaxValue = 50000)]
        public int Period { get; set; }

        [Parameter("Weight", DefaultValue = 4.0, MinValue = 0.1, MaxValue = 400.0)]
        public double Weight { get; set; }

        [Parameter("True:High_Low False:Close", DefaultValue = false)]
        public bool UseHighAndLow { get; set; }

        [Parameter(DefaultValue = 16000)]
        public int LoadHistory_for_ind { get; set; }

        [Parameter("Загрузка ист. в индикаторе", DefaultValue = false)]
        public bool LoadIndHist { get; set; }

        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        [Output("My")]
        public IndicatorDataSeries _myIsLong { get; set; }

        private ATRMTF_time_History _atr;
        public bool _isLong;

        private MarketSeries _marketSeries;

        //private AverageTrueRange_Cust_lag[,] stop_ind = new ATRStops[perCount, weightCount];
        private Bars Bars2;

        public StreamWriter file3;

        protected override void Initialize()
        {
            Print("Start");

            Bars2 = MarketData.GetBars(TF, Symbol.Name);
            Print("{0} bar on the chart. Loading 2.000.000 bars", Bars2.Count);

            if (LoadIndHist == true)
            {
                while (Bars2.Count < LoadHistory_for_ind)
                {
                    var loadedCount = Bars2.LoadMoreHistory();

                    if (loadedCount == 0)
                        break;
                }
                Print("Finished, total bars {0}", Bars2.Count);
            }

            Print("1");

            _atr = Indicators.GetIndicator<ATRMTF_time_History>(Period, TF, LoadHistory_for_ind, LoadIndHist);

            _marketSeries = MarketData.GetSeries(MarketData.GetSymbol(Symbol.Name), TF);

            //else
            //Print("Не загружено {0} баров", BarCount_set);
        }

        public override void Calculate(int index)
        {
            var currentAtr = Weight * _atr.Result[index];

            if (double.IsNaN(currentAtr))
                return;

            if (double.IsNaN(Result[index - 1]) && !double.IsNaN(_atr.Result[index - 1]))
            {
                var previousATR = Weight * _atr.Result[index - 1];

                _isLong = MarketSeries.Close.IsRising();

                var previous = UseHighAndLow ? (_isLong ? this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])] : this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])]) : this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index - 1])];

                Result[index] = _isLong ? previous - previousATR : previous + previousATR;
            }
            else
            {
                var current = this._marketSeries.Close[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

                if (_isLong)
                {
                    if (current >= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Max(Result[index - 1], current - currentAtr);
                    }
                    else
                    {
                        _isLong = false;
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current + currentAtr;
                    }
                }
                else
                {
                    if (current <= Result[index - 1])
                    {
                        if (UseHighAndLow)
                            current = this._marketSeries.Low[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = Math.Min(Result[index - 1], current + currentAtr);
                    }
                    else
                    {
                        _isLong = true;
                        if (UseHighAndLow)
                            current = this._marketSeries.High[_marketSeries.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
                        Result[index] = current - currentAtr;
                    }
                }
            }

            if (_isLong)
                _myIsLong[index] = 2;
            else
                _myIsLong[index] = 1;
        }
    }
}

Inside your "_myIsLong" series 2 means True and 1 means False.


@amusleh

travkinsm1
12 Mar 2021, 12:22 ( Updated at: 21 Dec 2023, 09:22 )

Re5:

Fixed indicator and bot. All the same, the values partially coincide, partially not. (As in the screenshot)


@travkinsm1

amusleh
14 Mar 2021, 12:29

I see you load more historical bars data on your cBot, and indicators, which might cause this issue, please follow this:

1. Use only one indicator instance on your cBot not an array of indicator instances as it will make testing hard

2. Remove load bars data from all three, and check again, if the data matches then the issue is with new loaded bars

3. If the data didn't match then post the new code here without load historical bars data code and I will check (only if you do the two above steps first)

The difference in indicator data can happen if the data is different in your cBot and indicator, to solve it you can call each indicator calculate method inside a for loop manually from your cBot.

Your code amount is very large and missy, if you couldn't solve the issue you can ask a consultant to develop your cBot for you. 


@amusleh