It's a great indicator - it projects future price movement with draw objects similar to the zigzag indicator. I highly recommend looking it up!
I'm getting a few errors that appear simple to fix but I'm at a loss. Any help is greatly appreciated!
All the errors I'm' getting say the following names do "not exist in the current context:"
Draw (line 192, column 7),
DashStyleHelper (line 195, column 22),
Draw (line 215, column 17),
DashStyleHelper (line 223, column 21).
Here's the converted code:
region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Windows.Media;
using NinjaTrader.Cbi;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using System.Xml.Serialization; // Added this namespace for XmlIgnore attribute
#endregion
namespace NinjaTrader.NinjaScript.Indicators
{
public class TheNextPivot : Indicator
{
private class ZigZagPoint
{
public int BarIndex { get; set; }
public double Price { get; set; }
public bool IsHigh { get; set; }
}
private readonly List<ZigZagPoint> zigZagPoints = new List<ZigZagPoint>();
private readonly List<double> priceData = new List<double>();
private readonly List<double> recentSequence = new List<double>();
private readonly Dictionary<int, double> similarityScores = new Dictionary<int, double>();
private int lastCalculatedBar = -1;
private double deviationThreshold = 0.00001;
private int pivotLegs = 5;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = "The Next Pivot [Converted from TradingView]";
Name = "TheNextPivot";
IsOverlay = true;
Historical = 20;
ForecastLen = 50;
TypeC = "Cosine Similarity";
SimType = "Price";
Tim = 5000;
ZOnly = true;
POnly = true;
// Define colors
ProjColor = Brushes.LimeGreen;
ForecastColor = Brushes.White;
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < Historical + ForecastLen) return;
// Update price data
double currentPrice = SimType == "Price" ? Close[0] : Math.Log(Close[0] / Close[1]);
if (priceData.Count >= Tim) priceData.RemoveAt(0);
priceData.Add(currentPrice);
// Update recent sequence for comparison
if (Calculate == Calculate.OnBarClose && CurrentBar == CurrentBars[0])
{
recentSequence.Clear();
for (int i = 0; i < Historical; i++)
{
recentSequence.Add(SimType == "Price" ? Close[i] : Math.Log(Close[i] / Close[i + 1]));
}
// Calculate similarities
CalculateSimilarities();
// Update ZigZag points
UpdateZigZag();
// Project future path
if (similarityScores.Any())
{
int bestMatchIndex = similarityScores.OrderByDescending(x => x.Value).First().Key;
ProjectFuturePath(bestMatchIndex);
}
}
}
private void CalculateSimilarities()
{
similarityScores.Clear();
for (int i = 0; i <= priceData.Count - Historical - ForecastLen; i++)
{
var historicalSequence = new List<double>();
for (int j = 0; j < Historical; j++)
{
historicalSequence.Add(priceData[i + j]);
}
double similarity = 0;
switch (TypeC)
{
case "Cosine Similarity":
similarity = CalculateCosineSimilarity(historicalSequence, recentSequence);
break;
case "Pearson":
similarity = CalculatePearsonCorrelation(historicalSequence, recentSequence);
break;
// Add other similarity methods as needed
}
similarityScores[i] = similarity;
}
}
private double CalculateCosineSimilarity(List<double> sequence1, List<double> sequence2)
{
double dotProduct = 0;
double norm1 = 0;
double norm2 = 0;
for (int i = 0; i < sequence1.Count; i++)
{
dotProduct += sequence1[i] * sequence2[i];
norm1 += sequence1[i] * sequence1[i];
norm2 += sequence2[i] * sequence2[i];
}
return dotProduct / (Math.Sqrt(norm1) * Math.Sqrt(norm2));
}
private double CalculatePearsonCorrelation(List<double> sequence1, List<double> sequence2)
{
double mean1 = sequence1.Average();
double mean2 = sequence2.Average();
double sum1 = 0;
double sum2 = 0;
double sum3 = 0;
for (int i = 0; i < sequence1.Count; i++)
{
double diff1 = sequence1[i] - mean1;
double diff2 = sequence2[i] - mean2;
sum1 += diff1 * diff2;
sum2 += diff1 * diff1;
sum3 += diff2 * diff2;
}
return sum1 / Math.Sqrt(sum2 * sum3);
}
private void UpdateZigZag()
{
if (!ZOnly) return;
// Find potential turning points
double currentPrice = Close[0];
double prevPrice = Close[1];
if (zigZagPoints.Count < 2)
{
zigZagPoints.Add(new ZigZagPoint
{
BarIndex = CurrentBar,
Price = currentPrice,
IsHigh = currentPrice > prevPrice
});
return;
}
var lastPoint = zigZagPoints.Last();
double priceChange = Math.Abs((currentPrice - lastPoint.Price) / lastPoint.Price);
if (priceChange >= deviationThreshold)
{
bool isPotentialHigh = currentPrice > lastPoint.Price;
if (lastPoint.IsHigh != isPotentialHigh)
{
zigZagPoints.Add(new ZigZagPoint
{
BarIndex = CurrentBar,
Price = currentPrice,
IsHigh = isPotentialHigh
});
// Draw ZigZag line
if (zigZagPoints.Count >= 2)
{
var prevZigZag = zigZagPoints[zigZagPoints.Count - 2];
Draw.Line(this, "ZigZag_" + CurrentBar.ToString(), false,
prevZigZag.BarIndex, prevZigZag.Price,
CurrentBar, currentPrice,
ProjColor, DashStyleHelper.Solid, 2);
}
}
}
}
private void ProjectFuturePath(int bestMatchIndex)
{
if (!POnly) return;
// Project future path based on best matching historical sequence
double lastPrice = Close[0];
for (int i = 0; i < ForecastLen; i++)
{
double projectedPrice = priceData[bestMatchIndex + Historical + i];
if (SimType == "%Change")
{
projectedPrice = lastPrice * (1 + projectedPrice);
}
Draw.Line(this,
"Forecast_" + CurrentBar.ToString() + "_" + i.ToString(),
false,
i == 0 ? CurrentBar : CurrentBar + i - 1,
i == 0 ? lastPrice : Values[0][CurrentBar + i - 1],
CurrentBar + i,
projectedPrice,
ForecastColor,
DashStyleHelper.Dash,
1);
lastPrice = projectedPrice;
if (i < ForecastLen - 1)
Values[0][CurrentBar + i] = projectedPrice;
}
}
region Properties
[Range(5, 100), NinjaScriptProperty]
[Display(Name = "Historical Length", Order = 1, GroupName = "Parameters")]
public int Historical { get; set; }
[Range(15, 250), NinjaScriptProperty]
[Display(Name = "Forecast Length", Order = 2, GroupName = "Parameters")]
public int ForecastLen { get; set; }
[NinjaScriptProperty]
[Display(Name = "Similarity Type", Order = 3, GroupName = "Parameters")]
public string TypeC { get; set; }
[NinjaScriptProperty]
[Display(Name = "Similarity Basis", Order = 4, GroupName = "Parameters")]
public string SimType { get; set; }
[Range(500, 5000), NinjaScriptProperty]
[Display(Name = "Bars Back", Order = 5, GroupName = "Parameters")]
public int Tim { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show ZigZag", Order = 6, GroupName = "Visuals")]
public bool ZOnly { get; set; }
[NinjaScriptProperty]
[Display(Name = "Show Price Path", Order = 7, GroupName = "Visuals")]
public bool POnly { get; set; }
[XmlIgnore] // Fixed: Corrected the attribute name from Xmllgnore to XmlIgnore
[Display(Name = "Projection Color", Order = 8, GroupName = "Visuals")]
public Brush ProjColor { get; set; }
[XmlIgnore] // Fixed: Corrected the attribute name from Xmllgnore to XmlIgnore
[Display(Name = "Forecast Color", Order = 9, GroupName = "Visuals")]
public Brush ForecastColor { get; set; }
#endregion
}
}

Comment