Lean  $LEAN_TAG$
VolumeRenkoConsolidator.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
18 
20 {
21  /// <summary>
22  /// This consolidator can transform a stream of <see cref="BaseData"/> instances into a stream of <see cref="RenkoBar"/>
23  /// with a constant volume for each bar.
24  /// </summary>
25  public class VolumeRenkoConsolidator : DataConsolidator<BaseData>
26  {
27  private VolumeRenkoBar _currentBar;
28  private decimal _barSize;
29 
30  /// <summary>
31  /// Gets a clone of the data being currently consolidated
32  /// </summary>
33  public override IBaseData WorkingData => _currentBar;
34 
35  /// <summary>
36  /// Gets <see cref="VolumeRenkoBar"/> which is the type emitted in the <see cref="IDataConsolidator.DataConsolidated"/> event.
37  /// </summary>
38  public override Type OutputType => typeof(VolumeRenkoBar);
39 
40  /// <summary>
41  /// Event handler that fires when a new piece of data is produced
42  /// </summary>
43  public new event EventHandler<VolumeRenkoBar> DataConsolidated;
44 
45  /// <summary>
46  /// Initializes a new instance of the <see cref="VolumeRenkoConsolidator"/> class using the specified <paramref name="barSize"/>.
47  /// </summary>
48  /// <param name="barSize">The constant volume size of each bar</param>
49  public VolumeRenkoConsolidator(decimal barSize)
50  {
51  _barSize = barSize;
52  }
53 
54  /// <summary>
55  /// Updates this consolidator with the specified data
56  /// </summary>
57  /// <param name="data">The new data for the consolidator</param>
58  public override void Update(BaseData data)
59  {
60  var close = data.Price;
61  var dataType = data.GetType();
62 
63  decimal volume;
64  decimal open;
65  decimal high;
66  decimal low;
67 
68  if (dataType == typeof(TradeBar))
69  {
70  var tradeBar = (TradeBar)data;
71  volume = tradeBar.Volume;
72  open = tradeBar.Open;
73  high = tradeBar.High;
74  low = tradeBar.Low;
75  }
76  else if (dataType == typeof(Tick))
77  {
78  var tick = (Tick)data;
79  // Only include actual trade information
80  if (tick.TickType != TickType.Trade)
81  {
82  return;
83  }
84 
85  volume = tick.Quantity;
86  open = close;
87  high = close;
88  low = close;
89  }
90  else
91  {
92  throw new ArgumentException("VolumeRenkoConsolidator() must be used with TradeBar or Tick data.");
93  }
94 
95  if (_currentBar == null)
96  {
97  _currentBar = new VolumeRenkoBar(data.Symbol, data.Time, data.EndTime, _barSize, open, high, low, close, 0);
98  }
99  var volumeLeftOver = _currentBar.Update(data.EndTime, high, low, close, volume);
100  while (volumeLeftOver >= 0)
101  {
102  OnDataConsolidated(_currentBar);
103  _currentBar = _currentBar.Rollover();
104  volumeLeftOver = _currentBar.Update(data.EndTime, high, low, close, volumeLeftOver);
105  }
106  }
107 
108  /// <summary>
109  /// Scans this consolidator to see if it should emit a bar due to time passing
110  /// </summary>
111  /// <param name="currentLocalTime">The current time in the local time zone (same as <see cref="BaseData.Time"/>)</param>
112  public override void Scan(DateTime currentLocalTime)
113  {
114  }
115 
116  /// <summary>
117  /// Resets the consolidator
118  /// </summary>
119  public override void Reset()
120  {
121  base.Reset();
122  _currentBar = null;
123  }
124 
125  /// <summary>
126  /// Event invocator for the DataConsolidated event. This should be invoked
127  /// by derived classes when they have consolidated a new piece of data.
128  /// </summary>
129  /// <param name="consolidated">The newly consolidated data</param>
130  protected void OnDataConsolidated(VolumeRenkoBar consolidated)
131  {
132  base.OnDataConsolidated(consolidated);
133  DataConsolidated?.Invoke(this, consolidated);
134  }
135  }
136 }