pep8 conversion of python algos (#7942)

* pep8 conversion of python algos

* adding 10 more pep8 converted algos
This commit is contained in:
Ashutosh
2024-04-18 23:44:56 +05:30
committed by GitHub
parent ed351c8726
commit 1cae47ab25
15 changed files with 363 additions and 360 deletions
+19 -16
View File
@@ -23,35 +23,38 @@ from QuantConnect.Data.Custom.Tiingo import *
### <meta name="tag" content="tiingo" />
class TiingoPriceAlgorithm(QCAlgorithm):
def Initialize(self):
def initialize(self):
# Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
self.SetStartDate(2017, 1, 1)
self.SetEndDate(2017, 12, 31)
self.SetCash(100000)
self.set_start_date(2017, 1, 1)
self.set_end_date(2017, 12, 31)
self.set_cash(100000)
# Set your Tiingo API Token here
Tiingo.SetAuthCode("my-tiingo-api-token")
Tiingo.set_auth_code("my-tiingo-api-token")
self.ticker = "AAPL"
self.symbol = self.AddData(TiingoPrice, self.ticker, Resolution.Daily).Symbol
self.equity = self.add_equity(self.ticker).symbol
self.aapl = self.add_data(TiingoPrice, self.ticker, Resolution.DAILY).symbol
self.emaFast = self.EMA(self.symbol, 5)
self.emaSlow = self.EMA(self.symbol, 10)
self.ema_fast = self.ema(self.equity, 5)
self.ema_slow = self.ema(self.equity, 10)
def OnData(self, slice):
def on_data(self, slice):
# OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
if not slice.ContainsKey(self.ticker): return
if not slice.contains_key(self.ticker): return
# Extract Tiingo data from the slice
row = slice[self.ticker]
self.Log(f"{self.Time} - {row.Symbol.Value} - {row.Close} {row.Value} {row.Price} - EmaFast:{self.emaFast} - EmaSlow:{self.emaSlow}")
if row is not None:
if self.ema_fast.is_ready and self.ema_slow.is_ready:
self.log(f"{self.time} - {row.symbol.value} - {row.close} {row.value} {row.price} - EmaFast:{self.ema_fast} - EmaSlow:{self.ema_slow}")
# Simple EMA cross
if not self.Portfolio.Invested and self.emaFast > self.emaSlow:
self.SetHoldings(self.symbol, 1)
# Simple EMA cross
if not self.portfolio.invested and self.ema_fast > self.ema_slow:
self.set_holdings(self.equity, 1)
elif self.Portfolio.Invested and self.emaFast < self.emaSlow:
self.Liquidate(self.symbol)
elif self.portfolio.invested and self.ema_fast < self.ema_slow:
self.liquidate(self.equity)
+39 -39
View File
@@ -22,81 +22,81 @@ from AlgorithmImports import *
class TimeInForceAlgorithm(QCAlgorithm):
# Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.
def Initialize(self):
def initialize(self):
self.SetStartDate(2013,10,7)
self.SetEndDate(2013,10,11)
self.SetCash(100000)
self.set_start_date(2013,10,7)
self.set_end_date(2013,10,11)
self.set_cash(100000)
# The default time in force setting for all orders is GoodTilCancelled (GTC),
# uncomment this line to set a different time in force.
# We currently only support GTC and DAY.
# self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
# self.default_order_properties.time_in_force = TimeInForce.day
self.symbol = self.AddEquity("SPY", Resolution.Minute).Symbol
self.symbol = self.add_equity("SPY", Resolution.MINUTE).symbol
self.gtcOrderTicket1 = None
self.gtcOrderTicket2 = None
self.dayOrderTicket1 = None
self.dayOrderTicket2 = None
self.gtdOrderTicket1 = None
self.gtdOrderTicket2 = None
self.expectedOrderStatuses = {}
self.gtc_order_ticket1 = None
self.gtc_order_ticket2 = None
self.day_order_ticket1 = None
self.day_order_ticket2 = None
self.gtd_order_ticket1 = None
self.gtd_order_ticket2 = None
self.expected_order_statuses = {}
# OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
# Arguments:
# data: Slice object keyed by symbol containing the stock data
def OnData(self, data):
def on_data(self, data):
if self.gtcOrderTicket1 is None:
if self.gtc_order_ticket1 is None:
# These GTC orders will never expire and will not be canceled automatically.
self.DefaultOrderProperties.TimeInForce = TimeInForce.GoodTilCanceled
self.default_order_properties.time_in_force = TimeInForce.GOOD_TIL_CANCELED
# this order will not be filled before the end of the backtest
self.gtcOrderTicket1 = self.LimitOrder(self.symbol, 10, 100)
self.expectedOrderStatuses[self.gtcOrderTicket1.OrderId] = OrderStatus.Submitted
self.gtc_order_ticket1 = self.limit_order(self.symbol, 10, 100)
self.expected_order_statuses[self.gtc_order_ticket1.order_id] = OrderStatus.SUBMITTED
# this order will be filled before the end of the backtest
self.gtcOrderTicket2 = self.LimitOrder(self.symbol, 10, 160)
self.expectedOrderStatuses[self.gtcOrderTicket2.OrderId] = OrderStatus.Filled
self.gtc_order_ticket2 = self.limit_order(self.symbol, 10, 160)
self.expected_order_statuses[self.gtc_order_ticket2.order_id] = OrderStatus.FILLED
if self.dayOrderTicket1 is None:
if self.day_order_ticket1 is None:
# These DAY orders will expire at market close,
# if not filled by then they will be canceled automatically.
self.DefaultOrderProperties.TimeInForce = TimeInForce.Day
self.default_order_properties.time_in_force = TimeInForce.DAY
# this order will not be filled before market close and will be canceled
self.dayOrderTicket1 = self.LimitOrder(self.symbol, 10, 140)
self.expectedOrderStatuses[self.dayOrderTicket1.OrderId] = OrderStatus.Canceled
self.day_order_ticket1 = self.limit_order(self.symbol, 10, 140)
self.expected_order_statuses[self.day_order_ticket1.order_id] = OrderStatus.CANCELED
# this order will be filled before market close
self.dayOrderTicket2 = self.LimitOrder(self.symbol, 10, 180)
self.expectedOrderStatuses[self.dayOrderTicket2.OrderId] = OrderStatus.Filled
self.day_order_ticket2 = self.limit_order(self.symbol, 10, 180)
self.expected_order_statuses[self.day_order_ticket2.order_id] = OrderStatus.FILLED
if self.gtdOrderTicket1 is None:
if self.gtd_order_ticket1 is None:
# These GTD orders will expire on October 10th at market close,
# if not filled by then they will be canceled automatically.
self.DefaultOrderProperties.TimeInForce = TimeInForce.GoodTilDate(datetime(2013, 10, 10))
self.default_order_properties.time_in_force = TimeInForce.good_til_date(datetime(2013, 10, 10))
# this order will not be filled before expiry and will be canceled
self.gtdOrderTicket1 = self.LimitOrder(self.symbol, 10, 100)
self.expectedOrderStatuses[self.gtdOrderTicket1.OrderId] = OrderStatus.Canceled
self.gtd_order_ticket1 = self.limit_order(self.symbol, 10, 100)
self.expected_order_statuses[self.gtd_order_ticket1.order_id] = OrderStatus.CANCELED
# this order will be filled before expiry
self.gtdOrderTicket2 = self.LimitOrder(self.symbol, 10, 160)
self.expectedOrderStatuses[self.gtdOrderTicket2.OrderId] = OrderStatus.Filled
self.gtd_order_ticket2 = self.limit_order(self.symbol, 10, 160)
self.expected_order_statuses[self.gtd_order_ticket2.order_id] = OrderStatus.FILLED
# Order event handler. This handler will be called for all order events, including submissions, fills, cancellations.
# This method can be called asynchronously, ensure you use proper locks on thread-unsafe objects
def OnOrderEvent(self, orderEvent):
self.Debug(f"{self.Time} {orderEvent}")
def on_order_event(self, orderEvent):
self.debug(f"{self.time} {orderEvent}")
# End of algorithm run event handler. This method is called at the end of a backtest or live trading operation.
def OnEndOfAlgorithm(self):
for orderId, expectedStatus in self.expectedOrderStatuses.items():
order = self.Transactions.GetOrderById(orderId)
if order.Status != expectedStatus:
raise Exception(f"Invalid status for order {orderId} - Expected: {expectedStatus}, actual: {order.Status}")
def on_end_of_algorithm(self):
for orderId, expectedStatus in self.expected_order_statuses.items():
order = self.transactions.get_order_by_id(orderId)
if order.status != expectedStatus:
raise Exception(f"Invalid status for order {orderId} - Expected: {expectedStatus}, actual: {order.status}")
@@ -22,64 +22,64 @@ from AlgorithmImports import *
class TrailingStopOrderRegressionAlgorithm(QCAlgorithm):
'''Basic algorithm demonstrating how to place trailing stop orders.'''
BuyTrailingAmount = 2
SellTrailingAmount = 0.5
buy_trailing_amount = 2
sell_trailing_amount = 0.5
def Initialize(self):
def initialize(self):
self.SetStartDate(2013,10, 7)
self.SetEndDate(2013,10,11)
self.SetCash(100000)
self.set_start_date(2013,10, 7)
self.set_end_date(2013,10,11)
self.set_cash(100000)
self._symbol = self.AddEquity("SPY").Symbol
self._symbol = self.add_equity("SPY").symbol
self._buyOrderTicket: OrderTicket = None
self._sellOrderTicket: OrderTicket = None
self._previousSlice: Slice = None
self._buy_order_ticket: OrderTicket = None
self._sell_order_ticket: OrderTicket = None
self._previous_slice: Slice = None
def OnData(self, slice: Slice):
if not slice.ContainsKey(self._symbol):
def on_data(self, slice: Slice):
if not slice.contains_key(self._symbol):
return
if self._buyOrderTicket is None:
self._buyOrderTicket = self.TrailingStopOrder(self._symbol, 100, trailingAmount=self.BuyTrailingAmount, trailingAsPercentage=False)
elif self._buyOrderTicket.Status != OrderStatus.Filled:
stopPrice = self._buyOrderTicket.Get(OrderField.StopPrice)
if self._buy_order_ticket is None:
self._buy_order_ticket = self.trailing_stop_order(self._symbol, 100, trailing_amount=self.buy_trailing_amount, trailing_as_percentage=False)
elif self._buy_order_ticket.status != OrderStatus.FILLED:
stop_price = self._buy_order_ticket.get(OrderField.STOP_PRICE)
# Get the previous bar to compare to the stop price,
# because stop price update attempt with the current slice data happens after OnData.
low = self._previousSlice.QuoteBars[self._symbol].Ask.Low if self._previousSlice.QuoteBars.ContainsKey(self._symbol) \
else self._previousSlice.Bars[self._symbol].Low
low = self._previous_slice.quote_bars[self._symbol].ask.low if self._previous_slice.quote_bars.contains_key(self._symbol) \
else self._previous_slice.bars[self._symbol].low
stopPriceToMarketPriceDistance = stopPrice - low
if stopPriceToMarketPriceDistance > self.BuyTrailingAmount:
raise Exception(f"StopPrice {stopPrice} should be within {self.BuyTrailingAmount} of the previous low price {low} at all times.")
stop_price_to_market_price_distance = stop_price - low
if stop_price_to_market_price_distance > self.buy_trailing_amount:
raise Exception(f"StopPrice {stop_price} should be within {self.buy_trailing_amount} of the previous low price {low} at all times.")
if self._sellOrderTicket is None:
if self.Portfolio.Invested:
self._sellOrderTicket = self.TrailingStopOrder(self._symbol, -100, trailingAmount=self.SellTrailingAmount, trailingAsPercentage=False)
elif self._sellOrderTicket.Status != OrderStatus.Filled:
stopPrice = self._sellOrderTicket.Get(OrderField.StopPrice)
if self._sell_order_ticket is None:
if self.portfolio.invested:
self._sell_order_ticket = self.trailing_stop_order(self._symbol, -100, trailing_amount=self.sell_trailing_amount, trailing_as_percentage=False)
elif self._sell_order_ticket.status != OrderStatus.FILLED:
stop_price = self._sell_order_ticket.get(OrderField.STOP_PRICE)
# Get the previous bar to compare to the stop price,
# because stop price update attempt with the current slice data happens after OnData.
high = self._previousSlice.QuoteBars[self._symbol].Bid.High if self._previousSlice.QuoteBars.ContainsKey(self._symbol) \
else self._previousSlice.Bars[self._symbol].High
stopPriceToMarketPriceDistance = high - stopPrice
if stopPriceToMarketPriceDistance > self.SellTrailingAmount:
raise Exception(f"StopPrice {stopPrice} should be within {self.SellTrailingAmount} of the previous high price {high} at all times.")
high = self._previous_slice.quote_bars[self._symbol].bid.high if self._previous_slice.quote_bars.contains_key(self._symbol) \
else self._previous_slice.bars[self._symbol].high
stop_price_to_market_price_distance = high - stop_price
if stop_price_to_market_price_distance > self.sell_trailing_amount:
raise Exception(f"StopPrice {stop_price} should be within {self.sell_trailing_amount} of the previous high price {high} at all times.")
self._previousSlice = slice
self._previous_slice = slice
def OnOrderEvent(self, orderEvent: OrderEvent):
if orderEvent.Status == OrderStatus.Filled:
if orderEvent.Direction == OrderDirection.Buy:
stopPrice = self._buyOrderTicket.Get(OrderField.StopPrice)
if orderEvent.FillPrice < stopPrice:
raise Exception(f"Buy trailing stop order should have filled with price greater than or equal to the stop price {stopPrice}. "
f"Fill price: {orderEvent.FillPrice}")
def on_order_event(self, orderEvent: OrderEvent):
if orderEvent.status == OrderStatus.FILLED:
if orderEvent.direction == OrderDirection.BUY:
stop_price = self._buy_order_ticket.get(OrderField.STOP_PRICE)
if orderEvent.fill_price < stop_price:
raise Exception(f"Buy trailing stop order should have filled with price greater than or equal to the stop price {stop_price}. "
f"Fill price: {orderEvent.fill_price}")
else:
stopPrice = self._sellOrderTicket.Get(OrderField.StopPrice)
if orderEvent.FillPrice > stopPrice:
raise Exception(f"Sell trailing stop order should have filled with price less than or equal to the stop price {stopPrice}. "
f"Fill price: {orderEvent.FillPrice}")
stop_price = self._sell_order_ticket.get(OrderField.STOP_PRICE)
if orderEvent.fill_price > stop_price:
raise Exception(f"Sell trailing stop order should have filled with price less than or equal to the stop price {stop_price}. "
f"Fill price: {orderEvent.fill_price}")
+11 -11
View File
@@ -15,31 +15,31 @@ from AlgorithmImports import *
from time import sleep
### <summary>
### Example algorithm showing how to use QCAlgorithm.Train method
### Example algorithm showing how to use QCAlgorithm.train method
### </summary>
### <meta name="tag" content="using quantconnect" />
### <meta name="tag" content="training" />
class TrainingExampleAlgorithm(QCAlgorithm):
'''Example algorithm showing how to use QCAlgorithm.Train method'''
'''Example algorithm showing how to use QCAlgorithm.train method'''
def Initialize(self):
def initialize(self):
self.SetStartDate(2013, 10, 7)
self.SetEndDate(2013, 10, 14)
self.set_start_date(2013, 10, 7)
self.set_end_date(2013, 10, 14)
self.AddEquity("SPY", Resolution.Daily)
self.add_equity("SPY", Resolution.DAILY)
# Set TrainingMethod to be executed immediately
self.Train(self.TrainingMethod)
self.train(self.training_method)
# Set TrainingMethod to be executed at 8:00 am every Sunday
self.Train(self.DateRules.Every(DayOfWeek.Sunday), self.TimeRules.At(8 , 0), self.TrainingMethod)
self.train(self.date_rules.every(DayOfWeek.SUNDAY), self.time_rules.at(8 , 0), self.training_method)
def TrainingMethod(self):
def training_method(self):
self.Log(f'Start training at {self.Time}')
self.log(f'Start training at {self.time}')
# Use the historical data to train the machine learning model
history = self.History(["SPY"], 200, Resolution.Daily)
history = self.history(["SPY"], 200, Resolution.DAILY)
# ML code:
pass
@@ -21,25 +21,25 @@ from time import sleep
### test sets to 0.5 minutes.
### </summary>
class TrainingInitializeRegressionAlgorithm(QCAlgorithm):
'''Example algorithm showing how to use QCAlgorithm.Train method'''
'''Example algorithm showing how to use QCAlgorithm.train method'''
def Initialize(self):
def initialize(self):
self.SetStartDate(2013, 10, 7)
self.SetEndDate(2013, 10, 11)
self.set_start_date(2013, 10, 7)
self.set_end_date(2013, 10, 11)
self.AddEquity("SPY", Resolution.Daily)
self.add_equity("SPY", Resolution.DAILY)
# this should cause the algorithm to fail
# the regression test sets the time limit to 30 seconds and there's one extra
# minute in the bucket, so a two minute sleep should result in RuntimeError
self.Train(lambda: sleep(150))
self.train(lambda: sleep(150))
# DateRules.Tomorrow combined with TimeRules.Midnight enforces that this event schedule will
# DateRules.tomorrow combined with TimeRules.midnight enforces that this event schedule will
# have exactly one time, which will fire between the first data point and the next day at
# midnight. So after the first data point, it will run this event and sleep long enough to
# exceed the static max algorithm time loop time and begin to consume from the leaky bucket
# the regression test sets the "algorithm-manager-time-loop-maximum" value to 30 seconds
self.Train(self.DateRules.Tomorrow, self.TimeRules.Midnight, lambda: sleep(60))
self.train(self.date_rules.tomorrow, self.time_rules.midnight, lambda: sleep(60))
# this will consume the single 'minute' available in the leaky bucket
# and the regression test will confirm that the leaky bucket is empty
@@ -17,46 +17,46 @@ from AlgorithmImports import *
### Regression algorithm which tests that a two leg currency conversion happens correctly
### </summary>
class TwoLegCurrencyConversionRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 4, 4)
self.SetEndDate(2018, 4, 4)
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
def initialize(self):
self.set_start_date(2018, 4, 4)
self.set_end_date(2018, 4, 4)
self.set_brokerage_model(BrokerageName.GDAX, AccountType.CASH)
# GDAX doesn't have LTCETH or ETHLTC, but they do have ETHUSD and LTCUSD to form a path between ETH and LTC
self.SetAccountCurrency("ETH")
self.SetCash("ETH", 100000)
self.SetCash("LTC", 100000)
self.SetCash("USD", 100000)
self.set_account_currency("ETH")
self.set_cash("ETH", 100000)
self.set_cash("LTC", 100000)
self.set_cash("USD", 100000)
self._ethUsdSymbol = self.AddCrypto("ETHUSD", Resolution.Minute).Symbol
self._ltcUsdSymbol = self.AddCrypto("LTCUSD", Resolution.Minute).Symbol
self._eth_usd_symbol = self.add_crypto("ETHUSD", Resolution.MINUTE).symbol
self._ltc_usd_symbol = self.add_crypto("LTCUSD", Resolution.MINUTE).symbol
def OnData(self, data):
if not self.Portfolio.Invested:
self.MarketOrder(self._ltcUsdSymbol, 1)
def on_data(self, data):
if not self.portfolio.invested:
self.market_order(self._ltc_usd_symbol, 1)
def OnEndOfAlgorithm(self):
ltcCash = self.Portfolio.CashBook["LTC"]
def on_end_of_algorithm(self):
ltc_cash = self.portfolio.cash_book["LTC"]
conversionSymbols = [x.Symbol for x in ltcCash.CurrencyConversion.ConversionRateSecurities]
conversion_symbols = [x.symbol for x in ltc_cash.currency_conversion.conversion_rate_securities]
if len(conversionSymbols) != 2:
if len(conversion_symbols) != 2:
raise ValueError(
f"Expected two conversion rate securities for LTC to ETH, is {len(conversionSymbols)}")
f"Expected two conversion rate securities for LTC to ETH, is {len(conversion_symbols)}")
if conversionSymbols[0] != self._ltcUsdSymbol:
if conversion_symbols[0] != self._ltc_usd_symbol:
raise ValueError(
f"Expected first conversion rate security from LTC to ETH to be {self._ltcUsdSymbol}, is {conversionSymbols[0]}")
f"Expected first conversion rate security from LTC to ETH to be {self._ltc_usd_symbol}, is {conversion_symbols[0]}")
if conversionSymbols[1] != self._ethUsdSymbol:
if conversion_symbols[1] != self._eth_usd_symbol:
raise ValueError(
f"Expected second conversion rate security from LTC to ETH to be {self._ethUsdSymbol}, is {conversionSymbols[1]}")
f"Expected second conversion rate security from LTC to ETH to be {self._eth_usd_symbol}, is {conversion_symbols[1]}")
ltcUsdValue = self.Securities[self._ltcUsdSymbol].GetLastData().Value
ethUsdValue = self.Securities[self._ethUsdSymbol].GetLastData().Value
ltc_usd_value = self.securities[self._ltc_usd_symbol].get_last_data().value
eth_usd_value = self.securities[self._eth_usd_symbol].get_last_data().value
expectedConversionRate = ltcUsdValue / ethUsdValue
actualConversionRate = ltcCash.ConversionRate
expected_conversion_rate = ltc_usd_value / eth_usd_value
actual_conversion_rate = ltc_cash.conversion_rate
if actualConversionRate != expectedConversionRate:
if actual_conversion_rate != expected_conversion_rate:
raise ValueError(
f"Expected conversion rate from LTC to ETH to be {expectedConversionRate}, is {actualConversionRate}")
f"Expected conversion rate from LTC to ETH to be {expected_conversion_rate}, is {actual_conversion_rate}")
@@ -19,22 +19,22 @@ from AlgorithmImports import *
### </summary>
class UniverseOnlyRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 12, 1)
self.SetEndDate(2020, 12, 12)
self.SetCash(100000)
def initialize(self):
self.set_start_date(2020, 12, 1)
self.set_end_date(2020, 12, 12)
self.set_cash(100000)
self.UniverseSettings.Resolution = Resolution.Daily
self.universe_settings.resolution = Resolution.DAILY
# Add universe without a security added
self.AddUniverse(self.Universe.ETF("GDVD", self.UniverseSettings, self.FilterUniverse))
self.add_universe(self.universe.etf("GDVD", self.universe_settings, self.filter_universe))
self.selection_done = False
def FilterUniverse(self, constituents: List[ETFConstituentData]) -> List[Symbol]:
def filter_universe(self, constituents: List[ETFConstituentData]) -> List[Symbol]:
self.selection_done = True
return [x.Symbol for x in constituents]
return [x.symbol for x in constituents]
def OnEndOfAlgorithm(self):
def on_end_of_algorithm(self):
if not self.selection_done:
raise Exception("Universe selection was not performed")
@@ -14,36 +14,36 @@
from AlgorithmImports import *
### <summary>
### Regression algorithm asserting the behavior of Universe.Selected collection
### Regression algorithm asserting the behavior of Universe.SELECTED collection
### </summary>
class UniverseSelectedRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2014, 3, 25)
self.SetEndDate(2014, 3, 27)
def initialize(self):
self.set_start_date(2014, 3, 25)
self.set_end_date(2014, 3, 27)
self.UniverseSettings.Resolution = Resolution.Daily
self.universe_settings.resolution = Resolution.DAILY
self._universe = self.AddUniverse(self.SelectionFunction)
self.selectionCount = 0
self._universe = self.add_universe(self.selection_function)
self.selection_count = 0
def SelectionFunction(self, fundamentals):
sortedByDollarVolume = sorted(fundamentals, key=lambda x: x.DollarVolume, reverse=True)
def selection_function(self, fundamentals):
sorted_by_dollar_volume = sorted(fundamentals, key=lambda x: x.dollar_volume, reverse=True)
sortedByDollarVolume = sortedByDollarVolume[self.selectionCount:]
self.selectionCount = self.selectionCount + 1
sorted_by_dollar_volume = sorted_by_dollar_volume[self.selection_count:]
self.selection_count = self.selection_count + 1
# return the symbol objects of the top entries from our sorted collection
return [ x.Symbol for x in sortedByDollarVolume[:self.selectionCount] ]
return [ x.symbol for x in sorted_by_dollar_volume[:self.selection_count] ]
def OnData(self, data):
if Symbol.Create("TSLA", SecurityType.Equity, Market.USA) in self._universe.Selected:
def on_data(self, data):
if Symbol.create("TSLA", SecurityType.EQUITY, Market.USA) in self._universe.selected:
raise ValueError(f"TSLA shouldn't of been selected")
self.Buy(next(iter(self._universe.Selected)), 1)
self.buy(next(iter(self._universe.selected)), 1)
def OnEndOfAlgorithm(self):
if self.selectionCount != 3:
raise ValueError(f"Unexpected selection count {self.selectionCount}")
if self._universe.Selected.Count != 3 or self._universe.Selected.Count == self._universe.Members.Count:
raise ValueError(f"Unexpected universe selected count {self._universe.Selected.Count}")
def on_end_of_algorithm(self):
if self.selection_count != 3:
raise ValueError(f"Unexpected selection count {self.selection_count}")
if self._universe.selected.count != 3 or self._universe.selected.count == self._universe.members.count:
raise ValueError(f"Unexpected universe selected count {self._universe.selected.count}")
@@ -21,40 +21,40 @@ from AlgorithmImports import *
### <meta name="tag" content="coarse universes" />
class UniverseSelectionDefinitionsAlgorithm(QCAlgorithm):
def Initialize(self):
def initialize(self):
# subscriptions added via universe selection will have this resolution
self.UniverseSettings.Resolution = Resolution.Daily
self.universe_settings.resolution = Resolution.DAILY
self.SetStartDate(2014,3,24) # Set Start Date
self.SetEndDate(2014,3,28) # Set End Date
self.SetCash(100000) # Set Strategy Cash
self.set_start_date(2014,3,24) # Set Start Date
self.set_end_date(2014,3,28) # Set End Date
self.set_cash(100000) # Set Strategy Cash
# add universe for the top 3 stocks by dollar volume
self.AddUniverse(self.Universe.Top(3))
self.add_universe(self.universe.top(3))
self.changes = None
self.onSecuritiesChangedWasCalled = False
self.on_securities_changed_was_called = False
def OnData(self, data):
def on_data(self, data):
if self.changes is None: return
# liquidate securities that fell out of our universe
for security in self.changes.RemovedSecurities:
if security.Invested:
self.Liquidate(security.Symbol)
for security in self.changes.removed_securities:
if security.invested:
self.liquidate(security.symbol)
# invest in securities just added to our universe
for security in self.changes.AddedSecurities:
if not security.Invested:
self.MarketOrder(security.Symbol, 10)
for security in self.changes.added_securities:
if not security.invested:
self.market_order(security.symbol, 10)
self.changes = None
# this event fires whenever we have changes to our universe
def OnSecuritiesChanged(self, changes):
def on_securities_changed(self, changes):
self.changes = changes
self.onSecuritiesChangedWasCalled = True
self.on_securities_changed_was_called = True
def OnEndOfAlgorithm(self):
if not self.onSecuritiesChangedWasCalled:
def on_end_of_algorithm(self):
if not self.on_securities_changed_was_called:
raise Exception("OnSecuritiesChanged() method was never called!")
@@ -19,60 +19,60 @@ from AlgorithmImports import *
### <meta name="tag" content="regression test" />
class UniverseSelectionRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
def initialize(self):
self.SetStartDate(2014,3,22) #Set Start Date
self.SetEndDate(2014,4,7) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.set_start_date(2014,3,22) #Set Start Date
self.set_end_date(2014,4,7) #Set End Date
self.set_cash(100000) #Set Strategy Cash
# Find more symbols here: http://quantconnect.com/data
# security that exists with no mappings
self.AddEquity("SPY", Resolution.Daily)
self.add_equity("SPY", Resolution.DAILY)
# security that doesn't exist until half way in backtest (comes in as GOOCV)
self.AddEquity("GOOG", Resolution.Daily)
self.add_equity("GOOG", Resolution.DAILY)
self.UniverseSettings.Resolution = Resolution.Daily
self.AddUniverse(self.CoarseSelectionFunction)
self.universe_settings.resolution = Resolution.DAILY
self.add_universe(self.coarse_selection_function)
self.delistedSymbols = []
self.delisted_symbols = []
self.changes = None
def CoarseSelectionFunction(self, coarse):
return [ c.Symbol for c in coarse if c.Symbol.Value == "GOOG" or c.Symbol.Value == "GOOCV" or c.Symbol.Value == "GOOAV" or c.Symbol.Value == "GOOGL" ]
def coarse_selection_function(self, coarse):
return [ c.symbol for c in coarse if c.symbol.value == "GOOG" or c.symbol.value == "GOOCV" or c.symbol.value == "GOOAV" or c.symbol.value == "GOOGL" ]
def OnData(self, data):
if self.Transactions.OrdersCount == 0:
self.MarketOrder("SPY", 100)
def on_data(self, data):
if self.transactions.orders_count == 0:
self.market_order("SPY", 100)
for kvp in data.Delistings:
self.delistedSymbols.append(kvp.Key)
for kvp in data.delistings:
self.delisted_symbols.append(kvp.key)
if self.changes is None:
return
if not all(data.Bars.ContainsKey(x.Symbol) for x in self.changes.AddedSecurities):
if not all(data.bars.contains_key(x.symbol) for x in self.changes.added_securities):
return
for security in self.changes.AddedSecurities:
self.Log("{0}: Added Security: {1}".format(self.Time, security.Symbol))
self.MarketOnOpenOrder(security.Symbol, 100)
for security in self.changes.added_securities:
self.log("{0}: Added Security: {1}".format(self.time, security.symbol))
self.market_on_open_order(security.symbol, 100)
for security in self.changes.RemovedSecurities:
self.Log("{0}: Removed Security: {1}".format(self.Time, security.Symbol))
if security.Symbol not in self.delistedSymbols:
self.Log("Not in delisted: {0}:".format(security.Symbol))
self.MarketOnOpenOrder(security.Symbol, -100)
for security in self.changes.removed_securities:
self.log("{0}: Removed Security: {1}".format(self.time, security.symbol))
if security.symbol not in self.delisted_symbols:
self.log("Not in delisted: {0}:".format(security.symbol))
self.market_on_open_order(security.symbol, -100)
self.changes = None
def OnSecuritiesChanged(self, changes):
def on_securities_changed(self, changes):
self.changes = changes
def OnOrderEvent(self, orderEvent):
if orderEvent.Status == OrderStatus.Submitted:
self.Log("{0}: Submitted: {1}".format(self.Time, self.Transactions.GetOrderById(orderEvent.OrderId)))
if orderEvent.Status == OrderStatus.Filled:
self.Log("{0}: Filled: {1}".format(self.Time, self.Transactions.GetOrderById(orderEvent.OrderId)))
def on_order_event(self, orderEvent):
if orderEvent.status == OrderStatus.SUBMITTED:
self.log("{0}: Submitted: {1}".format(self.time, self.transactions.get_order_by_id(orderEvent.order_id)))
if orderEvent.status == OrderStatus.FILLED:
self.log("{0}: Filled: {1}".format(self.time, self.transactions.get_order_by_id(orderEvent.order_id)))
@@ -14,49 +14,49 @@
from AlgorithmImports import *
### <summary>
### Regression algorithm used to test a fine and coarse selection methods returning Universe.Unchanged
### Regression algorithm used to test a fine and coarse selection methods returning Universe.UNCHANGED
### </summary>
class UniverseUnchangedRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
self.UniverseSettings.Resolution = Resolution.Daily
def initialize(self):
self.universe_settings.resolution = Resolution.DAILY
# Order margin value has to have a minimum of 0.5% of Portfolio value, allows filtering out small trades and reduce fees.
# Commented so regression algorithm is more sensitive
#self.Settings.MinimumOrderMarginPortfolioPercentage = 0.005
self.SetStartDate(2014,3,25)
self.SetEndDate(2014,4,7)
#self.settings.minimum_order_margin_portfolio_percentage = 0.005
self.set_start_date(2014,3,25)
self.set_end_date(2014,4,7)
self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(days = 1), 0.025, None))
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(days = 1), 0.025, None))
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
self.add_universe(self.coarse_selection_function, self.fine_selection_function)
self.numberOfSymbolsFine = 2
self.number_of_symbols_fine = 2
def CoarseSelectionFunction(self, coarse):
def coarse_selection_function(self, coarse):
# the first and second selection
if self.Time.date() <= date(2014, 3, 26):
if self.time.date() <= date(2014, 3, 26):
tickers = [ "AAPL", "AIG", "IBM" ]
return [ Symbol.Create(x, SecurityType.Equity, Market.USA) for x in tickers ]
return [ Symbol.create(x, SecurityType.EQUITY, Market.USA) for x in tickers ]
# will skip fine selection
return Universe.Unchanged
return Universe.UNCHANGED
def FineSelectionFunction(self, fine):
if self.Time.date() == date(2014, 3, 25):
sortedByPeRatio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=True)
return [ x.Symbol for x in sortedByPeRatio[:self.numberOfSymbolsFine] ]
def fine_selection_function(self, fine):
if self.time.date() == date(2014, 3, 25):
sorted_by_pe_ratio = sorted(fine, key=lambda x: x.valuation_ratios.pe_ratio, reverse=True)
return [ x.symbol for x in sorted_by_pe_ratio[:self.number_of_symbols_fine] ]
# the second selection will return unchanged, in the following fine selection will be skipped
return Universe.Unchanged
return Universe.UNCHANGED
# assert security changes, throw if called more than once
def OnSecuritiesChanged(self, changes):
addedSymbols = [ x.Symbol for x in changes.AddedSecurities ]
if (len(changes.AddedSecurities) != 2
or self.Time.date() != date(2014, 3, 25)
or Symbol.Create("AAPL", SecurityType.Equity, Market.USA) not in addedSymbols
or Symbol.Create("IBM", SecurityType.Equity, Market.USA) not in addedSymbols):
def on_securities_changed(self, changes):
added_symbols = [ x.symbol for x in changes.added_securities ]
if (len(changes.added_securities) != 2
or self.time.date() != date(2014, 3, 25)
or Symbol.create("AAPL", SecurityType.EQUITY, Market.USA) not in added_symbols
or Symbol.create("IBM", SecurityType.EQUITY, Market.USA) not in added_symbols):
raise ValueError("Unexpected security changes")
self.Log(f"OnSecuritiesChanged({self.Time}):: {changes}")
self.log(f"OnSecuritiesChanged({self.time}):: {changes}")
@@ -17,35 +17,35 @@ from AlgorithmImports import *
### Example and regression algorithm asserting the behavior of registering and unregistering an indicator from the engine
### </summary>
class UnregisterIndicatorRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
def initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(2013,10, 7)
self.SetEndDate(2013,10,11)
self.set_start_date(2013,10, 7)
self.set_end_date(2013,10,11)
spy = self.AddEquity("SPY")
ibm = self.AddEquity("IBM")
spy = self.add_equity("SPY")
ibm = self.add_equity("IBM")
self._symbols = [ spy.Symbol, ibm.Symbol ]
self._trin = self.TRIN(self._symbols, Resolution.Minute)
self._symbols = [ spy.symbol, ibm.symbol ]
self._trin = self.trin(self._symbols, Resolution.MINUTE)
self._trin2 = None
def OnData(self, data):
def on_data(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
Arguments:
data: Slice object keyed by symbol containing the stock data
'''
if self._trin.IsReady:
self._trin.Reset()
self.UnregisterIndicator(self._trin)
if self._trin.is_ready:
self._trin.reset()
self.unregister_indicator(self._trin)
# let's create a new one with a differente resolution
self._trin2 = self.TRIN(self._symbols, Resolution.Hour)
self._trin2 = self.trin(self._symbols, Resolution.HOUR)
if not self._trin2 is None and self._trin2.IsReady:
if self._trin.IsReady:
if not self._trin2 is None and self._trin2.is_ready:
if self._trin.is_ready:
raise ValueError("Indicator should of stop getting updates!")
if not self.Portfolio.Invested:
self.SetHoldings(self._symbols[0], 0.5)
self.SetHoldings(self._symbols[1], 0.5)
if not self.portfolio.invested:
self.set_holdings(self._symbols[0], 0.5)
self.set_holdings(self._symbols[1], 0.5)
@@ -20,15 +20,15 @@ from math import copysign
### <meta name="tag" content="regression test" />
class UpdateOrderRegressionAlgorithm(QCAlgorithm):
def Initialize(self):
def initialize(self):
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
self.SetStartDate(2013,1,1) #Set Start Date
self.SetEndDate(2015,1,1) #Set End Date
self.SetCash(100000) #Set Strategy Cash
self.set_start_date(2013,1,1) #Set Start Date
self.set_end_date(2015,1,1) #Set End Date
self.set_cash(100000) #Set Strategy Cash
# Find more symbols here: http://quantconnect.com/data
self.security = self.AddEquity("SPY", Resolution.Daily)
self.security = self.add_equity("SPY", Resolution.DAILY)
self.last_month = -1
self.quantity = 100
@@ -39,86 +39,86 @@ class UpdateOrderRegressionAlgorithm(QCAlgorithm):
self.limit_percentage = 0.025
self.limit_percentage_delta = 0.005
OrderTypeEnum = [OrderType.Market, OrderType.Limit, OrderType.StopMarket, OrderType.StopLimit, OrderType.MarketOnOpen, OrderType.MarketOnClose, OrderType.TrailingStop]
self.order_types_queue = CircularQueue[OrderType](OrderTypeEnum)
self.order_types_queue.CircleCompleted += self.onCircleCompleted
order_type_enum = [OrderType.MARKET, OrderType.LIMIT, OrderType.STOP_MARKET, OrderType.STOP_LIMIT, OrderType.MARKET_ON_OPEN, OrderType.MARKET_ON_CLOSE, OrderType.TRAILING_STOP]
self.order_types_queue = CircularQueue[OrderType](order_type_enum)
self.order_types_queue.circle_completed += self.on_circle_completed
self.tickets = []
def onCircleCompleted(self, sender, event):
def on_circle_completed(self, sender, event):
'''Flip our signs when we've gone through all the order types'''
self.quantity *= -1
def OnData(self, data):
def on_data(self, data):
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.'''
if not data.ContainsKey("SPY"):
if not data.contains_key("SPY"):
return
if self.Time.month != self.last_month:
if self.time.month != self.last_month:
# we'll submit the next type of order from the queue
orderType = self.order_types_queue.Dequeue()
order_type = self.order_types_queue.dequeue()
#Log("")
self.Log("\r\n--------------MONTH: {0}:: {1}\r\n".format(self.Time.strftime("%B"), orderType))
self.Log("\r\n--------------MONTH: {0}:: {1}".format(self.time.strftime("%B"), order_type))
#Log("")
self.last_month = self.Time.month
self.Log("ORDER TYPE:: {0}".format(orderType))
isLong = self.quantity > 0
stopPrice = (1 + self.stop_percentage)*data["SPY"].High if isLong else (1 - self.stop_percentage)*data["SPY"].Low
limitPrice = (1 - self.limit_percentage)*stopPrice if isLong else (1 + self.limit_percentage)*stopPrice
self.last_month = self.time.month
self.log("ORDER TYPE:: {0}".format(order_type))
is_long = self.quantity > 0
stop_price = (1 + self.stop_percentage)*data["SPY"].high if is_long else (1 - self.stop_percentage)*data["SPY"].low
limit_price = (1 - self.limit_percentage)*stop_price if is_long else (1 + self.limit_percentage)*stop_price
if orderType == OrderType.Limit:
limitPrice = (1 + self.limit_percentage)*data["SPY"].High if not isLong else (1 - self.limit_percentage)*data["SPY"].Low
if order_type == OrderType.LIMIT:
limit_price = (1 + self.limit_percentage)*data["SPY"].high if not is_long else (1 - self.limit_percentage)*data["SPY"].low
request = SubmitOrderRequest(orderType, self.security.Symbol.SecurityType, "SPY", self.quantity, stopPrice, limitPrice, 0, 0.01, True,
self.UtcTime, str(orderType))
ticket = self.Transactions.AddOrder(request)
request = SubmitOrderRequest(order_type, self.security.symbol.security_type, "SPY", self.quantity, stop_price, limit_price, 0, 0.01, True,
self.utc_time, str(order_type))
ticket = self.transactions.add_order(request)
self.tickets.append(ticket)
elif len(self.tickets) > 0:
ticket = self.tickets[-1]
if self.Time.day > 8 and self.Time.day < 14:
if len(ticket.UpdateRequests) == 0 and ticket.Status is not OrderStatus.Filled:
self.Log("TICKET:: {0}".format(ticket))
updateOrderFields = UpdateOrderFields()
updateOrderFields.Quantity = ticket.Quantity + copysign(self.delta_quantity, self.quantity)
updateOrderFields.Tag = "Change quantity: {0}".format(self.Time.day)
ticket.Update(updateOrderFields)
if self.time.day > 8 and self.time.day < 14:
if len(ticket.update_requests) == 0 and ticket.status is not OrderStatus.FILLED:
self.log("TICKET:: {0}".format(ticket))
update_order_fields = UpdateOrderFields()
update_order_fields.quantity = ticket.quantity + copysign(self.delta_quantity, self.quantity)
update_order_fields.tag = "Change quantity: {0}".format(self.time.day)
ticket.update(update_order_fields)
elif self.Time.day > 13 and self.Time.day < 20:
if len(ticket.UpdateRequests) == 1 and ticket.Status is not OrderStatus.Filled:
self.Log("TICKET:: {0}".format(ticket))
updateOrderFields = UpdateOrderFields()
updateOrderFields.LimitPrice = self.security.Price*(1 - copysign(self.limit_percentage_delta, ticket.Quantity))
updateOrderFields.StopPrice = self.security.Price*(1 + copysign(self.stop_percentage_delta, ticket.Quantity)) if ticket.OrderType != OrderType.TrailingStop else None
updateOrderFields.Tag = "Change prices: {0}".format(self.Time.day)
ticket.Update(updateOrderFields)
elif self.time.day > 13 and self.time.day < 20:
if len(ticket.update_requests) == 1 and ticket.status is not OrderStatus.FILLED:
self.log("TICKET:: {0}".format(ticket))
update_order_fields = UpdateOrderFields()
update_order_fields.limit_price = self.security.price*(1 - copysign(self.limit_percentage_delta, ticket.quantity))
update_order_fields.stop_price = self.security.price*(1 + copysign(self.stop_percentage_delta, ticket.quantity)) if ticket.order_type != OrderType.TRAILING_STOP else None
update_order_fields.tag = "Change prices: {0}".format(self.time.day)
ticket.update(update_order_fields)
else:
if len(ticket.UpdateRequests) == 2 and ticket.Status is not OrderStatus.Filled:
self.Log("TICKET:: {0}".format(ticket))
ticket.Cancel("{0} and is still open!".format(self.Time.day))
self.Log("CANCELLED:: {0}".format(ticket.CancelRequest))
if len(ticket.update_requests) == 2 and ticket.status is not OrderStatus.FILLED:
self.log("TICKET:: {0}".format(ticket))
ticket.cancel("{0} and is still open!".format(self.time.day))
self.log("CANCELLED:: {0}".format(ticket.cancel_request))
def OnOrderEvent(self, orderEvent):
order = self.Transactions.GetOrderById(orderEvent.OrderId)
ticket = self.Transactions.GetOrderTicket(orderEvent.OrderId)
def on_order_event(self, orderEvent):
order = self.transactions.get_order_by_id(orderEvent.order_id)
ticket = self.transactions.get_order_ticket(orderEvent.order_id)
#order cancelations update CanceledTime
if order.Status == OrderStatus.Canceled and order.CanceledTime != orderEvent.UtcTime:
if order.status == OrderStatus.CANCELED and order.canceled_time != orderEvent.utc_time:
raise ValueError("Expected canceled order CanceledTime to equal canceled order event time.")
#fills update LastFillTime
if (order.Status == OrderStatus.Filled or order.Status == OrderStatus.PartiallyFilled) and order.LastFillTime != orderEvent.UtcTime:
if (order.status == OrderStatus.FILLED or order.status == OrderStatus.PARTIALLY_FILLED) and order.last_fill_time != orderEvent.utc_time:
raise ValueError("Expected filled order LastFillTime to equal fill order event time.")
# check the ticket to see if the update was successfully processed
if len([ur for ur in ticket.UpdateRequests if ur.Response is not None and ur.Response.IsSuccess]) > 0 and order.CreatedTime != self.UtcTime and order.LastUpdateTime is None:
if len([ur for ur in ticket.update_requests if ur.response is not None and ur.response.is_success]) > 0 and order.created_time != self.utc_time and order.last_update_time is None:
raise ValueError("Expected updated order LastUpdateTime to equal submitted update order event time")
if orderEvent.Status == OrderStatus.Filled:
self.Log("FILLED:: {0} FILL PRICE:: {1}".format(self.Transactions.GetOrderById(orderEvent.OrderId), orderEvent.FillPrice))
if orderEvent.status == OrderStatus.FILLED:
self.log("FILLED:: {0} FILL PRICE:: {1}".format(self.transactions.get_order_by_id(orderEvent.order_id), orderEvent.fill_price))
else:
self.Log(orderEvent.ToString())
self.Log("TICKET:: {0}".format(ticket))
self.log(orderEvent.to_string())
self.log("TICKET:: {0}".format(ticket))
@@ -26,26 +26,26 @@ from System.Collections.Generic import List
### <meta name="tag" content="custom universes" />
class UserDefinedUniverseAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetCash(100000)
self.SetStartDate(2015,1,1)
self.SetEndDate(2015,12,1)
def initialize(self):
self.set_cash(100000)
self.set_start_date(2015,1,1)
self.set_end_date(2015,12,1)
self.symbols = [ "SPY", "GOOG", "IBM", "AAPL", "MSFT", "CSCO", "ADBE", "WMT"]
self.UniverseSettings.Resolution = Resolution.Hour
self.AddUniverse('my_universe_name', Resolution.Hour, self.selection)
self.universe_settings.resolution = Resolution.HOUR
self.add_universe('my_universe_name', Resolution.HOUR, self.selection)
def selection(self, time):
index = time.hour%len(self.symbols)
return self.symbols[index]
return [self.symbols[index]]
def OnData(self, slice):
def on_data(self, slice):
pass
def OnSecuritiesChanged(self, changes):
for removed in changes.RemovedSecurities:
if removed.Invested:
self.Liquidate(removed.Symbol)
def on_securities_changed(self, changes):
for removed in changes.removed_securities:
if removed.invested:
self.liquidate(removed.symbol)
for added in changes.AddedSecurities:
self.SetHoldings(added.Symbol, 1/float(len(changes.AddedSecurities)))
for added in changes.added_securities:
self.set_holdings(added.symbol, 1/float(len(changes.added_securities)))
@@ -21,53 +21,53 @@ from AlgorithmImports import *
### <meta name="tag" content="consolidating data" />
class VolumeRenkoConsolidatorAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2013, 10, 7)
self.SetEndDate(2013, 10, 11)
self.SetCash(100000)
def initialize(self):
self.set_start_date(2013, 10, 7)
self.set_end_date(2013, 10, 11)
self.set_cash(100000)
self.sma = SimpleMovingAverage(10)
self.tick_consolidated = False
self.spy = self.AddEquity("SPY", Resolution.Minute).Symbol
self.spy = self.add_equity("SPY", Resolution.MINUTE).symbol
self.tradebar_volume_consolidator = VolumeRenkoConsolidator(1000000)
self.tradebar_volume_consolidator.DataConsolidated += self.OnSPYDataConsolidated
self.tradebar_volume_consolidator.data_consolidated += self.on_spy_data_consolidated
self.ibm = self.AddEquity("IBM", Resolution.Tick).Symbol
self.ibm = self.add_equity("IBM", Resolution.TICK).symbol
self.tick_volume_consolidator = VolumeRenkoConsolidator(1000000)
self.tick_volume_consolidator.DataConsolidated += self.OnIBMDataConsolidated
self.tick_volume_consolidator.data_consolidated += self.on_ibm_data_consolidated
history = self.History[TradeBar](self.spy, 1000, Resolution.Minute);
history = self.history[TradeBar](self.spy, 1000, Resolution.MINUTE)
for bar in history:
self.tradebar_volume_consolidator.Update(bar)
self.tradebar_volume_consolidator.update(bar)
def OnSPYDataConsolidated(self, sender, bar):
self.sma.Update(bar.EndTime, bar.Value)
self.Debug(f"SPY {bar.Time} to {bar.EndTime} :: O:{bar.Open} H:{bar.High} L:{bar.Low} C:{bar.Close} V:{bar.Volume}")
if bar.Volume != 1000000:
def on_spy_data_consolidated(self, sender, bar):
self.sma.update(bar.end_time, bar.value)
self.debug(f"SPY {bar.time} to {bar.end_time} :: O:{bar.open} H:{bar.high} L:{bar.low} C:{bar.close} V:{bar.volume}")
if bar.volume != 1000000:
raise Exception("Volume of consolidated bar does not match set value!")
def OnIBMDataConsolidated(self, sender, bar):
self.Debug(f"IBM {bar.Time} to {bar.EndTime} :: O:{bar.Open} H:{bar.High} L:{bar.Low} C:{bar.Close} V:{bar.Volume}")
if bar.Volume != 1000000:
def on_ibm_data_consolidated(self, sender, bar):
self.debug(f"IBM {bar.time} to {bar.end_time} :: O:{bar.open} H:{bar.high} L:{bar.low} C:{bar.close} V:{bar.volume}")
if bar.volume != 1000000:
raise Exception("Volume of consolidated bar does not match set value!")
self.tick_consolidated = True
def OnData(self, slice):
def on_data(self, slice):
# Update by TradeBar
if slice.Bars.ContainsKey(self.spy):
self.tradebar_volume_consolidator.Update(slice.Bars[self.spy])
if slice.bars.contains_key(self.spy):
self.tradebar_volume_consolidator.update(slice.bars[self.spy])
# Update by Tick
if slice.Ticks.ContainsKey(self.ibm):
for tick in slice.Ticks[self.ibm]:
self.tick_volume_consolidator.Update(tick)
if slice.ticks.contains_key(self.ibm):
for tick in slice.ticks[self.ibm]:
self.tick_volume_consolidator.update(tick)
if self.sma.IsReady and self.sma.Current.Value < self.Securities[self.spy].Price:
self.SetHoldings(self.spy, 1)
if self.sma.is_ready and self.sma.current.value < self.securities[self.spy].price:
self.set_holdings(self.spy, 1)
else:
self.SetHoldings(self.spy, 0)
self.set_holdings(self.spy, 0)
def OnEndOfAlgorithm(self):
def on_end_of_algorithm(self):
if not self.tick_consolidated:
raise Exception("Tick consolidator was never been called")