How to reference custom indicator in cBot?
15 Feb 2023, 14:53
Mr PanagiotisCharalampous sends everybody with similar question to https://help.ctrader.com/ctrader-automate/guides/indicators/ , but I don's see there correct response.
I know Indicators.GetIndicator<>() function, but it doesn't work. I always get "15/02/2023 13:49:37.095 | Crashed in Initialize with NullReferenceException: Object reference not set to an instance of an object." error. I give correct type of indicator and all parameters.
Could anybody please write working simplest possible example in documentation?
Or place there useful link?
Replies
ctid5292619
17 Feb 2023, 10:17
RE:
Thank your for your response.
Could you PLEASE give me a link to working demo of custom indicator and cBot?
I'm learning to code in cTrader and I prefer to have generic simple example then something complicated (and my indicator is a little complicated), I may have trouble to use later in different circumstances.
Thank you!
@ctid5292619
ctid5292619
18 Feb 2023, 13:52
( Updated at: 18 Feb 2023, 13:56 )
RE:
I have found working example of custom indicator in cBot ( https://ctrader.com/algos/indicators/show/1086 ).
Indicator name: Renko.
I didn't test if everything is working fine, but code compiles (with many warnings as indicator is quite old).
Indicator:
usingcAlgo.API;
usingcAlgo.API.Indicators;
usingcAlgo.API.Internals;
usingcAlgo.Indicators;
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
namespacecAlgo
{
[Indicator("Renko", IsOverlay =true, AutoRescale =true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
publicclassRenko : Indicator
{
[Parameter("Renko (Pips)", DefaultValue = 10, MinValue = 0.1, Step = 1)]
publicdoubleRenkoPips {get;set; }
[Parameter("Bricks To Show", DefaultValue = 100, MinValue = 1)]
publicintBricksToShow {get;set; }
[Parameter("Zoom Level", DefaultValue = 3, MinValue = 0, MaxValue = 5, Step = 1)]
publicdoubleZoomLevel {get;set; }
[Parameter("Bullish Color", DefaultValue ="SeaGreen")]
publicstringColorBull {get;set; }
[Parameter("Bearish Color", DefaultValue ="Tomato")]
publicstringColorBear {get;set; }
[Output("Open", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
publicIndicatorDataSeries Open {get;set; }
[Output("High", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
publicIndicatorDataSeries High {get;set; }
[Output("Low", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
publicIndicatorDataSeries Low {get;set; }
[Output("Close", Color = Colors.DimGray, Thickness = 1, PlotType = PlotType.Points)]
publicIndicatorDataSeries Close {get;set; }
publicclassBrick
{
publicdoubleOpen {get;set; }
publicdoubleClose {get;set; }
}
publicList<Brick> Bricks =newList<Brick>();
privatedoublecloseLastValue, thickness, renkoPips, renkoLastValue;
privateColors colorBull, colorBear;
privateboolcolorError;
privateintlastCount;
protectedoverridevoidInitialize()
{
if(!Enum.TryParse<Colors>(ColorBull,outcolorBull) || !Enum.TryParse<Colors>(ColorBear,outcolorBear))
colorError =true;
renkoPips = RenkoPips * Symbol.PipSize;
thickness = Math.Pow(2, ZoomLevel) - (ZoomLevel > 0 ? 1 : 0);
renkoLastValue = 0;
}
publicoverridevoidCalculate(intindex)
{
if(colorError)
{
ChartObjects.DrawText("Error0","{o,o}\n/)_)\n \" \"\nOops! Incorrect colors.", StaticPosition.TopCenter, Colors.Gray);
return;
}
if(renkoLastValue == 0)
{
var open = MarketSeries.Open.LastValue;
renkoLastValue = open - (open % renkoPips) + renkoPips / 2;
}
closeLastValue = MarketSeries.Close.LastValue;
while(closeLastValue >= renkoLastValue + renkoPips * 1.5)
{
renkoLastValue += renkoPips;
Bricks.Insert(0,newBrick
{
Open = renkoLastValue - renkoPips / 2,
Close = renkoLastValue + renkoPips / 2
});
if(Bricks.Count() > BricksToShow)
Bricks.RemoveRange(BricksToShow, Bricks.Count() - BricksToShow);
if(IsLastBar)
UpdateHistory(index);
}
while(closeLastValue <= renkoLastValue - renkoPips * 1.5)
{
renkoLastValue -= renkoPips;
Bricks.Insert(0,newBrick
{
Open = renkoLastValue + renkoPips / 2,
Close = renkoLastValue - renkoPips / 2
});
if(Bricks.Count() > BricksToShow)
Bricks.RemoveRange(BricksToShow, Bricks.Count() - BricksToShow);
if(IsLastBar)
UpdateHistory(index);
}
boolisNewBar = MarketSeries.Close.Count > lastCount;
if(IsLastBar && isNewBar)
{
UpdateHistory(index);
Open[index - BricksToShow] =double.NaN;
High[index - BricksToShow] =double.NaN;
Low[index - BricksToShow] =double.NaN;
Close[index - BricksToShow] =double.NaN;
lastCount = MarketSeries.Close.Count;
}
if(IsRealTime)
UpdateLive(index);
}
privatevoidUpdateHistory(intindex)
{
for(inti = 0; i < BricksToShow - 1 && i < Bricks.Count() - 1; i++)
{
var color = Bricks[i].Open < Bricks[i].Close ? colorBull : colorBear;
ChartObjects.DrawLine(string.Format("renko.Last({0})", i + 1), index - i - 1, Bricks[i].Open, index - i - 1, Bricks[i].Close, color, thickness, LineStyle.Solid);
Open[index - i - 1] = Bricks[i].Open;
High[index - i - 1] = Math.Max(Bricks[i].Open, Bricks[i].Close);
Low[index - i - 1] = Math.Min(Bricks[i].Open, Bricks[i].Close);
Close[index - i - 1] = Bricks[i].Close;
}
}
privatevoidUpdateLive(intindex)
{
doubley1, y2;
var top = Math.Max(Bricks[0].Open, Bricks[0].Close);
var bottom = Math.Min(Bricks[0].Open, Bricks[0].Close);
if(closeLastValue > top)
y1 = top;
elseif(closeLastValue < bottom)
y1 = bottom;
else
y1 = closeLastValue;
y2 = closeLastValue;
var colorLive = y1 < y2 ? colorBull : colorBear;
ChartObjects.DrawLine("renko.Live", index, y1, index, y2, colorLive, thickness, LineStyle.Solid);
Open[index] = y1;
High[index] = y1 > y2 ? y1 : y2;
Low[index] = y1 < y2 ? y1 : y2;
Close[index] = y2;
}
}
}
and cBot:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using cAlgo.API;
using cAlgo.API.Collections;
using cAlgo.API.Indicators;
using cAlgo.API.Internals;namespace cAlgo.Robots
{
[Robot(AccessRights = AccessRights.None)]
public class ReferencecustomindicatordemocBot : Robot
{
public double RenkoPips = 10;
public int BricksToShow = 10;
private Renko renko;
protected override void OnStart()
{
renko = Indicators.GetIndicator<Renko>(RenkoPips, BricksToShow, 3, "SeaGreen", "Tomato");
}
protected override void OnTick()
{
bool isLastBrickBullish = renko.Open.Last(1) < renko.Close.Last(1);
if (isLastBrickBullish)
{
ExecuteMarketOrder(TradeType.Buy, Symbol, 1000);
}
}
}
}
@ctid5292619
ctid5292619
18 Feb 2023, 14:10
RE:
I have found example of custom indicator in cBot, but I need also more complicated demo, when cBot is using outputs of custom indicator.
Could you please Mr PanagiotisChar place a link to such example?
Thank you!
@ctid5292619

PanagiotisChar
16 Feb 2023, 15:57
Hi there,
The exception indicates that you are doing something wrong in your indicator code. Share your cBot and indicator code so that we can advise further.
Aieden Technologies
Need help? Join us on Telegram
Need premium support? Trade with us
@PanagiotisChar