-
-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Expand file tree
/
Copy pathConsolidateWithSizeAttributeRegressionAlgorithm.py
More file actions
98 lines (85 loc) · 5.24 KB
/
ConsolidateWithSizeAttributeRegressionAlgorithm.py
File metadata and controls
98 lines (85 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from AlgorithmImports import *
### <summary>
### This regression algorithm tests various overloads of the Consolidate method
### using RenkoBar, VolumeRenkoBar, and RangeBar types,
### as well as common bars like TradeBar and QuoteBar with a maxCount parameter.
### It ensures each overload behaves as expected and that the appropriate consolidator instances are correctly created and triggered.
### </summary>
class ConsolidateWithSizeAttributeRegressionAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2013, 10, 7)
self.set_end_date(2013, 10, 7)
self.set_cash(100000)
self.add_equity("SPY", Resolution.MINUTE)
self.sma_indicators = [
SimpleMovingAverage("RenkoBarSMA", 10),
SimpleMovingAverage("VolumeRenkoBarSMA", 10),
SimpleMovingAverage("RangeBarSMA", 10),
SimpleMovingAverage("TradeBarSMA", 10),
SimpleMovingAverage("QuoteBarSMA", 10),
SimpleMovingAverage("BaseDataSMA", 10)
]
self.consolidators = [
self.consolidate(RenkoBar, "SPY", 0.1, None, lambda bar: self.update_with_renko_bar(bar, 0)),
self.consolidate(VolumeRenkoBar, "SPY", 10000, None, lambda bar: self.update_with_volume_renko_bar(bar, 1)),
self.consolidate(RangeBar, "SPY", 12, None, lambda bar: self.update_with_range_bar(bar, 2)),
# Trade and Quote consolidators with max count
self.consolidate(TradeBar, "SPY", 10, None, lambda bar: self.update_with_trade_bar(bar, 3)),
self.consolidate(QuoteBar, "SPY", 10, None, lambda bar: self.update_with_quote_bar(bar, 4)),
self.consolidate(BaseData, "SPY", 10, None, lambda bar: self.update_with_base_data(bar, 5))
]
def update_with_base_data(self, base_data, position):
self.sma_indicators[position].update(base_data.end_time, base_data.value)
if type(base_data) != TradeBar:
raise AssertionError(f"The type of the bar should be Trade, but was {type(base_data)}")
def update_with_trade_bar(self, trade_bar, position):
self.sma_indicators[position].update(trade_bar.end_time, trade_bar.high)
if type(trade_bar) != TradeBar:
raise AssertionError(f"The type of the bar should be Trade, but was {type(trade_bar)}")
def update_with_quote_bar(self, quote_bar, position):
self.sma_indicators[position].update(quote_bar.end_time, quote_bar.high)
if type(quote_bar) != QuoteBar:
raise AssertionError(f"The type of the bar should be Quote, but was {type(quote_bar)}")
def update_with_renko_bar(self, renko_bar, position):
self.sma_indicators[position].update(renko_bar.end_time, renko_bar.high)
if type(renko_bar) != RenkoBar:
raise AssertionError(f"The type of the bar should be Renko, but was {type(renko_bar)}")
def update_with_volume_renko_bar(self, volume_renko_bar, position):
self.sma_indicators[position].update(volume_renko_bar.end_time, volume_renko_bar.high)
if type(volume_renko_bar) != VolumeRenkoBar:
raise AssertionError(f"The type of the bar should be VolumeRenko, but was {type(volume_renko_bar)}")
def update_with_range_bar(self, range_bar, position):
self.sma_indicators[position].update(range_bar.end_time, range_bar.high)
if type(range_bar) != RangeBar:
raise AssertionError(f"The type of the bar should be Range, but was {type(range_bar)}")
def on_end_of_algorithm(self):
# Verifies that each SMA was updated and is ready, confirming the Consolidate overloads functioned correctly.
for sma in self.sma_indicators:
if (sma.samples == 0):
raise AssertionError(f'The indicator {sma.name} did not receive any updates. This indicates the associated consolidator was not triggered.')
if (not sma.is_ready):
raise AssertionError(f'The indicator {sma.name} is not ready. It received only {sma.samples} samples, but requires at least {sma.period} to be ready.')
expected_consolidator_types = [
RenkoConsolidator,
VolumeRenkoConsolidator,
RangeConsolidator,
TradeBarConsolidator,
QuoteBarConsolidator,
BaseDataConsolidator
]
for i in range(len(self.consolidators)):
consolidator = self.consolidators[i]
if type(consolidator) != expected_consolidator_types[i]:
raise AssertionError(f"Expected consolidator type {expected_consolidator_types[i]} but received {type(consolidator)}")