CA
Custom indicator throws nullreference exception on indicatorarea
23 Aug 2019, 02:44
Hi everyone,
My bot is calling a custom indicator which draws lines in the indicator area where the MACD crosses. When I execute the bot and it comes to a macd cross, the indicator blows up with a nullreference exception in the indicator code.
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 PipnRunBluedottest : Robot
{
[Parameter("2nd Macd Indicator TimeFrame", DefaultValue = "Minute15")]
public TimeFrame SecondaryMacdTimeframe { get; set; }
public Bluedottest Bdt;
public IndicatorArea IndicatorArea;
protected override void OnStart()
{
Bdt = Indicators.GetIndicator<Bluedottest>(SecondaryMacdTimeframe);
Chart.DrawStaticText("bearish", Bdt.secondary_Macd_bearish.ToString(), VerticalAlignment.Center, HorizontalAlignment.Left, "orange");
}
protected override void OnTick()
{
// Put your core logic here
}
protected override void OnBar()
{
int index = MarketSeries.Close.Count - 1;
Bdt.Calculate(index);
}
protected override void OnStop()
{
// Put your deinitialization logic here
}
}
}
Indicator:
using System;
using System.Collections.Generic;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
namespace cAlgo
{
[Indicator(IsOverlay = false, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class Bluedottest : Indicator
{
[Parameter("2nd Macd Indicator TimeFrame", DefaultValue = "Minute15")]
public TimeFrame SecondaryMacdTimeframe { get; set; }
[Output("MACD_current", LineColor = "blue", Thickness = 3)]
public IndicatorDataSeries Blueline { get; set; }
[Output("Signal_current", LineColor = "red", Thickness = 1)]
public IndicatorDataSeries Redline { get; set; }
[Output("Histogram_current", IsHistogram = true, LineColor = "lightblue", Thickness = 2)]
public IndicatorDataSeries Histogram { get; set; }
[Output("MACD", LineColor = "lightgreen", Thickness = 3)]
public IndicatorDataSeries Greenline { get; set; }
[Output("Signal", LineColor = "lavender", Thickness = 3)]
public IndicatorDataSeries Lavenderline { get; set; }
[Output("Histogram", IsHistogram = true, LineColor = "lightblue", Thickness = 2)]
public IndicatorDataSeries Histogram2 { get; set; }
#region indicators
public MacdCrossOver Macd_current;
public MarketSeries Series_current;
public MacdCrossOver Macd_secondary;
public MarketSeries Series_secondary;
#endregion
#region variables
public int Lastindex;
public int hcfra; //histogram cross from above
public int hcfrb; //histogram cross from below
public List<int> T_List_C;
public List<int> T_List_S;
public bool secondary_Macd_bearish; // MACD below Signal on higher TF
public bool secondary_Macd_bullish; // MACD above Signal on higher TF
#endregion
protected override void Initialize()
{
// Initialize and create nested indicators
Macd_current = Indicators.MacdCrossOver(MarketSeries.Close, 26, 12, 9);
Series_secondary = MarketData.GetSeries(SecondaryMacdTimeframe);
Macd_secondary = Indicators.MacdCrossOver(Series_secondary.Close, 26, 12, 9);
hcfra = 0;
hcfrb = 0;
T_List_C = new List<int>();
T_List_S = new List<int>();
secondary_Macd_bearish = false; // MACD below Signal on higher TF
secondary_Macd_bullish = false;
}
public override void Calculate(int index)
{
var index_special = Series_secondary.OpenTime.GetIndexByExactTime(MarketSeries.OpenTime[index]);
// Calculate value at specified index
// Result[index] = ...
Blueline[index] = Macd_current.MACD[index];
Redline[index] = Macd_current.Signal[index];
if (index_special != -1)
{
Greenline[index] = Macd_secondary.MACD[index_special];
Lavenderline[index] = Macd_secondary.Signal[index_special];
}
if (index > Lastindex)
{
OnBarClosed(Lastindex, index_special);
Lastindex = index;
}
}
public void OnBarClosed(int index, int index_special)
{
int HistCrossValue_C = CalcHistZero_C(index);
if (HistCrossValue_C != 0)
{
IndicatorArea.DrawVerticalLine("current_hist_cross" + index.ToString(), index, "orange", 1, LineStyle.DotsRare);
if(HistCrossValue_C == 1)
{
Calclocalmin_C(hcfrb, hcfra);
}
}
if (index_special != -1)
{
if (CalcHistZero_S(index_special) != 0)
{
IndicatorArea.DrawVerticalLine("Second_hist_cross" + index.ToString(), index, "orange", 2, LineStyle.LinesDots);
}
if (Macd_secondary.MACD[index_special] > Macd_secondary.Signal[index_special])
{
secondary_Macd_bullish = true;
secondary_Macd_bearish = false;
}
if (Macd_secondary.MACD[index_special] < Macd_secondary.Signal[index_special])
{
secondary_Macd_bearish = true;
secondary_Macd_bullish = false;
}
}
}
private void Calclocalmin_C(int hcfrb, int hcfra)
{
int period = (MarketSeries.Close.Count - 1) - hcfrb;
int minimum = hcfrb;
for(int index = hcfrb; index > hcfra; index--)
{
if (Macd_current.MACD[index] < Macd_current.MACD[minimum]) minimum = index;
}
IndicatorArea.DrawVerticalLine("current_local_min" + minimum.ToString(), minimum, "red", 1, LineStyle.DotsRare);
T_List_C.Add(minimum);
}
public int CalcHistZero_C(int index)
{
//current index is Marketseries...Count -1, we want to know if ..Count-2 and ..Count-3 have different signs for histogram value
if (Macd_current.Histogram[index] < 0 && Macd_current.Histogram[index - 1] > 0)
{
//here we have the macd line crossing the signal line from above (falling)
hcfra = index;
return -1;
}
if (Macd_current.Histogram[index] > 0 && Macd_current.Histogram[index - 1] < 0)
{
//here we have the macd line crossing the signal line from below (rising)
hcfrb = index;
return 1;
}
return 0;
}
public int CalcHistZero_S(int index)
{
//current index is Marketseries...Count -1, we want to know if ..Count-2 and ..Count-3 have different signs for histogram value
if (Macd_secondary.Histogram[index] < 0 && Macd_secondary.Histogram[index - 1] > 0)
{
return 1;
}
if (Macd_secondary.Histogram[index] > 0 && Macd_secondary.Histogram[index - 1] < 0)
{
return 1;
}
return 0;
}
}
}
IndicatorArea.DrawVerticalLine("current_hist_cross" + index.ToString(), index, "orange", 1, LineStyle.DotsRare); Is what blows up on me.
Thanks!
CaD

srubtsov
23 Aug 2019, 15:35
Hi,
It happens because of an indicator in a cBot doesn't create `IndicatorArea`. Create an indicator in a cBot doesn't equal to add indicator on the chart. You have several ways to solve the problem, for example: Check `IndicatorArea` on null and doesn't draw anything. Or if possible to use `Chart` use method:
private ChartArea GetChartArea() { if (IndicatorArea == null) return Chart; return IndicatorArea; }@srubtsov