public void ConsolidatesOnBrickLow() { RenkoBar bar = null; var consolidator = new RenkoConsolidator(10, x => x.Value, x => 0); consolidator.DataConsolidated += (sender, consolidated) => { bar = consolidated; }; var reference = DateTime.Today; consolidator.Update(new IndicatorDataPoint(reference, 10m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddHours(1), 2m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddHours(2), 0m)); Assert.IsNotNull(bar); Assert.AreEqual(10m, bar.Open); Assert.AreEqual(0m, bar.Close); Assert.IsTrue(bar.IsClosed); }
/// <summary> /// Updates this consolidator with the specified data /// </summary> /// <param name="data">The new data for the consolidator</param> public void Update(IBaseData data) { var currentValue = _selector(data); var volume = _volumeSelector(data); decimal?close = null; // if we're already in a bar then update it if (_currentBar != null) { _currentBar.Update(data.Time, currentValue, volume); // if the update caused this bar to close, fire the event and reset the bar if (_currentBar.IsClosed) { close = _currentBar.Close; OnDataConsolidated(_currentBar); _currentBar = null; } } if (_currentBar == null) { var open = close ?? currentValue; if (_evenBars && !close.HasValue) { open = Math.Ceiling(open / _barSize) * _barSize; } _currentBar = new RenkoBar(data.Symbol, data.Time, _barSize, open, volume); } }
/// <summary> /// Event invocator for the DataConsolidated event. This should be invoked /// by derived classes when they have consolidated a new piece of data. /// </summary> /// <param name="consolidated">The newly consolidated data</param> protected void OnDataConsolidated(RenkoBar consolidated) { DataConsolidated?.Invoke(this, consolidated); _currentBar = consolidated; _dataConsolidatedHandler?.Invoke(this, consolidated); Consolidated = consolidated; }
public override void Update(IBaseData data) { var currentValue = _selector(data); var volume = _volumeSelector(data); decimal?close = null; if (_currentBar != null) { _currentBar.Update(data.Time, currentValue, volume); if (_currentBar.IsClosed) { close = _currentBar.Close; OnDataConsolidated(_currentBar); _currentBar = null; } } if (_currentBar == null) { var open = close ?? currentValue; if (_evenBars && !close.HasValue) { open = Math.Ceiling(open / _barSize) * _barSize; } _currentBar = new RenkoBar(data.Symbol, data.Time, _barSize, open, volume); } }
/// <summary> /// This function is called by our renkoClose consolidator defined in Initialize() /// </summary> /// <param name="data">The new renko bar produced by the consolidator</param> public void HandleRenkoClose(RenkoBar data) { if (!Portfolio.Invested) { SetHoldings(data.Symbol, 1.0); } Console.WriteLine("CLOSE - {0} - {1} {2}", data.Time.ToString("o"), data.Open, data.Close); }
/// <summary> /// This function is called by our renko7bar onsolidator defined in Initialize() /// </summary> /// <param name="data">The new renko bar produced by the consolidator</param> public void HandleRenko7Bar(RenkoBar data) { if (Portfolio.Invested) { Liquidate(data.Symbol); } Log($"7BAR - {data.Time.ToString("o")} - {data.Open} {data.Close}"); }
/// <summary> /// Event invocator for the DataConsolidated event. This should be invoked /// by derived classes when they have consolidated a new piece of data. /// </summary> /// <param name="consolidated">The newly consolidated data</param> protected virtual void OnDataConsolidated(RenkoBar consolidated) { DataConsolidated?.Invoke(this, consolidated); _dataConsolidatedHandler?.Invoke(this, consolidated); Consolidated = consolidated; }
/// <summary> /// This function is called by our renko7bar onsolidator defined in Initialize() /// </summary> /// <param name="data">The new renko bar produced by the consolidator</param> public void HandleRenko7Bar(RenkoBar data) { if (Portfolio.Invested) { Liquidate(data.Symbol); } Log($"7BAR - {data.Time.ToIso8601Invariant()} - {data.Open} {data.Close}"); }
/// <summary> /// Event invocator for the DataConsolidated event. This should be invoked /// by derived classes when they have consolidated a new piece of data. /// </summary> /// <param name="consolidated">The newly consolidated data</param> private void OnDataConsolidated(RenkoBar consolidated) { DataConsolidated?.Invoke(this, consolidated); _dataConsolidatedHandler?.Invoke(this, consolidated); Consolidated = consolidated; }
/// <summary> /// This function is called by our renkoClose consolidator defined in Initialize() /// </summary> /// <param name="data">The new renko bar produced by the consolidator</param> public void HandleRenkoClose(RenkoBar data) { if (!Portfolio.Invested) { SetHoldings(data.Symbol, 1.0); } Log($"CLOSE - {data.Time.ToIso8601Invariant()} - {data.Open} {data.Close}"); }
protected virtual void OnDataConsolidated(RenkoBar consolidated) { var handler = DataConsolidated; if (handler != null) { handler(this, consolidated); } base.OnDataConsolidated(consolidated); }
private void Falling(IBaseData data) { decimal limit; while (_closeRate < (limit = _openRate - _barSize)) { var wicko = new RenkoBar(data.Symbol, _openOn, _closeOn, _barSize, _openRate, _highRate, limit, limit); _lastWicko = wicko; OnDataConsolidated(wicko); _openOn = _closeOn; _openRate = limit; _highRate = limit; } }
private void Falling(IBaseData data) { decimal limit; while (CloseRate < (limit = OpenRate - BarSize)) { var wicko = new RenkoBar(data.Symbol, OpenOn, CloseOn, BarSize, OpenRate, HighRate, limit, limit); _lastWicko = wicko; OnDataConsolidated(wicko); OpenOn = CloseOn; OpenRate = limit; HighRate = limit; } }
private void Rising(IBaseData data) { decimal limit; while (_closeRate > (limit = (_openRate + BarSize))) { var wicko = new RenkoBar(data.Symbol, _openOn, _closeOn, BarSize, _openRate, limit, _lowRate, limit); _lastWicko = wicko; OnDataConsolidated(wicko); _openOn = _closeOn; _openRate = limit; _lowRate = limit; } }
/// <summary> /// Event invocator for the DataConsolidated event. This should be invoked /// by derived classes when they have consolidated a new piece of data. /// </summary> /// <param name="consolidated">The newly consolidated data</param> protected virtual void OnDataConsolidated(RenkoBar consolidated) { var handler = DataConsolidated; if (handler != null) { handler(this, consolidated); } var explicitHandler = _dataConsolidatedHandler; if (explicitHandler != null) { explicitHandler(this, consolidated); } Consolidated = consolidated; }
/// <summary> /// This function is called by our renko7bar onsolidator defined in Initialize() /// </summary> /// <param name="data">The new renko bar produced by the consolidator</param> public void HandleRenko7Bar(RenkoBar data) { Console.WriteLine("7BAR - {0} - {1} {2}", data.Time.ToString("o"), data.Open, data.Close); }
/// <summary> /// Updates this consolidator with the specified data /// </summary> /// <param name="data">The new data for the consolidator</param> public void Update(IBaseData data) { var rate = data.Price; if (_firstTick) { _firstTick = false; OpenOn = data.Time; CloseOn = data.Time; OpenRate = rate; HighRate = rate; LowRate = rate; CloseRate = rate; } else { CloseOn = data.Time; if (rate > HighRate) { HighRate = rate; } if (rate < LowRate) { LowRate = rate; } CloseRate = rate; if (CloseRate > OpenRate) { if (_lastWicko == null || _lastWicko.Direction == BarDirection.Rising) { Rising(data); return; } var limit = _lastWicko.Open + BarSize; if (CloseRate > limit) { var wicko = new RenkoBar(data.Symbol, OpenOn, CloseOn, BarSize, _lastWicko.Open, limit, LowRate, limit); _lastWicko = wicko; OnDataConsolidated(wicko); OpenOn = CloseOn; OpenRate = limit; LowRate = limit; Rising(data); } } else if (CloseRate < OpenRate) { if (_lastWicko == null || _lastWicko.Direction == BarDirection.Falling) { Falling(data); return; } var limit = _lastWicko.Open - BarSize; if (CloseRate < limit) { var wicko = new RenkoBar(data.Symbol, OpenOn, CloseOn, BarSize, _lastWicko.Open, HighRate, limit, limit); _lastWicko = wicko; OnDataConsolidated(wicko); OpenOn = CloseOn; OpenRate = limit; HighRate = limit; Falling(data); } } } }
/// <summary> /// Updates this consolidator with the specified data /// </summary> /// <param name="data">The new data for the consolidator</param> public void Update(IBaseData data) { var rate = data.Price; if (_firstTick) { _firstTick = false; // Round our first rate to the same length as BarSize var decimalPlaces = BitConverter.GetBytes(decimal.GetBits(BarSize)[3])[2]; rate = Math.Round(rate, decimalPlaces); OpenOn = data.Time; CloseOn = data.Time; OpenRate = rate; HighRate = rate; LowRate = rate; CloseRate = rate; } else { CloseOn = data.Time; if (rate > HighRate) { HighRate = rate; } if (rate < LowRate) { LowRate = rate; } CloseRate = rate; if (CloseRate > OpenRate) { if (_lastWicko == null || _lastWicko.Direction == BarDirection.Rising) { Rising(data); return; } var limit = _lastWicko.Open + BarSize; if (CloseRate > limit) { var wicko = new RenkoBar(data.Symbol, OpenOn, CloseOn, BarSize, _lastWicko.Open, limit, LowRate, limit); _lastWicko = wicko; OnDataConsolidated(wicko); OpenOn = CloseOn; OpenRate = limit; LowRate = limit; Rising(data); } } else if (CloseRate < OpenRate) { if (_lastWicko == null || _lastWicko.Direction == BarDirection.Falling) { Falling(data); return; } var limit = _lastWicko.Open - BarSize; if (CloseRate < limit) { var wicko = new RenkoBar(data.Symbol, OpenOn, CloseOn, BarSize, _lastWicko.Open, HighRate, limit, limit); _lastWicko = wicko; OnDataConsolidated(wicko); OpenOn = CloseOn; OpenRate = limit; HighRate = limit; Falling(data); } } } }
private void UpdateWicked(IBaseData data) { var rate = data.Price; if (_firstTick) { _firstTick = false; _openOn = data.Time; _closeOn = data.Time; _openRate = rate; _highRate = rate; _lowRate = rate; _closeRate = rate; } else { _closeOn = data.Time; if (rate > _highRate) { _highRate = rate; } if (rate < _lowRate) { _lowRate = rate; } _closeRate = rate; if (_closeRate > _openRate) { if (_lastWicko == null || _lastWicko.Direction == BarDirection.Rising) { Rising(data); return; } var limit = _lastWicko.Open + _barSize; if (_closeRate > limit) { var wicko = new RenkoBar(data.Symbol, _openOn, _closeOn, _barSize, _lastWicko.Open, limit, _lowRate, limit); _lastWicko = wicko; OnDataConsolidated(wicko); _openOn = _closeOn; _openRate = limit; _lowRate = limit; Rising(data); } } else if (_closeRate < _openRate) { if (_lastWicko == null || _lastWicko.Direction == BarDirection.Falling) { Falling(data); return; } var limit = _lastWicko.Open - _barSize; if (_closeRate < limit) { var wicko = new RenkoBar(data.Symbol, _openOn, _closeOn, _barSize, _lastWicko.Open, _highRate, limit, limit); _lastWicko = wicko; OnDataConsolidated(wicko); _openOn = _closeOn; _openRate = limit; _highRate = limit; Falling(data); } } } }
public void CyclesUpAndDown() { RenkoBar bar = null; int count = 0; int rcount = 0; var consolidator = new RenkoConsolidator(1m, x => x.Value, x => 0); consolidator.DataConsolidated += (sender, consolidated) => { rcount++; bar = consolidated; }; var reference = DateTime.Today; // opens at 0 consolidator.Update(new IndicatorDataPoint(reference, 0)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(1), .5m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(2), 1m)); Assert.IsNotNull(bar); Assert.AreEqual(0m, bar.Open); Assert.AreEqual(1m, bar.Close); Assert.AreEqual(0, bar.Volume); Assert.AreEqual(1m, bar.High); Assert.AreEqual(0m, bar.Low); Assert.IsTrue(bar.IsClosed); Assert.AreEqual(reference, bar.Start); Assert.AreEqual(reference.AddSeconds(2), bar.EndTime); bar = null; consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(3), 1.5m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(4), 1m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(5), .5m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(6), 0m)); Assert.IsNotNull(bar); // ReSharper disable HeuristicUnreachableCode - ReSharper doesn't realiz this can be set via the event handler Assert.AreEqual(1m, bar.Open); Assert.AreEqual(0m, bar.Close); Assert.AreEqual(0, bar.Volume); Assert.AreEqual(1.5m, bar.High); Assert.AreEqual(0m, bar.Low); Assert.IsTrue(bar.IsClosed); Assert.AreEqual(reference.AddSeconds(2), bar.Start); Assert.AreEqual(reference.AddSeconds(6), bar.EndTime); bar = null; consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(7), -0.5m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(8), -0.9999999m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(9), -0.01m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(10), 0.25m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(9), 0.75m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(10), 0.9999999m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(10), 0.25m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(9), -0.25m)); Assert.IsNull(bar); consolidator.Update(new IndicatorDataPoint(reference.AddSeconds(10), -1m)); Assert.IsNotNull(bar); Assert.AreEqual(0m, bar.Open); Assert.AreEqual(-1m, bar.Close); Assert.AreEqual(0, bar.Volume); Assert.AreEqual(0.9999999m, bar.High); Assert.AreEqual(-1m, bar.Low); Assert.IsTrue(bar.IsClosed); Assert.AreEqual(reference.AddSeconds(6), bar.Start); Assert.AreEqual(reference.AddSeconds(10), bar.EndTime); // ReSharper restore HeuristicUnreachableCode }