using System.Windows.Media;
namespace NinjaTrader.NinjaScript.Indicators
{
public class OrderBlockIndicator : Indicator
{
private double _marketVolume;
private double _limitVolume;
private double _totalVolume;
private int _startBar;
private int _endBar;
protected override void OnStateChange()
{
if (State == State.SetDefaults)
{
Description = @"Identify potential order blocks";
Name = "OrderBlockIndicator";
Calculate = Calculate.OnBarClose;
IsOverlay = true;
DisplayInDataBox = false;
DrawOnPricePanel = true;
DrawHorizontalGridLines = true;
DrawVerticalGridLines = true;
PaintPriceMarkers = false;
ScaleJustification = ScaleJustification.Right;
IsSuspendedWhileInactive = true;
BlockVolumeRatio = 2.0;
ContourLineColor = Brushes.Yellow;
ContourLineWidth = 2;
}
else if (State == State.Configure)
{
AddDataSeries(Data.BarsPeriodType.Minute, 1);
}
}
protected override void OnBarUpdate()
{
if (BarsInProgress == 1)
{
// Calculate market and limit volumes
double volume = Instrument.MasterInstrument.InstrumentType == Cbi.InstrumentType.CryptoCurrency ? Core.Globals.ToCryptocurrencyVolume((long)Volume[1][0]) : Volume[1][0];
if (Close[1][0] > Open[1][0])
{
_marketVolume += volume;
}
else
{
_limitVolume += volume;
}
_totalVolume += volume;
// Check for potential order block
double blockVolume = BlockVolumeRatio * _marketVolume;
if (_limitVolume >= blockVolume)
{
_startBar = Math.Max(0, CurrentBar - Bars.Period.Value);
}
if (_marketVolume >= blockVolume && _startBar > 0)
{
_endBar = CurrentBar;
// Mark order block with contour line
double low = Low[1][_startBar];
double high = High[1][_endBar];
Draw.Rectangle(this, "OrderBlock" + _startBar, true, _startBar, low, _endBar, high, null, ContourLineColor, ContourLineWidth);
}
}
else if (BarsInProgress == 0)
{
// Reset volumes at the start of a new session
if (Bars.IsFirstBarOfSession)
{
_marketVolume = 0;
_limitVolume = 0;
_totalVolume = 0;
_startBar = -1;
_endBar = -1;
}
}
}
region Properties
[NinjaScriptProperty]
[Range(0.1, double.MaxValue)]
[Display(Name = "BlockVolumeRatio", Description = "Ratio of market order volume to limit order volume for a potential order block", Order = 1, GroupName = "Parameters")]
public double BlockVolumeRatio { get; set; }
[NinjaScriptProperty]
[XmlIgnore]
[Display(Name = "ContourLineColor", Description = "Color of contour line marking potential order blocks", Order = 2, GroupName = "Parameters")]
public Brush ContourLineColor { get; set; }
[Browsable(false)]
Comment