private DateTime TimeToBarTime(Bars bars, DateTime time, bool isBar) { if (SessionIterator.IsNewSession(time, isBar)) { SessionIterator.GetNextSession(time, isBar); } if (bars.IsResetOnNewTradingDay || !bars.IsResetOnNewTradingDay && bars.Count == 0) { DateTime barTimeStamp = isBar ? SessionIterator.ActualSessionBegin.AddSeconds(Math.Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value) : SessionIterator.ActualSessionBegin.AddSeconds(bars.BarsPeriod.Value + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value); if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd) // Cut last bar in session down to session end on odd session end time { barTimeStamp = SessionIterator.ActualSessionEnd; } return(barTimeStamp); } else { DateTime lastBarTime = bars.GetTime(bars.Count - 1); DateTime barTimeStamp = isBar ? lastBarTime.AddSeconds(Math.Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(lastBarTime).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value) : lastBarTime.AddSeconds(bars.BarsPeriod.Value + Math.Floor(Math.Floor(Math.Max(0, time.Subtract(lastBarTime).TotalSeconds)) / bars.BarsPeriod.Value) * bars.BarsPeriod.Value); if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd) { DateTime saveActualSessionEnd = SessionIterator.ActualSessionEnd; SessionIterator.GetNextSession(SessionIterator.ActualSessionEnd.AddSeconds(1), isBar); barTimeStamp = SessionIterator.ActualSessionBegin.AddSeconds((int)barTimeStamp.Subtract(saveActualSessionEnd).TotalSeconds); } return(barTimeStamp); } }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Session Volume Profile"; Name = "SessionVolumeProfile"; Calculate = Calculate.OnEachTick; IsChartOnly = true; IsOverlay = true; DrawOnPricePanel = false; PrintDebug = false; sessionWidth = 90; EnableValueArea = true; VpBrush = Brushes.SlateGray; VaBrush = Brushes.Black; alpha = 50; } else if (State == State.Configure) { ZOrder = -1; } else if (State == State.DataLoaded) { sessItr = new SessionIterator(Bars); volProfiles = new List <VolProfile>(); } else if (State == State.Historical) { if (Calculate != Calculate.OnEachTick) { Draw.TextFixed(this, "NinjaScriptInfo", string.Format(NinjaTrader.Custom.Resource.NinjaScriptOnBarCloseError, Name), TextPosition.BottomRight); } } }
protected override void OnStateChange() { if (State == State.SetDefaults) { BarsRequiredToPlot = 0; Description = @"High and low of first x seconds of day"; Name = "SessionOpeningRange"; Calculate = Calculate.OnPriceChange; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = false; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; CutoffSeconds = 30; HighBrush = Brushes.Yellow; HighBrushWidth = 2; LowBrush = Brushes.Yellow; LowBrushWidth = 2; // The or high low lines on the chart are not plots, just lines // Adding transparent plot values to display high low values in databox AddPlot(Brushes.Transparent, "OrHigh"); AddPlot(Brushes.Transparent, "OrLow"); ArePlotsConfigurable = false; ShowTransparentPlotsInDataBox = true; } else if (State == State.DataLoaded) { sessionIterator = new SessionIterator(Bars); } }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Managed Set Order Example"; Name = "ProfitChaseStopTrailSetMethodsExample"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; TraceOrders = false; BarsRequiredToTrade = 1; IsInstantiatedOnEachOptimizationIteration = false; ChaseProfitTarget = true; PrintDetails = false; ProfitTargetDistance = 10; StopLossDistance = 10; TrailStopLoss = true; UseProfitTarget = true; UseStopLoss = true; } else if (State == State.Configure) { AddDataSeries(BarsPeriodType.Tick, 1); } else if (State == State.DataLoaded) { sessionIterator = new SessionIterator(Bars); exitOnCloseWait = false; } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } if (bars.Count == 0) { AddBar(bars, open, high, low, close, TimeToBarTime(bars, time, isBar), volume); } else if (!isBar && time < bars.LastBarTime) { UpdateBar(bars, high, low, close, bars.LastBarTime, volume); } else if (isBar && time <= bars.LastBarTime) { UpdateBar(bars, high, low, close, bars.LastBarTime, volume); } else { time = TimeToBarTime(bars, time, isBar); AddBar(bars, open, high, low, close, time, volume); } }
protected override void OnStateChange() { if (State == State.SetDefaults) { BarsRequiredToPlot = 0; Description = @"Session true VWAP."; Name = "SessionVwap"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = false; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; PrintDebug = false; curPlotBrush = null; AddPlot(Brushes.DarkTurquoise, "Vwap"); } else if (State == State.DataLoaded) { sessionIterator = new SessionIterator(Bars); } else if (State == State.Historical) { if (Calculate != Calculate.OnEachTick) { Draw.TextFixed(this, "NinjaScriptInfo", "Tick Data Required for VWAP", TextPosition.BottomRight); } } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } if (bars.BarsPeriod.Value == 1) { AddBar(bars, open, high, low, close, time, volume, bid, ask); } else if (bars.Count == 0) { AddBar(bars, open, high, low, close, time, volume); } else if (bars.Count > 0 && (!bars.IsResetOnNewTradingDay || !isNewSession) && bars.BarsPeriod.Value > 1 && bars.TickCount < bars.BarsPeriod.Value) { UpdateBar(bars, high, low, close, time, volume); } else { AddBar(bars, open, high, low, close, time, volume); } }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionVolumeProfile; Name = NinjaTrader.Custom.Resource.NinjaScriptIndicatorNameVolumeProfile; Calculate = Calculate.OnEachTick; DrawLines = false; IsChartOnly = true; IsOverlay = true; DrawOnPricePanel = false; LineBrush = Brushes.DarkGray; VolumeDownBrush = Brushes.Crimson; VolumeNeutralBrush = Brushes.DarkGray; VolumeUpBrush = Brushes.DarkCyan; } else if (State == State.Configure) { ZOrder = -1; } else if (State == State.DataLoaded) { storedSession = new SessionIterator(Bars); } else if (State == State.Historical) { if (Calculate != Calculate.OnEachTick) { Draw.TextFixed(this, "NinjaScriptInfo", string.Format(NinjaTrader.Custom.Resource.NinjaScriptOnBarCloseError, Name), TextPosition.BottomRight); } } }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "CumulativeDelta"; Calculate = Calculate.OnBarClose; IsOverlay = false; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; //Disable this property if your indicator requires custom values that cumulate with each new market data event. //See Help Guide for additional information. IsSuspendedWhileInactive = true; AddPlot(Brushes.CornflowerBlue, "CumDelta"); ResetDeltaOn = CumulativeDeltaTimeframe.Never; } else if (State == State.Configure) { sessionIterator = new SessionIterator(Bars); } }
public override double GetPercentComplete(Bars bars, DateTime now) { if (SessionIterator == null || SessionIterator.ActualTradingDayExchange == Core.Globals.MinDate) { return(1); } DateTime tradingDayBegin = SessionIterator.GetTradingDayBeginLocal(SessionIterator.ActualTradingDayExchange); return(now > tradingDayBegin && now < SessionIterator.ActualTradingDayEndLocal ? now.Subtract(tradingDayBegin).TotalSeconds / SessionIterator.ActualTradingDayEndLocal.Subtract(tradingDayBegin).TotalSeconds : 1); }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionBarTimer; Name = NinjaTrader.Custom.Resource.NinjaScriptIndicatorNameBarTimer; Calculate = Calculate.OnEachTick; DrawOnPricePanel = false; IsChartOnly = true; IsOverlay = true; DisplayInDataBox = false; } else if (State == State.Realtime) { if (timer == null) { if (Bars.BarsType.IsTimeBased && Bars.BarsType.IsIntraday) { lock (Connection.Connections) { if (Connection.Connections.ToList().FirstOrDefault(c => c.Status == ConnectionStatus.Connected && c.InstrumentTypes.Contains(Instrument.MasterInstrument.InstrumentType)) == null) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerDisconnectedError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } else { if (!SessionIterator.IsInSession(Now, false, true)) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerSessionTimeError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } else { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerWaitingOnDataError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } } } } else { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerTimeBasedError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } } } else if (State == State.Terminated) { if (timer == null) { return; } timer.IsEnabled = false; timer = null; } }
public void RecalculateSession(DateTime time) { if (sessionIterator == null) { if (BarsArray != null) { sessionIterator = new SessionIterator(BarsArray[1]); } } sessionIterator.GetNextSession(time, false); }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } long barsPeriodValue = bars.BarsPeriod.Value; if (bars.Instrument.MasterInstrument.InstrumentType == InstrumentType.CryptoCurrency) { barsPeriodValue = Core.Globals.FromCryptocurrencyVolume(bars.BarsPeriod.Value); } if (bars.Count == 0) { while (volume > barsPeriodValue) { AddBar(bars, open, high, low, close, time, barsPeriodValue); volume -= barsPeriodValue; } if (volume > 0) { AddBar(bars, open, high, low, close, time, volume); } } else { long volumeTmp = 0; if (!bars.IsResetOnNewTradingDay || !isNewSession) { volumeTmp = Math.Min(barsPeriodValue - bars.GetVolume(bars.Count - 1), volume); if (volumeTmp > 0) { UpdateBar(bars, high, low, close, time, volumeTmp); } } volumeTmp = volume - volumeTmp; while (volumeTmp > 0) { AddBar(bars, open, high, low, close, time, Math.Min(volumeTmp, barsPeriodValue)); volumeTmp -= barsPeriodValue; } } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } if (bars.Count == 0) { if (isBar || bars.TradingHours.Sessions.Count == 0) { AddBar(bars, open, high, low, close, time.Date, volume); } else { SessionIterator.CalculateTradingDay(time, false); AddBar(bars, open, high, low, close, SessionIterator.ActualTradingDayExchange, volume); } } else { DateTime barTime; if (isBar) { barTime = time.Date; } else { if (SessionIterator.IsNewSession(time, false)) { SessionIterator.CalculateTradingDay(time, false); barTime = SessionIterator.ActualTradingDayExchange; if (barTime < bars.LastBarTime.Date) { barTime = bars.LastBarTime.Date; // Make sure timestamps are ascending } } else { barTime = bars.LastBarTime.Date; // Make sure timestamps are ascending } } if (bars.DayCount < bars.BarsPeriod.Value || isBar && bars.Count > 0 && barTime == bars.LastBarTime.Date || !isBar && bars.Count > 0 && barTime <= bars.LastBarTime.Date) { UpdateBar(bars, high, low, close, barTime, volume); } else { AddBar(bars, open, high, low, close, barTime, volume); } } }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Unmanaged Order Example"; Name = "ProfitChaseStopTrailUnmanagedExample"; Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = true; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; TraceOrders = true; BarsRequiredToTrade = 1; IsInstantiatedOnEachOptimizationIteration = false; IsUnmanaged = true; ChaseProfitTarget = true; PrintDetails = false; ProfitTargetDistance = 10; StopLossDistance = 10; TrailStopLoss = true; UseProfitTarget = true; UseStopLoss = true; } else if (State == State.Configure) { TraceOrders = PrintDetails; AddDataSeries(BarsPeriodType.Tick, 1); } else if (State == State.Historical) { if (PrintDetails) { ClearOutputWindow(); } sessionIterator = new SessionIterator(Bars); currentPtPrice = 0; currentSlPrice = 0; entryName = string.Empty; exitName = string.Empty; message = string.Empty; ptName = string.Empty; slName = string.Empty; exitOnCloseWait = false; suppressCancelExit = false; placeHolderOrder = new Order(); tickSizeSecondary = BarsArray[1].Instrument.MasterInstrument.TickSize; } }
private DateTime TimeToBarTimeSecond(Bars bars, DateTime time, bool isBar) { if (SessionIterator.IsNewSession(time, isBar)) { SessionIterator.GetNextSession(time, isBar); } DateTime barTimeStamp = SessionIterator.ActualSessionBegin.AddSeconds(Math.Ceiling(Math.Ceiling(Math.Max(0, time.Subtract(SessionIterator.ActualSessionBegin).TotalSeconds)) / bars.BarsPeriod.BaseBarsPeriodValue) * bars.BarsPeriod.BaseBarsPeriodValue); if (bars.TradingHours.Sessions.Count > 0 && barTimeStamp > SessionIterator.ActualSessionEnd) { barTimeStamp = SessionIterator.ActualSessionEnd <= Core.Globals.MinDate ? barTimeStamp : SessionIterator.ActualSessionEnd; } return(barTimeStamp); }
private void OnTimerTick(object sender, EventArgs e) { ForceRefresh(); if (DisplayTime()) { if (timer != null && !timer.IsEnabled) { timer.IsEnabled = true; } if (connected) { if (SessionIterator.IsInSession(Now, false, true)) { if (hasRealtimeData) { TimeSpan barTimeLeft = Bars.GetTime(Bars.Count - 1).Subtract(Now); timeLeft = (barTimeLeft.Ticks < 0 ? "00:00:00" : barTimeLeft.Hours.ToString("00") + ":" + barTimeLeft.Minutes.ToString("00") + ":" + barTimeLeft.Seconds.ToString("00")); Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerTimeRemaining + timeLeft, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } else { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerWaitingOnDataError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } } else { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerSessionTimeError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); } } else { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.BarTimerDisconnectedError, TextPosition.BottomRight, ChartControl.Properties.ChartText, ChartControl.Properties.LabelFont, Brushes.Transparent, Brushes.Transparent, 0); if (timer != null) { timer.IsEnabled = false; } } } }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "SessionMid"; BarsRequiredToPlot = 0; Calculate = Calculate.OnPriceChange; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = false; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = false; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; //Disable this property if your indicator requires custom values that cumulate with each new market data event. //See Help Guide for additional information. IsSuspendedWhileInactive = true; AddPlot(Brushes.LightSeaGreen, "MidPoint"); } else if (State == State.DataLoaded) { sessionIterator = new SessionIterator(Bars); } else if (State == State.Historical) { // Only calc on bar close for historical backfill to // speed up processing Calculate = Calculate.OnBarClose; } else if (State == State.Transition) { // When changing to real time feed, calc and display // indicator for each trade for real time indicator updates Calculate = Calculate.OnPriceChange; } }
protected override void OnStateChange() { base.OnStateChange(); if (State == State.SetDefaults) { Description = "Difference in cumulative delta for each price level between current cumulative delta and cumulative delta the last time that price was touched."; Name = "CumulativeDeltaDifference"; Calculate = Calculate.OnEachTick; IsOverlay = true; IsAutoScale = false; DrawOnPricePanel = true; PaintPriceMarkers = false; IsSuspendedWhileInactive = false; BarsRequiredToPlot = 2; ScaleJustification = ScaleJustification.Right; positiveColor = Brushes.CornflowerBlue; negativeColor = Brushes.Orange; neutralColor = Brushes.White; textSize = 11; ResizableWidth = 30; } else if (State == State.Configure) { ZOrder = ChartBars.ZOrder - 1; if (!Bars.IsTickReplay) { Draw.TextFixed(this, "tickReplay", "Please enable Tick Replay!", TextPosition.TopRight); } //AddDataSeries(BarsPeriodType.Day, 1); sessionIterator = new SessionIterator(Bars); } }
protected override void OnStateChange() { base.OnStateChange(); if (State == State.SetDefaults) { Description = "Shows volume traded at each price for specified time period."; Name = "Volume Profile Column"; Calculate = Calculate.OnEachTick; IsOverlay = true; IsAutoScale = false; DrawOnPricePanel = true; PaintPriceMarkers = false; IsSuspendedWhileInactive = false; BarsRequiredToPlot = 2; ScaleJustification = ScaleJustification.Right; positiveColor = Brushes.CornflowerBlue; negativeColor = Brushes.Orange; neutralColor = Brushes.White; textSize = 11; ResizableWidth = 30; } else if (State == State.Configure) { ZOrder = ChartBars.ZOrder - 1; if (!Bars.IsTickReplay) { Draw.TextFixed(this, "tickReplay", "Please enable Tick Replay!", TextPosition.TopRight); } //AddDataSeries(BarsPeriodType.Day, 1); sessionIterator = new SessionIterator(Bars); } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } double haClose = 0.0; double haHigh = 0.0; double haLow = 0.0; double haOpen = 0.0; switch (BarsPeriod.BaseBarsPeriodType) { case BarsPeriodType.Day: { if (bars.Count == 0) { if (isBar || bars.TradingHours.Sessions.Count == 0) { AddBar(bars, open, high, low, close, time.Date, volume); } else { SessionIterator.CalculateTradingDay(time, false); AddBar(bars, open, high, low, close, SessionIterator.ActualTradingDayExchange, volume); } } else { DateTime barTime; if (isBar) { barTime = time.Date; } else { if (bars.TradingHours.Sessions.Count > 0 && SessionIterator.IsNewSession(time, false)) { SessionIterator.CalculateTradingDay(time, false); barTime = SessionIterator.ActualTradingDayExchange; if (barTime < bars.LastBarTime.Date) { barTime = bars.LastBarTime.Date; // Make sure timestamps are ascending } } else { barTime = bars.LastBarTime.Date; // Make sure timestamps are ascending } } if (bars.DayCount < bars.BarsPeriod.BaseBarsPeriodValue || isBar && bars.Count > 0 && barTime == bars.LastBarTime.Date || !isBar && bars.Count > 0 && barTime <= bars.LastBarTime.Date) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, barTime, volume); } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, barTime, volume); } } break; } case BarsPeriodType.Minute: { if (bars.Count == 0) { AddBar(bars, open, high, low, close, TimeToBarTimeMinute(bars, time, isBar), volume); } else if (!isBar && time < bars.LastBarTime) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume); } else if (isBar && time <= bars.LastBarTime) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume); } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); time = TimeToBarTimeMinute(bars, time, isBar); AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume); } break; } case BarsPeriodType.Month: { if (bars.Count == 0) { AddBar(bars, open, high, low, close, TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue), volume); } else if (time.Month <= bars.LastBarTime.Month && time.Year == bars.LastBarTime.Year || time.Year < bars.LastBarTime.Year) { if (high.ApproxCompare(bars.GetHigh(bars.Count - 1)) != 0 || low.ApproxCompare(bars.GetLow(bars.Count - 1)) != 0 || close.ApproxCompare(bars.GetClose(bars.Count - 1)) != 0 || volume > 0) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume); } } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue), volume); } break; } case BarsPeriodType.Second: { if (bars.Count == 0) { DateTime barTime = TimeToBarTimeSecond(bars, time, isBar); AddBar(bars, open, high, low, close, barTime, volume); } else { if (bars.BarsPeriod.BaseBarsPeriodValue > 1 && time < bars.LastBarTime || bars.BarsPeriod.BaseBarsPeriodValue == 1 && time <= bars.LastBarTime) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume); } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); time = TimeToBarTimeSecond(bars, time, isBar); AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume); } } break; } case BarsPeriodType.Tick: { bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } if (bars.BarsPeriod.BaseBarsPeriodValue == 1) { haOpen = haOpen.ApproxCompare(0.0) == 0 ? open : (haOpen + haClose) / 2.0; haClose = haClose.ApproxCompare(0.0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume); } else if (bars.Count == 0) { AddBar(bars, open, high, low, close, time, volume); } else if (bars.Count > 0 && (!isNewSession || !bars.IsResetOnNewTradingDay) && bars.BarsPeriod.BaseBarsPeriodValue > 1 && bars.TickCount < bars.BarsPeriod.BaseBarsPeriodValue) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, time, volume); } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume); } break; } case BarsPeriodType.Volume: { if (bars.Count == 0) { while (volume > bars.BarsPeriod.BaseBarsPeriodValue) { haOpen = haOpen.ApproxCompare(0.0) == 0 ? open : (haOpen + haClose) / 2.0; haClose = haClose.ApproxCompare(0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, time, bars.BarsPeriod.BaseBarsPeriodValue); volume -= bars.BarsPeriod.BaseBarsPeriodValue; } if (volume > 0) { haOpen = haOpen.ApproxCompare(0.0) == 0 ? open : bars.Instrument.MasterInstrument.RoundToTickSize((haOpen + haClose) / 2.0); haClose = haClose.ApproxCompare(0.0) == 0 ? close : bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, time, volume); } } else { long volumeTmp = 0; bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (!bars.IsResetOnNewTradingDay || !isNewSession) { volumeTmp = Math.Min(bars.BarsPeriod.BaseBarsPeriodValue - bars.GetVolume(bars.Count - 1), volume); if (volumeTmp > 0) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, time, volumeTmp); } } if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } volumeTmp = volume - volumeTmp; while (volumeTmp > 0) { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, time, Math.Min(volumeTmp, bars.BarsPeriod.BaseBarsPeriodValue)); volumeTmp -= bars.BarsPeriod.BaseBarsPeriodValue; } } break; } case BarsPeriodType.Week: { if (bars.Count == 0) { AddBar(bars, open, high, low, close, TimeToBarTimeWeek(time, time.AddDays(6 - ((int)time.DayOfWeek + 1) % 7 + (bars.BarsPeriod.BaseBarsPeriodValue - 1) * 7), bars.BarsPeriod.BaseBarsPeriodValue), volume); } else if (time.Date <= bars.LastBarTime.Date) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume); } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeWeek(time.Date, bars.LastBarTime.Date, bars.BarsPeriod.BaseBarsPeriodValue), volume); } break; } case BarsPeriodType.Year: { if (bars.Count == 0) { AddBar(bars, open, high, low, close, TimeToBarTimeYear(time, bars.BarsPeriod.BaseBarsPeriodValue), volume); } else { if (time.Year <= bars.LastBarTime.Year) { haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, bars.GetOpen(bars.Count - 1))); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, bars.GetOpen(bars.Count - 1))); UpdateBar(bars, haHigh, haLow, haClose, bars.LastBarTime, volume); } else { haOpen = bars.Instrument.MasterInstrument.RoundToTickSize((bars.GetOpen(bars.Count - 1) + bars.GetClose(bars.Count - 1)) / 2.0); haClose = bars.Instrument.MasterInstrument.RoundToTickSize((open + high + low + close) / 4.0); haHigh = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Max(high, haOpen)); haLow = bars.Instrument.MasterInstrument.RoundToTickSize(Math.Min(low, haOpen)); AddBar(bars, haOpen, haHigh, haLow, haClose, TimeToBarTimeYear(time.Date, bars.BarsPeriod.BaseBarsPeriodValue), volume); } } break; } } bars.LastPrice = haClose; }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } if (bars.Count == 0 && tmpTime != Core.Globals.MinDate) // Reset caching when live request trimmed existing bars { tmpTime = Core.Globals.MinDate; } bool endOfBar = true; if (tmpTime == Core.Globals.MinDate) { tmpTime = time; tmpDayCount = 1; tmpTickCount = 1; } else if (bars.Count < tmpCount && bars.Count == 0) // Reset cache when bars are trimmed { tmpTime = Core.Globals.MinDate; tmpVolume = 0; tmpDayCount = 0; tmpTickCount = 0; } else if (bars.Count < tmpCount && bars.Count > 0) // Reset cache when bars are trimmed { tmpTime = bars.GetTime(bars.Count - 1); tmpVolume = bars.GetVolume(bars.Count - 1); tmpTickCount = bars.TickCount; tmpDayCount = bars.DayCount; } switch (BarsPeriod.BaseBarsPeriodType) { case BarsPeriodType.Day: { if (bars.Count == 0 || bars.Count > 0 && (bars.LastBarTime.Month < time.Month || bars.LastBarTime.Year < time.Year)) { tmpTime = time.Date; bars.LastPrice = close; newSession = true; } else { tmpTime = time.Date; tmpVolume += volume; bars.LastPrice = close; tmpDayCount++; if (tmpDayCount < BarsPeriod.BaseBarsPeriodValue || bars.Count > 0 && bars.LastBarTime.Date == time.Date) { endOfBar = false; } } break; } case BarsPeriodType.Minute: { if (bars.Count == 0 || SessionIterator.IsNewSession(time, isBar) && bars.IsResetOnNewTradingDay) { tmpTime = TimeToBarTimeMinute(bars, time, isBar); newSession = true; tmpVolume = 0; } else { if (!isBar && time < bars.LastBarTime || isBar && time <= bars.LastBarTime) { tmpTime = bars.LastBarTime; endOfBar = false; } else { tmpTime = TimeToBarTimeMinute(bars, time, isBar); } tmpVolume += volume; } break; } case BarsPeriodType.Month: { if (tmpTime == Core.Globals.MinDate) { tmpTime = TimeToBarTimeMonth(time, BarsPeriod.BaseBarsPeriodValue); if (bars.Count == 0) { break; } endOfBar = false; } else if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year) { tmpVolume += volume; bars.LastPrice = close; endOfBar = false; } break; } case BarsPeriodType.Second: { if (SessionIterator.IsNewSession(time, isBar)) { tmpTime = TimeToBarTimeSecond(bars, time, isBar); if (bars.Count == 0) { break; } endOfBar = false; newSession = true; } else if (time <= tmpTime) { tmpVolume += volume; bars.LastPrice = close; endOfBar = false; } else { tmpTime = TimeToBarTimeSecond(bars, time, isBar); } break; } case BarsPeriodType.Tick: { if (SessionIterator.IsNewSession(time, isBar)) { SessionIterator.GetNextSession(time, isBar); newSession = true; tmpTime = time; tmpTickCount = 1; if (bars.Count == 0) { break; } endOfBar = false; } else if (BarsPeriod.BaseBarsPeriodValue > 1 && tmpTickCount < BarsPeriod.BaseBarsPeriodValue) { tmpTime = time; tmpVolume += volume; tmpTickCount++; bars.LastPrice = close; endOfBar = false; } else { tmpTime = time; } break; } case BarsPeriodType.Volume: { if (SessionIterator.IsNewSession(time, isBar)) { SessionIterator.GetNextSession(time, isBar); newSession = true; } else if (bars.Count == 0 && volume > 0) { break; } else { tmpVolume += volume; if (tmpVolume < BarsPeriod.BaseBarsPeriodValue) { bars.LastPrice = close; endOfBar = false; } else if (tmpVolume == 0) { endOfBar = false; } } tmpTime = time; break; } case BarsPeriodType.Week: { if (tmpTime == Core.Globals.MinDate) { tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, BarsPeriod.BaseBarsPeriodValue); if (bars.Count == 0) { break; } endOfBar = false; } else if (time.Date <= tmpTime.Date) { tmpVolume += volume; bars.LastPrice = close; endOfBar = false; } break; } case BarsPeriodType.Year: { if (tmpTime == Core.Globals.MinDate) { tmpTime = TimeToBarTimeYear(time, BarsPeriod.BaseBarsPeriodValue); if (bars.Count == 0) { break; } endOfBar = false; } else if (time.Year <= tmpTime.Year) { tmpVolume += volume; bars.LastPrice = close; endOfBar = false; } break; } } if (bars.Count > 0 && tmpTime < bars.GetTime(bars.Count - 1) && BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Second) { tmpTime = bars.GetTime(bars.Count - 1); } if (bars.Count == 0 || newSession && IsIntraday) { AddBar(bars, open, close, close, close, tmpTime, volume); upTrend = open < close; newSessionIdx = bars.Count - 1; newSession = false; firstBarOfSession = true; anchorPrice = close; switchPrice = open; } else if (firstBarOfSession && endOfBar == false) { double prevOpen = bars.GetOpen(bars.Count - 1); RemoveLastBar(bars); if (SessionIterator.IsNewSession(tmpTime, true)) { SessionIterator.GetNextSession(tmpTime, true); } AddBar(bars, prevOpen, close, close, close, tmpTime, tmpVolume); upTrend = prevOpen < close; anchorPrice = close; } else { int breakCount = BarsPeriod.Value; double breakMax = double.MinValue; double breakMin = double.MaxValue; if (firstBarOfSession) { AddBar(bars, anchorPrice, close, close, close, tmpTime, volume); firstBarOfSession = false; tmpVolume = volume; tmpTime = Core.Globals.MinDate; return; } if (bars.Count - newSessionIdx - 1 < breakCount) { breakCount = bars.Count - (newSessionIdx + 1); } for (int k = 1; k <= breakCount; k++) { breakMax = Math.Max(breakMax, bars.GetOpen(bars.Count - k - 1)); breakMax = Math.Max(breakMax, bars.GetClose(bars.Count - k - 1)); breakMin = Math.Min(breakMin, bars.GetOpen(bars.Count - k - 1)); breakMin = Math.Min(breakMin, bars.GetClose(bars.Count - k - 1)); } bars.LastPrice = close; if (upTrend) { if (endOfBar) { bool adding = false; if (bars.Instrument.MasterInstrument.Compare(bars.GetClose(bars.Count - 1), anchorPrice) > 0) { anchorPrice = bars.GetClose(bars.Count - 1); switchPrice = bars.GetOpen(bars.Count - 1); tmpVolume = volume; adding = true; } else if (bars.Instrument.MasterInstrument.Compare(breakMin, bars.GetClose(bars.Count - 1)) > 0) { anchorPrice = bars.GetClose(bars.Count - 1); switchPrice = bars.GetOpen(bars.Count - 1); tmpVolume = volume; upTrend = false; adding = true; } if (adding) { double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice); AddBar(bars, tmpOpen, close, close, close, tmpTime, volume); } else { RemoveLastBar(bars); double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice); if (SessionIterator.IsNewSession(tmpTime, true)) { SessionIterator.GetNextSession(tmpTime, true); } AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume); } } else { RemoveLastBar(bars); double tmpOpen = Math.Min(Math.Max(switchPrice, close), anchorPrice); if (SessionIterator.IsNewSession(tmpTime, true)) { SessionIterator.GetNextSession(tmpTime, true); } AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume); } } else if (endOfBar) { bool adding = false; if (bars.Instrument.MasterInstrument.Compare(bars.GetClose(bars.Count - 1), anchorPrice) < 0) { anchorPrice = bars.GetClose(bars.Count - 1); switchPrice = bars.GetOpen(bars.Count - 1); tmpVolume = volume; adding = true; } else if (bars.Instrument.MasterInstrument.Compare(breakMax, bars.GetClose(bars.Count - 1)) < 0) { anchorPrice = bars.GetClose(bars.Count - 1); switchPrice = bars.GetOpen(bars.Count - 1); tmpVolume = volume; upTrend = true; adding = true; } if (adding) { double tmpOpen = upTrend ? Math.Min(Math.Max(switchPrice, close), anchorPrice) : Math.Max(Math.Min(switchPrice, close), anchorPrice); AddBar(bars, tmpOpen, close, close, close, tmpTime, volume); } else { RemoveLastBar(bars); double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice); if (SessionIterator.IsNewSession(tmpTime, true)) { SessionIterator.GetNextSession(tmpTime, true); } AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume); } } else { RemoveLastBar(bars); double tmpOpen = Math.Max(Math.Min(switchPrice, close), anchorPrice); if (SessionIterator.IsNewSession(tmpTime, true)) { SessionIterator.GetNextSession(tmpTime, true); } AddBar(bars, tmpOpen, close, close, close, tmpTime, tmpVolume); } } if (endOfBar) { tmpTime = Core.Globals.MinDate; } tmpCount = bars.Count; }
protected override void OnMarketData(MarketDataEventArgs e) { if (Bars.Count <= 0) { return; } double price; long volume; VolumeInfoItem volumeInfoItem; DateTime lastBarTimeStamp = GetLastBarSessionDate(Time[0]); if (lastBarTimeStamp != currentDate) { cacheDictionary = new Dictionary <double, VolumeInfoItem>(); sortedDicList.Add(cacheDictionary); } currentDate = lastBarTimeStamp; if (Bars.IsTickReplay) { if (e.MarketDataType == MarketDataType.Last) { price = e.Price; volume = e.Volume; if (!cacheDictionary.ContainsKey(price)) { cacheDictionary.Add(price, new VolumeInfoItem()); } volumeInfoItem = cacheDictionary[price]; if (price >= e.Ask) { volumeInfoItem.up += volume; } else if (price <= e.Bid) { volumeInfoItem.down += volume; } else { volumeInfoItem.neutral += volume; } } } else { if (e.MarketDataType == MarketDataType.Ask) { askPrice = e.Price; return; } if (e.MarketDataType == MarketDataType.Bid) { bidPrice = e.Price; return; } if (e.MarketDataType != MarketDataType.Last || ChartControl == null || askPrice == 0 || bidPrice == 0) { return; } if (Bars != null && !SessionIterator.IsInSession(Core.Globals.Now, true, true)) { return; } price = e.Price; volume = e.Volume; if (!cacheDictionary.ContainsKey(price)) { cacheDictionary.Add(price, new VolumeInfoItem()); } volumeInfoItem = cacheDictionary[price]; if (price >= askPrice) { volumeInfoItem.up += volume; } else if (price <= bidPrice) { volumeInfoItem.down += volume; } else { volumeInfoItem.neutral += volume; } } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { double lastBarClose = bars.GetClose(bars.Count - 1); // Trae el Ășltimo precio de cierre if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } offset = bars.BarsPeriod.Value * bars.Instrument.MasterInstrument.TickSize; // Periocidad * tick (Tamaño de la caja) bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } // Si es una grĂĄfica nueva o una sesiĂłn nueva y estĂĄ en un nuevo dĂa if (bars.Count == 0 || bars.IsResetOnNewTradingDay && isNewSession) { // una sesiĂłn nueva y estĂĄ en un nuevo dĂa if (bars.Count > 0) { // Close out last bar in session and set open == close DateTime lastBarTime = bars.GetTime(bars.Count - 1); // Trae la Ășltima fecha del precio de cierre long lastBarVolume = bars.GetVolume(bars.Count - 1); // Trae el Ășltimo volumen de precio de cierre RemoveLastBar(bars); // Elimina la Ășltima barra AddBar(bars, lastBarClose, lastBarClose, lastBarClose, lastBarClose, lastBarTime, lastBarVolume); // Crea una nueva barra con la informaciĂłn obtenida } renkoHigh = close + offset; // Suma el valor de cierre y tamaño de la caja renkoLow = close - offset; // Diferencia del valor de cierre y el tamaño de la caja // ÂżHay un nuevo precio negociado? isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); // Entonces traiga el Ășltimo precio } // Pinte el Ășltimo precio negociado AddBar(bars, close, close, close, close, time, volume); bars.LastPrice = close; return; } double barOpen = bars.GetOpen(bars.Count - 1); // Obtiene el valor de apertura de la Ășltima barra double barHigh = bars.GetHigh(bars.Count - 1); // Obtiene el valor mĂĄs alto negociado de la Ășltima barra double barLow = bars.GetLow(bars.Count - 1); // Obtiene el valor mĂĄs bajo negociado de la Ășltima barra long barVolume = bars.GetVolume(bars.Count - 1); // Obtiene el volumen de la Ășltima barra DateTime barTime = bars.GetTime(bars.Count - 1); // Obtiene la fecha de la Ășltima barra // renkoHigh == 0 || renkoLow == 0 // ApproxCompare: Compares two double or float values for equality or being greater than / less than the compared to value. if (renkoHigh.ApproxCompare(0.0) == 0 || renkoLow.ApproxCompare(0.0) == 0) { if (bars.Count == 1) { renkoHigh = barOpen + offset; // suma = valor de apertura de la Ășltima barra + el tamaño de la caja renkoLow = barOpen - offset; // diferencia = valor de apertura de la Ășltima barra - el tamaño de la caja } // Penultimo valor de cierre es mayor al penultimo valor de apertura? else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2)) { renkoHigh = bars.GetClose(bars.Count - 2) + offset; // Suma tamaño de la caja + el penultimo valor de cierre renkoLow = bars.GetClose(bars.Count - 2) - offset * 2; // Resta el doble del tamaño de la caja - el penultimo valor de cierre } else { renkoHigh = bars.GetClose(bars.Count - 2) + offset * 2; // Suma el doble tamaño de la caja + el penultimo valor de cierre renkoLow = bars.GetClose(bars.Count - 2) - offset; // Resta el tamaño de la caja - el penultimo valor de cierre } } bool isRail2Rail = false; // Hay cambio de tendencia hacia bajista? if (close <= (renkoHigh)) { // Elimina la barra de Update RemoveLastBar(bars); // Agrega la nueva barra con los nuevos valores renkoLow = renkoHigh - 2.0 * offset; // RenkoHigh - el doble del tamaño de la caja renkoHigh = renkoHigh + offset; // Renkohigh + el tamaño de la caja // Agrega barra alcista //AddBar(bars, _renkoLow - offset, Math.Max(_renkoLow - offset, _renkoLow), Math.Min(_renkoLow - offset, _renkoLow), _renkoLow, barTime, barVolume); //AddBar(bars, _renkoHigh + offset, Math.Max(_renkoHigh + offset, _renkoHigh), Math.Min(_renkoHigh + offset, _renkoHigh), _renkoHigh, barTime, barVolume); //AddBar(Bars bars, double open, double high, double low, double close, DateTime time, long volume) //Barra de una grĂĄfica bajista AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume); isRail2Rail = true; } //bool isRail2Rail = false; // Hay cambio de tendencia hacia alcista? if (close >= (renkoLow)) { // Elimina la barra la barra de Update RemoveLastBar(bars); // Agrega la nueva barra con los nuevos valores // Original //AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume); // Bajista renkoHigh = renkoLow + 2.0 * offset; // RenkoLow - el doble del tamaño de la caja renkoLow = renkoLow - offset; // RenkoLow - el tamaño de la caja //AddBar(bars, _renkoHigh + offset, Math.Max(_renkoHigh + offset, _renkoHigh), Math.Min(_renkoHigh + offset, _renkoHigh), _renkoHigh, barTime, barVolume); //AddBar(bars, _renkoLow - offset, Math.Max(_renkoLow - offset, _renkoLow), Math.Min(_renkoLow - offset, _renkoLow), _renkoLow, barTime, barVolume); //Barra de grĂĄfica alcista AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, barTime, barVolume); isRail2Rail = true; } // el precio de cierre es mayor renkohigh? // [DETECTA COMPORTAMIENTO ALCISTA] if (close.ApproxCompare(renkoHigh) >= 0) { /* if (trend != 0 && trend != 1) { * // Elimina la barra de Update * RemoveLastBar(bars); * * // Agrega la nueva barra con los nuevos valores * var _renkoLow = renkoHigh - 1.0 * offset; // RenkoHigh - el doble del tamaño de la caja * var _renkoHigh = renkoHigh + offset; // Renkohigh + el tamaño de la caja * // Agrega barra alcista * AddBar(bars, _renkoLow - offset, Math.Max(_renkoLow - offset, _renkoLow), Math.Min(_renkoLow - offset, _renkoLow), _renkoLow, barTime, barVolume); * * isRail2Rail = true; * } */ // (1) Obtiene el valor mayor entre renkoHigh y, renkoHigh - tamaño de la caja // (2) Si el valor de x es igual a y entonces retorna 0 // Si el valor de x es mayor a y entonces retorna 1 // Si el valor de x es menor a y entonces retorna -1 if (barOpen.ApproxCompare(renkoHigh - offset) != 0 || // valor de apertura de la (Ășltima barra - el tamño de la caja) es mayor o menor a barOpen? barHigh.ApproxCompare(Math.Max(renkoHigh - offset, renkoHigh)) != 0 || // Es barHigh mayor o menor a (1)? barLow.ApproxCompare(Math.Min(renkoHigh - offset, renkoHigh)) != 0) // Es barLow mayor o menor a (1)? { // No hubo cambio de tendencia if (!isRail2Rail) { // Elimina la Ășltima barra de Update RemoveLastBar(bars); } // Agrega una barra nueva con los nuevos valores // Alcista AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, barTime, barVolume); } renkoLow = renkoHigh - 2.0 * offset; // RenkoHigh - el doble del tamaño de la caja renkoHigh = renkoHigh + offset; // Renkohigh + el tamaño de la caja // ÂżHay un nuevo valor negociado? isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); // Obtiene el Ășltimo valor negociado } // Agrega barras vacĂas para llenar el gap si el precio salta while (close.ApproxCompare(renkoHigh) >= 0) { AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, renkoHigh), Math.Min(renkoHigh - offset, renkoHigh), renkoHigh, time, 0); renkoLow = renkoHigh - 2.0 * offset; renkoHigh = renkoHigh + offset; } // Agrega la barra final parcial AddBar(bars, renkoHigh - offset, Math.Max(renkoHigh - offset, close), Math.Min(renkoHigh - offset, close), close, time, volume); trend = 1; } // el precio de cierre es menor o igual a renkohigh? // El precio de cierre es menor o igual al renkolow // [DETECTA COMPORTAMIENTO BAJISTA] else if (close.ApproxCompare(renkoLow) <= 0) { /* if (trend != 0 && trend != -1) { * // Elimina la barra la barra de Update * RemoveLastBar(bars); * // Agrega la nueva barra con los nuevos valores * // Original * //AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume); * // Bajista * var _renkoHigh = renkoLow + 1.0 * offset; // RenkoLow - el doble del tamaño de la caja * var _renkoLow = renkoLow - offset; // RenkoLow - el tamaño de la caja * AddBar(bars, _renkoHigh + offset, Math.Max(_renkoHigh + offset, _renkoHigh), Math.Min(_renkoHigh + offset, _renkoHigh), _renkoHigh, barTime, barVolume); * isRail2Rail = true; * } */ // (1) Obtiene el valor mayor entre renkoLow y, renkoLow + tamaño de la caja // (2) Si el valor de x es igual a y entonces retorna 0 // Si el valor de x es mayor a y entonces retorna 1 // Si el valor de x es menor a y entonces retorna -1 if (barOpen.ApproxCompare(renkoLow + offset) != 0 || // Valor de apertura de (renkolow + el tamaño de la caja) es mayor o menor a barOpen? barHigh.ApproxCompare(Math.Max(renkoLow + offset, renkoLow)) != 0 || // Es barHigh mayor o menor a (1)? barLow.ApproxCompare(Math.Min(renkoLow + offset, renkoLow)) != 0) // Es barlow mayor o menor a (1)? { // TODO: Validar si la condiciĂłn cambia, si si, entonces no elimine la Ășltima barra if (!isRail2Rail) { // Elimine la barra de Update RemoveLastBar(bars); } // Agrega la nueva barra con los nuevos valores // AddBar(Bars bars, double open, double high, double low, double close, DateTime time, long volume) //Bajista AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, barTime, barVolume); } renkoHigh = renkoLow + 2.0 * offset; // RenkoLow - el doble del tamaño de la caja renkoLow = renkoLow - offset; // RenkoLow - el tamaño de la caja // ÂżHay un nuevo valor negociado? isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); // Obtiene el Ășltimo valor negociado } // Agrega barras vacĂas para llenar el gap si el precio salta while (close.ApproxCompare(renkoLow) <= 0) { AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, renkoLow), Math.Min(renkoLow + offset, renkoLow), renkoLow, time, 0); renkoHigh = renkoLow + 2.0 * offset; renkoLow = renkoLow - offset; } // Agrega la barra final parcial AddBar(bars, renkoLow + offset, Math.Max(renkoLow + offset, close), Math.Min(renkoLow + offset, close), close, time, volume); trend = -1; } // El precio de cierre mayor al renkolow else { // Actualiza la barra UpdateBar(bars, close, close, close, time, volume); } // El Ășltimo precio el valor de cierre bars.LastPrice = close; }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = NinjaTrader.Custom.Resource.NinjaScriptIndicatorDescriptionPivots; Name = NinjaTrader.Custom.Resource.NinjaScriptIndicatorNamePivots; Calculate = Calculate.OnBarClose; DisplayInDataBox = true; DrawOnPricePanel = false; IsAutoScale = false; IsOverlay = true; PaintPriceMarkers = true; ScaleJustification = ScaleJustification.Right; AddPlot(Brushes.Goldenrod, NinjaTrader.Custom.Resource.PivotsPP); AddPlot(Brushes.DodgerBlue, NinjaTrader.Custom.Resource.PivotsR1); AddPlot(Brushes.DodgerBlue, NinjaTrader.Custom.Resource.PivotsR2); AddPlot(Brushes.DodgerBlue, NinjaTrader.Custom.Resource.PivotsR3); AddPlot(Brushes.Crimson, NinjaTrader.Custom.Resource.PivotsS1); AddPlot(Brushes.Crimson, NinjaTrader.Custom.Resource.PivotsS2); AddPlot(Brushes.Crimson, NinjaTrader.Custom.Resource.PivotsS3); } else if (State == State.Configure) { if (priorDayHlc == HLCCalculationMode.DailyBars) { AddDataSeries(BarsPeriodType.Day, 1); } } else if (State == State.DataLoaded) { storedSession = new SessionIterator(Bars); } else if (State == State.Historical) { if (priorDayHlc == HLCCalculationMode.DailyBars && BarsArray[1].DayCount <= 0) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PiviotsDailyDataError, TextPosition.BottomRight); Log(NinjaTrader.Custom.Resource.PiviotsDailyDataError, LogLevel.Error); return; } if (!Bars.BarsType.IsIntraday && BarsPeriod.BarsPeriodType != BarsPeriodType.Day && (BarsPeriod.BarsPeriodType != BarsPeriodType.HeikenAshi && BarsPeriod.BarsPeriodType != BarsPeriodType.Volumetric || BarsPeriod.BaseBarsPeriodType != BarsPeriodType.Day)) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PiviotsDailyBarsError, TextPosition.BottomRight); Log(NinjaTrader.Custom.Resource.PiviotsDailyBarsError, LogLevel.Error); } if ((BarsPeriod.BarsPeriodType == BarsPeriodType.Day || ((BarsPeriod.BarsPeriodType == BarsPeriodType.HeikenAshi || BarsPeriod.BarsPeriodType == BarsPeriodType.Volumetric) && BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Day)) && pivotRangeType == PivotRange.Daily) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PiviotsWeeklyBarsError, TextPosition.BottomRight); Log(NinjaTrader.Custom.Resource.PiviotsWeeklyBarsError, LogLevel.Error); } if ((BarsPeriod.BarsPeriodType == BarsPeriodType.Day || ((BarsPeriod.BarsPeriodType == BarsPeriodType.HeikenAshi || BarsPeriod.BarsPeriodType == BarsPeriodType.Volumetric) && BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Day)) && BarsPeriod.Value > 1) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PiviotsPeriodTypeError, TextPosition.BottomRight); Log(NinjaTrader.Custom.Resource.PiviotsPeriodTypeError, LogLevel.Error); } if ((priorDayHlc == HLCCalculationMode.DailyBars && (pivotRangeType == PivotRange.Monthly && BarsArray[1].GetTime(0).Date >= BarsArray[1].GetTime(BarsArray[1].Count - 1).Date.AddMonths(-1) || pivotRangeType == PivotRange.Weekly && BarsArray[1].GetTime(0).Date >= BarsArray[1].GetTime(BarsArray[1].Count - 1).Date.AddDays(-7) || pivotRangeType == PivotRange.Daily && BarsArray[1].GetTime(0).Date >= BarsArray[1].GetTime(BarsArray[1].Count - 1).Date.AddDays(-1))) || pivotRangeType == PivotRange.Monthly && BarsArray[0].GetTime(0).Date >= BarsArray[0].GetTime(BarsArray[0].Count - 1).Date.AddMonths(-1) || pivotRangeType == PivotRange.Weekly && BarsArray[0].GetTime(0).Date >= BarsArray[0].GetTime(BarsArray[0].Count - 1).Date.AddDays(-7) || pivotRangeType == PivotRange.Daily && BarsArray[0].GetTime(0).Date >= BarsArray[0].GetTime(BarsArray[0].Count - 1).Date.AddDays(-1) ) { Draw.TextFixed(this, "NinjaScriptInfo", NinjaTrader.Custom.Resource.PiviotsInsufficentDataError, TextPosition.BottomRight); Log(NinjaTrader.Custom.Resource.PiviotsInsufficentDataError, LogLevel.Error); } } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { // method variables bool isNewSession = SessionIterator.IsNewSession(time, isBar); double tickSize = bars.Instrument.MasterInstrument.TickSize; if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } if (bars.Count == 0 || (bars.IsResetOnNewTradingDay && isNewSession)) { // update fields rangeMax = AddTwoDoubles(bars, bars.BarsPeriod.BaseBarsPeriodValue * tickSize, 0); rangeMin = AddTwoDoubles(bars, bars.BarsPeriod.Value * tickSize, 0); // set initial range, factoring dynamic thisRange = isDynamic ? rangeMin : rangeMax; AdjustMaxMin(bars, close, close); // add first bar AddBar(bars, thisOpen, thisOpen, thisOpen, thisOpen, time, volume); } else { // local variables double barOpen = bars.GetOpen(bars.Count - 1); double barHigh = bars.GetHigh(bars.Count - 1); double barLow = bars.GetLow(bars.Count - 1); int maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax); int minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin); double thisClose = maxCompare > 0 ? Math.Min(close, thisMax) : minCompare < 0 ? Math.Max(close, thisMin) : close; // range exceeded; create new bar(s) if (maxCompare > 0 || minCompare < 0) { // local variables bool newBar = true; // update bias prevBias = thisBias; thisBias = close > barOpen ? 1 : close < barOpen ? -1 : 0; // close current bar; volume included for on-touch only // see this post for more info on volume calculation: http://www.ninjatrader.com/support/forum/showthread.php?p=302208#post302208 UpdateBar(bars, (maxCompare > 0 ? thisClose : barHigh), (minCompare < 0 ? thisClose : barLow), thisClose, time, 0); // add next bar and loop phantom bars, if needed do { // update thisRange for dynamic if (isDynamic) { // increment range for same bias, if range has not exceeded max if ((thisBias == prevBias || prevBias == 0) && thisRange < rangeMax) { thisRange = AddTwoDoubles(bars, thisRange, tickSize); } // increment range after trend change (will only fire once) else if (thisBias != prevBias && prevBias != 0) { thisRange = AddTwoDoubles(bars, rangeMin, tickSize); } // ensure valid range thisRange = Math.Min(thisRange, rangeMax); } // update fields AdjustMaxMin(bars, thisClose, close); thisClose = (maxCompare > 0) ? Math.Min(close, thisMax) : (minCompare < 0) ? Math.Max(close, thisMin) : close; // add new bar; include volume once (except for on-touch), then create phantom bars // see this post for more info on volume calculation: http://www.ninjatrader.com/support/forum/showthread.php?p=302208#post302208 AddBar(bars, thisOpen, (maxCompare > 0 ? thisClose : thisOpen), (minCompare < 0 ? thisClose : thisOpen), thisClose, time, (newBar ? volume : 0)); newBar = false; // update fields maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax); minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin); }while (maxCompare > 0 || minCompare < 0); } else { UpdateBar(bars, (close > barHigh ? close : barHigh), (close < barLow ? close : barLow), close, time, volume); } } bars.LastPrice = close; }
protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"Enter the description for your new custom Indicator here."; Name = "JBMarketProfileLevels"; Calculate = Calculate.OnEachTick; IsOverlay = true; DisplayInDataBox = true; DrawOnPricePanel = true; DrawHorizontalGridLines = true; DrawVerticalGridLines = true; PaintPriceMarkers = true; ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right; //Disable this property if your indicator requires custom values that cumulate with each new market data event. //See Help Guide for additional information. IsSuspendedWhileInactive = true; LineWidth = 2; LineStyle = DashStyleHelper.Dot; ShowPOC = true; ShowONPOC = true; ShowVA = false; ShowONVA = false; ShowHILO = true; ShowONHILO = true; ShowSettlement = true; HILOColor = Brushes.Red; VAColor = Brushes.White; POCColor = Brushes.Magenta; ONHILOColor = Brushes.Red; ONVAColor = Brushes.White; ONPOCColor = Brushes.Magenta; SettlementColor = Brushes.DarkOrange; Opacity = 100; BrokenOpacity = 45; LabelFont = new Gui.Tools.SimpleFont("Arial", 8); RTHTemplate = "CME US Index Futures RTH"; ONTemplate = "Overnight Template"; tpoProfiles = new List <JBTPOProfile>(); initDone = false; } else if (State == State.Configure) { try { TradingHours.String2TradingHours(RTHTemplate).GetPreviousTradingDayEnd(DateTime.Now); // Test if template exists AddDataSeries(BarsArray[0].Instrument.FullName, new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 30 }, RTHTemplate); try { TradingHours.String2TradingHours(ONTemplate).GetPreviousTradingDayEnd(DateTime.Now); // Test if template exists AddDataSeries(BarsArray[0].Instrument.FullName, new BarsPeriod { BarsPeriodType = BarsPeriodType.Minute, Value = 30 }, ONTemplate); initDone = true; } catch (Exception e) { Draw.TextFixed(this, "NinjaScriptInfo", "JBMarketProfileLevels error loading trading hours with template name '" + ONTemplate + "', check properties", TextPosition.Center); Log("JBMarketProfileLevels could not load specified trading hours templates", LogLevel.Error); } } catch (Exception e) { Draw.TextFixed(this, "NinjaScriptInfo", "JBMarketProfileLevels error loading trading hours with template name '" + RTHTemplate + "', check properties", TextPosition.Center); Log("JBMarketProfileLevels could not load specified trading hours templates", LogLevel.Error); } AllowRemovalOfDrawObjects = true; //test(); } else if (State == State.Historical) { if (!initDone) { return; } if (!Bars.IsTickReplay) { Draw.TextFixed(this, "NinjaScriptInfo", "JBMarketProfileLevels needs tick replay enabled on the data series", TextPosition.Center); Log("JBMarketProfileLevels needs tick replay enabled on the data series", LogLevel.Error); initDone = false; } else { rthSessionIterator = new SessionIterator(BarsArray[RTH]); ethSessionIterator = new SessionIterator(BarsArray[ETH]); SetZOrder(-1); } } else if (State == State.Transition) { if (!initDone) { return; } if (tpoProfile != null) { update(tpoProfile); } requestAndDrawSettlement(DateTime.Now); } else if (State == State.Realtime) { if (Instrument != null && Instrument.MarketData != null && Instrument.MarketData.Settlement != null) { settlement = Instrument.MarketData.Settlement.Price; requestAndDrawSettlement(DateTime.Now); } } }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } if (bars.Count == 0 || bars.IsResetOnNewTradingDay && isNewSession) { AddBar(bars, open, high, low, close, time, volume); } else { double barClose = bars.GetClose(bars.Count - 1); double barHigh = bars.GetHigh(bars.Count - 1); double barLow = bars.GetLow(bars.Count - 1); double tickSize = bars.Instrument.MasterInstrument.TickSize; double rangeValue = Math.Floor(10000000.0 * bars.BarsPeriod.Value * tickSize) / 10000000.0; if (close.ApproxCompare(barLow + rangeValue) > 0) { double newClose = barLow + rangeValue; // Every bar closes either with high or low if (newClose.ApproxCompare(barClose) > 0) { UpdateBar(bars, newClose, barLow, newClose, time, 0); } // If there's still a gap, fill with phantom bars double newBarOpen = newClose + tickSize; while (close.ApproxCompare(newClose) > 0) { newClose = Math.Min(close, newBarOpen + rangeValue); AddBar(bars, newBarOpen, newClose, newBarOpen, newClose, time, close.ApproxCompare(newClose) > 0 ? 0 : volume); newBarOpen = newClose + tickSize; } } else if ((barHigh - rangeValue).ApproxCompare(close) > 0) { double newClose = barHigh - rangeValue; // Every bar closes either with high or low if (barClose.ApproxCompare(newClose) > 0) { UpdateBar(bars, barHigh, newClose, newClose, time, 0); } // if there's still a gap, fill with phantom bars double newBarOpen = newClose - tickSize; while (newClose.ApproxCompare(close) > 0) { newClose = Math.Max(close, newBarOpen - rangeValue); AddBar(bars, newBarOpen, newBarOpen, newClose, newClose, time, newClose.ApproxCompare(close) > 0 ? 0 : volume); newBarOpen = newClose - tickSize; } } else { UpdateBar(bars, close > barHigh ? close : barHigh, close < barLow ? close : barLow, close, time, volume); } } bars.LastPrice = close; }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } #region Building Bars from Base Period if (bars.Count != tmpCount) // Reset cache when bars are trimmed { if (bars.Count == 0) { tmpTime = Core.Globals.MinDate; tmpVolume = 0; tmpDayCount = 0; tmpTickCount = 0; } else { tmpTime = bars.GetTime(bars.Count - 1); tmpVolume = bars.GetVolume(bars.Count - 1); tmpTickCount = bars.TickCount; tmpDayCount = bars.DayCount; bars.LastPrice = bars.GetClose(bars.Count - 1); anchorPrice = bars.LastPrice; } } bool isNewSession = SessionIterator.IsNewSession(time, isBar); bool isCalculateTradingDayDone = false; switch (bars.BarsPeriod.BaseBarsPeriodType) { case BarsPeriodType.Day: tmpTime = time.Date; // Will be modified for realtime only if (!isBar && time >= cacheSessionEnd /* on realtime includesEndTimeStamp is always false */) { if (isNewSession) { SessionIterator.GetNextSession(time, isBar); isCalculateTradingDayDone = true; } cacheSessionEnd = SessionIterator.ActualSessionEnd; if (tmpTime < time.Date) { tmpTime = time.Date; // Make sure timestamps are ascending } } if (prevTime != tmpTime) { tmpDayCount++; } if (tmpDayCount < bars.BarsPeriod.BaseBarsPeriodValue || isBar && bars.Count > 0 && tmpTime == bars.LastBarTime.Date || !isBar && bars.Count > 0 && tmpTime <= bars.LastBarTime.Date) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; } break; case BarsPeriodType.Minute: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeMinute(bars, time, isBar); } if (isBar && time <= tmpTime || !isBar && time < tmpTime) { endOfBar = false; } else { prevTime = tmpTime; tmpTime = TimeToBarTimeMinute(bars, time, isBar); endOfBar = true; } break; case BarsPeriodType.Volume: if (tmpTime == Core.Globals.MinDate) { tmpVolume = volume; endOfBar = tmpVolume >= bars.BarsPeriod.BaseBarsPeriodValue; prevTime = tmpTime = time; if (endOfBar) { tmpVolume = 0; } break; } tmpVolume += volume; endOfBar = tmpVolume >= bars.BarsPeriod.BaseBarsPeriodValue; if (endOfBar) { prevTime = tmpTime; tmpVolume = 0; } tmpTime = time; break; case BarsPeriodType.Tick: if (tmpTime == Core.Globals.MinDate || bars.BarsPeriod.BaseBarsPeriodValue == 1) { prevTime = tmpTime == Core.Globals.MinDate ? time : tmpTime; tmpTime = time; tmpTickCount = bars.BarsPeriod.BaseBarsPeriodValue == 1 ? 0 : 1; endOfBar = bars.BarsPeriod.BaseBarsPeriodValue == 1; break; } if (tmpTickCount < bars.BarsPeriod.BaseBarsPeriodValue) { tmpTime = time; endOfBar = false; tmpTickCount++; } else { prevTime = tmpTime; tmpTime = time; endOfBar = true; tmpTickCount = 1; } break; case BarsPeriodType.Month: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue); } if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeMonth(time, bars.BarsPeriod.BaseBarsPeriodValue); } break; case BarsPeriodType.Second: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeSecond(bars, time, isBar); } if (bars.BarsPeriod.BaseBarsPeriodValue > 1 && time < tmpTime || bars.BarsPeriod.BaseBarsPeriodValue == 1 && time <= tmpTime) { endOfBar = false; } else { prevTime = tmpTime; tmpTime = TimeToBarTimeSecond(bars, time, isBar); endOfBar = true; } break; case BarsPeriodType.Week: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.BarsPeriod.BaseBarsPeriodValue); } if (time.Date <= tmpTime.Date) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, bars.BarsPeriod.BaseBarsPeriodValue); } break; case BarsPeriodType.Year: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeYear(time, bars.BarsPeriod.Value); } if (time.Year <= tmpTime.Year) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeYear(time, bars.BarsPeriod.Value); } break; } #endregion #region Kagi Logic reversalPoint = bars.BarsPeriod.ReversalType == ReversalType.Tick ? bars.BarsPeriod.Value * bars.Instrument.MasterInstrument.TickSize : bars.BarsPeriod.Value / 100.0 * anchorPrice; if (bars.Count == 0 || IsIntraday && (bars.BarsPeriod.BaseBarsPeriodType != BarsPeriodType.Second && bars.IsResetOnNewTradingDay && isNewSession || bars.BarsPeriod.BaseBarsPeriodType == BarsPeriodType.Second && bars.IsResetOnNewTradingDay && isNewSession)) { if (isNewSession && !isCalculateTradingDayDone) { SessionIterator.GetNextSession(tmpTime, isBar); } if (bars.Count > 0) { double lastOpen = bars.GetOpen(bars.Count - 1); double lastHigh = bars.GetHigh(bars.Count - 1); double lastLow = bars.GetLow(bars.Count - 1); double lastClose = bars.GetClose(bars.Count - 1); if (bars.Count == tmpCount) { CalculateKagiBar(bars, lastOpen, lastHigh, lastLow, lastClose, prevTime, volume); } } AddBar(bars, close, close, close, close, tmpTime, volume); anchorPrice = close; trend = Trend.Undetermined; prevTime = tmpTime; volumeCount = 0; bars.LastPrice = close; tmpCount = bars.Count; return; } double c = bars.GetClose(bars.Count - 1); double o = bars.GetOpen(bars.Count - 1); double h = bars.GetHigh(bars.Count - 1); double l = bars.GetLow(bars.Count - 1); if (endOfBar) { CalculateKagiBar(bars, o, h, l, c, prevTime, volume); } else { volumeCount += volume; } bars.LastPrice = close; tmpCount = bars.Count; #endregion }
protected override void OnDataPoint(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isBar, double bid, double ask) { if (SessionIterator == null) { SessionIterator = new SessionIterator(bars); } bool isNewSession = SessionIterator.IsNewSession(time, isBar); if (isNewSession) { SessionIterator.GetNextSession(time, isBar); } #region Building Bars from Base Period if (bars.Count != tmpCount) // Reset cache when bars are trimmed { if (bars.Count == 0) { tmpTime = Core.Globals.MinDate; tmpVolume = 0; tmpDayCount = 0; tmpTickCount = 0; } else { tmpTime = bars.GetTime(bars.Count - 1); tmpVolume = bars.GetVolume(bars.Count - 1); tmpTickCount = bars.TickCount; tmpDayCount = bars.DayCount; bars.LastPrice = anchorPrice = bars.GetClose(bars.Count - 1); } } switch (BarsPeriod.BaseBarsPeriodType) { case BarsPeriodType.Day: tmpTime = time.Date; if (!isBar) { tmpDayCount++; if (tmpTime < time.Date) { tmpTime = time.Date; // Make sure timestamps are ascending } } if (isBar && prevTimeD != tmpTime) { tmpDayCount++; } if (isBar && bars.Count > 0 && tmpTime == bars.LastBarTime.Date || !isBar && bars.Count > 0 && tmpTime <= bars.LastBarTime.Date || tmpDayCount < BarsPeriod.BaseBarsPeriodValue) { endOfBar = false; } else { prevTime = prevTimeD == Core.Globals.MinDate ? tmpTime : prevTimeD; prevTimeD = tmpTime; endOfBar = true; } break; case BarsPeriodType.Minute: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeMinute(bars, time, isBar); } if (isBar && time <= tmpTime || !isBar && time < tmpTime) { endOfBar = false; } else { prevTime = tmpTime; tmpTime = TimeToBarTimeMinute(bars, time, isBar); endOfBar = true; } break; case BarsPeriodType.Volume: if (tmpTime == Core.Globals.MinDate) { tmpVolume = volume; endOfBar = tmpVolume >= BarsPeriod.BaseBarsPeriodValue; prevTime = tmpTime = time; if (endOfBar) { tmpVolume = 0; } break; } tmpVolume += volume; endOfBar = tmpVolume >= BarsPeriod.BaseBarsPeriodValue; if (endOfBar) { prevTime = tmpTime; tmpVolume = 0; tmpTime = time; } break; case BarsPeriodType.Month: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeMonth(time, BarsPeriod.BaseBarsPeriodValue); } if (time.Month <= tmpTime.Month && time.Year == tmpTime.Year || time.Year < tmpTime.Year) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeMonth(time, BarsPeriod.BaseBarsPeriodValue); } break; case BarsPeriodType.Second: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeSecond(bars, time, isBar); } if (time <= tmpTime) { endOfBar = false; } else { prevTime = tmpTime; tmpTime = TimeToBarTimeSecond(bars, time, isBar); endOfBar = true; } break; case BarsPeriodType.Tick: if (tmpTime == Core.Globals.MinDate || BarsPeriod.BaseBarsPeriodValue == 1) { prevTime = tmpTime; if (prevTime == Core.Globals.MinDate) { prevTime = time; } tmpTime = time; endOfBar = BarsPeriod.BaseBarsPeriodValue == 1; break; } if (tmpTickCount < BarsPeriod.BaseBarsPeriodValue) { tmpTime = time; endOfBar = false; tmpTickCount++; } else { prevTime = tmpTime; tmpTime = time; endOfBar = true; tmpTickCount = 1; } break; case BarsPeriodType.Week: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, BarsPeriod.BaseBarsPeriodValue); } if (time.Date <= tmpTime.Date) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeWeek(time.Date, tmpTime.Date, BarsPeriod.BaseBarsPeriodValue); } break; case BarsPeriodType.Year: if (tmpTime == Core.Globals.MinDate) { prevTime = tmpTime = TimeToBarTimeYear(time, BarsPeriod.BaseBarsPeriodValue); } if (time.Year <= tmpTime.Year) { endOfBar = false; } else { prevTime = tmpTime; endOfBar = true; tmpTime = TimeToBarTimeYear(time, BarsPeriod.BaseBarsPeriodValue); } break; } #endregion #region P&F logic double tickSize = bars.Instrument.MasterInstrument.TickSize; boxSize = Math.Floor(10000000.0 * BarsPeriod.Value * tickSize) / 10000000.0; reversalSize = BarsPeriod.Value2 * boxSize; if (bars.Count == 0 || IsIntraday && bars.IsResetOnNewTradingDay && isNewSession) { if (bars.Count > 0) { double lastHigh = bars.GetHigh(bars.Count - 1); double lastLow = bars.GetLow(bars.Count - 1); double lastClose = bars.GetClose(bars.Count - 1); DateTime lastTime = bars.GetTime(bars.Count - 1); bars.LastPrice = anchorPrice = lastClose; if (bars.Count == tmpCount) { CalculatePfBar(bars, lastHigh, lastLow, lastClose, prevTime == Core.Globals.MinDate ? time : prevTime, lastTime); } } AddBar(bars, close, close, close, close, tmpTime, volume); anchorPrice = close; trend = Trend.Undetermined; prevTime = tmpTime; volumeCount = 0; bars.LastPrice = close; tmpCount = bars.Count; tmpHigh = high; tmpLow = low; return; } double c = bars.GetClose(bars.Count - 1); double h = bars.GetHigh(bars.Count - 1); double l = bars.GetLow(bars.Count - 1); DateTime t = bars.GetTime(bars.Count - 1); if (endOfBar) { CalculatePfBar(bars, h, l, c, prevTime, t); volumeCount = volume; tmpHigh = high; tmpLow = low; } else { tmpHigh = high > tmpHigh ? high : tmpHigh; tmpLow = low < tmpLow ? low : tmpLow; volumeCount += volume; } bars.LastPrice = close; tmpCount = bars.Count; #endregion }