How to transfer consistent trading signals to bot

Created at 21 Feb 2022, 11:03
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!
BJ

BJORNBERNAU

Joined 21.07.2020

How to transfer consistent trading signals to bot
21 Feb 2022, 11:03


Hello, 

I've built a very simple entry and liquidation signal that is produced in a customized indicator. It alternates between one trade signal and a liquidation signal.

However, despite signals sent, the SELL vs liquidation (LIQ) signals are not alternating, instead the SELL-bar = LIQ-bar. What is the problem?

Sincerely,

Björn Bernau

_________________________

 

This is the indicator output

The signals in the c-bot

 

This are the signal data that the c-bot produces, an alternating on off at the same bar. Apparently, the LIQ signal is ignored. Delaying with a Last-bar “0” and “2” for SELL and LIQ respectively, as in eg.,  if (!double.IsNaN(S2.liq_ONE.Last(2)) == true), liberates basically the same result.

 

20/01/2022 01:00:00.000 | Backtesting started

20/01/2022 05:00:00.000 | SELL    129      IndicatorDataSeries (Count: 127, LastValue: NaN)

20/01/2022 05:00:00.000 | LIQ    129      IndicatorDataSeries (Count: 127, LastValue: NaN)

20/01/2022 12:00:00.000 | SELL    136      IndicatorDataSeries (Count: 134, LastValue: NaN)

20/01/2022 12:00:00.000 | LIQ    136      IndicatorDataSeries (Count: 134, LastValue: NaN)

21/01/2022 13:00:00.000 | SELL    161      IndicatorDataSeries (Count: 159, LastValue: NaN)

21/01/2022 13:00:00.000 | LIQ    161      IndicatorDataSeries (Count: 159, LastValue: NaN)

21/01/2022 18:00:00.000 | SELL    166      IndicatorDataSeries (Count: 164, LastValue: NaN)

21/01/2022 18:00:00.000 | LIQ    166      IndicatorDataSeries (Count: 164, LastValue: NaN)

24/01/2022 22:00:00.000 | SELL    194      IndicatorDataSeries (Count: 192, LastValue: NaN)

24/01/2022 22:00:00.000 | LIQ    194      IndicatorDataSeries (Count: 192, LastValue: NaN)

28/01/2022 18:00:00.000 | SELL    286      IndicatorDataSeries (Count: 284, LastValue: NaN)

28/01/2022 18:00:00.000 | LIQ    286      IndicatorDataSeries (Count: 284, LastValue: NaN)

31/01/2022 12:00:00.000 | SELL    304      IndicatorDataSeries (Count: 302, LastValue: NaN)

31/01/2022 12:00:00.000 | LIQ    304      IndicatorDataSeries (Count: 302, LastValue: NaN)

31/01/2022 23:01:00.000 | SELL    315      IndicatorDataSeries (Count: 313, LastValue: NaN)

31/01/2022 23:01:00.000 | LIQ    315      IndicatorDataSeries (Count: 313, LastValue: NaN)

01/02/2022 12:00:00.000 | SELL    328      IndicatorDataSeries (Count: 326, LastValue: NaN)

01/02/2022 12:00:00.000 | LIQ    328      IndicatorDataSeries (Count: 326, LastValue: NaN)

01/02/2022 15:00:00.000 | SELL    331      IndicatorDataSeries (Count: 329, LastValue: NaN)

01/02/2022 15:00:00.000 | LIQ    331      IndicatorDataSeries (Count: 329, LastValue: NaN)

02/02/2022 17:00:00.000 | SELL    357      IndicatorDataSeries (Count: 355, LastValue: NaN)

02/02/2022 17:00:00.000 | LIQ    357      IndicatorDataSeries (Count: 355, LastValue: NaN)

03/02/2022 20:00:00.000 | SELL    384      IndicatorDataSeries (Count: 382, LastValue: NaN)

03/02/2022 20:00:00.000 | LIQ    384      IndicatorDataSeries (Count: 382, LastValue: NaN)

04/02/2022 11:00:00.000 | SELL    399      IndicatorDataSeries (Count: 397, LastValue: NaN)

04/02/2022 11:00:00.000 | LIQ    399      IndicatorDataSeries (Count: 397, LastValue: NaN)

04/02/2022 15:00:00.000 | SELL    403      IndicatorDataSeries (Count: 401, LastValue: NaN)

04/02/2022 15:00:00.000 | LIQ    403      IndicatorDataSeries (Count: 401, LastValue: NaN)

07/02/2022 16:00:00.000 | SELL    428      IndicatorDataSeries (Count: 426, LastValue: NaN)

07/02/2022 16:00:00.000 | LIQ    428      IndicatorDataSeries (Count: 426, LastValue: NaN)

07/02/2022 20:00:00.000 | SELL    432      IndicatorDataSeries (Count: 430, LastValue: NaN)

07/02/2022 20:00:00.000 | LIQ    432      IndicatorDataSeries (Count: 430, LastValue: NaN)

09/02/2022 07:00:00.000 | SELL    467      IndicatorDataSeries (Count: 465, LastValue: NaN)

09/02/2022 07:00:00.000 | LIQ    467      IndicatorDataSeries (Count: 465, LastValue: NaN)

09/02/2022 14:00:00.000 | SELL    474      IndicatorDataSeries (Count: 472, LastValue: NaN)

09/02/2022 14:00:00.000 | LIQ    474      IndicatorDataSeries (Count: 472, LastValue: NaN)

09/02/2022 17:00:00.000 | SELL    477      IndicatorDataSeries (Count: 475, LastValue: NaN)

09/02/2022 17:00:00.000 | LIQ    477      IndicatorDataSeries (Count: 475, LastValue: NaN)

09/02/2022 21:00:00.000 | SELL    481      IndicatorDataSeries (Count: 479, LastValue: NaN)

09/02/2022 21:00:00.000 | LIQ    481      IndicatorDataSeries (Count: 479, LastValue: NaN)

10/02/2022 13:00:00.000 | SELL    497      IndicatorDataSeries (Count: 495, LastValue: NaN)

10/02/2022 13:00:00.000 | LIQ    497      IndicatorDataSeries (Count: 495, LastValue: NaN)

10/02/2022 20:00:00.000 | SELL    504      IndicatorDataSeries (Count: 502, LastValue: NaN)

10/02/2022 20:00:00.000 | LIQ    504      IndicatorDataSeries (Count: 502, LastValue: NaN)

11/02/2022 17:00:00.000 | SELL    525      IndicatorDataSeries (Count: 523, LastValue: NaN)

11/02/2022 17:00:00.000 | LIQ    525      IndicatorDataSeries (Count: 523, LastValue: NaN)

11/02/2022 20:00:00.000 | SELL    528      IndicatorDataSeries (Count: 526, LastValue: NaN)

11/02/2022 20:00:00.000 | LIQ    528      IndicatorDataSeries (Count: 526, LastValue: NaN)

15/02/2022 14:00:00.000 | SELL    570      IndicatorDataSeries (Count: 568, LastValue: NaN)

15/02/2022 14:00:00.000 | LIQ    570      IndicatorDataSeries (Count: 568, LastValue: NaN)

15/02/2022 17:00:00.000 | SELL    573      IndicatorDataSeries (Count: 571, LastValue: NaN)

15/02/2022 17:00:00.000 | LIQ    573      IndicatorDataSeries (Count: 571, LastValue: NaN)

15/02/2022 20:00:00.000 | SELL    576      IndicatorDataSeries (Count: 574, LastValue: NaN)

15/02/2022 20:00:00.000 | LIQ    576      IndicatorDataSeries (Count: 574, LastValue: NaN)

16/02/2022 12:00:00.000 | SELL    592      IndicatorDataSeries (Count: 590, LastValue: NaN)

16/02/2022 12:00:00.000 | LIQ    592      IndicatorDataSeries (Count: 590, LastValue: NaN)

16/02/2022 23:01:00.000 | SELL    603      IndicatorDataSeries (Count: 601, LastValue: NaN)

16/02/2022 23:01:00.000 | LIQ    603      IndicatorDataSeries (Count: 601, LastValue: NaN)

18/02/2022 13:00:00.000 | SELL    641      IndicatorDataSeries (Count: 639, LastValue: NaN)

18/02/2022 13:00:00.000 | LIQ    641      IndicatorDataSeries (Count: 639, LastValue: NaN)

21/02/2022 00:59:00.000 | Backtesting finished

Signal code

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ : Indicator
    {

        ////  SELL SIGNAL  ////

        [Output("sell_ONE", PlotType = PlotType.Points, LineColor = "#B511F7", Thickness = 4)]
        public IndicatorDataSeries sell_ONE { get; set; }


        ////  LIQUDATION SIGNAL  ////

        [Output("liq_ONE", PlotType = PlotType.Points, LineColor = "#FF7CFC00", Thickness = 4)]
        public IndicatorDataSeries liq_ONE { get; set; }


        ////   BOLLINGER    //// 

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }


        private BollingerBands boll;


        protected override void Initialize()
        {
            boll = Indicators.BollingerBands(Source, BandPeriod, std, MAType);
        }

        int high = 0;
        int HIGHstartCountIndexZERO = 0;
        double d = double.NaN;


        public override void Calculate(int index)
        {
            liquidator(index);
        }

        private void liquidator(int index)
        {

            high = 0;


            double high0 = Bars.HighPrices[index - 0];
            double high1 = Bars.HighPrices[index - 1];
            double high2 = Bars.HighPrices[index - 2];
            double high3 = Bars.HighPrices[index - 3];
            double high4 = Bars.HighPrices[index - 4];
            double close0 = Bars.ClosePrices[index - 0];

            var BBT2 = boll.Top[index - 2];

            if (high4 <= high2)
                if (high3 <= high2)
                    if (high2 > BBT2)
                        if (high2 >= high1)
                            if (high2 >= close0)
                            {
                                high = 1;
                            }

            if (high == 1)
            {
                HIGHstartCountIndexZERO += 1;
            }

            if (high == 0)
            {
                sell_ONE[index - 2] = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 != 0)
                {
                    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                }

            if (high == 0)
            {
                liq_ONE[index - 2] = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 == 0)
                {
                    liq_ONE[index - 2] = Bars.HighPrices[index - 2];
                }

        }
    }
}



 

 

c-bot code

 

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

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ_220220 : Robot
    {

        ////////////////////////////////////
        /////   TRADING PARAMETERS    //////
        ////////////////////////////////////

        [Parameter("Volume", DefaultValue = 1000)]
        public int Volume { get; set; }

        [Parameter("StopLoss", DefaultValue = 50)]
        public int StopLoss { get; set; }

        [Parameter("LIMIT", DefaultValue = 200)]
        public int LIMIT { get; set; }


        ////////////////////////////
        ////   INITIAL PARAM    //// 

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }


        //////////////////////////////
        ////       LITTERALS      //// 

        [Parameter("littFACTOR", DefaultValue = 5)]
        public double littFACTOR { get; set; }

        private SELL_LIQ S2;

        protected override void OnStart()
        {
            S2 = Indicators.GetIndicator<SELL_LIQ>(Source, BandPeriod, std, MAType);
        }

        protected override void OnBar()
        {

            if (!double.IsNaN(S2.sell_ONE.Last(0)) == true)
            {
                Print("SELL    ", Bars.Count, "      ", S2.sell_ONE);
            }

            if (!double.IsNaN(S2.liq_ONE.Last(0)) == true)
            {
                Print("LIQ    ", Bars.Count, "      ", S2.liq_ONE);
            }

        }
    }
}


 

 

 


@BJORNBERNAU
Replies

firemyst
21 Feb 2022, 15:16 ( Updated at: 21 Feb 2022, 15:26 )

Glancing at your code, a possible problem is you never actually set the last value of either data series.

You only ever populate [index - 2] of either sell_One or liq_one, never [index].

Therefore:

s2.liq_one.last(0) is NAN

s2.sell_one.last(0) is NAN

s2.liq_one.last(1) is NAN

s2.sell_one.last(1) is NAN

 

so the .Last(0) values are both the same, hence the reason they both print out and don't alternate.

Similarly, the .Last(1) values are both the same too.


@firemyst

BJORNBERNAU
21 Feb 2022, 16:30

RE:

firemyst said:

Glancing at your code, a possible problem is you never actually set the last value of either data series.

You only ever populate [index - 2] of either sell_One or liq_one, never [index].

Therefore:

s2.liq_one.last(0) is NAN

s2.sell_one.last(0) is NAN

s2.liq_one.last(1) is NAN

s2.sell_one.last(1) is NAN

 

so the .Last(0) values are both the same, hence the reason they both print out and don't alternate.

Similarly, the .Last(1) values are both the same too.

 

Hello Firemyst,

And thank you for putting your time into this.

I actually tried this and in fact, there are indeed given IndicatorDataSeries as expected, they are not finalised as double.NAN as suggested. Adding printing snippets to the signal code, with the following script

 

  if (high4 <= high2)
                if (high3 <= high2)
                    if (high2 > BBT2)
                        if (high2 >= high1)
                            if (high2 >= close0)
                            {
                                high = 1;
                            }

            if (high == 1)
            {
                HIGHstartCountIndexZERO += 1;
            }

            if (high == 0)
            {
                sell_ONE[index - 2] = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 != 0)
                {
                    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                    Print(index, "   SELL   ", sell_ONE);
                }

            if (high == 0)
            {
                liq_ONE[index - 2] = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 == 0)
                {
                    liq_ONE[index - 2] = Bars.HighPrices[index - 2];
                    Print(index, "   LIQ   ", liq_ONE);

                }

        }

 

 

liberates full data sets as I understand them. Alternating nicely. But they are not transferred correctly into the robot. Which is my current problem.

 

21/02/2022 14:26:10.032 | 22   SELL   IndicatorDataSeries (Count: 21, LastValue: 1,16132)

21/02/2022 14:26:10.032 | 27   LIQ   IndicatorDataSeries (Count: 26, LastValue: 1,1626)

21/02/2022 14:26:10.032 | 47   SELL   IndicatorDataSeries (Count: 46, LastValue: 1,16144)

21/02/2022 14:26:10.032 | 54   LIQ   IndicatorDataSeries (Count: 53, LastValue: 1,16922)

21/02/2022 14:26:10.032 | 95   SELL   IndicatorDataSeries (Count: 94, LastValue: 1,15754)

21/02/2022 14:26:10.032 | 105   LIQ   IndicatorDataSeries (Count: 104, LastValue: 1,16087)

21/02/2022 14:26:10.032 | 107   SELL   IndicatorDataSeries (Count: 106, LastValue: 1,16092)

21/02/2022 14:26:10.032 | 118   LIQ   IndicatorDataSeries (Count: 117, LastValue: 1,16134)

21/02/2022 14:26:10.032 | 144   SELL   IndicatorDataSeries (Count: 143, LastValue: 1,15979)

21/02/2022 14:26:10.032 | 153   LIQ   IndicatorDataSeries (Count: 152, LastValue: 1,16164)

21/02/2022 14:26:10.032 | 190   SELL   IndicatorDataSeries (Count: 189, LastValue: 1,1563)

21/02/2022 14:26:10.032 | 200   LIQ   IndicatorDataSeries (Count: 199, LastValue: 1,15684)

 

Cancelling out the “index-2” and setting it to "zero" - e.g.    

liq_ONE[index - 0] = Bars.HighPrices[index - 0];

in both the Indicator and Robot liberates this, several SELL after one another and then flipping back to LIQ.

 

20/01/2022 01:00:00.000 | Backtesting started

20/01/2022 04:00:00.000 | LIQ    128      IndicatorDataSeries (Count: 128, LastValue: 1,13549)

20/01/2022 11:00:00.000 | LIQ    135      IndicatorDataSeries (Count: 135, LastValue: 1,13476)

21/01/2022 12:00:00.000 | LIQ    160      IndicatorDataSeries (Count: 160, LastValue: 1,13391)

21/01/2022 17:00:00.000 | LIQ    165      IndicatorDataSeries (Count: 165, LastValue: 1,1346)

24/01/2022 21:00:00.000 | LIQ    193      IndicatorDataSeries (Count: 193, LastValue: 1,13198)

28/01/2022 17:00:00.000 | LIQ    285      IndicatorDataSeries (Count: 285, LastValue: 1,11643)

31/01/2022 11:00:00.000 | LIQ    303      IndicatorDataSeries (Count: 303, LastValue: 1,11747)

31/01/2022 18:00:00.000 | LIQ    310      IndicatorDataSeries (Count: 310, LastValue: 1,12101)

31/01/2022 22:00:00.000 | SELL    314      IndicatorDataSeries (Count: 314, LastValue: 1,12354)

01/02/2022 11:00:00.000 | SELL    327      IndicatorDataSeries (Count: 327, LastValue: 1,12614)

01/02/2022 14:00:00.000 | SELL    330      IndicatorDataSeries (Count: 330, LastValue: 1,12617)

02/02/2022 16:00:00.000 | SELL    356      IndicatorDataSeries (Count: 356, LastValue: 1,13048)

03/02/2022 19:00:00.000 | SELL    383      IndicatorDataSeries (Count: 383, LastValue: 1,14436)

04/02/2022 10:00:00.000 | SELL    398      IndicatorDataSeries (Count: 398, LastValue: 1,14602)

04/02/2022 14:00:00.000 | SELL    402      IndicatorDataSeries (Count: 402, LastValue: 1,14655)

07/02/2022 15:00:00.000 | SELL    427      IndicatorDataSeries (Count: 427, LastValue: 1,14398)

07/02/2022 19:00:00.000 | SELL    431      IndicatorDataSeries (Count: 431, LastValue: 1,14186)

09/02/2022 06:00:00.000 | SELL    466      IndicatorDataSeries (Count: 466, LastValue: 1,14269)

09/02/2022 13:00:00.000 | SELL    473      IndicatorDataSeries (Count: 473, LastValue: 1,14295)

09/02/2022 16:00:00.000 | SELL    476      IndicatorDataSeries (Count: 476, LastValue: 1,14317)

09/02/2022 20:00:00.000 | SELL    480      IndicatorDataSeries (Count: 480, LastValue: 1,14326)

10/02/2022 12:00:00.000 | SELL    496      IndicatorDataSeries (Count: 496, LastValue: 1,14359)

10/02/2022 16:00:00.000 | SELL    500      IndicatorDataSeries (Count: 500, LastValue: 1,14074)

10/02/2022 19:00:00.000 | LIQ    503      IndicatorDataSeries (Count: 503, LastValue: 1,14645)

11/02/2022 16:00:00.000 | LIQ    524      IndicatorDataSeries (Count: 524, LastValue: 1,13888)

11/02/2022 19:00:00.000 | LIQ    527      IndicatorDataSeries (Count: 527, LastValue: 1,13966)

15/02/2022 13:00:00.000 | LIQ    569      IndicatorDataSeries (Count: 569, LastValue: 1,13459)

15/02/2022 16:00:00.000 | LIQ    572      IndicatorDataSeries (Count: 572, LastValue: 1,1322)

15/02/2022 19:00:00.000 | LIQ    575      IndicatorDataSeries (Count: 575, LastValue: 1,13586)

16/02/2022 11:00:00.000 | LIQ    591      IndicatorDataSeries (Count: 591, LastValue: 1,13775)

16/02/2022 22:00:00.000 | LIQ    602      IndicatorDataSeries (Count: 602, LastValue: 1,13821)

18/02/2022 12:00:00.000 | LIQ    640      IndicatorDataSeries (Count: 640, LastValue: 1,13611)

21/02/2022 00:59:00.000 | Backtesting finished


@BJORNBERNAU

firemyst
22 Feb 2022, 02:38

HI @BJORNBERNAU

Running through Visual studio on a chart:

most of the data series in the indicator itself is NaN as you can see above.

In your bot you never get the latest indicator values before checking the latest indicator values.

It could the "lazy loading" of indicators from cbots as @Panagiotis mentioned in your thread here from Aug 3, 2020:

Also see the last post in this thread:

 

So you need to force the indicator to call the calculate method before you access any of the indicator's data series.

 


@firemyst

BJORNBERNAU
22 Feb 2022, 09:40 ( Updated at: 21 Dec 2023, 09:22 )

RE:

firemyst said:

HI @BJORNBERNAU

Running through Visual studio on a chart:

most of the data series in the indicator itself is NaN as you can see above.

In your bot you never get the latest indicator values before checking the latest indicator values.

It could the "lazy loading" of indicators from cbots as @Panagiotis mentioned in your thread here from Aug 3, 2020:

Also see the last post in this thread:

 

So you need to force the indicator to call the calculate method before you access any of the indicator's data series.

 

Again, thank you. 

I've just posted a broader inquiry on this issue. 

https://ctrader.com/forum/indicator-support/37673

A new problem arises when I define a VAR as you suggest. How then is it converted into a IndicatorDataSeries which is defined as a parameter in the program? In doing so the Indicator doesn't work anymore. 

And do we really have to go that far as to define the LAZY class to use this system? 

Thank you! 


@BJORNBERNAU

BJORNBERNAU
22 Feb 2022, 09:43 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

BJORNBERNAU said:

firemyst said:

HI @BJORNBERNAU

Running through Visual studio on a chart:

most of the data series in the indicator itself is NaN as you can see above.

In your bot you never get the latest indicator values before checking the latest indicator values.

It could the "lazy loading" of indicators from cbots as @Panagiotis mentioned in your thread here from Aug 3, 2020:

Also see the last post in this thread:

 

So you need to force the indicator to call the calculate method before you access any of the indicator's data series.

 

Again, thank you. 

I've just posted a broader inquiry on this issue. 

https://ctrader.com/forum/indicator-support/37673

A new problem arises when I define a VAR as you suggest. How then is it converted into a IndicatorDataSeries which is defined as a parameter in the program? In doing so the Indicator doesn't work anymore. 

And do we really have to go that far as to define the LAZY class to use this system? 

Thank you! 

 

 

This is what I tried. I don't know if it is in accordance with your recommendations. 

 

 if (high == 1)
            {
                HIGHstartCountIndexZERO += 1;
            }

            var sell_ONE = Bars.HighPrices.Last(0);


            if (high == 0)
            {
                sell_ONE = d;
            }


            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 != 0)
                {
                    sell_ONE = Bars.HighPrices.Last(0);
                }

            var liq_ONE = Bars.HighPrices.Last(0);

            if (high == 0)
            {
                liq_ONE = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 == 0)
                {
                    liq_ONE = Bars.HighPrices[index - 0];

                }

        }


@BJORNBERNAU

BJORNBERNAU
22 Feb 2022, 09:59 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE: RE:

BJORNBERNAU said:

BJORNBERNAU said:

firemyst said:

HI @BJORNBERNAU

Running through Visual studio on a chart:

most of the data series in the indicator itself is NaN as you can see above.

In your bot you never get the latest indicator values before checking the latest indicator values.

It could the "lazy loading" of indicators from cbots as @Panagiotis mentioned in your thread here from Aug 3, 2020:

Also see the last post in this thread:

 

So you need to force the indicator to call the calculate method before you access any of the indicator's data series.

 

Again, thank you. 

I've just posted a broader inquiry on this issue. 

https://ctrader.com/forum/indicator-support/37673

A new problem arises when I define a VAR as you suggest. How then is it converted into a IndicatorDataSeries which is defined as a parameter in the program? In doing so the Indicator doesn't work anymore. 

And do we really have to go that far as to define the LAZY class to use this system? 

Thank you! 

 

 

This is what I tried. I don't know if it is in accordance with your recommendations. 

 

 if (high == 1)
            {
                HIGHstartCountIndexZERO += 1;
            }

            var sell_ONE = Bars.HighPrices.Last(0);


            if (high == 0)
            {
                sell_ONE = d;
            }


            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 != 0)
                {
                    sell_ONE = Bars.HighPrices.Last(0);
                }

            var liq_ONE = Bars.HighPrices.Last(0);

            if (high == 0)
            {
                liq_ONE = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 == 0)
                {
                    liq_ONE = Bars.HighPrices[index - 0];

                }

        }

Converting the HIGH sighnal to VAR does not help either. 

 public override void Calculate(int index)
        {
            liquidator(index);
        }

        private void liquidator(int index)
        {



            var high = 0;


            double high0 = Bars.HighPrices[index - 0];
            double high1 = Bars.HighPrices[index - 1];
            double high2 = Bars.HighPrices[index - 2];
            double high3 = Bars.HighPrices[index - 3];
            double high4 = Bars.HighPrices[index - 4];
            double close0 = Bars.ClosePrices[index - 0];

            var BBT1 = boll.Top[index - 1];
            var BBT2 = boll.Top[index - 2];


            if (high4 <= high2)
                if (high3 <= high2)
                    if (high2 > BBT2)
                        if (high2 >= high1)
                            if (high2 >= close0)
                            {
                                high = 1;
                            }


            if (high == 1)
            {
                HIGHstartCountIndexZERO += 1;
            }

            if (high == 0)
            {
                sell_ONE[index - 2] = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 != 0)
                {
                    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                    //   Print(index, "    ", sell_ONE);
                }

            if (high == 0)
            {
                liq_ONE[index - 2] = d;
            }

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 == 0)
                {
                    liq_ONE[index - 2] = Bars.HighPrices[index - 2];
                    //     Print(index, "    ", liq_ONE);

                }

        }


@BJORNBERNAU

firemyst
22 Feb 2022, 10:00

RE: RE:

BJORNBERNAU said:

Again, thank you. 

I've just posted a broader inquiry on this issue. 

https://ctrader.com/forum/indicator-support/37673

A new problem arises when I define a VAR as you suggest. How then is it converted into a IndicatorDataSeries which is defined as a parameter in the program? In doing so the Indicator doesn't work anymore. 

And do we really have to go that far as to define the LAZY class to use this system? 

Thank you! 

You're doing it wrong, and I see you don't appear to understand some basic concepts.

I have no idea why you changed liq_one and sell_one to get a double value? Those are indicator data series, so leave them be!

You just have to FORCE the indicator to return a value. The value returned will be a double. So just create a new double variable and assign it an indicator value _before_ you actually need to compare values in your indicator data series.

As per the second article link I provided:

var a = S2.sell_ONE.Last(0);

or you could do:

double a = S2.sell_ONE.Last(0);

Do the same for liq_one right after the sell_one:

a = S2.liq_ONE.Last(0); //who cares if you overwrite the value in "a" because it's just a dummy to force the indicator to run the calculate method.

 

Now that you've forced the indicator to run the calculate method, just leave the rest of the code as you had it and all the indicator's values will be "full loaded". So you DO NOT have to do:

.a = S2.liq_ONE.Last(1);

.a = S2.liq_ONE.Last(2)

etc etc;


@firemyst

amusleh
22 Feb 2022, 10:30

Hi,

I tried to find the issue, there were several issues on your indicator.

First it's repints, it returns data for two previous bar, and in cBot you are trying to get the current bar, that's one issue.

The other one is related to your indicator HIGHstartCountIndexZERO variable, this causes not deterministic results between cBot indicator and the one you attached on the chart.

Try my attached versions of your indicator and cBot, and you will see that their results will match on visual back test.

Indicator:

using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ : Indicator
    {
        [Output("sell_ONE", PlotType = PlotType.Points, LineColor = "#B511F7", Thickness = 4)]
        public IndicatorDataSeries sell_ONE { get; set; }

        [Output("liq_ONE", PlotType = PlotType.Points, LineColor = "#FF7CFC00", Thickness = 4)]
        public IndicatorDataSeries liq_ONE { get; set; }

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }

        private BollingerBands boll;

        protected override void Initialize()
        {
            boll = Indicators.BollingerBands(Source, BandPeriod, std, MAType);
        }

        private int HIGHstartCountIndexZERO = 0;

        public override void Calculate(int index)
        {
            sell_ONE[index - 2] = double.NaN;
            liq_ONE[index - 2] = double.NaN;

            var high = 0;

            double high1 = Bars.HighPrices[index - 1];
            double high2 = Bars.HighPrices[index - 2];
            double high3 = Bars.HighPrices[index - 3];
            double high4 = Bars.HighPrices[index - 4];
            double close = Bars.ClosePrices[index];

            var BBT2 = boll.Top[index - 2];

            if (high4 <= high2 && high3 <= high2 && high2 > BBT2 && high2 >= high1 && high2 >= close)
            {
                high = 1;
            }

            if (high == 0)
            {
                sell_ONE[index - 2] = double.NaN;
                liq_ONE[index - 2] = double.NaN;
            }
            else if (high == 1)
            {
                // I changed the logic here to find what's causing the discrepancy
                // between bot and indicator outputs
                if (Bars.ClosePrices[index - 2] > Bars.OpenPrices[index - 2])
                {
                    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                }
                else
                {
                    liq_ONE[index - 2] = Bars.LowPrices[index - 2];
                }

                //HIGHstartCountIndexZERO += 1;

                //if (HIGHstartCountIndexZERO % 2 != 0)
                //{
                //    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                //}
                //else
                //{
                //    liq_ONE[index - 2] = Bars.LowPrices[index - 2];
                //}
            }
        }
    }
}

cBot:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ_220220 : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }

        private SELL_LIQ S2;

        protected override void OnStart()
        {
            S2 = Indicators.GetIndicator<SELL_LIQ>(Source, BandPeriod, std, MAType);
        }

        protected override void OnTick()
        {
            var index = Bars.Count - 1;

            var indicatorIndex = index - 2;

            Chart.RemoveObject(indicatorIndex.ToString());

            if (double.IsNaN(S2.sell_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#B511F7"));
            }
            else if (double.IsNaN(S2.liq_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#FF7CFC00"));
            }
        }
    }
}

Attach the indicator on visual back test chart, do some back testing on tick data not m1 bars, my result:

cTrader back tester loads some bars without running the cBot on those bars for warming up the indicators.

And if your indicator has some kind of non deterministic code like yours then the results will not match.

You see on my result, the first signal is not marked by cBot, because those bars were loaded by back tester for warm up.


@amusleh

BJORNBERNAU
22 Feb 2022, 11:13 ( Updated at: 21 Dec 2023, 09:22 )

RE:

amusleh said:

Hi,

I tried to find the issue, there were several issues on your indicator.

First it's repints, it returns data for two previous bar, and in cBot you are trying to get the current bar, that's one issue.

The other one is related to your indicator HIGHstartCountIndexZERO variable, this causes not deterministic results between cBot indicator and the one you attached on the chart.

Try my attached versions of your indicator and cBot, and you will see that their results will match on visual back test.

Indicator:

using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ : Indicator
    {
        [Output("sell_ONE", PlotType = PlotType.Points, LineColor = "#B511F7", Thickness = 4)]
        public IndicatorDataSeries sell_ONE { get; set; }

        [Output("liq_ONE", PlotType = PlotType.Points, LineColor = "#FF7CFC00", Thickness = 4)]
        public IndicatorDataSeries liq_ONE { get; set; }

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }

        private BollingerBands boll;

        protected override void Initialize()
        {
            boll = Indicators.BollingerBands(Source, BandPeriod, std, MAType);
        }

        private int HIGHstartCountIndexZERO = 0;

        public override void Calculate(int index)
        {
            sell_ONE[index - 2] = double.NaN;
            liq_ONE[index - 2] = double.NaN;

            var high = 0;

            double high1 = Bars.HighPrices[index - 1];
            double high2 = Bars.HighPrices[index - 2];
            double high3 = Bars.HighPrices[index - 3];
            double high4 = Bars.HighPrices[index - 4];
            double close = Bars.ClosePrices[index];

            var BBT2 = boll.Top[index - 2];

            if (high4 <= high2 && high3 <= high2 && high2 > BBT2 && high2 >= high1 && high2 >= close)
            {
                high = 1;
            }

            if (high == 0)
            {
                sell_ONE[index - 2] = double.NaN;
                liq_ONE[index - 2] = double.NaN;
            }
            else if (high == 1)
            {
                // I changed the logic here to find what's causing the discrepancy
                // between bot and indicator outputs
                if (Bars.ClosePrices[index - 2] > Bars.OpenPrices[index - 2])
                {
                    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                }
                else
                {
                    liq_ONE[index - 2] = Bars.LowPrices[index - 2];
                }

                //HIGHstartCountIndexZERO += 1;

                //if (HIGHstartCountIndexZERO % 2 != 0)
                //{
                //    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                //}
                //else
                //{
                //    liq_ONE[index - 2] = Bars.LowPrices[index - 2];
                //}
            }
        }
    }
}

cBot:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ_220220 : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }

        private SELL_LIQ S2;

        protected override void OnStart()
        {
            S2 = Indicators.GetIndicator<SELL_LIQ>(Source, BandPeriod, std, MAType);
        }

        protected override void OnTick()
        {
            var index = Bars.Count - 1;

            var indicatorIndex = index - 2;

            Chart.RemoveObject(indicatorIndex.ToString());

            if (double.IsNaN(S2.sell_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#B511F7"));
            }
            else if (double.IsNaN(S2.liq_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#FF7CFC00"));
            }
        }
    }
}

Attach the indicator on visual back test chart, do some back testing on tick data not m1 bars, my result:

cTrader back tester loads some bars without running the cBot on those bars for warming up the indicators.

And if your indicator has some kind of non deterministic code like yours then the results will not match.

You see on my result, the first signal is not marked by cBot, because those bars were loaded by back tester for warm up.

Thank you! 

Interesting set up. The vertical lines though, just flashed up once on back-testing and dissappeared. 

 


@BJORNBERNAU

BJORNBERNAU
22 Feb 2022, 11:27 ( Updated at: 21 Dec 2023, 09:22 )

RE: RE:

BJORNBERNAU said:

amusleh said:

Hi,

I tried to find the issue, there were several issues on your indicator.

First it's repints, it returns data for two previous bar, and in cBot you are trying to get the current bar, that's one issue.

The other one is related to your indicator HIGHstartCountIndexZERO variable, this causes not deterministic results between cBot indicator and the one you attached on the chart.

Try my attached versions of your indicator and cBot, and you will see that their results will match on visual back test.

Indicator:

using cAlgo.API;
using cAlgo.API.Indicators;

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ : Indicator
    {
        [Output("sell_ONE", PlotType = PlotType.Points, LineColor = "#B511F7", Thickness = 4)]
        public IndicatorDataSeries sell_ONE { get; set; }

        [Output("liq_ONE", PlotType = PlotType.Points, LineColor = "#FF7CFC00", Thickness = 4)]
        public IndicatorDataSeries liq_ONE { get; set; }

        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }

        private BollingerBands boll;

        protected override void Initialize()
        {
            boll = Indicators.BollingerBands(Source, BandPeriod, std, MAType);
        }

        private int HIGHstartCountIndexZERO = 0;

        public override void Calculate(int index)
        {
            sell_ONE[index - 2] = double.NaN;
            liq_ONE[index - 2] = double.NaN;

            var high = 0;

            double high1 = Bars.HighPrices[index - 1];
            double high2 = Bars.HighPrices[index - 2];
            double high3 = Bars.HighPrices[index - 3];
            double high4 = Bars.HighPrices[index - 4];
            double close = Bars.ClosePrices[index];

            var BBT2 = boll.Top[index - 2];

            if (high4 <= high2 && high3 <= high2 && high2 > BBT2 && high2 >= high1 && high2 >= close)
            {
                high = 1;
            }

            if (high == 0)
            {
                sell_ONE[index - 2] = double.NaN;
                liq_ONE[index - 2] = double.NaN;
            }
            else if (high == 1)
            {
                // I changed the logic here to find what's causing the discrepancy
                // between bot and indicator outputs
                if (Bars.ClosePrices[index - 2] > Bars.OpenPrices[index - 2])
                {
                    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                }
                else
                {
                    liq_ONE[index - 2] = Bars.LowPrices[index - 2];
                }

                //HIGHstartCountIndexZERO += 1;

                //if (HIGHstartCountIndexZERO % 2 != 0)
                //{
                //    sell_ONE[index - 2] = Bars.HighPrices[index - 2];
                //}
                //else
                //{
                //    liq_ONE[index - 2] = Bars.LowPrices[index - 2];
                //}
            }
        }
    }
}

cBot:

using cAlgo.API;

namespace cAlgo
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class SELL_LIQ_220220 : Robot
    {
        [Parameter("Source")]
        public DataSeries Source { get; set; }

        [Parameter("BandPeriods", DefaultValue = 16)]
        public int BandPeriod { get; set; }

        [Parameter("Std", DefaultValue = 1.6)]
        public double std { get; set; }

        [Parameter("MAType")]
        public MovingAverageType MAType { get; set; }

        private SELL_LIQ S2;

        protected override void OnStart()
        {
            S2 = Indicators.GetIndicator<SELL_LIQ>(Source, BandPeriod, std, MAType);
        }

        protected override void OnTick()
        {
            var index = Bars.Count - 1;

            var indicatorIndex = index - 2;

            Chart.RemoveObject(indicatorIndex.ToString());

            if (double.IsNaN(S2.sell_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#B511F7"));
            }
            else if (double.IsNaN(S2.liq_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#FF7CFC00"));
            }
        }
    }
}

Attach the indicator on visual back test chart, do some back testing on tick data not m1 bars, my result:

cTrader back tester loads some bars without running the cBot on those bars for warming up the indicators.

And if your indicator has some kind of non deterministic code like yours then the results will not match.

You see on my result, the first signal is not marked by cBot, because those bars were loaded by back tester for warm up.

Thank you! 

Interesting set up. The vertical lines though, just flashed up once on back-testing and dissappeared. 

 

So, Firemyst! 

I'm indeed not the professional, as you are, and trying to understand the meaning of the forcing of the Indicator method not to be lazy. How is the configuration made? This does not work

 var a = sell_ONE.Last(0);

            if (high == 1)
                if (HIGHstartCountIndexZERO % 2 != 0)
                {

                    a = sell_ONE.Last(0);
                }

So how should you go about it? 

Thank you!


@BJORNBERNAU

firemyst
22 Feb 2022, 12:17

protected override void OnTick()
        {
            //This is all you would have had to do:
            double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);
            //That's it! Now the Calculate method has been 
            //forced to calculate for each sell_One and liq_one.
            //You can now get any values from your indicator
            //and they will be readily available.
             


            var index = Bars.Count - 1;

            var indicatorIndex = index - 2;

            Chart.RemoveObject(indicatorIndex.ToString());

            if (double.IsNaN(S2.sell_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#B511F7"));
            }
            else if (double.IsNaN(S2.liq_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#FF7CFC00"));
            }
        }

 

See code example above. It's not really necessary with amusleh's rewrite, but it illustrates the point. It's literally that simple. You'd have to do that for any other custom indicator you need values for.

Advice is to put all those calls into one method, and then just call the method at OnTick, OnBar, or whenever you'll need values from your indicators.

 


@firemyst

BJORNBERNAU
22 Feb 2022, 12:26

RE:

firemyst said:

protected override void OnTick()
        {
            //This is all you would have had to do:
            double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);
            //That's it! Now the Calculate method has been 
            //forced to calculate for each sell_One and liq_one.
            //You can now get any values from your indicator
            //and they will be readily available.
             


            var index = Bars.Count - 1;

            var indicatorIndex = index - 2;

            Chart.RemoveObject(indicatorIndex.ToString());

            if (double.IsNaN(S2.sell_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#B511F7"));
            }
            else if (double.IsNaN(S2.liq_ONE[indicatorIndex]) == false)
            {
                Chart.DrawVerticalLine(indicatorIndex.ToString(), Bars.OpenTimes[indicatorIndex], Color.FromHex("#FF7CFC00"));
            }
        }

See code example above. It's not really necessary with amusleh's rewrite, but it illustrates the point. It's literally that simple. You'd have to do that for any other custom indicator you need values for.

Advice is to put all those calls into one method, and then just call the method at OnTick, OnBar, or whenever you'll need values from your indicators.

 

So the "forcing" is actually happening in the Robot, not the Indicator?

Then you have to convert the double.IsNaN(S2.liq_ONE[indicatorIndex]

into 

double.IsNaN(a) == false

is it or how does the Robot find "a"?


@BJORNBERNAU

firemyst
22 Feb 2022, 12:42

RE: RE:

BJORNBERNAU said:

So the "forcing" is actually happening in the Robot, not the Indicator?

Yes. You don't need to do it in the indicator. The indicator always gets its own values. However, to save on resources, the robots don't load indicator data until they're actually needed. That's why you need to force it to load to tell the robot it's needed.

Then you have to convert the double.IsNaN(S2.liq_ONE[indicatorIndex]

into 

double.IsNaN(a) == false

is it or how does the Robot find "a"?

You do not care about "a" any more as I said previously.

"a" is just used as some place to force a value to be returned from the indicator.

Now that the indicator data has been loaded by the bot, you can go about getting any values you want from the indicator. Nothing else in the code needs to be changed unless you need data from other indicators.


@firemyst

BJORNBERNAU
22 Feb 2022, 12:55

RE: RE: RE:

firemyst said:

BJORNBERNAU said:

So the "forcing" is actually happening in the Robot, not the Indicator?

Yes. You don't need to do it in the indicator. The indicator always gets its own values. However, to save on resources, the robots don't load indicator data until they're actually needed. That's why you need to force it to load to tell the robot it's needed.

Then you have to convert the double.IsNaN(S2.liq_ONE[indicatorIndex]

into 

double.IsNaN(a) == false

is it or how does the Robot find "a"?

You do not care about "a" any more as I said previously.

"a" is just used as some place to force a value to be returned from the indicator.

Now that the indicator data has been loaded by the bot, you can go about getting any values you want from the indicator. Nothing else in the code needs to be changed unless you need data from other indicators.

 

Thank you! Well, I tried it. This does not change it. The code is now the following 

 

protected override void OnBar()
        {

            double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);

            double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);


            if (!double.IsNaN(S2.sell_ONE.Last(0)) == true)
            {
                Print("SELL    ", Bars.Count, "      ", S2.sell_ONE);
            }

            if (!double.IsNaN(S2.liq_ONE.Last(0)) == true)
            {
                Print("LIQ    ", Bars.Count, "      ", S2.liq_ONE);
            }

        }

 

Resulting in this data stream - a block-wise procurement of SELL and LIQ. 

 

21/02/2022 00:59:00.000 | Backtesting finished
18/02/2022 12:00:00.000 | LIQ    640      IndicatorDataSeries (Count: 640, LastValue: 1,13611)
16/02/2022 22:00:00.000 | LIQ    602      IndicatorDataSeries (Count: 602, LastValue: 1,13821)
16/02/2022 11:00:00.000 | LIQ    591      IndicatorDataSeries (Count: 591, LastValue: 1,13775)
15/02/2022 19:00:00.000 | LIQ    575      IndicatorDataSeries (Count: 575, LastValue: 1,13586)
15/02/2022 16:00:00.000 | LIQ    572      IndicatorDataSeries (Count: 572, LastValue: 1,1322)
15/02/2022 13:00:00.000 | LIQ    569      IndicatorDataSeries (Count: 569, LastValue: 1,13459)
11/02/2022 19:00:00.000 | LIQ    527      IndicatorDataSeries (Count: 527, LastValue: 1,13966)
11/02/2022 16:00:00.000 | LIQ    524      IndicatorDataSeries (Count: 524, LastValue: 1,13888)
10/02/2022 19:00:00.000 | LIQ    503      IndicatorDataSeries (Count: 503, LastValue: 1,14645)
10/02/2022 16:00:00.000 | SELL    500      IndicatorDataSeries (Count: 500, LastValue: 1,14074)
10/02/2022 12:00:00.000 | SELL    496      IndicatorDataSeries (Count: 496, LastValue: 1,14359)
09/02/2022 20:00:00.000 | SELL    480      IndicatorDataSeries (Count: 480, LastValue: 1,14326)
09/02/2022 16:00:00.000 | SELL    476      IndicatorDataSeries (Count: 476, LastValue: 1,14317)
09/02/2022 13:00:00.000 | SELL    473      IndicatorDataSeries (Count: 473, LastValue: 1,14295)
09/02/2022 06:00:00.000 | SELL    466      IndicatorDataSeries (Count: 466, LastValue: 1,14269)
07/02/2022 19:00:00.000 | SELL    431      IndicatorDataSeries (Count: 431, LastValue: 1,14186)
07/02/2022 15:00:00.000 | SELL    427      IndicatorDataSeries (Count: 427, LastValue: 1,14398)
04/02/2022 14:00:00.000 | SELL    402      IndicatorDataSeries (Count: 402, LastValue: 1,14655)
04/02/2022 10:00:00.000 | SELL    398      IndicatorDataSeries (Count: 398, LastValue: 1,14602)
03/02/2022 19:00:00.000 | SELL    383      IndicatorDataSeries (Count: 383, LastValue: 1,14436)
02/02/2022 16:00:00.000 | SELL    356      IndicatorDataSeries (Count: 356, LastValue: 1,13048)
01/02/2022 14:00:00.000 | SELL    330      IndicatorDataSeries (Count: 330, LastValue: 1,12617)
01/02/2022 11:00:00.000 | SELL    327      IndicatorDataSeries (Count: 327, LastValue: 1,12614)
31/01/2022 22:00:00.000 | SELL    314      IndicatorDataSeries (Count: 314, LastValue: 1,12354)
31/01/2022 18:00:00.000 | LIQ    310      IndicatorDataSeries (Count: 310, LastValue: 1,12101)
31/01/2022 11:00:00.000 | LIQ    303      IndicatorDataSeries (Count: 303, LastValue: 1,11747)
28/01/2022 17:00:00.000 | LIQ    285      IndicatorDataSeries (Count: 285, LastValue: 1,11643)
24/01/2022 21:00:00.000 | LIQ    193      IndicatorDataSeries (Count: 193, LastValue: 1,13198)
21/01/2022 17:00:00.000 | LIQ    165      IndicatorDataSeries (Count: 165, LastValue: 1,1346)
21/01/2022 12:00:00.000 | LIQ    160      IndicatorDataSeries (Count: 160, LastValue: 1,13391)
20/01/2022 11:00:00.000 | LIQ    135      IndicatorDataSeries (Count: 135, LastValue: 1,13476)
20/01/2022 04:00:00.000 | LIQ    128      IndicatorDataSeries (Count: 128, LastValue: 1,13549)
20/01/2022 01:00:00.000 | Backtesting started
 


@BJORNBERNAU

firemyst
22 Feb 2022, 13:28 ( Updated at: 22 Feb 2022, 13:31 )

RE: RE: RE: RE:

BJORNBERNAU said:

Thank you! Well, I tried it. This does not change it. The code is now the following 

 

protected override void OnBar()
        {

            double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);

            double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);


            if (!double.IsNaN(S2.sell_ONE.Last(0)) == true)
            {
                Print("SELL    ", Bars.Count, "      ", S2.sell_ONE);
            }

            if (!double.IsNaN(S2.liq_ONE.Last(0)) == true)
            {
                Print("LIQ    ", Bars.Count, "      ", S2.liq_ONE);
            }

        }

 

Resulting in this data stream - a block-wise procurement of SELL and LIQ. 

 

  double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);

WHY ARE YOU DOING THIS?! Not only are you assigning the same value to "b" twice, but you're also declaring a new variable, of which there's no need to declare a new "double b".

As I said, who cares if "a" gets overwritten with a new value?? -- you don't care about the value, and you never use it again. Don't take up extra computing resources by declaring another "double" that's not going to be used anywhere and that you're just assigning the same value to it twice in a row.

As for your overall print statements, it is working now. Your original issue was it kept printing "LastValue: NaN". It no longer does that. That issue is resolved.

If there's other logic issues in your indicator code, you'll have to figure those out or ask for help from others. :-)

 


@firemyst

BJORNBERNAU
22 Feb 2022, 14:22

RE: RE: RE: RE: RE:

firemyst said:

BJORNBERNAU said:

Thank you! Well, I tried it. This does not change it. The code is now the following 

 

protected override void OnBar()
        {

            double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);

            double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);


            if (!double.IsNaN(S2.sell_ONE.Last(0)) == true)
            {
                Print("SELL    ", Bars.Count, "      ", S2.sell_ONE);
            }

            if (!double.IsNaN(S2.liq_ONE.Last(0)) == true)
            {
                Print("LIQ    ", Bars.Count, "      ", S2.liq_ONE);
            }

        }

 

Resulting in this data stream - a block-wise procurement of SELL and LIQ. 

 

  double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);

WHY ARE YOU DOING THIS?! Not only are you assigning the same value to "b" twice, but you're also declaring a new variable, of which there's no need to declare a new "double b".

As I said, who cares if "a" gets overwritten with a new value?? -- you don't care about the value, and you never use it again. Don't take up extra computing resources by declaring another "double" that's not going to be used anywhere and that you're just assigning the same value to it twice in a row.

As for your overall print statements, it is working now. Your original issue was it kept printing "LastValue: NaN". It no longer does that. That issue is resolved.

If there's other logic issues in your indicator code, you'll have to figure those out or ask for help from others. :-)

 

What does your code mean? 

If we declare 

          double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);

does this mean that we INVOKE both SELL and LIQ - which is forcing the bot to retrieve both SELL and LIQ? 

When I apply your code it liberates the below, if that is not true for you, please post the code for both the bot and indicator, so I am sure to see your point. 

Thank you!

 

21/02/2022 00:59:00.000 | Backtesting finished
18/02/2022 12:00:00.000 | LIQ    640      IndicatorDataSeries (Count: 640, LastValue: 1,13611)
16/02/2022 22:00:00.000 | LIQ    602      IndicatorDataSeries (Count: 602, LastValue: 1,13821)
16/02/2022 11:00:00.000 | LIQ    591      IndicatorDataSeries (Count: 591, LastValue: 1,13775)
15/02/2022 19:00:00.000 | LIQ    575      IndicatorDataSeries (Count: 575, LastValue: 1,13586)
15/02/2022 16:00:00.000 | LIQ    572      IndicatorDataSeries (Count: 572, LastValue: 1,1322)
15/02/2022 13:00:00.000 | LIQ    569      IndicatorDataSeries (Count: 569, LastValue: 1,13459)
11/02/2022 19:00:00.000 | LIQ    527      IndicatorDataSeries (Count: 527, LastValue: 1,13966)
11/02/2022 16:00:00.000 | LIQ    524      IndicatorDataSeries (Count: 524, LastValue: 1,13888)
10/02/2022 19:00:00.000 | LIQ    503      IndicatorDataSeries (Count: 503, LastValue: 1,14645)
10/02/2022 16:00:00.000 | SELL    500      IndicatorDataSeries (Count: 500, LastValue: 1,14074)
10/02/2022 12:00:00.000 | SELL    496      IndicatorDataSeries (Count: 496, LastValue: 1,14359)
09/02/2022 20:00:00.000 | SELL    480      IndicatorDataSeries (Count: 480, LastValue: 1,14326)
09/02/2022 16:00:00.000 | SELL    476      IndicatorDataSeries (Count: 476, LastValue: 1,14317)
09/02/2022 13:00:00.000 | SELL    473      IndicatorDataSeries (Count: 473, LastValue: 1,14295)
09/02/2022 06:00:00.000 | SELL    466      IndicatorDataSeries (Count: 466, LastValue: 1,14269)
07/02/2022 19:00:00.000 | SELL    431      IndicatorDataSeries (Count: 431, LastValue: 1,14186)
07/02/2022 15:00:00.000 | SELL    427      IndicatorDataSeries (Count: 427, LastValue: 1,14398)
04/02/2022 14:00:00.000 | SELL    402      IndicatorDataSeries (Count: 402, LastValue: 1,14655)
04/02/2022 10:00:00.000 | SELL    398      IndicatorDataSeries (Count: 398, LastValue: 1,14602)
03/02/2022 19:00:00.000 | SELL    383      IndicatorDataSeries (Count: 383, LastValue: 1,14436)
02/02/2022 16:00:00.000 | SELL    356      IndicatorDataSeries (Count: 356, LastValue: 1,13048)
01/02/2022 14:00:00.000 | SELL    330      IndicatorDataSeries (Count: 330, LastValue: 1,12617)
01/02/2022 11:00:00.000 | SELL    327      IndicatorDataSeries (Count: 327, LastValue: 1,12614)
31/01/2022 22:00:00.000 | SELL    314      IndicatorDataSeries (Count: 314, LastValue: 1,12354)
31/01/2022 18:00:00.000 | LIQ    310      IndicatorDataSeries (Count: 310, LastValue: 1,12101)
31/01/2022 11:00:00.000 | LIQ    303      IndicatorDataSeries (Count: 303, LastValue: 1,11747)
28/01/2022 17:00:00.000 | LIQ    285      IndicatorDataSeries (Count: 285, LastValue: 1,11643)
24/01/2022 21:00:00.000 | LIQ    193      IndicatorDataSeries (Count: 193, LastValue: 1,13198)
21/01/2022 17:00:00.000 | LIQ    165      IndicatorDataSeries (Count: 165, LastValue: 1,1346)
21/01/2022 12:00:00.000 | LIQ    160      IndicatorDataSeries (Count: 160, LastValue: 1,13391)
20/01/2022 11:00:00.000 | LIQ    135      IndicatorDataSeries (Count: 135, LastValue: 1,13476)
20/01/2022 04:00:00.000 | LIQ    128      IndicatorDataSeries (Count: 128, LastValue: 1,13549)
20/01/2022 01:00:00.000 | Backtesting started
 

 

 

 


@BJORNBERNAU

BJORNBERNAU
22 Feb 2022, 14:32

RE: RE: RE: RE: RE: RE:

BJORNBERNAU said:

firemyst said:

BJORNBERNAU said:

Thank you! Well, I tried it. This does not change it. The code is now the following 

 

protected override void OnBar()
        {

            double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);

            double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);


            if (!double.IsNaN(S2.sell_ONE.Last(0)) == true)
            {
                Print("SELL    ", Bars.Count, "      ", S2.sell_ONE);
            }

            if (!double.IsNaN(S2.liq_ONE.Last(0)) == true)
            {
                Print("LIQ    ", Bars.Count, "      ", S2.liq_ONE);
            }

        }

 

Resulting in this data stream - a block-wise procurement of SELL and LIQ. 

 

  double b = S2.liq_ONE.Last(0);
            b = S2.liq_ONE.Last(0);

WHY ARE YOU DOING THIS?! Not only are you assigning the same value to "b" twice, but you're also declaring a new variable, of which there's no need to declare a new "double b".

As I said, who cares if "a" gets overwritten with a new value?? -- you don't care about the value, and you never use it again. Don't take up extra computing resources by declaring another "double" that's not going to be used anywhere and that you're just assigning the same value to it twice in a row.

As for your overall print statements, it is working now. Your original issue was it kept printing "LastValue: NaN". It no longer does that. That issue is resolved.

If there's other logic issues in your indicator code, you'll have to figure those out or ask for help from others. :-)

 

What does your code mean? 

If we declare 

          double a = S2.sell_ONE.Last(0);
            a = S2.liq_ONE.Last(0);

does this mean that we INVOKE both SELL and LIQ - which is forcing the bot to retrieve both SELL and LIQ? 

When I apply your code it liberates the below, if that is not true for you, please post the code for both the bot and indicator, so I am sure to see your point. 

Thank you!

 

21/02/2022 00:59:00.000 | Backtesting finished
18/02/2022 12:00:00.000 | LIQ    640      IndicatorDataSeries (Count: 640, LastValue: 1,13611)
16/02/2022 22:00:00.000 | LIQ    602      IndicatorDataSeries (Count: 602, LastValue: 1,13821)
16/02/2022 11:00:00.000 | LIQ    591      IndicatorDataSeries (Count: 591, LastValue: 1,13775)
15/02/2022 19:00:00.000 | LIQ    575      IndicatorDataSeries (Count: 575, LastValue: 1,13586)
15/02/2022 16:00:00.000 | LIQ    572      IndicatorDataSeries (Count: 572, LastValue: 1,1322)
15/02/2022 13:00:00.000 | LIQ    569      IndicatorDataSeries (Count: 569, LastValue: 1,13459)
11/02/2022 19:00:00.000 | LIQ    527      IndicatorDataSeries (Count: 527, LastValue: 1,13966)
11/02/2022 16:00:00.000 | LIQ    524      IndicatorDataSeries (Count: 524, LastValue: 1,13888)
10/02/2022 19:00:00.000 | LIQ    503      IndicatorDataSeries (Count: 503, LastValue: 1,14645)
10/02/2022 16:00:00.000 | SELL    500      IndicatorDataSeries (Count: 500, LastValue: 1,14074)
10/02/2022 12:00:00.000 | SELL    496      IndicatorDataSeries (Count: 496, LastValue: 1,14359)
09/02/2022 20:00:00.000 | SELL    480      IndicatorDataSeries (Count: 480, LastValue: 1,14326)
09/02/2022 16:00:00.000 | SELL    476      IndicatorDataSeries (Count: 476, LastValue: 1,14317)
09/02/2022 13:00:00.000 | SELL    473      IndicatorDataSeries (Count: 473, LastValue: 1,14295)
09/02/2022 06:00:00.000 | SELL    466      IndicatorDataSeries (Count: 466, LastValue: 1,14269)
07/02/2022 19:00:00.000 | SELL    431      IndicatorDataSeries (Count: 431, LastValue: 1,14186)
07/02/2022 15:00:00.000 | SELL    427      IndicatorDataSeries (Count: 427, LastValue: 1,14398)
04/02/2022 14:00:00.000 | SELL    402      IndicatorDataSeries (Count: 402, LastValue: 1,14655)
04/02/2022 10:00:00.000 | SELL    398      IndicatorDataSeries (Count: 398, LastValue: 1,14602)
03/02/2022 19:00:00.000 | SELL    383      IndicatorDataSeries (Count: 383, LastValue: 1,14436)
02/02/2022 16:00:00.000 | SELL    356      IndicatorDataSeries (Count: 356, LastValue: 1,13048)
01/02/2022 14:00:00.000 | SELL    330      IndicatorDataSeries (Count: 330, LastValue: 1,12617)
01/02/2022 11:00:00.000 | SELL    327      IndicatorDataSeries (Count: 327, LastValue: 1,12614)
31/01/2022 22:00:00.000 | SELL    314      IndicatorDataSeries (Count: 314, LastValue: 1,12354)
31/01/2022 18:00:00.000 | LIQ    310      IndicatorDataSeries (Count: 310, LastValue: 1,12101)
31/01/2022 11:00:00.000 | LIQ    303      IndicatorDataSeries (Count: 303, LastValue: 1,11747)
28/01/2022 17:00:00.000 | LIQ    285      IndicatorDataSeries (Count: 285, LastValue: 1,11643)
24/01/2022 21:00:00.000 | LIQ    193      IndicatorDataSeries (Count: 193, LastValue: 1,13198)
21/01/2022 17:00:00.000 | LIQ    165      IndicatorDataSeries (Count: 165, LastValue: 1,1346)
21/01/2022 12:00:00.000 | LIQ    160      IndicatorDataSeries (Count: 160, LastValue: 1,13391)
20/01/2022 11:00:00.000 | LIQ    135      IndicatorDataSeries (Count: 135, LastValue: 1,13476)
20/01/2022 04:00:00.000 | LIQ    128      IndicatorDataSeries (Count: 128, LastValue: 1,13549)
20/01/2022 01:00:00.000 | Backtesting started
 

 

 

The code does not ALTERNATE between SELL and LIQ. 


@BJORNBERNAU