Thank you very much for your attention
region Using declarations
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Gui;
using NinjaTrader.Gui.Chart;
using NinjaTrader.Gui.SuperDom;
using NinjaTrader.Gui.Tools;
using NinjaTrader.Data;
using NinjaTrader.NinjaScript;
using NinjaTrader.Core.FloatingPoint;
using NinjaTrader.NinjaScript.DrawingTools;
using NinjaTrader.Custom.Indicators;
using NinjaTrader.NinjaScript.Indicators;
using NinjaTrader.NinjaScript.AddOns.SightEngine;
#endregion
namespace NinjaTrader.Custom.Indicators
{
public class OrderBookIndicator : Indicator
{
private readonly int _period;
private readonly decimal _valueAreaHigh;
private readonly decimal _valueAreaLow;
private readonly decimal _pointOfControl;
public OrderBookIndicator(int period, decimal valueAreaHigh, decimal valueAreaLow, decimal pointOfControl)
{
_period = period;
_valueAreaHigh = valueAreaHigh;
_valueAreaLow = valueAreaLow;
_pointOfControl = pointOfControl;
AddPlot(Brushes.Green, "ArrowUp");
AddPlot(Brushes.Red, "ArrowDown");
}
protected override void OnBarUpdate()
{
var orderBook = GetCurrentBidOrderBook();
var prices = orderBook.Select(x => x.Price).ToList();
var volumes = orderBook.Select(x => x.Quantity).ToList();
var valueArea = new ValueArea(prices, volumes, _period);
var result = valueArea.Value > _valueAreaHigh ? 1 :
valueArea.Value < _valueAreaLow ? -1 :
Close[0] > _pointOfControl ? 1 :
Close[0] < _pointOfControl ? -1 :
0;
if (result == 1)
{
PlotBrushes[0][0] = Brushes.Green;
PlotValues[0][0] = Low[0];
PlotBrushes[1][0] = Brushes.Transparent;
PlotValues[1][0] = double.NaN;
}
else if (result == -1)
{
PlotBrushes[0][0] = Brushes.Transparent;
PlotValues[0][0] = double.NaN;
PlotBrushes[1][0] = Brushes.Red;
PlotValues[1][0] = High[0];
}
else
{
PlotBrushes[0][0] = Brushes.Transparent;
PlotValues[0][0] = double.NaN;
PlotBrushes[1][0] = Brushes.Transparent;
PlotValues[1][0] = double.NaN;
}
}
private IReadOnlyList<OrderBookEntry> GetCurrentBidOrderBook()
{
var orderBookEntries = new List<OrderBookEntry>();
for (var i = 0; i < Depth.Bid.Count; i++)
{
var price = Depth.Bid[i].Price;
var quantity = Depth.Bid[i].Size;
orderBookEntries.Add(new OrderBookEntry(price, quantity));
}
return orderBookEntries.AsReadOnly();
}
}
public class ValueArea
{
private readonly int _period;
public ValueArea(IReadOnlyList<decimal> prices, IReadOnlyList<decimal> volumes, int period)
{
_period = period;
var volumeSum = volumes.Sum();
var volumeThreshold = volumeSum * 0.7m;
var priceVolumePairs = prices.Zip(volumes, (price, volume) => new { Price = price, Volume = volume })
.OrderBy(x => x.Price)
.ToList();
var cumulativeVolume = 0m;
var valueAreaLowIndex = 0;
var valueAreaHighIndex = priceVolumePairs.Count - 1;
for (var i = 0; i < priceVolumePairs.Count; i++)
{
cumulativeVolume += priceVolumePairs[i].Volume;
if (cumulativeVolume >= volumeThreshold)
{
valueAreaLowIndex = i == 0 ? 0 : i - 1;
break;
}
}
cumulativeVolume = 0m;
for (var i = priceVolumePairs.Count - 1; i >= 0; i--)
{
cumulativeVolume += priceVolumePairs[i].Volume;
if (cumulativeVolume >= volumeThreshold)
{
valueAreaHighIndex = i == priceVolumePairs.Count - 1 ? priceVolumePairs.Count - 1 : i + 1;
break;
}
}
ValueAreaLowPrice = priceVolumePairs[valueAreaLowIndex].Price;
ValueAreaHighPrice = priceVolumePairs[valueAreaHighIndex].Price;
}
//public decimal Value => ValueAreaHighPrice - ValueAreaLowPrice;
public decimal ValueAreaLowPrice { get; set; }
public decimal ValueAreaHighPrice { get; set; }
public decimal Value
{
get
{
return ValueAreaHighPrice - ValueAreaLowPrice;
}
}
}
public class OrderBookEntry
{
public OrderBookEntry(decimal price, decimal quantity)
{
Price = price;
Quantity = quantity;
}
public decimal Price { get; }
public decimal Quantity { get; }
}
}
region NinjaScript generated code. Neither change nor remove.
namespace NinjaTrader.NinjaScript.Indicators
{
public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
{
private OrderBookIndicator[] cacheOrderBookIndicator;
public OrderBookIndicator OrderBookIndicator()
{
return OrderBookIndicator(Input);
}
public OrderBookIndicator OrderBookIndicator(ISeries<double> input)
{
if (cacheOrderBookIndicator != null)
for (int idx = 0; idx < cacheOrderBookIndicator.Length; idx++)
if (cacheOrderBookIndicator[idx] != null && cacheOrderBookIndicator[idx].EqualsInput(input))
return cacheOrderBookIndicator[idx];
return CacheIndicator<OrderBookIndicator>(new OrderBookIndicator(), input, ref cacheOrderBookIndicator);
}
}
}
namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
{
public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
{
public Indicators.OrderBookIndicator OrderBookIndicator()
{
return indicator.OrderBookIndicator(Input);
}
public Indicators.OrderBookIndicator OrderBookIndicator(ISeries<double> input )
{
return indicator.OrderBookIndicator(input);
}
}
}
namespace NinjaTrader.NinjaScript.Strategies
{
public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
{
public Indicators.OrderBookIndicator OrderBookIndicator()
{
return indicator.OrderBookIndicator(Input);
}
public Indicators.OrderBookIndicator OrderBookIndicator(ISeries<double> input )
{
return indicator.OrderBookIndicator(input);
}
}
}
#endregion
Comment