This one would also use level 2 and tick data but I get errors.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.NinjaScript.DrawingTools;
using SharpDX;
using SharpDX.Direct2D1;
namespace NinjaTrader.NinjaScript.Indicators
{
public class TapeReaderReversals : Indicator
{
private Dictionary<string, DXMediaMap> dxmBrushes;
private SharpDX.RectangleF reuseRectangle;
private SharpDX.Vector2 reuseVector1, reuseVector2;
private Series vap;
private Series ma;
private Series spike;
private Series convic;
private Series exptypprice;
private Series allSpikes;
private Series convicInput;
private Series typPriceSeries;
private SMA sma;
private Series signalBrushKey;
// Tick data storage
private double buyVolume, sellVolume;
private Series buyVolumeSeries;
private Series sellVolumeSeries;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"TapeReader with Reversals for trend and volume analysis with buy/sell tick data. Paints candles: Blue (Reversal/Buy), Green (Bullish), Gray (Status Quo), Orange (Flux), Dark Red (Warning/Sell), Red (No Trend), Plum (Volume Divergence).";
Name = "TapeReaderReversals";
Calculate = Calculate.OnBarClose;
IsOverlay = true;
DisplayInDataBox = true;
PaintPriceMarkers = true;
IsSuspendedWhileInactive = false;
BarsRequiredToPlot = 60;
WantAllBuySpikes = true;
DarkMode = true;
ShowArrows = true;
ShowLabels = true;
Length = 12;
SellAlert = -1.75;
ReversalAlert = 1.25;
ConfirmLength = 18;
Lookback = 10;
DeviationLength = 60;
Deviate = 2.0;
ShadowWidth = 1;
BuySellRatioThreshold = 2.0; // Buy volume must be 2x sell volume for confirmation
DarkModeBuy = Brushes.White;
LiteModeBuy = Brushes.Blue;
Sell = CreateColor(210, 59, 104); // Dark Red
EndOfTrend = Brushes.Red;
OhMy = Brushes.Plum;
Flux = Brushes.Orange;
Stay = Brushes.Green;
Quo = Brushes.Gray;
if (DarkModeBuy != null && DarkModeBuy.CanFreeze) DarkModeBuy.Freeze();
if (LiteModeBuy != null && LiteModeBuy.CanFreeze) LiteModeBuy.Freeze();
if (Sell != null && Sell.CanFreeze) Sell.Freeze();
if (EndOfTrend != null && EndOfTrend.CanFreeze) EndOfTrend.Freeze();
if (OhMy != null && OhMy.CanFreeze) OhMy.Freeze();
if (Flux != null && Flux.CanFreeze) Flux.Freeze();
if (Stay != null && Stay.CanFreeze) Stay.Freeze();
if (Quo != null && Quo.CanFreeze) Quo.Freeze();
dxmBrushes = new Dictionary<string, DXMediaMap>
{
{ "darkModeBuy", new DXMediaMap { MediaBrush = DarkModeBuy } },
{ "liteModeBuy", new DXMediaMap { MediaBrush = LiteModeBuy } },
{ "sell", new DXMediaMap { MediaBrush = Sell } },
{ "endOfTrend", new DXMediaMap { MediaBrush = EndOfTrend } },
{ "ohMy", new DXMediaMap { MediaBrush = OhMy } },
{ "flux", new DXMediaMap { MediaBrush = Flux } },
{ "stay", new DXMediaMap { MediaBrush = Stay } },
{ "quo", new DXMediaMap { MediaBrush = Quo } }
};
Print($"TapeReaderReversals Version: 2025-08-24; Property Initialized: WantAllBuySpikes={WantAllBuySpikes}");
}
else if (State == State.Configure)
{
if (Length < 1) Length = 1;
if (ConfirmLength < 1) ConfirmLength = 1;
if (Lookback < 1) Lookback = 1;
if (DeviationLength < 1) DeviationLength = 1;
if (Deviate < 0) Deviate = 0;
if (ShadowWidth < 1) ShadowWidth = 1;
if (BuySellRatioThreshold < 1) BuySellRatioThreshold = 1;
vap = new Series<double>(this);
ma = new Series<double>(this);
spike = new Series<double>(this);
convic = new Series<double>(this);
exptypprice = new Series<double>(this);
allSpikes = new Series<double>(this);
convicInput = new Series<double>(this);
typPriceSeries = new Series<double>(this);
signalBrushKey = new Series<string>(this);
buyVolumeSeries = new Series<double>(this);
sellVolumeSeries = new Series<double>(this);
sma = SMA(vap, 12);
buyVolume = 0;
sellVolume = 0;
Print("TapeReaderReversals compiled successfully on " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
}
else if (State == State.DataLoaded)
{
// Ensure market data subscription for tick data
AddDataSeries(BarsPeriodType.Tick, 1);
}
}
protected override void OnMarketData(MarketDataEventArgs e)
{
if (CurrentBar < BarsRequiredToPlot) return;
if (e.MarketDataType == MarketDataType.Last)
{
double lastPrice = e.Price;
double bidPrice = e.Bid.Price;
double askPrice = e.Ask.Price;
if (lastPrice >= askPrice)
buyVolume += e.Volume;
else if (lastPrice <= bidPrice)
sellVolume += e.Volume;
Print($"Tick: LastPrice={lastPrice:F2}, Bid={bidPrice:F2}, Ask={askPrice:F2}, BuyVol={buyVolume:F0}, SellVol={sellVolume:F0}");
}
}
protected override void OnBarUpdate()
{
if (CurrentBar < 2) return;
// Store buy/sell volumes for the current bar
buyVolumeSeries[0] = buyVolume;
sellVolumeSeries[0] = sellVolume;
// Reset for next bar
buyVolume = 0;
sellVolume = 0;
BarBrushes[0] = Brushes.Transparent;
CandleOutlineBrushes[0] = Brushes.Transparent;
// Volume Accumulation Percentage
double totalBP = 0;
double totalVol = 0;
for (int i = 0; i < Length && CurrentBar - i >= 0; i++)
{
double bp = (High[i] != Low[i]) ? (2 * Close[i] - High[i] - Low[i]) / (High[i] - Low[i]) : 0;
totalBP += Volume[i] * (double.IsNaN(bp) ? 0 : bp);
totalVol += Volume[i];
}
vap[0] = totalVol != 0 ? 100 * totalBP / totalVol : 0;
ma[0] = sma[0];
// Spike Detection
double sDev = StDevLogReturns(Lookback) * Math.Sqrt(Lookback / (Lookback - 1.0));
double m = sDev * Close[1];
spike[0] = (Close[0] - Close[1]) / (m + double.Epsilon);
spike[0] = Math.Max(-5, Math.Min(5, spike[0]));
// Volume Divergence
double volStDev = RelativeVolumeStDev(DeviationLength);
bool aboveDev = volStDev >= Deviate;
bool increase = Volume[0] > Volume[1];
bool decrease = Volume[0] < Volume[1];
bool devIncrease = increase && aboveDev;
bool devDecrease = decrease && aboveDev;
bool volumeDivergence = devIncrease || devDecrease;
// Conviction Logic
double sumCon = 0;
for (int i = 0; i < ConfirmLength && CurrentBar - i >= 0; i++)
{
double convictSpread = High[i] - Low[i];
double bodyTop = Close[i] > Open[i] ? Close[i] : Open[i];
double bodyBottom = Close[i] < Open[i] ? Close[i] : Open[i];
double body = bodyTop - bodyBottom;
double perBody = convictSpread != 0 ? body / convictSpread : 0;
double rangePer = Low[i] != 0 ? convictSpread / Low[i] : 0;
double bodyPer = rangePer * perBody;
double bc = Close[i] > Open[i] && Volume[i] > Volume[i + 1] ? 2 + 2 * bodyPer :
Close[i] > Open[i] && Volume[i] <= Volume[i + 1] ? 1 + 1 * bodyPer : 0;
double brc = Close[i] < Open[i] && Volume[i] > Volume[i + 1] ? -2 - 2 * bodyPer :
Close[i] < Open[i] && Volume[i] <= Volume[i + 1] ? -1 - 1 * bodyPer : 0;
sumCon += bc + brc;
}
convicInput[0] = sumCon;
convic[0] = EMA(EMA(EMA(convicInput, 2), 2), 2)[0];
// Typical Price EMA
typPriceSeries[0] = (High[0] + Low[0] + Close[0]) / 3;
exptypprice[0] = EMA(EMA(EMA(typPriceSeries, 3), 3), 3)[0];
// Conviction and Flux Logic
bool flux = exptypprice[0] < exptypprice[1] && convic[0] < convic[1];
bool chop = (exptypprice[0] < exptypprice[1] && convic[0] > convic[1]) ||
(exptypprice[0] > exptypprice[1] && convic[0] < convic[1]);
bool stay = !flux && !chop;
// AllSpikes Logic
allSpikes[0] = ((spike[0] > ReversalAlert && Close[0] > Open[0]) || spike[0] > 2.95 ||
(volumeDivergence && spike[0] > 1)) ? 1 :
vap[0] < ma[1] ? -1 : allSpikes[1];
// Tick Data Enhanced Buy Condition
bool tickBuyConfirmation = sellVolumeSeries[0] > 0 ? buyVolumeSeries[0] / sellVolumeSeries[0] >= BuySellRatioThreshold : buyVolumeSeries[0] > 0;
bool buyCondition = (!WantAllBuySpikes && CrossesAbove(vap, ma, 3) &&
((spike[0] > ReversalAlert && Close[0] > Open[0]) || spike[0] > 2.95 ||
(volumeDivergence && spike[0] > 1)) && tickBuyConfirmation) ||
(WantAllBuySpikes && allSpikes[1] == -1 &&
((spike[0] > ReversalAlert && Close[0] > Open[0]) || spike[0] > 2.95 ||
(volumeDivergence && spike[0] > 1)) && tickBuyConfirmation);
// Signal Color Logic
string selectedBrush;
if (buyCondition)
selectedBrush = DarkMode ? "darkModeBuy" : "liteModeBuy"; // Blue (LiteMode) or White (DarkMode)
else if (vap[0] < ma[1])
selectedBrush = "endOfTrend"; // Red (No Trend)
else if (devIncrease || devDecrease)
selectedBrush = "ohMy"; // Plum (Volume Divergence)
else if (vap[0] < ma[0] || spike[0] <= SellAlert)
selectedBrush = "sell"; // Dark Red (Warning/Sell)
else if (flux)
selectedBrush = "flux"; // Orange (Flux/Downward)
else if (spike[0] > 0 || stay)
selectedBrush = "stay"; // Green (Bullish)
else
selectedBrush = "quo"; // Gray (Status Quo)
signalBrushKey[0] = selectedBrush;
// Arrows
if (ShowArrows && buyCondition)
{
Draw.ArrowUp(this, "BuyArrow" + CurrentBar, true, 0, Low[0] - TickSize * 2, DarkMode ? DarkModeBuy : LiteModeBuy);
}
if (ShowArrows && vap[0] < ma[1])
{
Draw.ArrowDown(this, "SellArrow" + CurrentBar, true, 0, High[0] + TickSize * 2, EndOfTrend);
}
// Labels
if (ShowLabels && CurrentBar >= BarsRequiredToPlot)
{
string labelText;
System.Windows.Media.Brush labelBrush;
if (buyCondition)
{
labelText = WantAllBuySpikes ? "REVERSING. Buy Signal" : "Beginning of Trend. Buy Signal";
labelBrush = DarkMode ? DarkModeBuy : LiteModeBuy;
}
else if (vap[0] < ma[1])
{
labelText = "End of Trend, Sell";
labelBrush = EndOfTrend;
}
else if (devIncrease || devDecrease)
{
labelText = "Something's Happening!";
labelBrush = OhMy;
}
else if (vap[0] < ma[0] || spike[0] <= SellAlert)
{
labelText = "Warning / Sell";
labelBrush = Sell;
}
else if (flux)
{
labelText = "Flux / Chop";
labelBrush = Flux;
}
else if (spike[0] > 0 || stay)
{
labelText = "Bullish";
labelBrush = Stay;
}
else
{
labelText = "Status Quo";
labelBrush = Quo;
}
Draw.Text(this, "Label" + CurrentBar, $"{labelText} ({selectedBrush})", 0, Low[0] - TickSize * 10, labelBrush);
Print($"Bar {CurrentBar}: selectedBrush={selectedBrush}, buyCondition={buyCondition}, vap[0]={vap[0]:F2}, ma[0]={ma[0]:F2}, spike[0]={spike[0]:F2}, flux={flux}, stay={stay}, devIncrease={devIncrease}, devDecrease={devDecrease}, volume[0]={Volume[0]:F0}, volume[1]={Volume[1]:F0}, volStDev={volStDev:F2}, buyVol={buyVolumeSeries[0]:F0}, sellVol={sellVolumeSeries[0]:F0}");
}
}
private double StDevLogReturns(int length)
{
double sum = 0, sumSquares = 0, count = 0;
for (int i = 1; i <= length && CurrentBar - i >= 1; i++)
{
double logReturn = Close[i + 1] != 0 ? Math.Log(Close[i] / Close[i + 1]) : 0;
sum += logReturn;
sumSquares += logReturn * logReturn;
count++;
}
double mean = count > 0 ? sum / count : 0;
return count > 1 ? Math.Sqrt(sumSquares / count - mean * mean) : 0;
}
private double RelativeVolumeStDev(int length)
{
double sum = 0, sumSquares = 0, count = 0;
for (int i = 0; i < length && CurrentBar - i >= 0; i++)
{
sum += Volume[i];
sumSquares += Volume[i] * Volume[i];
count++;
}
double mean = count > 0 ? sum / count : 0;
return count > 1 ? Math.Sqrt(sumSquares / count - mean * mean) / (mean + double.Epsilon) : 0;
}
private bool CrossesAbove(Series<double> series1, Series<double> series2, int withinBars)
{
for (int i = 0; i <= withinBars && CurrentBar - i >= 0; i++)
{
if (i + 1 < series1.Count && series1[i] > series2[i] && series1[i + 1] <= series2[i + 1])
return true;
}
return false;
}
#region Properties
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Want All Buy Spikes", Order = 1, GroupName = "Parameters")]
public bool WantAllBuySpikes { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Dark Mode", Order = 2, GroupName = "Parameters")]
public bool DarkMode { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Show Arrows", Order = 3, GroupName = "Parameters")]
public bool ShowArrows { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Show Labels", Order = 4, GroupName = "Parameters")]
public bool ShowLabels { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Length", Order = 5, GroupName = "Parameters")]
public int Length { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Sell Alert", Order = 6, GroupName = "Parameters")]
public double SellAlert { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Reversal Alert", Order = 7, GroupName = "Parameters")]
public double ReversalAlert { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Confirm Length", Order = 8, GroupName = "Parameters")]
public int ConfirmLength { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Lookback", Order = 9, GroupName = "Parameters")]
public int Lookback { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Deviation Length", Order = 10, GroupName = "Parameters")]
public int DeviationLength { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Deviate", Order = 11, GroupName = "Parameters")]
public double Deviate { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Shadow Width", Order = 12, GroupName = "Parameters")]
public int ShadowWidth { get; set; }
[NinjaScriptProperty]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Buy/Sell Ratio Threshold", Order = 13, GroupName = "Parameters")]
public double BuySellRatioThreshold { get; set; }
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Dark Mode Buy", Description = "Color for buy signals in DarkMode", Order = 14, GroupName = "Colors")]
public System.Windows.Media.Brush DarkModeBuy { get; set; }
[Browsable(false)]
public string DarkModeBuySerializable
{
get { return Serialize.BrushToString(DarkModeBuy); }
set { DarkModeBuy = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Lite Mode Buy", Description = "Color for buy signals in LiteMode", Order = 15, GroupName = "Colors")]
public System.Windows.Media.Brush LiteModeBuy { get; set; }
[Browsable(false)]
public string LiteModeBuySerializable
{
get { return Serialize.BrushToString(LiteModeBuy); }
set { LiteModeBuy = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Sell", Description = "Color for warning/sell conditions", Order = 16, GroupName = "Colors")]
public System.Windows.Media.Brush Sell { get; set; }
[Browsable(false)]
public string SellSerializable
{
get { return Serialize.BrushToString(Sell); }
set { Sell = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "End of Trend", Description = "Color for no trend signals", Order = 17, GroupName = "Colors")]
public System.Windows.Media.Brush EndOfTrend { get; set; }
[Browsable(false)]
public string EndOfTrendSerializable
{
get { return Serialize.BrushToString(EndOfTrend); }
set { EndOfTrend = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Oh My", Description = "Color for volume divergence signals", Order = 18, GroupName = "Colors")]
public System.Windows.Media.Brush OhMy { get; set; }
[Browsable(false)]
public string OhMySerializable
{
get { return Serialize.BrushToString(OhMy); }
set { OhMy = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Flux", Description = "Color for flux/downward conditions", Order = 19, GroupName = "Colors")]
public System.Windows.Media.Brush Flux { get; set; }
[Browsable(false)]
public string FluxSerializable
{
get { return Serialize.BrushToString(Flux); }
set { Flux = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Stay", Description = "Color for bullish conditions", Order = 20, GroupName = "Colors")]
public System.Windows.Media.Brush Stay { get; set; }
[Browsable(false)]
public string StaySerializable
{
get { return Serialize.BrushToString(Stay); }
set { Stay = Serialize.StringToBrush(value); }
}
[NinjaScriptProperty]
[XmlIgnore]
[NinjaTrader.Gui.NinjaScript.Display(Name = "Quo", Description = "Color for status quo conditions", Order = 21, GroupName = "Colors")]
public System.Windows.Media.Brush Quo { get; set; }
[Browsable(false)]
public string QuoSerializable
{
get { return Serialize.BrushToString(Quo); }
set { Quo = Serialize.StringToBrush(value); }
}
#endregion
#region Miscellaneous
public class DXMediaMap
{
public System.Windows.Media.Brush MediaBrush;
public SharpDX.Direct2D1.Brush DxBrush;
}
private System.Windows.Media.Brush CreateColor(int r, int g, int b)
{
System.Windows.Media.SolidColorBrush brush = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromRgb((byte)r, (byte)g, (byte)b));
if (brush.CanFreeze)
brush.Freeze();
return brush;
}
private void InitDxBrushes()
{
foreach (var item in dxmBrushes)
{
if (item.Value.DxBrush != null)
{
item.Value.DxBrush.Dispose();
item.Value.DxBrush = null;
}
}
if (RenderTarget == null || RenderTarget.IsDisposed)
return;
try
{
foreach (var item in dxmBrushes)
{
if (item.Value.MediaBrush != null)
{
item.Value.DxBrush = item.Value.MediaBrush.ToDxBrush(RenderTarget);
}
else
{
Log($"InitDxBrushes: MediaBrush for {item.Key} is null", LogLevel.Warning);
}
}
}
catch (Exception ex)
{
Log($"InitDxBrushes Error: {ex}", LogLevel.Error);
}
}
protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
if (Bars == null || ChartControl == null || !IsVisible)
return;
InitDxBrushes();
int barPaintWidth = chartControl.GetBarPaintWidth(ChartBars) - 1;
for (int idx = ChartBars.FromIndex; idx <= ChartBars.ToIndex; idx++)
{
if (idx - Displacement < 0 || idx - Displacement >= ChartBars.Count || idx - Displacement < BarsRequiredToPlot)
continue;
double open = Open.GetValueAt(idx);
double high = High.GetValueAt(idx);
double low = Low.GetValueAt(idx);
double close = Close.GetValueAt(idx);
int barX = chartControl.GetXByBarIndex(ChartBars, idx);
int barLeftX = barX - barPaintWidth / 2;
float yOpen = chartScale.GetYByValue(open);
float yHigh = chartScale.GetYByValue(high);
float yLow = chartScale.GetYByValue(low);
float yClose = chartScale.GetYByValue(close);
string brushKey = idx < signalBrushKey.Count ? signalBrushKey.GetValueAt(idx) : "quo";
if (brushKey == null || !dxmBrushes.ContainsKey(brushKey) || dxmBrushes[brushKey].DxBrush == null)
{
Print($"Error: brushKey {brushKey} not found or DxBrush is null at bar {idx}");
brushKey = "quo";
}
UpdateVectors(ref reuseVector1, ref reuseVector2, barX, yHigh, barX, yLow);
RenderTarget.DrawLine(reuseVector1, reuseVector2, dxmBrushes[brushKey].DxBrush, ShadowWidth);
if (close == open)
{
UpdateVectors(ref reuseVector1, ref reuseVector2, barLeftX - 1, yOpen, barX + barPaintWidth / 2 - 1, yOpen);
RenderTarget.DrawLine(reuseVector1, reuseVector2, dxmBrushes[brushKey].DxBrush, ShadowWidth);
}
else
{
float yTop = close > open ? yClose : yOpen;
float yBottom = close > open ? yOpen : yClose;
UpdateRect(ref reuseRectangle, barLeftX, yTop, barPaintWidth - 1, Math.Abs(yClose - yOpen));
RenderTarget.FillRectangle(reuseRectangle, dxmBrushes[brushKey].DxBrush);
UpdateRect(ref reuseRectangle, barLeftX - (ShadowWidth / 2), yBottom, barPaintWidth - (ShadowWidth / 2), Math.Abs(yClose - yOpen));
RenderTarget.DrawRectangle(reuseRectangle, dxmBrushes[brushKey].DxBrush, ShadowWidth);
}
Print($"Render Bar {idx}: brushKey={brushKey}, close={close:F2}, open={open:F2}");
}
}
public override void OnRenderTargetChanged()
{
InitDxBrushes();
}
private void UpdateRect(ref SharpDX.RectangleF rect, float x, float y, float width, float height)
{
rect.X = x;
rect.Y = y;
rect.Width = width;
rect.Height = height;
}
private void UpdateVectors(ref SharpDX.Vector2 v1, ref SharpDX.Vector2 v2, float x1, float y1, float x2, float y2)
{
v1.X = x1;
v1.Y = y1;
v2.X = x2;
v2.Y = y2;
}
#endregion
}
}
#region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private TapeReaderReversals cacheTapeReaderReversals;
public TapeReaderReversals TapeReaderReversals(bool wantAllBuySpikes, bool darkMode, bool showArrows, bool showLabels, int length, double sellAlert, double reversalAlert, int confirmLength, int lookback, int deviationLength, double deviate, int shadowWidth, double buySellRatioThreshold)
{
return TapeReaderReversals(Input, wantAllBuySpikes, darkMode, showArrows, showLabels, length, sellAlert, reversalAlert, confirmLength, lookback, deviationLength, deviate, shadowWidth, buySellRatioThreshold);
}
public TapeReaderReversals TapeReaderReversals(ISeries<double> input, bool wantAllBuySpikes, bool darkMode, bool showArrows, bool showLabels, int length, double sellAlert, double reversalAlert, int confirmLength, int lookback, int deviationLength, double deviate, int shadowWidth, double buySellRatioThreshold)
{
if (cacheTapeReaderReversals != null)
for (int idx = 0; idx < cacheTapeReaderReversals.Length; idx++)
if (cacheTapeReaderReversals[idx] != null && cacheTapeReaderReversals[idx].WantAllBuySpikes == wantAllBuySpikes && cacheTapeReaderReversals[idx].DarkMode == darkMode && cacheTapeReaderReversals[idx].ShowArrows == showArrows && cacheTapeReaderReversals[idx].ShowLabels == showLabels && cacheTapeReaderReversals[idx].Length == length && cacheTapeReaderReversals[idx].SellAlert == sellAlert && cacheTapeReaderReversals[idx].ReversalAlert == reversalAlert && cacheTapeReaderReversals[idx].ConfirmLength == confirmLength && cacheTapeReaderReversals[idx].Lookback == lookback && cacheTapeReaderReversals[idx].DeviationLength == deviationLength && cacheTapeReaderReversals[idx].Deviate == deviate && cacheTapeReaderReversals[idx].ShadowWidth == shadowWidth && cacheTapeReaderReversals[idx].BuySellRatioThreshold == buySellRatioThreshold && cacheTapeReaderReversals[idx].EqualsInput(input))
return cacheTapeReaderReversals[idx];
return CacheIndicator<TapeReaderReversals>(new TapeReaderReversals { WantAllBuySpikes = wantAllBuySpikes, DarkMode = darkMode, ShowArrows = showArrows, ShowLabels = showLabels, Length = length, SellAlert = sellAlert, ReversalAlert = reversalAlert, ConfirmLength = confirmLength, Lookback = lookback, DeviationLength = deviationLength, Deviate = deviate, ShadowWidth = shadowWidth, BuySellRatioThreshold = buySellRatioThreshold }, input, ref cacheTapeReaderReversals);
}
}
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.TapeReaderReversals TapeReaderReversals(bool wantAllBuySpikes, bool darkMode, bool showArrows, bool showLabels, int length, double sellAlert, double reversalAlert, int confirmLength, int lookback, int deviationLength, double deviate, int shadowWidth, double buySellRatioThreshold)
{
return indicator.TapeReaderReversals(Input, wantAllBuySpikes, darkMode, showArrows, showLabels, length, sellAlert, reversalAlert, confirmLength, lookback, deviationLength, deviate, shadowWidth, buySellRatioThreshold);
}
}
}
namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.TapeReaderReversals TapeReaderReversals(bool wantAllBuySpikes, bool darkMode, bool showArrows, bool showLabels, int length, double sellAlert, double reversalAlert, int confirmLength, int lookback, int deviationLength, double deviate, int shadowWidth, double buySellRatioThreshold)
{
return indicator.TapeReaderReversals(Input, wantAllBuySpikes, darkMode, showArrows, showLabels, length, sellAlert, reversalAlert, confirmLength, lookback, deviationLength, deviate, shadowWidth, buySellRatioThreshold);
}
}
}
#endregion