Multi-timeframe robots/indicators

cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  30 Aug 2013, 12:37
Multi-timeframe robots/indicators

We added new functionality to cAlgo - the ability for robots and indicators to retrieve OHLCV data for multiple timeframes. This can be done using the MarketData.GetSeries method:

MarketSeries m5series = MarketData.GetSeries(TimeFrame.Minute5);

We recommend to call the GetSeries method in the Robot.OnStart() or the Indicator.Initialize() methods.

When the series for a specified timeframe is received, you can access the series values or build an indicator based on that series:

private MarketSeries m10;
private MovingAverage ma;

protected override void OnStart()
{
    m10 = MarketData.GetSeries(TimeFrame.Minute10);
    ma = Indicators.SimpleMovingAverage(m10.High, 14);
}

The new version of our Demo cTrader and cAlgo is released and can be downloaded from www.spotware.com

Update: Backtesting of Multi-timeframe robots is supported now.

TRADERS FIRST
cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  30 Aug 2013, 12:53
TimeFrame parameters

Another feature that has been introduced, is parameters of TimeFrame type that can be used in multi-timeframe robots and indicators:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC)]
    public class MultiTimeFrameBot : Robot
    {
        [Parameter("Another Timeframe", DefaultValue = "Minute10")]
        public TimeFrame AnotherTimeFrame { get; set; }

        protected override void OnStart()
        {
            var anotherSeries = MarketData.GetSeries(AnotherTimeFrame);

            Print("My TimeFrame: {0}, Last high: {1}, Last Low: {2}", TimeFrame, MarketSeries.High.LastValue, MarketSeries.Low.LastValue);
            Print("Another TimeFrame: {0}, Last high: {1}, Last Low: {2}", AnotherTimeFrame, anotherSeries.High.LastValue, anotherSeries.Low.LastValue);
        }
    }
}

As a result we have a robot like this:


TRADERS FIRST
cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  30 Aug 2013, 12:56
Indicator example: Multi-timeframe moving average

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;
        }
    }
}
TRADERS FIRST
cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  30 Aug 2013, 14:02
Multi-timeframe robot

This is the RSI robot. It uses a daily Average True Range value as a filter, i.e. it does not trade if the ATR value is greater than the specified parameter value:

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

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC)]
    public class SampleRSIRobot : Robot
    {
        [Parameter("Max ATR Value", DefaultValue = 0.01)]
        public double MaxAtrValue { get; set; }

        private RelativeStrengthIndex rsi;
        private AverageTrueRange atr;

        protected override void OnStart()
        {
            rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, 14);

            var dailySeries = MarketData.GetSeries(TimeFrame.Daily);
            atr = Indicators.AverageTrueRange(dailySeries, 20, MovingAverageType.Simple);
        }

        protected override void OnTick()
        {
            if (Trade.IsExecuting)
                return;

            // Do nothing if daily ATR value > Max allowed value
            if (atr.Result.LastValue > MaxAtrValue)
                return;

            if (rsi.Result.LastValue < 30)
            {
                OpenPosition(TradeType.Buy);
            }
            else if (rsi.Result.LastValue > 70)
            {
                OpenPosition(TradeType.Sell);
            }
        }

        private void OpenPosition(TradeType tradeType)
        {
            foreach (var position in Account.Positions)
            {
                if (position.Label == "SampleRSIRobot" && position.TradeType != tradeType)
                {
                    Trade.Close(position);
                }
            }

            bool hasNeededPosition = Account.Positions.Any(position => position.Label == "SampleRSIRobot" && position.TradeType == tradeType);
            if (!hasNeededPosition)
            {
                var request = new MarketOrderRequest(tradeType, 10000) 
                {
                    Label = "SampleRSIRobot",
                    StopLossPips = 20
                };
                Trade.Send(request);
            }
        }
    }
}
TRADERS FIRST
kricka's avatar

kricka since: 13 Mar 2013;

  31 Aug 2013, 00:29

Hi,

we are welcoming this possibility to trade different time frames i cAlgo. A very much needed function for developers.

Thanks..

http://rmmrobot.com

Neob1y since: 17 Sep 2013;

  17 Sep 2013, 16:37
Hi,

when do support Multi-timeframe baktesting?

Thanks.

cAlgo_Development's avatar

cAlgo_Development since: 20 Feb 2013;

  17 Sep 2013, 17:12

We are already working on it. Backtesting will be available very soon.

TRADERS FIRST

Neob1y since: 17 Sep 2013;

  17 Sep 2013, 17:39
RE:

cAlgo_Development said:

We are already working on it. Backtesting will be available very soon.

Thanks for the answer.

andromeda since: 06 Sep 2013;

  24 Sep 2013, 01:35
RE:

Thank you for this upgrade which seems to be something I am looking for.

Is there any description of how to use these series in the context of Calculate method?

I know Calculate is called with an index parameter.

How that index relates to instantiated m10 or m1 for that matter ?

How often Calculate method is called by who and when and what is index relative to ?

(I know it is called at some irregular intervals in real time and any time a graph point is evaluated,

but I cannot correlate it to the last "10 minute" or "one minute" bar.)

My question may seem naive for you guys who know this software inside out, but this kind of

questions arise for anyone new to cAlgo. We badly need some glue logic described somewhere.

Descriptions are minimalistic. A simple question like Print method nowhere describes where

does the print go to. So far I know it goes o a log file, but could not find the log anywhere.

I find cAlgo exeptionally cool tool but I am having trouble to get started due to insufficient

description. C# is not an issue here but general concept of all classes and objects and how they tie together.

Of course I will slowly build the picture but it will be a long process.

Cheers

cAlgo_Development said:

We added new functionality to cAlgo - the ability for robots and indicators to retrieve OHLCV data for multiple timeframes. This can be done using the MarketData.GetSeries method:

MarketSeries m5series = MarketData.GetSeries(TimeFrame.Minute5);

We recommend to call the GetSeries method in the Robot.OnStart() or the Indicator.Initialize() methods.

When the series for a specified timeframe is received, you can access the series values or build an indicator based on that series:

private MarketSeries m10;
private MovingAverage ma;

protected override void OnStart()
{
    m10 = MarketData.GetSeries(TimeFrame.Minute10);
    ma = Indicators.SimpleMovingAverage(m10.High, 14);
}

The new version of our Demo cTrader and cAlgo is released and can be downloaded from www.spotware.com

Backtesting of Multi-timeframe robots in not supported yet. We will support it in the next version.

Spotware's avatar

Spotware since: 23 Sep 2013;

  24 Sep 2013, 12:31
RE: RE:

andromeda said:

How that index relates to instantiated m10 or m1 for that matter ?

How often Calculate method is called by who and when and what is index relative to ?

(I know it is called at some irregular intervals in real time and any time a graph point is evaluated,

but I cannot correlate it to the last "10 minute" or "one minute" bar.)

The Calculate method is called on each historical bar in the series the instance is attached to (i.e. EURUSD H1). Once it reaches real time, it is called on each incoming tick of that symbol, as well as on each incoming tick of any other symbols for which the series are retrieved.

The "index" that is the parameter to the Calculate method, is the index of the series that the instance is attached to. The series of other timeframes / symbols have different indexes. So, to get the index of a specific series you would need to use a method such as GetIndexByDate (Described in the example above: Multi-timeframe moving average)

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

Descriptions are minimalistic. A simple question like Print method nowhere describes where

does the print go to. So far I know it goes o a log file, but could not find the log anywhere.

I find cAlgo exeptionally cool tool but I am having trouble to get started due to insufficient

description. C# is not an issue here but general concept of all classes and objects and how they tie together.

 The Print method prints to the Log within the platform, not a log file. It is the last tab in the bottom panel of the chart view.

We are preparing a manual for cAlgo with more detailed descriptions of all the main classes in the API.

TRADERS FIRSTâ„¢ Vote for your favorite features: https://ctrader.com/forum/suggestions