Indicator returns error: NaN
Indicator returns error: NaN
06 Jun 2023, 09:40
Hi,
I have an indicator that seems to be creating the following error: Crashed in Calculate with ArgumentOutOfRangeException: Specified argument was out of the range of valid values. Parameter name: Y1. Actual value was: NaN.
What is Y1?
Here is the code:
using System;
using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;
using cAlgo.Indicators;
using System.Linq;
using System.Diagnostics;
namespace cAlgo
{
[Indicator(IsOverlay = true, TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
public class CombinedArrows : Indicator
{
[Parameter("Aroon Periods", Group = "Aroon", DefaultValue = 5, MinValue = 1)]
public int AroonPeriods { get; set; }
[Parameter("Max Doji Body Percentage", Group = "Dojis", DefaultValue = 25.00, MinValue = 1.00, MaxValue = 100.00, Step = 1)]
public double BodyMax { get; set; }
[Parameter("Min Doji Bigger Wick Pips", Group = "Dojis", DefaultValue = 3.5, MinValue = 0.1, Step = 0.5)]
public double WickMin { get; set; }
[Parameter("EMA Period 1", Group = "EMAs", DefaultValue = 12, MinValue = 1)]
public int EMA_Period1 { get; set; }
[Parameter("EMA Period 2", Group = "EMAs", DefaultValue = 26, MinValue = 1)]
public int EMA_Period2 { get; set; }
[Parameter("EMA Period 3", Group = "EMAs", DefaultValue = 50, MinValue = 1)]
public int EMA_Period3 { get; set; }
[Parameter("Arrow Offset (Pips)", Group = "Visual Settings", DefaultValue = 2.0, MinValue = 0.1, Step = 0.1)]
public double Offset { get; set; }
bool Buy, Sell;
double Body, Candle, LowerWick, UpperWick, BodyPercent;
string BuyArrow, SellArrow, BuyText, SellText;
Aroon AroonI;
ExponentialMovingAverage EMA1, EMA2, EMA3;
protected override void Initialize()
{
Offset *= Symbol.PipSize;
WickMin *= Symbol.PipSize;
BodyMax /= 100;
AroonI = Indicators.Aroon(AroonPeriods);
EMA1 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, EMA_Period1);
EMA2 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, EMA_Period2);
EMA3 = Indicators.ExponentialMovingAverage(Bars.ClosePrices, EMA_Period3);
}
public override void Calculate(int index)
{
BuyArrow = string.Format("Buy_Arrow_{0}", index.ToString());
BuyText = string.Format("Buy_Obj_{0}", index.ToString());
SellArrow = string.Format("Sell_Arrow_{0}", index.ToString());
SellText = string.Format("Sell_Obj_{0}", index.ToString());
Buy = GetBuy();
Sell = GetSell();
if (Buy)
{
Chart.DrawIcon(BuyArrow, ChartIconType.UpTriangle, Bars.OpenTimes.LastValue, Bars.LowPrices.LastValue - Offset, Color.Lime);
Chart.DrawText(BuyText, "BUY", Bars.OpenTimes.LastValue, Bars.LowPrices.LastValue - (Offset * 2), Color.White);
}
if (Sell)
{
Chart.DrawIcon(SellArrow, ChartIconType.DownTriangle, Bars.OpenTimes.LastValue, Bars.HighPrices.LastValue + Offset, Color.Red);
Chart.DrawText(SellText, "SELL", Bars.OpenTimes.LastValue, Bars.HighPrices.LastValue + (Offset * 2), Color.White);
}
if (!Buy)
{
Chart.RemoveObject(BuyArrow);
Chart.RemoveObject(BuyText);
}
if (!Sell)
{
Chart.RemoveObject(SellArrow);
Chart.RemoveObject(SellText);
}
}
private bool GetBuy()
{
bool EMARejection = GetEMARejection();
bool IsDragonfly = GetIsDragonfly();
bool IsAroonBuy = AroonI.Down.LastValue == 100;
if (EMARejection && IsDragonfly && IsAroonBuy) return true;
return false;
}
private bool GetSell()
{
bool EMARejection = GetEMARejection();
bool IsGravestone = GetIsGravestone();
bool IsAroonSell = AroonI.Up.LastValue == 100;
if (EMARejection && IsGravestone && IsAroonSell) return true;
return false;
}
private bool GetEMARejection()
{
int Direction = 0;
Direction = EMA1.Result.LastValue > EMA2.Result.LastValue && EMA2.Result.LastValue > EMA3.Result.LastValue ? 1 : 0;
Direction = EMA1.Result.LastValue < EMA2.Result.LastValue && EMA2.Result.LastValue < EMA3.Result.LastValue ? 2 : 0;
double[] ChartInfo = {
Bars.OpenPrices.LastValue, //0
Bars.HighPrices.LastValue, //1
Bars.LowPrices.LastValue, //2
Bars.ClosePrices.LastValue, //3
EMA1.Result.LastValue, //4
EMA2.Result.LastValue, //5
EMA3.Result.LastValue //6
};
if (Direction == 1) //buy
{
bool[] BuyChecks = {
ChartInfo[3] > ChartInfo[4] && ChartInfo[0] > ChartInfo[4] && ChartInfo[2] < ChartInfo[4],
ChartInfo[3] < ChartInfo[4] && ChartInfo[0] < ChartInfo[4] && ChartInfo[3] > ChartInfo[5] && ChartInfo[0] > ChartInfo[5] && ChartInfo[2] < ChartInfo[5],
ChartInfo[3] < ChartInfo[5] && ChartInfo[0] < ChartInfo[5] && ChartInfo[3] > ChartInfo[6] && ChartInfo[0] > ChartInfo[6] && ChartInfo[2] < ChartInfo[6],
};
if (BuyChecks.Any(Is => Is)) return true;
}
if (Direction == 2) //sell
{
bool[] SellChecks = {
ChartInfo[3] < ChartInfo[4] && ChartInfo[0] < ChartInfo[4] && ChartInfo[1] > ChartInfo[4],
ChartInfo[3] > ChartInfo[4] && ChartInfo[0] > ChartInfo[4] && ChartInfo[3] < ChartInfo[5] && ChartInfo[0] < ChartInfo[5] && ChartInfo[1] > ChartInfo[5],
ChartInfo[3] > ChartInfo[5] && ChartInfo[0] > ChartInfo[5] && ChartInfo[3] < ChartInfo[6] && ChartInfo[0] < ChartInfo[6] && ChartInfo[1] > ChartInfo[6],
};
if (SellChecks.Any(Is => Is)) return true;
}
return false;
}
private bool GetIsDragonfly()
{
Body = Bars.ClosePrices.LastValue > Bars.OpenPrices.LastValue ? Bars.ClosePrices.LastValue - Bars.OpenPrices.LastValue : Bars.OpenPrices.LastValue - Bars.ClosePrices.LastValue;
Candle = Bars.HighPrices.LastValue - Bars.LowPrices.LastValue;
LowerWick = Bars.ClosePrices.LastValue > Bars.OpenPrices.LastValue ? Bars.OpenPrices.LastValue - Bars.LowPrices.LastValue : Bars.ClosePrices.LastValue - Bars.LowPrices.LastValue;
UpperWick = Bars.ClosePrices.LastValue > Bars.OpenPrices.LastValue ? Bars.HighPrices.LastValue - Bars.ClosePrices.LastValue : Bars.HighPrices.LastValue - Bars.OpenPrices.LastValue;
bool IsWickMin = LowerWick >= WickMin;
BodyPercent = Math.Round(Body / Candle, 2);
if (BodyPercent < BodyMax && LowerWick > UpperWick && IsWickMin) return true;
else return false;
}
private bool GetIsGravestone()
{
Body = Bars.ClosePrices.LastValue > Bars.OpenPrices.LastValue ? Bars.ClosePrices.LastValue - Bars.OpenPrices.LastValue : Bars.OpenPrices.LastValue - Bars.ClosePrices.LastValue;
Candle = Bars.HighPrices.LastValue - Bars.LowPrices.LastValue;
LowerWick = Bars.ClosePrices.LastValue > Bars.OpenPrices.LastValue ? Bars.OpenPrices.LastValue - Bars.LowPrices.LastValue : Bars.ClosePrices.LastValue - Bars.LowPrices.LastValue;
UpperWick = Bars.ClosePrices.LastValue > Bars.OpenPrices.LastValue ? Bars.HighPrices.LastValue - Bars.ClosePrices.LastValue : Bars.HighPrices.LastValue - Bars.OpenPrices.LastValue;
bool IsWickMin = UpperWick >= WickMin;
BodyPercent = Math.Round(Body / Candle, 2);
if (BodyPercent < BodyMax && UpperWick > LowerWick && IsWickMin) return true;
else return false;
}
}
}
Replies
wmclennan77
07 Jun 2023, 09:00
RE:
firemyst said:
Y1 is typically the first parameter that specifies a value along the Y-axis of the chart.
However, looking at your code, I didn't see anything wrong.
I then ran it in Visual Studio and there were no crashes or faults among 5 forex pairs and the US30 charts.
So what symbol and timeframe were you running this on?
Hi, the error seems to have disappeared when I added: if (Direction == 0) return;
I don't know why, but that seems to have solved it.
@wmclennan77
... Deleted by UFO ...
firemyst
07 Jun 2023, 03:39
Y1 is typically the first parameter that specifies a value along the Y-axis of the chart.
However, looking at your code, I didn't see anything wrong.
I then ran it in Visual Studio and there were no crashes or faults among 5 forex pairs and the US30 charts.
So what symbol and timeframe were you running this on?
@firemyst