Issues with Multi-Symbol cBot

Created at 26 Apr 2019, 11:26
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!
JO

JohnK

Joined 31.01.2017

Issues with Multi-Symbol cBot
26 Apr 2019, 11:26


Dear cTDN Community,

I'd like to ask for some help in resolving an issue I'm having with a multi-symbol bot I'm putting together.

I was hoping someone might be able to see my issue with my code & support me in rectifying it. I'm not sure if I'm calling the API correctly. I've pasted the code segment below.

The issue:

  • I have a custom indicator that takes 2 market series as an input. I'm trying to feed the chart series (Y_Series) as well as the additional instrument series (X_Series) into the indicator.
  • The bot references a custom indicator which works without issue by itself, and has been added as a reference through the reference manager.
  • If I change both inputs to "X_Series" then I no longer receive the error.

The error that I receive is the following:

  • | cBot "Bot Trial v1" was started successfully for EURAUD, m1.
  • | Crashed in OnStart with ArgumentException: MarketSeries and source series must be from the same TimeFrame and Symbol
  • | cBot "Bot Trial v1" was stopped for EURAUD, m1.

I'm a bit new to this so I'm not familiar with what the errors are telling me or how to properly diagnose it. I'm hoping I've just made a silly rookie error.

 

I appreciate any help and support offered!

 

The code segment concerned:

    [Robot(AccessRights = AccessRights.None)]
    public class BotTrialv1 : Robot
    {
        [Parameter("X-Series")]
        public string SymbolCode { get; set; }

        private const string Long_label = "BotTrialv1_Long";
        private const string Short_label = "BotTrialv1_Short";

        private Symbol X_Symbol;
        private MarketSeries X_Series;
        private MarketSeries Y_Series;
        private Bot_Indicator_v1 BI;

        protected override void OnStart()
        {
            X_Symbol = MarketData.GetSymbol(SymbolCode);
            X_Series = MarketData.GetSeries(X_Symbol, TimeFrame);
            Y_Series = MarketData.GetSeries(Symbol, TimeFrame);
            BI = Indicators.GetIndicator<Bot_Indicator_v1>(X_Series.Close, Y_Series.Close);
        }

 


@JohnK
Replies

PanagiotisCharalampous
30 Apr 2019, 12:53

Hi JohnK,

Please share with us the indicator code as well.

Best Regards,

Panagiotis


@PanagiotisCharalampous

JohnK
30 Apr 2019, 14:54

RE:

Panagiotis Charalampous said:

Hi JohnK,

Please share with us the indicator code as well.

Best Regards,

Panagiotis

Hi Panagiotis,

Thank you for the reply & support with my issue. Below you'll find the cBot & indicator codes. You'll notice they don't really "do" anything - simply just a trial to make sure that I can call & use the multi-symbol functionality correctly.

Indicator code:

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class Bot_Indicator_v1 : Indicator
    {
        [Parameter("X Series")]
        public DataSeries X_Source { get; set; }

        [Parameter("Y Series")]
        public DataSeries Y_Source { get; set; }

        [Output("X Series", PlotType = PlotType.Line, LineColor = "#FFFF0000", LineStyle = LineStyle.Solid)]
        public IndicatorDataSeries X_Series { get; set; }

        [Output("Y Series", PlotType = PlotType.Line, LineColor = "#FF000000", LineStyle = LineStyle.Solid)]
        public IndicatorDataSeries Y_Series { get; set; }

        protected override void Initialize()
        {
        }

        public override void Calculate(int index)
        {
            X_Series[index] = X_Source[index];
            Y_Series[index] = Y_Source[index];
        }
    }
}

cBot code:

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

namespace cAlgo
{
    [Robot(AccessRights = AccessRights.None)]
    public class BotTrialv1 : Robot
    {
        [Parameter("X-Series")]
        public string SymbolCode { get; set; }

        private const string Long_label = "BotTrialv1_Long";
        private const string Short_label = "BotTrialv1_Short";

        private Symbol X_Symbol;
        private MarketSeries X_Series;
        private MarketSeries Y_Series;
        private Bot_Indicator_v1 BI;

        protected override void OnStart()
        {
            X_Symbol = MarketData.GetSymbol(SymbolCode);
            X_Series = MarketData.GetSeries(X_Symbol, TimeFrame);
            Y_Series = MarketData.GetSeries(Symbol, TimeFrame);
            BI = Indicators.GetIndicator<Bot_Indicator_v1>(X_Series.Close, Y_Series.Close);
        }

        protected override void OnBar()
        {
        }
    }
}

Again, I appreciate your support on this issue.

John


@JohnK

PanagiotisCharalampous
30 Apr 2019, 15:13

Thanks John,

Tell me if the alternative below works for you

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

namespace cAlgo
{
    [Indicator(IsOverlay = false, AccessRights = AccessRights.None)]
    public class Bot_Indicator_v1 : Indicator
    {

        [Parameter("Y-Series")]
        public string Y_Symbol { get; set; }

        [Parameter("X-Series")]
        public string X_Symbol { get; set; }

        [Output("X Series", PlotType = PlotType.Line, LineColor = "#FFFF0000", LineStyle = LineStyle.Solid)]
        public IndicatorDataSeries X_Series { get; set; }

        [Output("Y Series", PlotType = PlotType.Line, LineColor = "#FFFF0000", LineStyle = LineStyle.Solid)]
        public IndicatorDataSeries Y_Series { get; set; }

        private MarketSeries X_Source;
        private MarketSeries Y_Source;
        protected override void Initialize()
        {

            X_Source = MarketData.GetSeries(X_Symbol, TimeFrame);
            Y_Source = MarketData.GetSeries(Y_Symbol, TimeFrame);
        }

        public override void Calculate(int index)
        {
            X_Series[index] = X_Source.Close[index];
            Y_Series[index] = Y_Source.Close[index];
        }
    }
}
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;

namespace cAlgo
{
    [Robot(AccessRights = AccessRights.None)]
    public class BotTrialv1 : Robot
    {
        [Parameter("X-Series")]
        public string SymbolCode { get; set; }

        private Bot_Indicator_v1 BI;

        protected override void OnStart()
        {
            BI = Indicators.GetIndicator<Bot_Indicator_v1>(Symbol.Code, SymbolCode);
        }

        protected override void OnBar()
        {
        }
    }
}

Best Regards,

Panagiotis


@PanagiotisCharalampous

JohnK
02 May 2019, 12:28

RE:

Hi Panagiotis,

Thank you very much for your solution, it's very much appreciate. It appears to work just fine and solves my issue.

Just a couple of related questions:

1) Should the index in the indicator be indexed in the following way?

X_Series[index] = X_Source.Close[X_Source.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];
Y_Series[index] = Y_Source.Close[Y_Source.OpenTime.GetIndexByTime(MarketSeries.OpenTime[index])];

2) Is there a way to link the bot to the indicator without having to manually enter the chart symbol for the indicator? I've put an example below to illustrate what I mean. I know the example I'm giving doesn't work, and in this context of the indicator alone it's also useless, but just to understand the ways in which the API may be called.

[Parameter("X Series")]
public DataSeries X_Source { get; set; }

[Parameter("Y Series")]
public DataSeries Y_Source { get; set; }

private MarketSeries X_Series;
private MarketSeries Y_Series;

protected override void Initialize()
{
	X_Series = MarketData.GetSeries(X_Source.Symbol.Code, TimeFrame);
	Y_Series = MarketData.GetSeries(Y_Source.Symbol.Code, TimeFrame);
}

3) As I understand it there's no dropdown menu option for selecting a symbol (only manual input as a string). I see there is a "vote for feature" concerning "custom parameters" which is planned (since August 2018) to be implemented in a following update. I just wonder if a dropdown for symbols will also be implemented seeing as it's a somewhat standard parameter?

[Ref.: http://vote.spotware.com/forums/229166-ideas-and-suggestions-for-ctrader-and-calgo/suggestions/5502949-custom-parameters]

 

Again, many thanks for your support.

John


@JohnK

PanagiotisCharalampous
06 May 2019, 12:10

Hi John,

1) If you plan to use a different timeframe then yes.

2) Could you explain the business need for this. What are you trying to achieve. If you want to use different symbols then you will need to somehow input them.

3) There are no such plans at the moment but we can consider it if it gets enough support by the community.

Best Regards,

Panagiotis


@PanagiotisCharalampous