Multi currency robot and indicator

Created at 08 Feb 2019, 04:12
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!
UW

uwyness

Joined 08.02.2019

Multi currency robot and indicator
08 Feb 2019, 04:12


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

 


@uwyness
Replies

uwyness
13 Feb 2019, 00:15

MarketData.GetSeries returns incorrect data

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.


@uwyness

PanagiotisCharalampous
13 Feb 2019, 10:18

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


@PanagiotisCharalampous

uwyness
14 Feb 2019, 03:52

multi currency for Indicators.RelativeStrengthIndex

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?


@uwyness

uwyness
14 Feb 2019, 05:20

Solved : multi currency indicator

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.


@uwyness

PJ_Ctrader
04 Feb 2022, 20:02

QMP Filter

Hey

Do you happen to have the converted QMP Filter indicator for C trader. The one that shows the dot on chart?

 

THanks

PJ


@PJ_Ctrader