Multi-timeframe robots/indicators

01 Oct 2013, 14:59Multi-timeframe robots/indicators#11
Spotwareposts: 3274since: 23 Sep 2013

New version of cAlgo supports backtesting of multi-timeframe robots. Please check our demo build.


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/
14 Jun 2014, 08:51RE:#12
PCWalkerposts: 21since: 19 Nov 2012

Spotware said:

New version of cAlgo supports backtesting of multi-timeframe robots. Please check our demo build.

Great upgrade.

11 Nov 2014, 07:04#13
zofoyobisposts: 1since: 11 Nov 2014

I am trying to use this feature to create Heikin-Ashi indicator with custom timeframe as below. The value of haClose in the HeikinAshiClose series looks correct but I am always getting NaN for haOpen. I am not sure if something like below is supported?

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TFHeikinAshiIndicator : Indicator
    {
        [Parameter("Heikin-Ashi Timeframe")]
        public TimeFrame HeikinAshiTimeframe { get; set; }

        [Output("Open", Color = Colors.DarkSlateBlue)]
        public IndicatorDataSeries HeikinAshiOpen { get; set; }

        [Output("Close", Color = Colors.SlateBlue)]
        public IndicatorDataSeries HeikinAshiClose { get; set; }

        private MarketSeries heikinAshiSeries;

        protected override void Initialize()
        {
            heikinAshiSeries = MarketData.GetSeries(HeikinAshiTimeframe);
        }

        public override void Calculate(int index)
        {
            int heikinAshiSeriesIndex = GetIndexByDate(heikinAshiSeries, MarketSeries.OpenTime[index]);

            double open = heikinAshiSeries.Open[heikinAshiSeriesIndex];
            double high = heikinAshiSeries.High[heikinAshiSeriesIndex];
            double low = heikinAshiSeries.Low[heikinAshiSeriesIndex];
            double close = heikinAshiSeries.Close[heikinAshiSeriesIndex];

            double haClose = (open + high + low + close) / 4;
            double haOpen;
            if (heikinAshiSeriesIndex != -1)
                haOpen = (HeikinAshiOpen[heikinAshiSeriesIndex - 1] + HeikinAshiClose[heikinAshiSeriesIndex - 1]) / 2;
            else
                haOpen = (open + close) / 2;

            ChartObjects.DrawText("ha", string.Format("heikinAshiSeriesIndex={0} haOpen={1}, haClose={2}", heikinAshiSeriesIndex, haOpen, haClose), StaticPosition.TopLeft, Colors.Red);

            HeikinAshiOpen[heikinAshiSeriesIndex] = haOpen;
            HeikinAshiClose[heikinAshiSeriesIndex] = haClose;
        }

        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;
        }
    }
}

 

12 Nov 2014, 09:35#14
Spotwareposts: 3274since: 23 Sep 2013

We can recommend you to contact one of our Partners or post a job in Development Jobs section.


TRADERS FIRST™ Vote for your favorite features: http://vote.spotware.com/
02 Jan 2015, 22:22RE: Indicator example: Multi-timeframe moving average#15
crankposts: 17since: 11 Nov 2014

Without plotting the actual moving average lines, how would I just output the numerical value of how far the 100 DAY moving average is from the current price on a one HOUR price chart, plotting just the numerical value in the top left corner of the a one hour price chart, i.e.,

(100 DAY moving average value) - (Current price on a one HOUR chart). With the numerical value output in the top left corner of the one hour chart. When I'm looking at shorter time frame charts like an hour or 15 minute charts, I want to know how far the close is from DAILY moving averages. The code below really only works if you want to know the MAs of shorter timeframes than the chart that you are viewing. I want to know the opposite, i.e, show longer timeframe MAs on shorter timeframe charts.

In this example, we output moving averages with the same period for different timeframes on a single chart:

 

Source code:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiTF_MA : Indicator
    {
        [Parameter(DefaultValue = 50)]
        public int Period { get; set; }

        [Output("MA", Color = Colors.Yellow)]
        public IndicatorDataSeries MA { get; set; }

        [Output("MA5", Color = Colors.Orange)]
        public IndicatorDataSeries MA5 { get; set; }

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

        private MarketSeries series5;
        private MarketSeries series10;

        private MovingAverage ma;
        private MovingAverage ma5;
        private MovingAverage ma10;

        protected override void Initialize()
        {
            series5 = MarketData.GetSeries(TimeFrame.Minute5);
            series10 = MarketData.GetSeries(TimeFrame.Minute10);

            ma = Indicators.MovingAverage(MarketSeries.Close, Period, MovingAverageType.Triangular);
            ma5 = Indicators.MovingAverage(series5.Close, Period, MovingAverageType.Triangular);
            ma10 = Indicators.MovingAverage(series10.Close, Period, MovingAverageType.Triangular);
        }

        public override void Calculate(int index)
        {
            MA[index] = ma.Result[index];

            var index5 = GetIndexByDate(series5, MarketSeries.OpenTime[index]);
            if (index5 != -1)
                MA5[index] = ma5.Result[index5];

            var index10 = GetIndexByDate(series10, MarketSeries.OpenTime[index]);
            if (index10 != -1)
                MA10[index] = ma10.Result[index10];
        }


        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;
        }
    }
}

 

 

24 Mar 2015, 02:46RE:#16
cjdduarteposts: 38since: 16 Jan 2015

able to implement this code?
Really needed it

 

zofoyobis said:

I am trying to use this feature to create Heikin-Ashi indicator with custom timeframe as below. The value of haClose in the HeikinAshiClose series looks correct but I am always getting NaN for haOpen. I am not sure if something like below is supported?

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

namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class TFHeikinAshiIndicator : Indicator
    {
        [Parameter("Heikin-Ashi Timeframe")]
        public TimeFrame HeikinAshiTimeframe { get; set; }

        [Output("Open", Color = Colors.DarkSlateBlue)]
        public IndicatorDataSeries HeikinAshiOpen { get; set; }

        [Output("Close", Color = Colors.SlateBlue)]
        public IndicatorDataSeries HeikinAshiClose { get; set; }

        private MarketSeries heikinAshiSeries;

        protected override void Initialize()
        {
            heikinAshiSeries = MarketData.GetSeries(HeikinAshiTimeframe);
        }

        public override void Calculate(int index)
        {
            int heikinAshiSeriesIndex = GetIndexByDate(heikinAshiSeries, MarketSeries.OpenTime[index]);

            double open = heikinAshiSeries.Open[heikinAshiSeriesIndex];
            double high = heikinAshiSeries.High[heikinAshiSeriesIndex];
            double low = heikinAshiSeries.Low[heikinAshiSeriesIndex];
            double close = heikinAshiSeries.Close[heikinAshiSeriesIndex];

            double haClose = (open + high + low + close) / 4;
            double haOpen;
            if (heikinAshiSeriesIndex != -1)
                haOpen = (HeikinAshiOpen[heikinAshiSeriesIndex - 1] + HeikinAshiClose[heikinAshiSeriesIndex - 1]) / 2;
            else
                haOpen = (open + close) / 2;

            ChartObjects.DrawText("ha", string.Format("heikinAshiSeriesIndex={0} haOpen={1}, haClose={2}", heikinAshiSeriesIndex, haOpen, haClose), StaticPosition.TopLeft, Colors.Red);

            HeikinAshiOpen[heikinAshiSeriesIndex] = haOpen;
            HeikinAshiClose[heikinAshiSeriesIndex] = haClose;
        }

        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;
        }
    }
}

 

 


Robots do not cry!
16 Oct 2015, 09:48RE: Indicator example: Multi-timeframe moving average#17
aharonzbaidaposts: 32since: 01 Jan 2015

cAlgo_Development said:

In this example, we output moving averages with the same period for different timeframes on a single chart:

 

Source code:

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiTF_MA : Indicator
    {
        [Parameter(DefaultValue = 50)]
        public int Period { get; set; }

        [Output("MA", Color = Colors.Yellow)]
        public IndicatorDataSeries MA { get; set; }

        [Output("MA5", Color = Colors.Orange)]
        public IndicatorDataSeries MA5 { get; set; }

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

        private MarketSeries series5;
        private MarketSeries series10;

        private MovingAverage ma;
        private MovingAverage ma5;
        private MovingAverage ma10;

        protected override void Initialize()
        {
            series5 = MarketData.GetSeries(TimeFrame.Minute5);
            series10 = MarketData.GetSeries(TimeFrame.Minute10);

            ma = Indicators.MovingAverage(MarketSeries.Close, Period, MovingAverageType.Triangular);
            ma5 = Indicators.MovingAverage(series5.Close, Period, MovingAverageType.Triangular);
            ma10 = Indicators.MovingAverage(series10.Close, Period, MovingAverageType.Triangular);
        }

        public override void Calculate(int index)
        {
            MA[index] = ma.Result[index];

            var index5 = GetIndexByDate(series5, MarketSeries.OpenTime[index]);
            if (index5 != -1)
                MA5[index] = ma5.Result[index5];

            var index10 = GetIndexByDate(series10, MarketSeries.OpenTime[index]);
            if (index10 != -1)
                MA10[index] = ma10.Result[index10];
        }


        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;
        }
    }
}

 

A modification to the above example that solves missing values when attaching indicator to chart of lower time frame than the M5: the index function returns a match,or the closest previous value in higher time frame series.

//modified GetIndexByDate() from ctdn example

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

namespace cAlgo.Indicators
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC)]
    public class MultiTF_MA : Indicator
    {
        [Parameter(DefaultValue = 50)]
        public int Period { get; set; }
        
        [Output("MA", Color = Colors.Yellow)]
        public IndicatorDataSeries MA { get; set; }

        [Output("MA5", Color = Colors.Orange)]
        public IndicatorDataSeries MA5 { get; set; }

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

        private MarketSeries series5;
        private MarketSeries series10;

        private MovingAverage ma;
        private MovingAverage ma5;
        private MovingAverage ma10;

        protected override void Initialize()
        {
            series5 = MarketData.GetSeries(TimeFrame.Minute5);
            series10 = MarketData.GetSeries(TimeFrame.Minute10);

            ma = Indicators.MovingAverage(MarketSeries.Close, Period, MovingAverageType.Triangular);
            ma5 = Indicators.MovingAverage(series5.Close, Period, MovingAverageType.Triangular);
            ma10 = Indicators.MovingAverage(series10.Close, Period, MovingAverageType.Triangular);
        }

        public override void Calculate(int index)
        {
            MA[index] = ma.Result[index];

            //var index5 = GetIndexByDate(series5, MarketSeries.OpenTime[index]);
            var index5 = GetIndexByTime(series5, MarketSeries.OpenTime[index]); 
            if (index5 != -1)
                MA5[index] = ma5.Result[index5];

            //var index10 = GetIndexByDate(series10, MarketSeries.OpenTime[index]);
            var index10 = GetIndexByTime(series10, MarketSeries.OpenTime[index]);
            if (index10 != -1)
                MA10[index] = ma10.Result[index10];
        }


        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;
        }

        private int GetIndexByTime(MarketSeries searchSeries, DateTime desiredTime)
        {
            Print("desired time=" + desiredTime.ToString());
            //loop over time series backwards till closest match found
            for (int i = searchSeries.Close.Count - 1; i > 0; i--)
            {
                if (desiredTime == searchSeries.OpenTime[i])
                {
                    return i;
                }
                else if (searchSeries.OpenTime[i] < desiredTime) return i; //return last value prev. to desired
                
            }
            return -1;
        }
    }
}

16 Apr 2017, 22:46#18
emmamgibbons42posts: 1since: 16 Apr 2017

Thats a great feature. I love multiple EMA in with different time frame.  


Compare your broker before you choose them. here is the <a href="https://www.bestforexbrokers.com/" target="_blank">Best Forex Brokers of 2017</a>
27 Jul 2017, 08:17#19
Roman_Volodkoposts: 1since: 17 Nov 2016

MarketData.GetSeries doesnt work properly!!!

For example, If indicator is on Hour1 Timeframe and I want to get DataSeries from Minute1 Timeframe, it only get truncated Minute1 DataSeries.

DataSeries.Close.Count = 6000

M1DataSeries.Close.Count = 9000, but it should be at least 6 000 x 60 = 360 000!

And when you scroll to the beginning DataSeries.Close is updated, but M1DataSeries.Close is the same = 9000.

Please, fix it!