Reference to Custom Indicator

Created at 08 Sep 2022, 08:43
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!
VE

velu130486

Joined 08.11.2019 Blocked

Reference to Custom Indicator
08 Sep 2022, 08:43


Dear Team,

I am using the Variable moving average (available in Ctrader) and with help of Ctrader support team I modified the code to work with custom time frame. Now I reference the same to my Cbot and the build was successful, however when I start the Cbot it crashes.

04/08/2022 00:00:00.000 | Crashed in OnStart with ArgumentException: Incorrect parameters count. (Parameter 'parameterValues')
04/08/2022 00:00:00.000 | CBot instance [Test, XAUUSD, h1] crashed with error "Crashed in OnStart with ArgumentException: Incorrect parameters count. (Parameter 'parameterValues')"

I use the same logic of EMA and it works fine, only I am getting error with VMA. I am sure there is a mistake but not able to fix it, please support because I want to use this Indicator in my multi symbol Cbot

Below is the Indicator code

using System;
using cAlgo.API;
using cAlgo.API.Internals;
namespace cAlgo
{
    [Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class VariableMovingAverageMT : Indicator
    {
        [Parameter(DefaultValue = 6)]
        public int Period { get; set; }
        [Parameter("TimeFrame")]
        public TimeFrame BaseTimeFrame { get; set; }
        [Output("Main", LineColor = "Cyan")]
        public IndicatorDataSeries Result { get; set; }

        private double K = 1;
        private IndicatorDataSeries pdmS, mdmS, pdiS, mdiS, iS, tempResult;
        private Bars _baseBars;
        protected override void Initialize()
        {
            _baseBars = MarketData.GetBars(BaseTimeFrame);
            K /= Period;
            pdmS = CreateDataSeries();
            mdmS = CreateDataSeries();
            pdiS = CreateDataSeries();
            mdiS = CreateDataSeries();
            iS = CreateDataSeries();
            tempResult = CreateDataSeries();
        }
        public override void Calculate(int index)
        {
            var baseIndex = _baseBars.OpenTimes.GetIndexByTime(Bars.OpenTimes[index]);
            if (baseIndex < Period)
                return;
            double pdm = Math.Max(_baseBars[baseIndex].Close - _baseBars[baseIndex - 1].Close, 0), mdm = Math.Max(_baseBars[baseIndex - 1].Close - _baseBars[baseIndex].Close, 0);
            pdmS[index] = ((1 - K) * (double.IsNaN(pdmS[index - 1]) ? 0 : pdmS[index - 1]) + K * pdm);
            mdmS[index] = ((1 - K) * (double.IsNaN(mdmS[index - 1]) ? 0 : mdmS[index - 1]) + K * mdm);
            double pdi = pdmS[index] / (pdmS[index] + mdmS[index]);
            double mdi = mdmS[index] / (pdmS[index] + mdmS[index]);
            pdiS[index] = ((1 - K) * (double.IsNaN(pdiS[index - 1]) ? 0 : pdiS[index - 1]) + K * pdi);
            mdiS[index] = ((1 - K) * (double.IsNaN(mdiS[index - 1]) ? 0 : mdiS[index - 1]) + K * mdi);
            iS[index] = ((1 - K) * (double.IsNaN(iS[index - 1]) ? 0 : iS[index - 1]) + K * Math.Abs(pdiS[index] - mdiS[index]) / (pdiS[index] + mdiS[index]));
            double hhv = iS.Maximum(Period);
            double llv = iS.Minimum(Period);
            tempResult[index] = (1 - K * (iS[index] - llv) / (hhv - llv)) * (double.IsNaN(tempResult[index - 1]) ? 0 : tempResult[index - 1]) + _baseBars[baseIndex].Close * K * (iS[index] - llv) / (hhv - llv);
            if (index > Period * 10)
                Result[index] = tempResult[index];
        }
    }
}

Below is my Cbot Code where I had linked the VMA

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using FeatureFXlib;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.IO;
namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class Test : Robot
    {
        [Parameter("MID", Group = "TIMEFRAME")]
        public TimeFrame midtf { get; set; }
        [Parameter("XAUUSD", Group = "METALS", DefaultValue = false)]
        public bool XAUUSD { get; set; }
        [Parameter("XAUEUR", Group = "METALS", DefaultValue = false)]
        public bool XAUEUR { get; set; }
        [Parameter("XAGUSD", Group = "METALS", DefaultValue = false)]
        public bool XAGUSD { get; set; }
        [Parameter("XAGEUR", Group = "METALS", DefaultValue = false)]
        public bool XAGEUR { get; set; }
        [Parameter("XPTUSD", Group = "METALS", DefaultValue = false)]
        public bool XPTUSD { get; set; }
        [Parameter("XPDUSD", Group = "METALS", DefaultValue = false)]
        public bool XPDUSD { get; set; }

        FeatureFX API = new FeatureFX();
        BarFX bar = new BarFX();
        Dictionary<string, Bars> midBar = new Dictionary<string, Bars>();
        Dictionary<string, ExponentialMovingAverage> ema = new Dictionary<string, ExponentialMovingAverage>();
        Dictionary<string, VariableMovingAverageMT> vma = new Dictionary<string, VariableMovingAverageMT>();

        protected override void OnStart()
        {
            bar.glob = MarketData;
            bar.AddCustomListMetals(XAUUSD, XAUEUR, XAGUSD, XAGEUR, XPTUSD, XPDUSD);
            foreach (var sym in bar.customList)
            {
                midBar.Add(sym, bar.@get(midtf, sym));
                ema.Add(sym, Indicators.ExponentialMovingAverage(midBar[sym].ClosePrices, 20));
                vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(midBar[sym].ClosePrices, 6));
            }
        }
        protected override void OnTick()
        {
            try
            {
                createnew();
            }
            catch
            {
                Print("On_Tick() is showing error");
            }
        }
        void createnew()
        {
            foreach (var sym in bar.customList)
            {
                var close = midBar[sym].ClosePrices.LastValue;
                double vmacur = vma[sym].Result.LastValue;
                double emacur = ema[sym].Result.LastValue;
                double minvolume = Symbols.GetSymbol(sym).VolumeInUnitsMin;
                if (close > vmacur)
                {
                    ExecuteMarketOrder(TradeType.Buy, sym, minvolume, "EA", 0, 0);
                }
                if (close < vmacur)
                {
                    ExecuteMarketOrder(TradeType.Sell, sym, minvolume, "EA", 0, 0);
                }
            }
        }
}
}

Thanks and Regards

R. Vadivelan


Replies

PanagiotisCharalampous
08 Sep 2022, 08:51

Hi Vadivelan,

You are missing the timeframe parameter here

 vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(midBar[sym].ClosePrices, 6));

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


@PanagiotisCharalampous

velu130486
08 Sep 2022, 09:55

RE:

Hi Panagiotis,

Thanks for your reply, but I have the same code in my file as below and I don't know how to fix this issues

ema.Add(sym, Indicators.ExponentialMovingAverage(midBar[sym].ClosePrices, 20));
vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(midBar[sym].ClosePrices, 6));

midbar[sym].ClosePrices is my timeframe parameter. Please help me to fix this if something is wrong.

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

You are missing the timeframe parameter here

 vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(midBar[sym].ClosePrices, 6));

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


PanagiotisCharalampous
08 Sep 2022, 11:40

Hi Vadivelan,

It should look like this

vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(14, TimeFrame.Daily));

Best Regards,

Panagiotis 

Join us on Telegram and Facebook


@PanagiotisCharalampous

velu130486
08 Sep 2022, 12:39

RE:

Hi Panagiotis,

I followed your instruction, and copy paste the same code, but still I get the same error. Please help me to fix this issue

using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
using FeatureFXlib;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.IO;

namespace cAlgo.Robots
{
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.FullAccess)]
    public class Test : Robot
    {
        [Parameter("MID", Group = "TIMEFRAME")]
        public TimeFrame midtf { get; set; }
        [Parameter("XAUUSD", Group = "METALS", DefaultValue = false)]
        public bool XAUUSD { get; set; }
        [Parameter("XAUEUR", Group = "METALS", DefaultValue = false)]
        public bool XAUEUR { get; set; }
        [Parameter("XAGUSD", Group = "METALS", DefaultValue = false)]
        public bool XAGUSD { get; set; }
        [Parameter("XAGEUR", Group = "METALS", DefaultValue = false)]
        public bool XAGEUR { get; set; }
        [Parameter("XPTUSD", Group = "METALS", DefaultValue = false)]
        public bool XPTUSD { get; set; }
        [Parameter("XPDUSD", Group = "METALS", DefaultValue = false)]
        public bool XPDUSD { get; set; }
        FeatureFX API = new FeatureFX();
        BarFX bar = new BarFX();
        Dictionary<string, Bars> midBar = new Dictionary<string, Bars>();
        Dictionary<string, ExponentialMovingAverage> ema = new Dictionary<string, ExponentialMovingAverage>();
        Dictionary<string, VariableMovingAverageMT> vma = new Dictionary<string, VariableMovingAverageMT>();

        protected override void OnStart()
        {
            bar.glob = MarketData;
            bar.AddCustomListMetals(XAUUSD, XAUEUR, XAGUSD, XAGEUR, XPTUSD, XPDUSD);
            foreach (var sym in bar.customList)
            {
                midBar.Add(sym, bar.@get(midtf, sym));
                ema.Add(sym, Indicators.ExponentialMovingAverage(midBar[sym].ClosePrices, 20));
                vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(6, TimeFrame.Hour));
            }
        }
        protected override void OnTick()
        {
            try
            {
                createnew();
            }
            catch
            {
                Print("On_Tick() is showing error");
            }
        }
        void createnew()
        {
            foreach (var sym in bar.customList)
            {
                var close = midBar[sym].ClosePrices.LastValue;
                double vmacur = vma[sym].Result.LastValue;
                if (close > vmacur)
                {
                    Print("BUY");
                }
                if (close < vmacur)
                {
                    Print("SELL");
                }
            }
        }
    }
}

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

It should look like this

vma.Add(sym, Indicators.GetIndicator<VariableMovingAverageMT>(14, TimeFrame.Daily));

Best Regards,

Panagiotis 

Join us on Telegram and Facebook

 


PanagiotisCharalampous
08 Sep 2022, 12:48

Hi Vadivelan,

I can't build your project because I am missing references. Can you please simplify it and remove FeatureFXlib?

Panagiotis 

Join us on Telegram and Facebook


@PanagiotisCharalampous

velu130486
08 Sep 2022, 13:09

RE:

Hi Panagiotis,

Actually my bot is multisymbol bot, so If I remove the library I will have problems in the coding. So I send the Library files and indicator files to your telegram. Could you please assist me to fix it there.

Thanks and Regards

R. Vadivelan

PanagiotisCharalampous said:

Hi Vadivelan,

I can't build your project because I am missing references. Can you please simplify it and remove FeatureFXlib?

Panagiotis 

Join us on Telegram and Facebook