Skip to content

Instantly share code, notes, and snippets.

@vijay-v
Created August 6, 2014 15:28
Show Gist options
  • Save vijay-v/c691cb905d015fa55279 to your computer and use it in GitHub Desktop.
Save vijay-v/c691cb905d015fa55279 to your computer and use it in GitHub Desktop.
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