Accessing Custom Indicator Data in a Bot
Accessing Custom Indicator Data in a Bot
12 May 2020, 14:56
I am working on a custom indicator, the result of which is basically a data series of colors, thank of a color-coded moving average (for simplicity these are represented as an integer between -3 and 3).
My code looks like this:
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class TestIndicator : Indicator
{
[Parameter(DefaultValue = 5, MinValue = 1)]
public int Periods { get; set; }
[Parameter("MA Type", DefaultValue = MovingAverageType.Simple)]
public MovingAverageType MAType { get; set; }
private MovingAverage maOpen;
private MovingAverage maClose;
public IndicatorDataSeries ColorData;
protected override void Initialize()
{
maOpen = Indicators.MovingAverage(MarketSeries.Open, Periods, MAType);
maClose = Indicators.MovingAverage(MarketSeries.Close, Periods, MAType);
/** Init Color Data Structure **/
ColorData = CreateDataSeries();
}
public override void Calculate(int index)
{
Colors Color;
Color = this.GetBarColor(index);
ChartObjects.DrawLine(<< some stuff here>>);
/** Assign Color Data for each bar **/
ColorData[index] = this.ColorToInt(Color);
}
}
This indicator basically works (it's not done yet, but it so far correctly draws the chart).
Now, when I try to use this indicator in a bot, I have the problem that the ColorData is not set (ie: values return NaN). My bot code looks like this:
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TestBot : Robot
{
[Parameter("MA Period", Group = "Heiken Ashi", DefaultValue = 5)]
public int __Period { get; set; }
[Parameter("MA Type", Group = "Heiken Ashi")]
public MovingAverageType __Type { get; set; }
private _TestIndicator;
protected override void OnStart()
{
this._TestIndicator= Indicators.GetIndicator<MyTestIndicator>(__Period , __Type );
}
protected override void OnBar()
{
var haCurr = _TestIndicator.ColorData.Last(0);
var haPrev = _TestIndicator.ColorData.Last(1);
/** WHY?? **/
Print(haCurr); /* Returns NaN */
Print(haPrev); /* Returns NaN */
}
}
}
Does anybody know what I'm doing wrong here?
Replies
rgasch
12 May 2020, 16:47
RE:
Thank you for your reply. Please find attached a complete test case of a minimum reduced indicator and bot (the bot doesn't do anything useful, but it logs the test/evaluation of the color values the indicator fills).
Indicator:
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class TestIndicator : Indicator
{
private MovingAverage _ma;
[Parameter("MA Period", DefaultValue = 34)]
public int maPeriod { get; set; }
[Parameter("MA Type", DefaultValue = MovingAverageType.Weighted)]
public MovingAverageType MAType { get; set; }
[OutputAttribute("Moving Average", LineColor = "Red", LineStyle = LineStyle.Lines)]
public IndicatorDataSeries MaResult { get; set; }
public IndicatorDataSeries ColorData;
protected override void Initialize()
{
_ma = Indicators.MovingAverage(Bars.ClosePrices, maPeriod, MAType);
this.ColorData = CreateDataSeries();
}
public override void Calculate(int index)
{
var color = Color.White;
var open = Bars.OpenPrices[index];
var high = Bars.HighPrices[index];
var low = Bars.LowPrices[index];
var close = Bars.ClosePrices[index];
var maValue = _ma.Result[index];
MaResult[index] = maValue;
ColorData[index] = open > close ? -1 : 1;
}
}
}
Bot
using System;
using System.Linq;
using cAlgo.API;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;
using cAlgo.Indicators;
namespace cAlgo.Robots
{
[Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class TestBot : Robot
{
[Parameter("MA Period", Group = "Main Moving Average", DefaultValue = 25)]
public int __MAPeriod { get; set; }
[Parameter("MA Type", Group = "Main Moving Average")]
public MovingAverageType __MAType { get; set; }
[Parameter("Source", Group = "Main Moving Average")]
public DataSeries __SourceSeries { get; set; }
private TestIndicator _MA;
private string _label = "TestBot";
protected override void OnStart()
{
this._MA = Indicators.GetIndicator<TestIndicator>(__MAPeriod, __MAType);
this._label = "TestBot " + this.SymbolName + this.TimeFrame;
}
protected override void OnBar()
{
var maCurr = _MA.ColorData.Last(0);
var maPrev = _MA.ColorData.Last(1);
Print(_MA.ColorData);
Print(maCurr);
Print(maPrev);
if (maCurr != maPrev)
{
// Do something useful here
}
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
}
Thank you for any insights.
PanagiotisCharalampous said:
Hi rgasch,
To advise further we will need a workable version of the indicator that we can use.
Best Regards,
Panagiotis
@rgasch
PanagiotisCharalampous
13 May 2020, 09:34
Hi rgasch,
Thanks. To fix this just mark the ColorData parameter with an OutputAttribute. See below
using System;
using cAlgo.API;
using cAlgo.API.Indicators;
namespace cAlgo.Indicators
{
[Indicator(IsOverlay = true, AccessRights = AccessRights.None)]
public class TestIndicator : Indicator
{
private MovingAverage _ma;
[Parameter("MA Period", DefaultValue = 34)]
public int maPeriod { get; set; }
[Parameter("MA Type", DefaultValue = MovingAverageType.Weighted)]
public MovingAverageType MAType { get; set; }
[OutputAttribute("Moving Average", LineColor = "Red", LineStyle = LineStyle.Lines)]
public IndicatorDataSeries MaResult { get; set; }
[OutputAttribute("Color Data")]
public IndicatorDataSeries ColorData { get; set; }
protected override void Initialize()
{
_ma = Indicators.MovingAverage(Bars.ClosePrices, maPeriod, MAType);
}
public override void Calculate(int index)
{
var color = Color.White;
var open = Bars.OpenPrices[index];
var high = Bars.HighPrices[index];
var low = Bars.LowPrices[index];
var close = Bars.ClosePrices[index];
var maValue = _ma.Result[index];
MaResult[index] = maValue;
ColorData[index] = open > close ? -1 : 1;
}
}
}
Best Regards,
Panagiotis
@PanagiotisCharalampous
PanagiotisCharalampous
12 May 2020, 15:12
Hi rgasch,
To advise further we will need a workable version of the indicator that we can use.
Best Regards,
Panagiotis
Join us on Telegram
@PanagiotisCharalampous