Multi currency robot and indicator

08 Feb 2019, 04:12Multi currency robot and indicator#1
uwynessposts: 5since: 08 Feb 2019

Hi all! I've got a robot that references an indicator that references another indicator that references another indicator. I'm looking to modify so it can trade multiple currencies.

 

 

 

 

Jim-method2 snippet:

private Jim_Indicator_v2 JimInd;

        protected override void OnStart()
        {
            JimInd = Indicators.GetIndicator<Jim_Indicator_v2>();
        }

        protected override void OnBar()
        {
            double lastResult = JimInd.Result.Last(1)
        }

Jim_Indicator snippet:

        private MACD_Platinum_v2 macdPlatinum;
        private QMP_Filter_v2 qmp;

        protected override void Initialize()
        {
            macdPlatinum = Indicators.GetIndicator<MACD_Platinum_v2>(12, 26, 9, true);
            qmp = Indicators.GetIndicator<QMP_Filter_v2>(0, 12, 26, 9, true, 1, 8, 3);
        }

        public override void Calculate(int index)
        {
            double macd = macdPlatinum.Avg[index];
            double qmpUpDot = qmp.Up[index];
        }

QQE_adv indicator snippet:

        public IndicatorDataSeries AtrRsi;
        public IndicatorDataSeries MaAtrRsi;
        public IndicatorDataSeries Rsi;

        private ExponentialMovingAverage _RsiMa;
        private ExponentialMovingAverage _TrLevelSlow;
        private IndicatorDataSeries _AtrRsi;
        private ExponentialMovingAverage _MaAtrRsi;
        private RelativeStrengthIndex _Rsi;

        protected override void Initialize()
        {
            _AtrRsi = CreateDataSeries();
            AtrRsi = CreateDataSeries();
            MaAtrRsi = CreateDataSeries();
            Rsi = CreateDataSeries();
            
            ...

            _Rsi = Indicators.RelativeStrengthIndex(MarketSeries.Close, RSI_Period);
            _RsiMa = Indicators.ExponentialMovingAverage(_Rsi.Result, SF);
            _MaAtrRsi = Indicators.ExponentialMovingAverage(_AtrRsi, Wilders_Period);
            _TrLevelSlow = Indicators.ExponentialMovingAverage(_MaAtrRsi.Result, Wilders_Period);
        }

        public override void Calculate(int index)
        {
            double rsi0, rsi1, dar, tr, dv;
            Rsi[index] = _Rsi.Result[index];
            RsiMa[index] = _RsiMa.Result[index];
            if (RsiMa[index - 1] == double.NaN)
                AtrRsi[index] = Math.Abs(0 - RsiMa[index]);
            else
                AtrRsi[index] = Math.Abs(RsiMa[index - 1] - RsiMa[index]);
            _AtrRsi[index] = AtrRsi[index];
            MaAtrRsi[index] = _MaAtrRsi.Result[index];

Making the robot multi-currency seems straight forward:

Jim-method2 snippet:

        [Parameter("Symbols List", DefaultValue = "EURUSD,AUDUSD,NZDUSD")]
        public string symbolInput { get; set; }

        private Position[] longPositions;
        private Symbol currentSymbol;

        protected override void OnBar()
        {
            string[] symbolList = symbolInput.Split(',');
            foreach (var word in symbolList)
            {
                currentSymbol = MarketData.GetSymbol(word);
                LongPositions = Positions.FindAll(label, currentSymbol, TradeType.Buy);
            }
        }

I'm not sure how to go about making the indicators multi currency. Is there an easy way? I assume I have to modify each indicator to receive a "symbol" input.

QQE_adv indicator snippet:

        [Parameter(DefaultValue = "AUDUSD")]
        public string symbolInput { get; set; }

        private MarketSeries series;

        protected override void Initialize()
        {
            _AtrRsi = CreateDataSeries();
            AtrRsi = CreateDataSeries();
            MaAtrRsi = CreateDataSeries();
            Rsi = CreateDataSeries();

            ...

            series = MarketData.GetSeries(symbolInput, TimeFrame);

            _Rsi = Indicators.RelativeStrengthIndex(series.Close, RSI_Period);
            _RsiMa = Indicators.ExponentialMovingAverage(_Rsi.Result, SF);
            _MaAtrRsi = Indicators.ExponentialMovingAverage(_AtrRsi, Wilders_Period);
            _TrLevelSlow = Indicators.ExponentialMovingAverage(_MaAtrRsi.Result, Wilders_Period);
        }

However, the indicator output looks totally different from expected.

AUDUSD QQE indicator:

EURUSD with "AUDUSD" as input in the QQE indicator:

I suspect it is the CreateDataSeries() code. Does it need to somehow take into account the "AUDUSD" symbol?

Let me know if I'm on the wrong track.

Attached is the full modified QQE indicator code for reference

// v1 - initial version.
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;

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

        [Parameter(DefaultValue = "AUDUSD")]
        public string symbolInput { get; set; }

        [Parameter(DefaultValue = 1)]
        public int SF { get; set; }

        [Parameter(DefaultValue = 8)]
        public int RSI_Period { get; set; }

        [Parameter(DefaultValue = 3)]
        public int WP { get; set; }

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

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

        public IndicatorDataSeries AtrRsi;
        public IndicatorDataSeries MaAtrRsi;
        public IndicatorDataSeries Rsi;

        int Wilders_Period;
        int StartBar;

        private ExponentialMovingAverage _RsiMa;
        private ExponentialMovingAverage _TrLevelSlow;
        private IndicatorDataSeries _AtrRsi;
        private ExponentialMovingAverage _MaAtrRsi;
        private RelativeStrengthIndex _Rsi;
        private MarketSeries series;

        protected override void Initialize()
        {
            _AtrRsi = CreateDataSeries();
            AtrRsi = CreateDataSeries();
            MaAtrRsi = CreateDataSeries();
            Rsi = CreateDataSeries();

            Wilders_Period = RSI_Period * 2 - 1;
            if (Wilders_Period < SF)
                StartBar = SF;
            else
                StartBar = Wilders_Period;

            series = MarketData.GetSeries(symbolInput, TimeFrame);

            _Rsi = Indicators.RelativeStrengthIndex(series.Close, RSI_Period);
            _RsiMa = Indicators.ExponentialMovingAverage(_Rsi.Result, SF);
            _MaAtrRsi = Indicators.ExponentialMovingAverage(_AtrRsi, Wilders_Period);
            _TrLevelSlow = Indicators.ExponentialMovingAverage(_MaAtrRsi.Result, Wilders_Period);
        }

        public override void Calculate(int index)
        {
            double rsi0, rsi1, dar, tr, dv;
            Rsi[index] = _Rsi.Result[index];
            RsiMa[index] = _RsiMa.Result[index];
            if (RsiMa[index - 1] == double.NaN)
                AtrRsi[index] = Math.Abs(0 - RsiMa[index]);
            else
                AtrRsi[index] = Math.Abs(RsiMa[index - 1] - RsiMa[index]);
            _AtrRsi[index] = AtrRsi[index];
            MaAtrRsi[index] = _MaAtrRsi.Result[index];

            if (index <= StartBar)
            {
                TrLevelSlow[index] = 0;
                return;
            }

            tr = TrLevelSlow[index - 1];
            rsi1 = _RsiMa.Result[index - 1];
            rsi0 = _RsiMa.Result[index];
            dar = _TrLevelSlow.Result[index] * WP;

            dv = tr;
            if (rsi0 < tr)
            {
                tr = rsi0 + dar;
                if (rsi1 < dv)
                {
                    if (tr > dv)
                        tr = dv;
                }
            }
            else if (rsi0 > tr)
            {
                tr = rsi0 - dar;
                if (rsi1 > dv)
                {
                    if (tr < dv)
                        tr = dv;
                }
            }

            TrLevelSlow[index] = tr;
        }
    }
}

 

13 Feb 2019, 00:15MarketData.GetSeries returns incorrect data#2
uwynessposts: 5since: 08 Feb 2019

Looks like MarketData.GetSeries returns incorrect data

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class NewIndicator : Indicator
    {
        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        private MarketSeries series;

        protected override void Initialize()
        {
            series = MarketData.GetSeries("AUDUSD", TimeFrame.Hour);
        }

        public override void Calculate(int index)
        {
            Result[index] = series.Close[index];
        }
    }
}

the AUDUSD H1 12/02/2019 10:00 UTC+2 close should be 0.70804. However, the above code is giving 0.76245.

13 Feb 2019, 10:18#3
Panagiotis Charalampousposts: 2168since: 13 Jan 2017

Hi uwyness,

The index for Results and series.Close do not necessarily match. To set a valid value to results use the following

Result[index] = series.Close[series.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

Best Regards,

Panagiotis


Head of Community Management at cTrader
14 Feb 2019, 03:52multi currency for Indicators.RelativeStrengthIndex#4
uwynessposts: 5since: 08 Feb 2019

Thanks. I would've never guessed from the examples in previous threads.

How would I pass the close prices series to an indicator?

series = MarketData.GetSeries("AUDUSD", TimeFrame);

_Rsi = Indicators.RelativeStrengthIndex(series.Close, RSI_Period);

Is there a page somewhere that explains how the Results and series.Close indexes differ?

14 Feb 2019, 05:20Solved : multi currency indicator#5
uwynessposts: 5since: 08 Feb 2019

Solved my own problem, though it isn't an elegant solution.

Created a simple Close indicator. Passed the new indicator to the Indicators.RelativeStrengthIndex method.

CloseIndicator:

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class CloseIndicator : Indicator
    {
        [Output("Main")]
        public IndicatorDataSeries Result { get; set; }

        [Parameter(DefaultValue = "AUDUSD")]
        public string symbolInput { get; set; }

        private MarketSeries series;

        protected override void Initialize()
        {
            series = MarketData.GetSeries(symbolInput, TimeFrame);
        }

        public override void Calculate(int index)
        {
            Result[index] = series.Close[series.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
        }
    }
}

Getting RSI of another currency:

        [Parameter(DefaultValue = "AUDUSD")]
        public string symbolInput { get; set; }

        private CloseIndicator closeInd;

        closeInd = Indicators.GetIndicator<CloseIndicator>(symbolInput);
        _Rsi = Indicators.RelativeStrengthIndex(closeInd.Result, RSI_Period);

Please let me know if you any other suggestions.