Refactor some unit and regression tests for speed improvements (#8970)
API Tests / build (push) Has been cancelled
Benchmarks / build (push) Has been cancelled
Build & Test Lean / build (push) Has been cancelled
Regression Tests / build (push) Has been cancelled
Report Generator Tests / build (push) Has been cancelled
Research Regression Tests / build (push) Has been cancelled
Syntax Tests / build (push) Has been cancelled
Python Virtual Environments / build (push) Has been cancelled
API Tests / build (push) Has been cancelled
Benchmarks / build (push) Has been cancelled
Build & Test Lean / build (push) Has been cancelled
Regression Tests / build (push) Has been cancelled
Report Generator Tests / build (push) Has been cancelled
Research Regression Tests / build (push) Has been cancelled
Syntax Tests / build (push) Has been cancelled
Python Virtual Environments / build (push) Has been cancelled
* Reduce history unit tests duration * Unit and regression tests speed improvements * Minor change * Fix unit test race condition
This commit is contained in:
@@ -33,10 +33,12 @@ class ConsolidateDifferentTickTypesRegressionAlgorithm(QCAlgorithm):
|
||||
# Tick consolidators with max count
|
||||
self.consolidate(TradeBar, equity.symbol, 10, TickType.TRADE, lambda trade_bar: self.on_trade_tick_max_count(trade_bar))
|
||||
self._there_is_at_least_one_trade_bar = False
|
||||
|
||||
|
||||
self.consolidate(QuoteBar, equity.symbol, 10, TickType.QUOTE, lambda quote_bar: self.on_quote_tick_max_count(quote_bar))
|
||||
self._there_is_at_least_one_quote_bar = False
|
||||
|
||||
|
||||
self._consolidation_count = 0
|
||||
|
||||
def on_trade_tick_max_count(self, trade_bar):
|
||||
self._there_is_at_least_one_trade_bar = True
|
||||
if type(trade_bar) != TradeBar:
|
||||
@@ -47,6 +49,11 @@ class ConsolidateDifferentTickTypesRegressionAlgorithm(QCAlgorithm):
|
||||
if type(quote_bar) != QuoteBar:
|
||||
raise AssertionError(f"The type of the bar should be Quote, but was {type(quote_bar)}")
|
||||
|
||||
self._consolidation_count += 1
|
||||
# Let's shortcut to reduce regression test duration: algorithms using tick data are too long
|
||||
if self._consolidation_count >= 1000:
|
||||
self.quit()
|
||||
|
||||
def on_quote_tick(self, tick):
|
||||
self.there_is_at_least_one_quote_tick = True
|
||||
if tick.tick_type != TickType.QUOTE:
|
||||
@@ -63,7 +70,7 @@ class ConsolidateDifferentTickTypesRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
if not self.there_is_at_least_one_trade_tick:
|
||||
raise AssertionError(f"There should have been at least one tick in OnTradeTick() method, but there wasn't")
|
||||
|
||||
|
||||
if not self._there_is_at_least_one_trade_bar:
|
||||
raise AssertionError("There should have been at least one bar in OnTradeTickMaxCount() method, but there wasn't")
|
||||
|
||||
|
||||
@@ -19,15 +19,24 @@ from AlgorithmImports import *
|
||||
class HistoryTickRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
def initialize(self):
|
||||
self.set_start_date(2013, 10, 11)
|
||||
self.set_end_date(2013, 10, 11)
|
||||
self.set_start_date(2013, 10, 12)
|
||||
self.set_end_date(2013, 10, 13)
|
||||
|
||||
self._symbol = self.add_equity("SPY", Resolution.TICK).symbol
|
||||
|
||||
def on_end_of_algorithm(self):
|
||||
history = list(self.history[Tick](self._symbol, timedelta(days=1), Resolution.TICK))
|
||||
quotes = [x for x in history if x.tick_type == TickType.QUOTE]
|
||||
trades = [x for x in history if x.tick_type == TickType.TRADE]
|
||||
trades_count = 0
|
||||
quotes_count = 0
|
||||
for point in self.history[Tick](self._symbol, timedelta(days=1), Resolution.TICK):
|
||||
if point.tick_type == TickType.TRADE:
|
||||
trades_count += 1
|
||||
elif point.tick_type == TickType.QUOTE:
|
||||
quotes_count += 1
|
||||
|
||||
if not quotes or not trades:
|
||||
if trades_count > 0 and quotes_count > 0:
|
||||
# We already found at least one tick of each type, we can exit the loop
|
||||
break
|
||||
|
||||
if trades_count == 0 or quotes_count == 0:
|
||||
raise AssertionError("Expected to find at least one tick of each type (quote and trade)")
|
||||
|
||||
self.quit()
|
||||
|
||||
+6
-2
@@ -34,13 +34,17 @@ class PeriodBasedHistoryRequestNotAllowedWithTickResolutionRegressionAlgorithm(Q
|
||||
"Tick history call with symbol array with explicit tick resolution")
|
||||
|
||||
history = self.history[Tick](spy, TimeSpan.from_hours(12))
|
||||
if len(list(history)) == 0:
|
||||
# Check whether history has data without enumerating the whole list
|
||||
if not any(x for x in history):
|
||||
raise AssertionError("On history call with implicit tick resolution: history returned no results")
|
||||
|
||||
history = self.history[Tick](spy, TimeSpan.from_hours(12), Resolution.TICK)
|
||||
if len(list(history)) == 0:
|
||||
if not any(x for x in history):
|
||||
raise AssertionError("On history call with explicit tick resolution: history returned no results")
|
||||
|
||||
# We already tested what we wanted to test, we can quit now
|
||||
self.quit()
|
||||
|
||||
def assert_that_history_throws_for_tick_resolution(self, history_call, history_call_description):
|
||||
try:
|
||||
history_call()
|
||||
|
||||
@@ -23,7 +23,7 @@ class RegressionAlgorithm(QCAlgorithm):
|
||||
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
|
||||
|
||||
self.set_start_date(2013,10,7) #Set Start Date
|
||||
self.set_end_date(2013,10,11) #Set End Date
|
||||
self.set_end_date(2013,10,8) #Set End Date
|
||||
self.set_cash(10000000) #Set Strategy Cash
|
||||
# Find more symbols here: http://quantconnect.com/data
|
||||
self.add_equity("SPY", Resolution.TICK)
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from datetime import timedelta
|
||||
from AlgorithmImports import *
|
||||
|
||||
# <summary>
|
||||
@@ -31,14 +32,16 @@ class TickDataFilteringAlgorithm(QCAlgorithm):
|
||||
#Add our custom data filter.
|
||||
spy.set_data_filter(TickExchangeDataFilter(self))
|
||||
|
||||
self._order_time = None
|
||||
|
||||
# <summary>
|
||||
# Data arriving here will now be filtered.
|
||||
# </summary>
|
||||
# <param name="data">Ticks data array</param>
|
||||
def on_data(self, data):
|
||||
if not data.contains_key("SPY"):
|
||||
if not data.contains_key("SPY"):
|
||||
return
|
||||
|
||||
|
||||
spy_tick_list = data["SPY"]
|
||||
|
||||
# Ticks return a list of ticks this second
|
||||
@@ -47,6 +50,10 @@ class TickDataFilteringAlgorithm(QCAlgorithm):
|
||||
|
||||
if not self.portfolio.invested:
|
||||
self.set_holdings("SPY", 1)
|
||||
self._order_time = self.time
|
||||
# Let's shortcut to reduce regression test duration
|
||||
elif self.time - self._order_time > timedelta(minutes=5):
|
||||
self.quit()
|
||||
|
||||
# <summary>
|
||||
# Exchange filter class
|
||||
@@ -73,5 +80,5 @@ class TickExchangeDataFilter(SecurityDataFilter):
|
||||
if isinstance(data, Tick):
|
||||
if data.exchange == str(Exchange.ARCA):
|
||||
return True
|
||||
|
||||
|
||||
return False
|
||||
|
||||
@@ -30,16 +30,16 @@ class TickHistoryRequestWithoutTickSubscriptionRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
# Requesting history for SPY and IBM (separately) with tick resolution
|
||||
spy_history = self.history[Tick](spy, timedelta(days=1), Resolution.TICK)
|
||||
if len(list(spy_history)) == 0:
|
||||
if not any(spy_history):
|
||||
raise AssertionError("SPY tick history is empty")
|
||||
|
||||
ibm_history = self.history[Tick](ibm, timedelta(days=1), Resolution.TICK)
|
||||
if len(list(ibm_history)) == 0:
|
||||
if not any(ibm_history):
|
||||
raise AssertionError("IBM tick history is empty")
|
||||
|
||||
# Requesting history for SPY and IBM (together) with tick resolution
|
||||
spy_ibm_history = self.history[Tick]([spy, ibm], timedelta(days=1), Resolution.TICK)
|
||||
if len(list(spy_ibm_history)) == 0:
|
||||
if not any(spy_ibm_history):
|
||||
raise AssertionError("Compound SPY and IBM tick history is empty")
|
||||
|
||||
self.quit()
|
||||
|
||||
Reference in New Issue
Block a user