Reference to Custom Indicator
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
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
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
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
PanagiotisCharalampous
08 Sep 2022, 08:51
Hi Vadivelan,
You are missing the timeframe parameter here
Best Regards,
Panagiotis
Join us on Telegram and Facebook
@PanagiotisCharalampous