/// <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, int volume, bool isRealtime) { if (bars.Count == 0) { AddBar(bars, open, high, low, close, time, volume); } else { UpdateBar(bars, open, high, low, close, time, volume); Data.Bar bar = (Bar)bars.Get(bars.Count - 1); double tall = 1 + ((bar.High - bar.Low) / bars.Instrument.MasterInstrument.TickSize); double denom = tall; if (tall > 10) { denom -= ((tall - 10) / 2.0); } if (tall > 20) { denom -= ((tall - 20) / 3.0); } if ((bar.Volume / denom) >= ((double)(bars.Period.Value))) { AddBar(bars, close, close, close, close, time, 0); } } }
public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { //### First Bar if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime)) { tickSize = bars.Instrument.MasterInstrument.TickSize; trendOffset = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize; reversalOffset = bars.Period.Value2 * bars.Instrument.MasterInstrument.TickSize; //bars.Period.BasePeriodValue = bars.Period.Value; //### Remove to customize OpenOffset openOffset = Math.Ceiling((double)bars.Period.BasePeriodValue * 1) * bars.Instrument.MasterInstrument.TickSize; barOpen = close; barMax = barOpen + (trendOffset * barDirection); barMin = barOpen - (trendOffset * barDirection); AddBar(bars, barOpen, barOpen, barOpen, barOpen, time, volume, isRealtime); } //### Subsequent Bars else { Data.Bar bar = (Bar)bars.Get(bars.Count - 1); maxExceeded = bars.Instrument.MasterInstrument.Compare(close, barMax) > 0 ? true : false; minExceeded = bars.Instrument.MasterInstrument.Compare(close, barMin) < 0 ? true : false; //### Defined Range Exceeded? if (maxExceeded || minExceeded) { double thisClose = maxExceeded ? Math.Min(close, barMax) : minExceeded?Math.Max(close, barMin) : close; barDirection = maxExceeded ? 1 : minExceeded ? -1 : 0; fakeOpen = thisClose - (openOffset * barDirection); //### Fake Open is halfway down the bar //### Close Current Bar UpdateBar(bars, bar.Open, (maxExceeded ? thisClose : bar.High), (minExceeded ? thisClose : bar.Low), thisClose, time, volume, isRealtime); //### Add New Bar barOpen = close; barMax = thisClose + ((barDirection > 0 ? trendOffset : reversalOffset)); barMin = thisClose - ((barDirection > 0 ? reversalOffset : trendOffset)); AddBar(bars, fakeOpen, (maxExceeded ? thisClose : fakeOpen), (minExceeded ? thisClose : fakeOpen), thisClose, time, volume, isRealtime); } //### Current Bar Still Developing else { UpdateBar(bars, bar.Open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime); } } bars.LastPrice = close; }
/// <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(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { if ((curdat == null) || (time < curdat.dt)) { extdat.Clear(); extdat.TrimExcess(); curdat = null; tickSize = bars.Instrument.MasterInstrument.TickSize; } if (bars.Count == 0) { AddBar(bars, open, high, low, close, time, volume, isRealtime); RWTAddExtDat(time, close, volume); } else { Data.Bar bar = (Bar)bars.Get(bars.Count - 1); if (curdat == null) { RWTAddExtDat(time, close, 0); } curdat.dt = time; if (upbar && ((curdat.dHigh - curdat.dClose) >= bars.Period.Value)) { AddBar(bars, close, close, close, close, time, volume, isRealtime); RWTAddExtDat(time, close, volume); upbar = false; } else if (!upbar && ((curdat.dClose - curdat.dLow) >= bars.Period.Value)) { AddBar(bars, close, close, close, close, time, volume, isRealtime); RWTAddExtDat(time, close, volume); upbar = true; } else { UpdateBar(bars, open, high, low, close, time, volume, isRealtime); // regular update... RWTUpdateCounts(close); RWTUpdateCurdat(close, volume); } } bars.LastPrice = close; // update the extended data... prevClose = close; }
public override void Add(Data.Bars bars, double open, double high, double low, double close, DateTime time, int volume, bool isRealtime) #endif { double brickSize = bars.Instrument.MasterInstrument.Round2TickSize(bars.Period.Value * bars.Instrument.MasterInstrument.TickSize); // #ticks per brick * tickSize // starting new bar at session boundary makes sure you have the same bars // reguadless of the first date that is loaded in the chart, feel free to remove #if NT7 if ((bars.Count == 0) || bars.IsNewSession(time)) #else if (bars.Count == 0) #endif { #if NT7 AddBar(bars, close, close, close, close, time, volume, isRealtime); #else AddBar(bars, close, close, close, close, time, volume); #endif barState = State.BarAccumulating; double mod = bars.Instrument.MasterInstrument.Round2TickSize(close % brickSize); double mid = bars.Instrument.MasterInstrument.Compare(mod, brickSize) == 0 ? close : close - mod; renkoHigh = mid + brickSize; renkoLow = mid - brickSize; } else { if (barState == State.BarComplete) { // this tick creates a new bar #if NT7 AddBar(bars, close, close, close, close, time, volume, isRealtime); #else AddBar(bars, close, close, close, close, time, volume); #endif if (RangeExceeded(bars, close)) { MoveLimits(bars, close, brickSize); } } else { if (RangeExceeded(bars, close)) { #if NT7 AddBar(bars, close, close, close, close, time, volume, isRealtime); #else AddBar(bars, close, close, close, close, time, volume); #endif MoveLimits(bars, close, brickSize); } else { Data.Bar bar = (Bar)bars.Get(bars.Count - 1); #if NT7 UpdateBar(bars, bar.Open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime); #else UpdateBar(bars, bar.Open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume); #endif } } CheckBarComplete(bars, close, brickSize); } #if NT7 bars.LastPrice = close; #endif }
/// <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) { if ((curdat == null) || (time < curdat.dt)) { extdat.Clear(); extdat.TrimExcess(); curdat = null; tickSize = bars.Instrument.MasterInstrument.TickSize; } if (bars.Count == 0 || bars.IsNewSession(time, isRealtime)) { AddBar(bars, open, high, low, close, time, volume, isRealtime); lastBarTime = time; RWTAddExtDat(time, close, volume); } 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 (curdat == null) { RWTAddExtDat(time, close, 0); } curdat.dt = time; if ((bars.Instrument.MasterInstrument.Compare(close, bar.Low + rangeValue) > 0) && (lastBarUP || ((time.Ticks - lastBarTime.Ticks) > 10000000L))) { bool isFirstNewBar = true; double newClose = bar.Low + rangeValue; // every bar closes either with high or low UpdateBar(bars, bar.Open, newClose, bar.Low, newClose, time, 0, isRealtime); curdat.addLevel(1); // if still gap, fill with phantom bars double newBarOpen = newClose + tickSize; while (bars.Instrument.MasterInstrument.Compare(close, newClose) > 0) { newClose = Math.Min(close, newBarOpen + rangeValue); AddBar(bars, newBarOpen, newClose, newBarOpen, newClose, time, isFirstNewBar ? volume : 1, isRealtime); RWTAddExtDat(time, newClose, (isFirstNewBar?volume:0)); newBarOpen = newClose + tickSize; isFirstNewBar = false; } prices[1] = newClose; lastMoveUp = true; lastBarUP = true; lastBarTime = time; } else if ((bars.Instrument.MasterInstrument.Compare(bar.High - rangeValue, close) > 0) && ((!lastBarUP) || ((time.Ticks - lastBarTime.Ticks) > 10000000L))) { bool isFirstNewBar = true; double newClose = bar.High - rangeValue; // every bar closes either with high or low UpdateBar(bars, bar.Open, bar.High, newClose, newClose, time, 0, isRealtime); curdat.addLevel(-1); // if still gap, fill with phantom bars double newBarOpen = newClose - tickSize; while (bars.Instrument.MasterInstrument.Compare(newClose, close) > 0) { newClose = Math.Max(close, newBarOpen - rangeValue); AddBar(bars, newBarOpen, newBarOpen, newClose, newClose, time, isFirstNewBar ? volume : 1, isRealtime); RWTAddExtDat(time, newClose, (isFirstNewBar?volume:0)); newBarOpen = newClose - tickSize; isFirstNewBar = false; } prices[0] = newClose; lastMoveUp = false; lastBarUP = false; lastBarTime = time; } else { UpdateBar(bars, open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime); RWTUpdateCounts(close); RWTUpdateCurdat(close, volume); } } bars.LastPrice = close; // update the extended data... prevClose = close; }
/// <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) { if ((curdat == null) || (time < curdat.dt)) { extdat.Clear(); extdat.TrimExcess(); curdat = null; tickSize = bars.Instrument.MasterInstrument.TickSize; if (bars.Period.Value > 100) { tlb = true; period = bars.Period.Value - 100; } else { tlb = false; period = bars.Period.Value; } } if (bars.Count == 0 || bars.IsNewSession(time, isRealtime)) { AddBar(bars, open, high, low, close, time, volume, isRealtime); lastBarTime = time; RWTAddExtDat(time, close, volume); } else { Data.Bar bar = (Bar)bars.Get(bars.Count - 1); double rangeValue = Math.Floor(10000000.0 * period * tickSize) / 10000000.0; if (curdat == null) { RWTAddExtDat(time, close, 0); } curdat.dt = time; double reverseRange = rangeValue * (tlb?3.0:1.0); if ((bars.Instrument.MasterInstrument.Compare(close, bar.Open + (lastBarUP?rangeValue:reverseRange)) > 0) && (lastBarUP || ((time.Ticks - lastBarTime.Ticks) > 10000000L))) { bool isFirstNewBar = true; double newBarOpen = bar.Open + (lastBarUP?rangeValue:reverseRange); double newClose = Math.Min(close, newBarOpen + rangeValue); UpdateBar(bars, bar.Open, newBarOpen, bar.Low, newBarOpen, time, 0, isRealtime); curdat.addLevel(1); do { AddBar(bars, newBarOpen, newClose, newBarOpen, newClose, time, isFirstNewBar ? volume : 0, isRealtime); RWTAddExtDat(time, newClose, (isFirstNewBar ? volume : 0)); if (bars.Instrument.MasterInstrument.Compare(close, newClose) == 0) { break; } newBarOpen = newClose; newClose = Math.Min(close, newBarOpen + rangeValue); isFirstNewBar = false; }while (true); prices[1] = newClose; lastMoveUp = true; lastBarUP = true; lastBarTime = time; } else if ((bars.Instrument.MasterInstrument.Compare(bar.Open - (lastBarUP?reverseRange:rangeValue), close) > 0) && ((!lastBarUP) || ((time.Ticks - lastBarTime.Ticks) > 10000000L))) { bool isFirstNewBar = true; double newBarOpen = bar.Open - (lastBarUP?reverseRange:rangeValue); double newClose = Math.Max(close, newBarOpen - rangeValue); UpdateBar(bars, bar.Open, bar.High, newBarOpen, newBarOpen, time, 0, isRealtime); curdat.addLevel(-1); do { AddBar(bars, newBarOpen, newBarOpen, newClose, newClose, time, isFirstNewBar ? volume : 0, isRealtime); RWTAddExtDat(time, newClose, (isFirstNewBar ? volume : 0)); if (bars.Instrument.MasterInstrument.Compare(close, newClose) == 0) { break; } newBarOpen = newClose; newClose = Math.Max(close, newBarOpen - rangeValue); isFirstNewBar = false; }while (true); prices[0] = newClose; lastMoveUp = false; lastBarUP = false; lastBarTime = time; } else { UpdateBar(bars, bar.Open, Math.Max(bar.High, close), Math.Min(bar.Low, close), close, time, volume, isRealtime); RWTUpdateCounts(close); RWTUpdateCurdat(close, volume); } } bars.LastPrice = close; // update the extended data... prevClose = close; }
/// <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) { if (tickSize == 0) { tickSize = bars.Instrument.MasterInstrument.TickSize; if (bars.Period.Value > 100) { tlb = true; period = bars.Period.Value - 100; } else { tlb = false; period = bars.Period.Value; } } if (bars.Count == 0 || bars.IsNewSession(time, isRealtime)) { AddBar(bars, open, high, low, close, time, volume, isRealtime); lastBarTime = time; } else { Data.Bar bar = (Bar)bars.Get(bars.Count - 1); double rangeValue = Math.Floor(10000000.0 * period * tickSize) / 10000000.0; double reverseRange = rangeValue * (tlb?3.0:1.0); if ((bars.Instrument.MasterInstrument.Compare(close, bar.Open + (lastBarUP?rangeValue:reverseRange)) > 0) && (lastBarUP || ((time.Ticks - lastBarTime.Ticks) > 10000000L))) { bool isFirstNewBar = true; double newBarOpen = bar.Open + (lastBarUP?rangeValue:reverseRange); double newClose = Math.Min(close, newBarOpen + rangeValue); UpdateBar(bars, bar.Open, newBarOpen, bar.Low, newBarOpen, time, 0, isRealtime); do { AddBar(bars, newBarOpen, newClose, newBarOpen, newClose, time, isFirstNewBar ? volume : 0, isRealtime); if (bars.Instrument.MasterInstrument.Compare(close, newClose) == 0) { break; } newBarOpen = newClose; newClose = Math.Min(close, newBarOpen + rangeValue); isFirstNewBar = false; }while (true); lastBarUP = true; lastBarTime = time; } else if ((bars.Instrument.MasterInstrument.Compare(bar.Open - (lastBarUP?reverseRange:rangeValue), close) > 0) && ((!lastBarUP) || ((time.Ticks - lastBarTime.Ticks) > 10000000L))) { bool isFirstNewBar = true; double newBarOpen = bar.Open - (lastBarUP?reverseRange:rangeValue); double newClose = Math.Max(close, newBarOpen - rangeValue); UpdateBar(bars, bar.Open, bar.High, newBarOpen, newBarOpen, time, 0, isRealtime); do { AddBar(bars, newBarOpen, newBarOpen, newClose, newClose, time, isFirstNewBar ? volume : 0, isRealtime); if (bars.Instrument.MasterInstrument.Compare(close, newClose) == 0) { break; } newBarOpen = newClose; newClose = Math.Max(close, newBarOpen - rangeValue); isFirstNewBar = false; }while (true); lastBarUP = false; lastBarTime = time; } else { UpdateBar(bars, bar.Open, Math.Max(bar.High, close), Math.Min(bar.Low, close), close, time, volume, isRealtime); } } bars.LastPrice = close; }
public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { // ******************* ADDED FROM RENKO CODE TO SOLVE MEMORY LEAK **************************** // brick size is the trendOffset (Value) + openOffset (BasePeriodValue) offset = (bars.Period.Value + bars.Period.BasePeriodValue) * bars.Instrument.MasterInstrument.TickSize; if (bars.Count < tmpCount && bars.Count > 0) // reset cache when bars are trimmed { barMax = bars.GetClose(bars.Count - 1) + offset; barMin = bars.GetClose(bars.Count - 1) - offset; } // ******************************************************************************************** //### First Bar if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime)) { tickSize = bars.Instrument.MasterInstrument.TickSize; //### Parse Long Param Specification if (bars.Period.Value >= 1000000) { int d; string str = bars.Period.Value.ToString("000000000"); d = 0; Int32.TryParse(str.Substring(0, 3), out d); bars.Period.Value = d; d = 0; Int32.TryParse(str.Substring(3, 3), out d); bars.Period.Value2 = d; d = 0; Int32.TryParse(str.Substring(6, 3), out d); bars.Period.BasePeriodValue = d; } //****** ADDED FROM RENKO ***************************************************************** if (bars.Count != 0) { // close out last bar in session and set open == close Bar lastBar = (Bar)bars.Get(bars.Count - 1); bars.RemoveLastBar(); // Note: bar is now just a local var and not in series! AddBar(bars, lastBar.Close, lastBar.High, lastBar.Low, lastBar.Close, lastBar.Time, lastBar.Volume, isRealtime); } //**************************************************************************************** trendOffset = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize; reversalOffset = bars.Period.Value2 * bars.Instrument.MasterInstrument.TickSize; //bars.Period.BasePeriodValue = bars.Period.Value; //### Remove to customize OpenOffset openOffset = Math.Ceiling((double)bars.Period.BasePeriodValue * 1) * bars.Instrument.MasterInstrument.TickSize; barOpen = close; barMax = barOpen + (trendOffset * barDirection); barMin = barOpen - (trendOffset * barDirection); AddBar(bars, barOpen, barOpen, barOpen, barOpen, time, volume, isRealtime); } //### Subsequent Bars else { Data.Bar bar = (Bar)bars.Get(bars.Count - 1); // *************ADDED FROM RENKO CODE (to deal with '0' values at Market Replay) ************ if (barMax == 0 || barMin == 0) //Not sure why, but happens { // trendOffset was also '0', so need to reinitialize trendOffset = bars.Period.Value * bars.Instrument.MasterInstrument.TickSize; reversalOffset = bars.Period.Value2 * bars.Instrument.MasterInstrument.TickSize; openOffset = Math.Ceiling((double)bars.Period.BasePeriodValue * 1) * bars.Instrument.MasterInstrument.TickSize; if (bars.Count == 1) { barMax = bar.Open + trendOffset; barMin = bar.Open - trendOffset; } else if (bars.GetClose(bars.Count - 2) > bars.GetOpen(bars.Count - 2)) { barMax = bars.GetClose(bars.Count - 2) + trendOffset; barMin = bars.GetClose(bars.Count - 2) - trendOffset * 2; } else { barMax = bars.GetClose(bars.Count - 2) + trendOffset * 2; barMin = bars.GetClose(bars.Count - 2) - trendOffset; } } // ************************************************************************************************ maxExceeded = bars.Instrument.MasterInstrument.Compare(close, barMax) > 0 ? true : false; minExceeded = bars.Instrument.MasterInstrument.Compare(close, barMin) < 0 ? true : false; //### Defined Range Exceeded? if (maxExceeded || minExceeded) { double thisClose = maxExceeded ? Math.Min(close, barMax) : minExceeded?Math.Max(close, barMin) : close; // thisClose is the minimum of BarMax and close (maxExceeded) barDirection = maxExceeded ? 1 : minExceeded ? -1 : 0; fakeOpen = thisClose - (openOffset * barDirection); //### Fake Open is halfway down the bar //### Close Current Bar UpdateBar(bars, bar.Open, (maxExceeded ? thisClose : bar.High), (minExceeded ? thisClose : bar.Low), thisClose, time, volume, isRealtime); //### Add New Bar barOpen = close; barMax = thisClose + ((barDirection > 0 ? trendOffset : reversalOffset)); barMin = thisClose - ((barDirection > 0 ? reversalOffset : trendOffset)); AddBar(bars, fakeOpen, (maxExceeded ? thisClose : fakeOpen), (minExceeded ? thisClose : fakeOpen), thisClose, time, volume, isRealtime); } //### Current Bar Still Developing else { UpdateBar(bars, bar.Open, (close > bar.High ? close : bar.High), (close < bar.Low ? close : bar.Low), close, time, volume, isRealtime); } } bars.LastPrice = close; tmpCount = bars.Count; // ADDED FROM RENKO CODE }
/// <summary> /// add new tick data to bars /// </summary> public override void Add(Bars bars, double open, double high, double low, double close, DateTime time, long volume, bool isRealtime) { // create initial bar on first tick and handle NT7 session-break issue (note: removing IsNewSession() creates invalid bars; remove if preferred) if ((bars.Count == 0) || bars.IsNewSession(time, isRealtime)) { // update fields tickSize = bars.Instrument.MasterInstrument.TickSize; rangeMax = AddTwoDoubles(bars, (double)Period.Value * tickSize, 0); rangeMin = AddTwoDoubles(bars, (double)Period.BasePeriodValue * tickSize, 0); /// swap min/max if entered incorrectly if (rangeMin > rangeMax) { double tmp = rangeMax; rangeMax = rangeMin; rangeMin = tmp; } // set initial range, factoring dynamic thisRange = isDynamic ? rangeMin : rangeMax; AdjustMaxMin(bars, close, close); // add first bar AddBar(bars, thisOpen, thisOpen, thisOpen, thisOpen, time, volume, isRealtime); } // continue all subsequent ticks/bars else { // local variables Data.Bar thisBar = (Bar)bars.Get(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 > thisBar.Open ? 1 : close < thisBar.Open ? -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, thisBar.Open, (maxCompare > 0 ? thisClose : thisBar.High), (minCompare < 0 ? thisClose : thisBar.Low), thisClose, time, 0, isRealtime); // 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), isRealtime); newBar = false; // update fields maxCompare = bars.Instrument.MasterInstrument.Compare(close, thisMax); minCompare = bars.Instrument.MasterInstrument.Compare(close, thisMin); }while (maxCompare > 0 || minCompare < 0); } // range not exceeded; continue current bar else { // update current bar UpdateBar(bars, thisBar.Open, (close > thisBar.High ? close : thisBar.High), (close < thisBar.Low ? close : thisBar.Low), close, time, volume, isRealtime); } } // update last price bars.LastPrice = close; }