Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

Created at 11 Apr 2024, 07:57
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!
YS

ys2310

Joined 03.12.2021

Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.
11 Apr 2024, 07:57


Hi, 

I have a custom indicator as below.

When I use it from cBot with 1 Hour timeframe, 

Print(_gmma.ShortEma1.Last(1)," ",_gmma.ShortEma4.Last(1));

always print NaN and NaN. Why is so, and how I can code my cBot so that it prints the correct values?

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.TokyoStandardTime, AccessRights = AccessRights.FullAccess)]
    public class GMMA : Indicator
    {
        [Output("Short EMA1", Color = Colors.Blue)]
        public IndicatorDataSeries ShortEma1 { get; set; }

        [Output("Short EMA2", Color = Colors.Blue)]
        public IndicatorDataSeries ShortEma2 { get; set; }

        [Output("Short EMA3", Color = Colors.Blue)]
        public IndicatorDataSeries ShortEma3 { get; set; }

        [Output("Short EMA4", Color = Colors.Blue)]
        public IndicatorDataSeries ShortEma4 { get; set; }

        [Output("Short EMA5", Color = Colors.Blue)]
        public IndicatorDataSeries ShortEma5 { get; set; }

        [Output("Short EMA6", Color = Colors.Blue)]
        public IndicatorDataSeries ShortEma6 { get; set; }



        [Output("Long EMA1", Color = Colors.Red)]
        public IndicatorDataSeries LongEma1 { get; set; }

        [Output("Long EMA2", Color = Colors.Red)]
        public IndicatorDataSeries LongEma2 { get; set; }

        [Output("Long EMA3", Color = Colors.Red)]
        public IndicatorDataSeries LongEma3 { get; set; }

        [Output("Long EMA4", Color = Colors.Red)]
        public IndicatorDataSeries LongEma4 { get; set; }

        [Output("Long EMA5", Color = Colors.Red)]
        public IndicatorDataSeries LongEma5 { get; set; }

        [Output("Long EMA6", Color = Colors.Red)]
        public IndicatorDataSeries LongEma6 { get; set; }





        private ExponentialMovingAverage m_shortEma1;
        private ExponentialMovingAverage m_shortEma2;
        private ExponentialMovingAverage m_shortEma3;
        private ExponentialMovingAverage m_shortEma4;
        private ExponentialMovingAverage m_shortEma5;
        private ExponentialMovingAverage m_shortEma6;

        private MovingAverage m_longEma1;
        private MovingAverage m_longEma2;
        private MovingAverage m_longEma3;
        private MovingAverage m_longEma4;
        private MovingAverage m_longEma5;
        private MovingAverage m_longEma6;



        protected override void Initialize()
        {
            m_shortEma1 = Indicators.ExponentialMovingAverage(MarketSeries.Close, 3);
            m_shortEma2 = Indicators.ExponentialMovingAverage(MarketSeries.Close, 5);
            m_shortEma3 = Indicators.ExponentialMovingAverage(MarketSeries.Close, 8);
            m_shortEma4 = Indicators.ExponentialMovingAverage(MarketSeries.Close, 10);
            m_shortEma5 = Indicators.ExponentialMovingAverage(MarketSeries.Close, 12);
            m_shortEma6 = Indicators.ExponentialMovingAverage(MarketSeries.Close, 15);

            m_longEma1 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour2).Close, 20);
            m_longEma2 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour4).Close, 20);
            m_longEma3 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour8).Close, 20);
            m_longEma4 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour12).Close, 20);
            m_longEma5 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Daily).Close, 20);
            m_longEma6 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Weekly).Close, 20);
        }

        public override void Calculate(int index)
        {
       
            var index1 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour), MarketSeries.OpenTime[index]);
            if (index1 != -1)
                ShortEma1[index] = m_shortEma1.Result[index1];
                
            var index2 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour), MarketSeries.OpenTime[index]);
            if (index2 != -1)
                ShortEma2[index] = m_shortEma2.Result[index2];

            var index3 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour), MarketSeries.OpenTime[index]);
            if (index3 != -1)
                ShortEma3[index] = m_shortEma3.Result[index3];
                
            var index4 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour), MarketSeries.OpenTime[index]);
            if (index4 != -1)
                ShortEma4[index] = m_shortEma4.Result[index4];
        
            var index5 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour), MarketSeries.OpenTime[index]);
            if (index5 != -1)
                ShortEma5[index] = m_shortEma5.Result[index5];
                
            var index6 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour), MarketSeries.OpenTime[index]);
            if (index6 != -1)
                ShortEma6[index] = m_shortEma6.Result[index6];
                
            var index7 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour2), MarketSeries.OpenTime[index]);
            if (index7 != -1)
                LongEma1[index] = m_longEma1.Result[index7];

            var index8 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour4), MarketSeries.OpenTime[index]);
            if (index8 != -1)
                LongEma2[index] = m_longEma2.Result[index8];
                
            var index9 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour8), MarketSeries.OpenTime[index]);
            if (index9 != -1)
                LongEma3[index] = m_longEma3.Result[index9];
                
            var index10 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Hour12), MarketSeries.OpenTime[index]);
            if (index10 != -1)
                LongEma4[index] = m_longEma4.Result[index10];
                
            var index11 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Daily), MarketSeries.OpenTime[index]);
            if (index11 != -1)
                LongEma5[index] = m_longEma5.Result[index11];
                
            var index12 = GetIndexByDate(MarketData.GetSeries(TimeFrame.Weekly), MarketSeries.OpenTime[index]);
            if (index12 != -1)
                LongEma6[index] = m_longEma6.Result[index12];
        }
        
        private int GetIndexByDate(MarketSeries series, DateTime time)
        {
            for (int i = series.Close.Count - 1; i > 0; i--)
            {
                if (time == series.OpenTime[i])
                    return i;
            }
            return -1;
        }
    }
}

@ys2310
Replies

PanagiotisCharalampous
11 Apr 2024, 11:45

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 


@PanagiotisCharalampous

ys2310
11 Apr 2024, 12:44 ( Updated at: 11 Apr 2024, 12:46 )

RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the Last(n) values of above custom indicator(multi-timeframe GMMA)'s 

TimeFrame.Hour2 ,TimeFrame.Hour4, TimeFrame.Hour8 ,TimeFrame.Hour16, TimeFrame.Daily, TimeFrame.Weekly.

Can you show me an example on how to code this correctly?


@ys2310

PanagiotisCharalampous
11 Apr 2024, 12:47

RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis


@PanagiotisCharalampous

ys2310
11 Apr 2024, 12:57

RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?


@ys2310

PanagiotisCharalampous
11 Apr 2024, 13:14

RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?


@PanagiotisCharalampous

ys2310
11 Apr 2024, 13:21 ( Updated at: 12 Apr 2024, 05:45 )

RE: RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?

Hi Panagiotis,

Yes, I can share the cBot code to you.

here it is.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo.Robots
{
    [Robot(AccessRights = AccessRights.FullAccess, TimeZone = TimeZones.TokyoStandardTime)]
    public class GMMASingle : Robot
    {        
     
        private GMMA _gmma;
      
        
        protected override void OnStart()
        {
            // To learn more about cTrader Automate visit our Help Center:
            // https://help.ctrader.com/ctrader-automate
            
            
            _gmma = Indicators.GetIndicator<GMMA>();
            
        }

        protected override void OnBar()        
        {
            
            
            Print(_gmma.LongEma1.Last(1)," ",_gmma.LongEma4.Last(1)); // <--- prints NaN NaN
            
            if (_gmma.LongEma1.IsRising() && _gmma.LongEma4.IsRising()) {

                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 100, "GMMA", null, null);
            }
            if (_gmma.LongEma1.IsFalling() && _gmma.LongEma4.IsFalling()) {

                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 100, "GMMA", null, null);
            }
        }

        protected override void OnStop()
        {
            // Handle cBot stop here
        }
        
        
    }
}

 


@ys2310

PanagiotisCharalampous
12 Apr 2024, 06:12

RE: RE: RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?

Hi Panagiotis,

Yes, I can share the cBot code to you.

here it is.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;using cAlgo.Indicators;namespace cAlgo.Robots{    [Robot(AccessRights = AccessRights.FullAccess, TimeZone = TimeZones.TokyoStandardTime)]    public class GMMASingle : Robot    {                     private GMMA _gmma;                      protected override void OnStart()        {            // To learn more about cTrader Automate visit our Help Center:            // https://help.ctrader.com/ctrader-automate                                    _gmma = Indicators.GetIndicator<GMMA>();                    }        protected override void OnBar()                {                                    Print(_gmma.LongEma1.Last(1)," ",_gmma.LongEma4.Last(1)); // <--- prints NaN NaN                        if (_gmma.LongEma1.IsRising() && _gmma.LongEma4.IsRising()) {                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 100, "GMMA", null, null);            }            if (_gmma.LongEma1.IsFalling() && _gmma.LongEma4.IsFalling()) {                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 100, "GMMA", null, null);            }        }        protected override void OnStop()        {            // Handle cBot stop here        }                    }}

 

Hi there,

Here is a visualization of your problem using the debugger

Your Indicator data series have NaN values because you do not assign anything to them when the time does not match the higher timeframe time. Hence the problems in your logic. 

I do not understand why you have created a separate indicator for this and have to manage all this complexity. You could just initialize the moving averages inside your cBot and use them.

Best regards,

Panagiotis


@PanagiotisCharalampous

ys2310
12 Apr 2024, 06:40 ( Updated at: 12 Apr 2024, 11:48 )

RE: RE: RE: RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?

Hi Panagiotis,

Yes, I can share the cBot code to you.

here it is.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;using cAlgo.Indicators;namespace cAlgo.Robots{    [Robot(AccessRights = AccessRights.FullAccess, TimeZone = TimeZones.TokyoStandardTime)]    public class GMMASingle : Robot    {                     private GMMA _gmma;                      protected override void OnStart()        {            // To learn more about cTrader Automate visit our Help Center:            // https://help.ctrader.com/ctrader-automate                                    _gmma = Indicators.GetIndicator<GMMA>();                    }        protected override void OnBar()                {                                    Print(_gmma.LongEma1.Last(1)," ",_gmma.LongEma4.Last(1)); // <--- prints NaN NaN                        if (_gmma.LongEma1.IsRising() && _gmma.LongEma4.IsRising()) {                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 100, "GMMA", null, null);            }            if (_gmma.LongEma1.IsFalling() && _gmma.LongEma4.IsFalling()) {                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 100, "GMMA", null, null);            }        }        protected override void OnStop()        {            // Handle cBot stop here        }                    }}

 

Hi there,

Here is a visualization of your problem using the debugger

Your Indicator data series have NaN values because you do not assign anything to them when the time does not match the higher timeframe time. Hence the problems in your logic. 

I do not understand why you have created a separate indicator for this and have to manage all this complexity. You could just initialize the moving averages inside your cBot and use them.

Best regards,

Panagiotis

Hi Panagiotis,

Thank you for the screenshot. I see the problem now.

I changed my cBot code as following and it seems to print higher time frame values correctly. 

However, how can I display, for example, this _longEma2 onto my bachtest chart?

private MovingAverage _longEma1, _longEma2, _longEma3, _longEma4;
 
protected override void OnStart()
{

      _longEma1 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour2).Close, 200);
      _longEma2 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour4).Close, 200);
      _longEma3 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour8).Close, 200);
      _longEma4 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour12).Close, 200);
}

@ys2310

PanagiotisCharalampous
12 Apr 2024, 11:50

RE: RE: RE: RE: RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?

Hi Panagiotis,

Yes, I can share the cBot code to you.

here it is.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;using cAlgo.Indicators;namespace cAlgo.Robots{    [Robot(AccessRights = AccessRights.FullAccess, TimeZone = TimeZones.TokyoStandardTime)]    public class GMMASingle : Robot    {                     private GMMA _gmma;                      protected override void OnStart()        {            // To learn more about cTrader Automate visit our Help Center:            // https://help.ctrader.com/ctrader-automate                                    _gmma = Indicators.GetIndicator<GMMA>();                    }        protected override void OnBar()                {                                    Print(_gmma.LongEma1.Last(1)," ",_gmma.LongEma4.Last(1)); // <--- prints NaN NaN                        if (_gmma.LongEma1.IsRising() && _gmma.LongEma4.IsRising()) {                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 100, "GMMA", null, null);            }            if (_gmma.LongEma1.IsFalling() && _gmma.LongEma4.IsFalling()) {                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 100, "GMMA", null, null);            }        }        protected override void OnStop()        {            // Handle cBot stop here        }                    }}

 

Hi there,

Here is a visualization of your problem using the debugger

Your Indicator data series have NaN values because you do not assign anything to them when the time does not match the higher timeframe time. Hence the problems in your logic. 

I do not understand why you have created a separate indicator for this and have to manage all this complexity. You could just initialize the moving averages inside your cBot and use them.

Best regards,

Panagiotis

Hi Panagiotis,

Thank you for the screenshot. I see the problem now.

I changed my cBot code as following and it seems to print higher time frame values correctly. 

However, how can I display, for example, this _longEma2 onto my bachtest chart?

private MovingAverage _longEma1, _longEma2, _longEma3, _longEma4; protected override void OnStart(){      _longEma1 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour2).Close, 200);      _longEma2 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour4).Close, 200);      _longEma3 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour8).Close, 200);      _longEma4 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour12).Close, 200);}

It's not possible to add them on the chart from the cBot but you could use your GMMA indicator for this purpose


@PanagiotisCharalampous

ys2310
12 Apr 2024, 12:06 ( Updated at: 14 Apr 2024, 08:02 )

RE: RE: RE: RE: RE: RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?

Hi Panagiotis,

Yes, I can share the cBot code to you.

here it is.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;using cAlgo.Indicators;namespace cAlgo.Robots{    [Robot(AccessRights = AccessRights.FullAccess, TimeZone = TimeZones.TokyoStandardTime)]    public class GMMASingle : Robot    {                     private GMMA _gmma;                      protected override void OnStart()        {            // To learn more about cTrader Automate visit our Help Center:            // https://help.ctrader.com/ctrader-automate                                    _gmma = Indicators.GetIndicator<GMMA>();                    }        protected override void OnBar()                {                                    Print(_gmma.LongEma1.Last(1)," ",_gmma.LongEma4.Last(1)); // <--- prints NaN NaN                        if (_gmma.LongEma1.IsRising() && _gmma.LongEma4.IsRising()) {                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 100, "GMMA", null, null);            }            if (_gmma.LongEma1.IsFalling() && _gmma.LongEma4.IsFalling()) {                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 100, "GMMA", null, null);            }        }        protected override void OnStop()        {            // Handle cBot stop here        }                    }}

 

Hi there,

Here is a visualization of your problem using the debugger

Your Indicator data series have NaN values because you do not assign anything to them when the time does not match the higher timeframe time. Hence the problems in your logic. 

I do not understand why you have created a separate indicator for this and have to manage all this complexity. You could just initialize the moving averages inside your cBot and use them.

Best regards,

Panagiotis

Hi Panagiotis,

Thank you for the screenshot. I see the problem now.

I changed my cBot code as following and it seems to print higher time frame values correctly. 

However, how can I display, for example, this _longEma2 onto my bachtest chart?

private MovingAverage _longEma1, _longEma2, _longEma3, _longEma4; protected override void OnStart(){      _longEma1 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour2).Close, 200);      _longEma2 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour4).Close, 200);      _longEma3 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour8).Close, 200);      _longEma4 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour12).Close, 200);}

It's not possible to add them on the chart from the cBot but you could use your GMMA indicator for this purpose

Hi Panagiotis,

So, in this my case scenario, we need to use my custom GMMA indicator during backtest.

The problem is how to solve the NaN values things. 

I'd like to get TimeFrame.Hour4 moviing average values in my 1 hour backtest resolution.

How can I do this correctly?


@ys2310

PanagiotisCharalampous
14 Apr 2024, 08:07

RE: RE: RE: RE: RE: RE: RE: RE: RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the above custom indicator(multi-timeframe GMMA)'s TimeFrame.Hour4 Last(n) values. 

Can you me an example on how to code this correctly?

Hi there,

I am sorry but I cannot write the code for you. If you have specific questions, I am happy to answer them. At the moment I do not see a reason to leave the data series values to NaN.

Best regards,

Panagiotis

Hello Panagiotis,

What do you mean by “At the moment I do not see a reason to leave the data series values to NaN.” ?

I made some mistakes in my code?

Can you share the cBot code as well so that I can tell you exactly where the problem is?

Hi Panagiotis,

Yes, I can share the cBot code to you.

here it is.

using System;using System.Collections.Generic;using System.Linq;using System.Text;using cAlgo.API;using cAlgo.API.Collections;using cAlgo.API.Indicators;using cAlgo.API.Internals;using cAlgo.Indicators;namespace cAlgo.Robots{    [Robot(AccessRights = AccessRights.FullAccess, TimeZone = TimeZones.TokyoStandardTime)]    public class GMMASingle : Robot    {                     private GMMA _gmma;                      protected override void OnStart()        {            // To learn more about cTrader Automate visit our Help Center:            // https://help.ctrader.com/ctrader-automate                                    _gmma = Indicators.GetIndicator<GMMA>();                    }        protected override void OnBar()                {                                    Print(_gmma.LongEma1.Last(1)," ",_gmma.LongEma4.Last(1)); // <--- prints NaN NaN                        if (_gmma.LongEma1.IsRising() && _gmma.LongEma4.IsRising()) {                    ExecuteMarketOrder(TradeType.Buy, Symbol.Name, 100, "GMMA", null, null);            }            if (_gmma.LongEma1.IsFalling() && _gmma.LongEma4.IsFalling()) {                    ExecuteMarketOrder(TradeType.Sell, Symbol.Name, 100, "GMMA", null, null);            }        }        protected override void OnStop()        {            // Handle cBot stop here        }                    }}

 

Hi there,

Here is a visualization of your problem using the debugger

Your Indicator data series have NaN values because you do not assign anything to them when the time does not match the higher timeframe time. Hence the problems in your logic. 

I do not understand why you have created a separate indicator for this and have to manage all this complexity. You could just initialize the moving averages inside your cBot and use them.

Best regards,

Panagiotis

Hi Panagiotis,

Thank you for the screenshot. I see the problem now.

I changed my cBot code as following and it seems to print higher time frame values correctly. 

However, how can I display, for example, this _longEma2 onto my bachtest chart?

private MovingAverage _longEma1, _longEma2, _longEma3, _longEma4; protected override void OnStart(){      _longEma1 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour2).Close, 200);      _longEma2 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour4).Close, 200);      _longEma3 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour8).Close, 200);      _longEma4 = Indicators.ExponentialMovingAverage(MarketData.GetSeries(TimeFrame.Hour12).Close, 200);}

It's not possible to add them on the chart from the cBot but you could use your GMMA indicator for this purpose

Hi Panagiotis,

So, in this my case scenario, we need to use my custom GMMA indicator during backtest.

The problem is how to solve the NaN values things. 

I'd like to get TimeFrame.Hour4 moviing average values in my 1 hour backtest resolution.

How can I do this correctly?

So, in this my case scenario, we need to use my custom GMMA indicator during backtest.

No you just need to use for visualization purposes. To solve the NaN issue requires some complicated code to be written. I cannot provide you guidance except than actually writing the code for, something I cannot afford to do at the moment.


@PanagiotisCharalampous

YesOrNot2
23 Jul 2024, 14:47 ( Updated at: 24 Jul 2024, 06:21 )

RE: RE: Custom indicator with TimeFrame.Hour4 not showing Last(1) value in cBot.

ys2310 said: 

PanagiotisCharalampous said: 

Hi there,

This happens because you only assign values to indicator data series, when the index of each higher timeframe changes. Hence for the rest of the array elements the value stays NaN. The solution to this depends on what you want to achieve. For example, why do you 

@PanagiotisCharalampous

Thank you for your reply. I want to test my GMMA strategy with multi-timeframe.

My cBot staretegy is 1hour resolution and should be able to access to the Last(n) values of above custom indicator(multi-timeframe GMMA)'s 

TimeFrame.Hour2 ,TimeFrame.Hour4, TimeFrame.Hour8 ,TimeFrame.Hour16, TimeFrame.Daily, TimeFrame.Weekly.

Can you show me an example on how to code this correctly?

I hope that help you : Loading Bars for all Timerframe you need. (I don't try your probleme)

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
namespace cAlgo.Indicators
{

    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class HeikinAshi : Indicator
    {
        [Output("Result", LineColor = "White")]
        public IndicatorDataSeries Result { get; set; }

        private IndicatorDataSeries[] Open, Close, High, Low;
        private Bars[] barsTF;
        private int[] indexTF, indexTF2;

        protected override void Initialize()
        {
            barsTF = new Bars[19];
            barsTF[0] = MarketData.GetBars(TimeFrame.Renko1);
            barsTF[1] = MarketData.GetBars(TimeFrame.Renko2);
            barsTF[2] = MarketData.GetBars(TimeFrame.Renko3);
            barsTF[3] = MarketData.GetBars(TimeFrame.Renko4);
            barsTF[4] = MarketData.GetBars(TimeFrame.Renko5);
            barsTF[5] = MarketData.GetBars(TimeFrame.Renko6);
            barsTF[6] = MarketData.GetBars(TimeFrame.Renko7);
            barsTF[7] = MarketData.GetBars(TimeFrame.Renko8);
            barsTF[8] = MarketData.GetBars(TimeFrame.Renko9);
            barsTF[9] = MarketData.GetBars(TimeFrame.Renko10);
            barsTF[10] = MarketData.GetBars(TimeFrame.Renko15);
            barsTF[11] = MarketData.GetBars(TimeFrame.Renko20);
            barsTF[12] = MarketData.GetBars(TimeFrame.Renko25);
            barsTF[13] = MarketData.GetBars(TimeFrame.Renko30);
            barsTF[14] = MarketData.GetBars(TimeFrame.Renko35);
            barsTF[15] = MarketData.GetBars(TimeFrame.Renko40);
            barsTF[16] = MarketData.GetBars(TimeFrame.Renko45);
            barsTF[17] = MarketData.GetBars(TimeFrame.Renko50);
            barsTF[18] = MarketData.GetBars(TimeFrame.Renko100);
            /*barsTF[19] = MarketData.GetBars(TimeFrame.Renko150);
            barsTF[20] = MarketData.GetBars(TimeFrame.Renko200);
            barsTF[21] = MarketData.GetBars(TimeFrame.Renko300);
            barsTF[22] = MarketData.GetBars(TimeFrame.Renko500);
            barsTF[23] = MarketData.GetBars(TimeFrame.Renko800);
            barsTF[24] = MarketData.GetBars(TimeFrame.Renko1000);
            barsTF[25] = MarketData.GetBars(TimeFrame.Renko2000);*/

            indexTF = new int[19];
            indexTF2 = new int[19];

            Open = new IndicatorDataSeries[19];
            Close = new IndicatorDataSeries[19];
            High = new IndicatorDataSeries[19];
            Low = new IndicatorDataSeries[19];

            for (int i = 0; i < 19; i++)
            {
                if (!IsBacktesting)
                {

                    while (barsTF[i].OpenTimes[0] > Bars.OpenTimes[0])
                        barsTF[i].LoadMoreHistory();
                }
                
                Open[i] = CreateDataSeries();
                Close[i] = CreateDataSeries();
                High[i] = CreateDataSeries();
                Low[i] = CreateDataSeries();
            }
        }

        public override void Calculate(int index)
        {
            if (index == 0)
                return;

            var up = 0.0;
            var down = 0.0;

            for (int i = 0; i < 19; i++)
            {
                indexTF[i] = barsTF[i].OpenTimes.GetIndexByTime(Bars.OpenTimes.Last(0));

                Open[i][index] = barsTF[i].OpenPrices[indexTF[i] - 1];
                Close[i][index] = barsTF[i].ClosePrices[indexTF[i] - 1];
                High[i][index] = barsTF[i].HighPrices[indexTF[i] - 1];
                Low[i][index] = barsTF[i].LowPrices[indexTF[i] - 1];

                up += Open[i][index] == Low[i][index] ? 2 : Close[i][index] > Open[i][index] ? 1 : 0;
                down += Open[i][index] == High[i][index] ? -2 : Close[i][index] < Open[i][index] ? -1 : 0;
            }

            Result[index] = up + down;

        }
    }
}

@YesOrNot2