Simple cBot from custom indicator

Created at 28 Mar 2021, 11:14
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!
MR

Mr4x

Joined 12.04.2019

Simple cBot from custom indicator
28 Mar 2021, 11:14


Hi,

I have an indicator (code posted below) which displays the output of the correlation between two symbols. How would I incorporate a simple ExecuteMarketOrder to a cBot say when correlation drops below 50? Are there any special steps to reference a custom indicator compared to referencing a standard one (such as moving average)?

 

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

// (C) 2014 marekfx

namespace cAlgo
{
    [Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None, AutoRescale = true)]
    public class Correlation : Indicator
    {
        private MarketSeries _symbol2Series;

        [Parameter(DefaultValue = "USDCHF")]
        public string Symbol2 { get; set; }

        [Parameter(DefaultValue = 50)]
        public int Lookback { get; set; }

        [Output("Correlation", PlotType = PlotType.DiscontinuousLine)]
        public IndicatorDataSeries Result { get; set; }

        protected override void Initialize()
        {
            _symbol2Series = MarketData.GetSeries(Symbol2, TimeFrame);
        }

        public override void Calculate(int index)
        {
            DateTime date = MarketSeries.OpenTime[index];

            //get index for Symbol 2 series
            var idx2 = _symbol2Series.OpenTime.GetIndexByExactTime(date);

            if (index < Lookback || idx2 < Lookback)
                return;

            double[] tab1 = new double[Lookback];
            double[] tab2 = new double[Lookback];

            //populate tab1 and tab2 arrays with close for Symbol 1 (MarketSeries) and Symbol 2
            for (int i = 0; i < Lookback; i++)
            {
                tab1[i] = MarketSeries.Close[index - Lookback + i];
                tab2[i] = _symbol2Series.Close[idx2 - Lookback + i];
            }

            Result[index] = Stat.Correlation(tab1, tab2);
        }
    }

    //Correlation from (c) http://mantascode.com/c-how-to-get-correlation-coefficient-of-two-arrays/
    public class Stat
    {
        public static double Correlation(double[] array1, double[] array2)
        {
            double[] array_xy = new double[array1.Length];
            double[] array_xp2 = new double[array1.Length];
            double[] array_yp2 = new double[array1.Length];
            for (int i = 0; i < array1.Length; i++)
                array_xy[i] = array1[i] * array2[i];
            for (int i = 0; i < array1.Length; i++)
                array_xp2[i] = Math.Pow(array1[i], 2.0);
            for (int i = 0; i < array1.Length; i++)
                array_yp2[i] = Math.Pow(array2[i], 2.0);
            double sum_x = 0;
            double sum_y = 0;
            foreach (double n in array1)
                sum_x += n;
            foreach (double n in array2)
                sum_y += n;
            double sum_xy = 0;
            foreach (double n in array_xy)
                sum_xy += n;
            double sum_xpow2 = 0;
            foreach (double n in array_xp2)
                sum_xpow2 += n;
            double sum_ypow2 = 0;
            foreach (double n in array_yp2)
                sum_ypow2 += n;
            double Ex2 = Math.Pow(sum_x, 2.0);
            double Ey2 = Math.Pow(sum_y, 2.0);

            return (array1.Length * sum_xy - sum_x * sum_y) / Math.Sqrt((array1.Length * sum_xpow2 - Ex2) * (array1.Length * sum_ypow2 - Ey2));
        }
    }
}


@Mr4x
Replies

amusleh
28 Mar 2021, 11:27

You can reference custom indicators on your cBots by following below steps:

1. Right click on your cBot name on cTrader automate, select "Manage References"

2. Find the indicator you want to reference in indicators tab and select it, then click "Apply" button

3. Re-build your indicator, then to use indicator:

using cAlgo.API;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class CorrelationBot : Robot
    {
        private Correlation _correlation;

        protected override void OnStart()
        {
            _correlation = Indicators.GetIndicator<Correlation>("USDCHF", 50);
        }

        protected override void OnTick()
        {
            if (_correlation.Result.Last(1) > 50)
            {
            }
            else
            {
            }
        }
    }
}

You have to pass all indicator parameters a value on "GetIndicator" method, otherwise it will not work, and you can only use the indicator outputs not properties.


@amusleh

JerryTrader
30 Mar 2021, 00:56

RE:

amusleh said:

You have to pass all indicator parameters a value on "GetIndicator" method, otherwise it will not work, and you can only use the indicator outputs not properties.

Why are you saying not to use properties ? In some of my bots and indicators, I use properties and events, and it seems to work fine.
I double checked the documentation, but no mentions saying if we should or shouldn't use properties.

I read in a topic (but can't find it back) that an indicator needs to be calculated (by accessing an output for example) before being able to access a property.

Can you please detail your answer a bit more ?

 

Thanks !


@JerryTrader

amusleh
30 Mar 2021, 09:57

RE: RE:

JerryTrader said:

amusleh said:

You have to pass all indicator parameters a value on "GetIndicator" method, otherwise it will not work, and you can only use the indicator outputs not properties.

Why are you saying not to use properties ? In some of my bots and indicators, I use properties and events, and it seems to work fine.
I double checked the documentation, but no mentions saying if we should or shouldn't use properties.

I read in a topic (but can't find it back) that an indicator needs to be calculated (by accessing an output for example) before being able to access a property.

Can you please detail your answer a bit more ?

 

Thanks !

Hi,

You can use properties and events, but some times they don't behave the way they should, so that's why I said not use properties when referencing custom indicators on a cBot.


@amusleh

JerryTrader
30 Mar 2021, 12:28

RE: RE: RE:

amusleh said:

You can use properties and events, but some times they don't behave the way they should, so that's why I said not use properties when referencing custom indicators on a cBot.

Interesting ! So I guess this is a bug.
Did you find under which conditions they don't work as expected ? Just so I can try to workaround this.

Thanks Ahmad !


@JerryTrader

amusleh
30 Mar 2021, 14:34

RE: RE: RE: RE:

JerryTrader said:

amusleh said:

You can use properties and events, but some times they don't behave the way they should, so that's why I said not use properties when referencing custom indicators on a cBot.

Interesting ! So I guess this is a bug.
Did you find under which conditions they don't work as expected ? Just so I can try to workaround this.

Thanks Ahmad !

Hi,

It was not working properly with generic collections, not sure if it's working now or not, it was a long time ago.


@amusleh

marcoraja
04 Apr 2023, 01:55

At the time I write this feedback it seems to work with params too.


@marcoraja