NinjaTrader7 new bar type : Range Bars, but fixed to not draw phantom / dummy bars in case there is a sudden move; jumps happen
// VJ : 20120321 : Fixed to not draw phantom / dummy bars in case there is a sudden move; i.e., all prices seen are real | |
// Problem : The built-in NT7 range bars do phantom / dummy bars to produce picture-perfect Range Bars. | |
// Amibroker does the same. But that is NOT what Iwant. I want real prices. | |
// Thus, only if price action is smooth (tick by tick, say) do we see perfect 250R range bars. | |
// Otherwise, the Close price might be > 250R. | |
// | |
// The difference between Range Bars, and my RangeAltBars: | |
// Default Range Bars : pretty 250R phantom bars with fake (computed) Close | |
// Range Alt Bars : no phantom bars; no fake Close | |
// | |
// File is to be placed in <Path to NinjaTrader 7>\bin\Custom\Type | |
// | |
// RangeAltBarsType - Range bars taht do not fill the gap. | |
// | |
// Adapted from V7B6 RangeBarsType 12/31/09 by Al Slane | |
// | |
#region Using declarations | |
using System; | |
using System.Collections; | |
using System.ComponentModel; | |
using System.Text; | |
#endregion | |
// This namespace holds all bars types. Do not change it. | |
namespace NinjaTrader.Data | |
{ | |
/// <summary> | |
/// </summary> | |
public class RangeAltBarsType : BarsType | |
{ | |
private static bool registered = Data.BarsType.Register(new RangeAltBarsType()); | |
/// <summary> | |
/// </summary> | |
/// <param name="bars"></param> | |
/// <param name="open"></param> | |
/// <param name="high"></param> | |
/// <param name="low"></param> | |
/// <param name="close"></param> | |
/// <param name="time"></param> | |
/// <param name="volume"></param> | |
/// <param name="isRealtime"></param> | |
public override void Add(Data.Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) | |
{ | |
// VJ : 20120325 : Attempt to bypass the issue that bars.Count == 0 not just at the beginning of the data series, but each time IsNewSession() is true, too! | |
// Add a new bar only if bar count is zero WITHOUT it being a new session! | |
// if (bars.Count == 0 || bars.IsNewSession(time, isRealtime)) | |
if (bars.Count == 0 && !bars.IsNewSession(time, isRealtime)) | |
AddBar(bars, open, high, low, close, time, volume, isRealtime); | |
else | |
{ | |
Data.Bar bar = (Bar) bars.Get(bars.Count - 1); | |
double tickSize = bars.Instrument.MasterInstrument.TickSize; | |
double rangeValue = Math.Floor(10000000.0 * (double) bars.Period.Value * tickSize) / 10000000.0; | |
if (bars.Instrument.MasterInstrument.Compare(close, bar.Low + rangeValue) > 0) | |
{ | |
// VJ : 20120321 : Fixed to not draw phantom / dummy bars in case there is a sudden move; i.e., all prices seen are real | |
// double newClose = bar.Low + rangeValue; // every bar closes either with high or low | |
// UpdateBar(bars, bar.Open, newClose, bar.Low, newClose, time, 0, isRealtime); | |
UpdateBar(bars, bar.Open, close, bar.Low, close, time, 0, isRealtime); | |
AddBar(bars, close, close, close, close, time, volume, isRealtime); | |
} | |
else if (bars.Instrument.MasterInstrument.Compare(bar.High - rangeValue, close) > 0) | |
{ | |
// VJ : 20120321 : Fixed to not draw phantom / dummy bars in case there is a sudden move; i.e., all prices seen are real | |
// double newClose = bar.High - rangeValue; // every bar closes either with high or low | |
// UpdateBar(bars, bar.Open, bar.High, newClose, newClose, time, 0, isRealtime); | |
UpdateBar(bars, bar.Open, bar.High, close, close, time, 0, isRealtime); | |
AddBar(bars, close, close, close, close, time, volume, isRealtime); | |
} | |
else | |
//UpdateBar(bars, open, high, low, close, time, volume, isRealtime); | |
UpdateBar(bars, open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime); | |
} | |
bars.LastPrice = close; | |
} | |
public override void ApplyDefaults(Gui.Chart.BarsData barsData) | |
{ | |
barsData.DaysBack = 3; | |
barsData.Period.Value = 4; | |
} | |
/// <summary> | |
/// </summary> | |
public override PeriodType BuiltFrom | |
{ | |
get { return PeriodType.Tick; } | |
} | |
/// <summary> | |
/// </summary> | |
/// <param name="time"></param> | |
/// <returns></returns> | |
public override string ChartDataBoxDate(DateTime time) | |
{ | |
return time.ToString(Cbi.Globals.CurrentCulture.DateTimeFormat.ShortDatePattern); | |
} | |
/// <summary> | |
/// </summary> | |
/// <param name="chartControl"></param> | |
/// <param name="time"></param> | |
/// <returns></returns> | |
public override string ChartLabel(NinjaTrader.Gui.Chart.ChartControl chartControl, DateTime time) | |
{ | |
return time.ToString(chartControl.LabelFormatTick, Cbi.Globals.CurrentCulture); | |
} | |
/// <summary> | |
/// Here is how you restrict the selectable chart styles by bars type | |
/// </summary> | |
public override Gui.Chart.ChartStyleType[] ChartStyleTypesSupported | |
{ | |
get { return new Gui.Chart.ChartStyleType[] { Gui.Chart.ChartStyleType.CandleStick, Gui.Chart.ChartStyleType.HiLoBars, Gui.Chart.ChartStyleType.LineOnClose, | |
Gui.Chart.ChartStyleType.OHLC, Gui.Chart.ChartStyleType.Custom0, Gui.Chart.ChartStyleType.Custom1, Gui.Chart.ChartStyleType.Custom2, Gui.Chart.ChartStyleType.Custom3, | |
Gui.Chart.ChartStyleType.Custom4, Gui.Chart.ChartStyleType.Custom5, Gui.Chart.ChartStyleType.Custom6, Gui.Chart.ChartStyleType.Custom7, Gui.Chart.ChartStyleType.Custom8, | |
Gui.Chart.ChartStyleType.Custom9, Gui.Chart.ChartStyleType.Final0, Gui.Chart.ChartStyleType.Final1, Gui.Chart.ChartStyleType.Final2, Gui.Chart.ChartStyleType.Final3, | |
Gui.Chart.ChartStyleType.Final4 }; } | |
} | |
/// <summary> | |
/// </summary> | |
/// <returns></returns> | |
public override object Clone() | |
{ | |
return new RangeAltBarsType(); | |
} | |
/// <summary> | |
/// </summary> | |
public override int DefaultValue | |
{ | |
get { return 4; } | |
} | |
/// <summary> | |
/// </summary> | |
public override string DisplayName | |
{ | |
get { return "RangeAlt"; } | |
} | |
/// <summary> | |
/// </summary> | |
/// <param name="period"></param> | |
/// <param name="barsBack"></param> | |
/// <returns></returns> | |
public override int GetInitialLookBackDays(Period period, int barsBack) | |
{ | |
return 1; | |
} | |
/// <summary> | |
/// </summary> | |
public override double GetPercentComplete(Data.Bars bars, DateTime now) | |
{ | |
throw new ApplicationException("GetPercentComplete not supported in " + DisplayName); | |
} | |
/// <summary> | |
/// </summary> | |
/// <param name="propertyDescriptor"></param> | |
/// <param name="period"></param> | |
/// <param name="attributes"></param> | |
/// <returns></returns> | |
public override PropertyDescriptorCollection GetProperties(PropertyDescriptor propertyDescriptor, Period period, Attribute[] attributes) | |
{ | |
PropertyDescriptorCollection properties = base.GetProperties(propertyDescriptor, period, attributes); | |
// here is how you remove properties not needed for that particular bars type | |
properties.Remove(properties.Find("BasePeriodType", true)); | |
properties.Remove(properties.Find("BasePeriodValue", true)); | |
properties.Remove(properties.Find("PointAndFigurePriceType", true)); | |
properties.Remove(properties.Find("ReversalType", true)); | |
properties.Remove(properties.Find("Value2", true)); | |
// here is how you change the display name of the property on the properties grid | |
Gui.Design.DisplayNameAttribute.SetDisplayName(properties, "Value", "\r\rValue"); | |
return properties; | |
} | |
/// <summary> | |
/// </summary> | |
public override bool IsIntraday | |
{ | |
get { return true; } | |
} | |
/// <summary> | |
/// </summary> | |
public RangeAltBarsType() : base(PeriodType.Final1) | |
{ | |
} | |
/// <summary> | |
/// </summary> | |
/// <param name="period"></param> | |
/// <returns></returns> | |
public override string ToString(Period period) | |
{ | |
return period.Value.ToString() + " RangeAlt" + (period.MarketDataType != MarketDataType.Last ? " - " + period.MarketDataType : string.Empty); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment