Skip to content

Commit 020cf01

Browse files
Fix bug/syntax in python examples (#8658)
* CustomDataRegressionAlgorithm * DescendingCustomDataObjectStoreRegressionAlgorithm * CustomDataPropertiesRegressionAlgorithm * DateTime -> should be datetime * KerasNeuralNetworkAlgorithm * OptionIndicatorsMirrorContractsRegressionAlgorithm * BybitCustomDataCryptoRegressionAlgorithm * DropboxBaseDataUniverseSelectionAlgorithm * UserDefinedUniverseAlgorithm * CompleteOrderTagUpdateAlgorithm * BasicTemplateOptionEquityStrategyAlgorithm hint * ETFConstituentUniverseFrameworkRegressionAlgorithm * FutureStopMarketOrderOnExtendedHoursRegressionAlgorithm * SecurityDynamicPropertyPythonClassAlgorithm * hint * hinting * CallbackCommandRegressionAlgorithm * CustomWarmUpPeriodIndicatorAlgorithm * CrunchDAOSignalExportDemonstrationAlgorithm * ExpiryHelperAlphaModelFrameworkAlgorithm * ClassicRenkoConsolidatorAlgorithm * SmaCrossUniverseSelectionAlgorithm * PEP8 Fix: Assigning to a Method * SliceGetByTypeRegressionAlgorithm * MarketOnCloseOrderBufferExtendedMarketHoursRegressionAlgorithm * MarketOnCloseOrderBufferRegressionAlgorithm * CustomIndicatorAlgorithm * ScheduledQueuingAlgorithm * ComboOrdersFillModelAlgorithm * CustomIndicatorWithExtensionAlgorithm * IndicatorWithRenkoBarsRegressionAlgorithm * CoarseFineOptionUniverseChainRegressionAlgorithm * NumeraiSignalExportDemonstrationAlgorithm * DropboxUniverseSelectionAlgorithm * WeeklyUniverseSelectionRegressionAlgorithm * AutoRegressiveIntegratedMovingAverageRegressionAlgorithm * DropboxBaseDataUniverseSelectionAlgorithm * IronCondorStrategyAlgorithm * LongAndShortButterflyPutStrategiesAlgorithm * FutureStopMarketOrderOnExtendedHoursRegressionAlgorithm * LongAndShortCallCalendarSpreadStrategiesAlgorithm * KerasNeuralNetworkAlgorithm * LongAndShortPutCalendarSpreadStrategiesAlgorithm * OptionPriceModelForOptionStylesBaseRegressionAlgorithm * TensorFlowNeuralNetworkAlgorithm * MarketOnCloseOrderBufferRegressionAlgorithm * MarketOnCloseOrderBufferExtendedMarketHoursRegressionAlgorithm * typing * ComboOrderTicketDemoAlgorithm * PytorchNeuralNetworkAlgorithm * MultipleSymbolConsolidationAlgorithm * fixes * revert getattr mypy syntax * address peer review * Addresses Peer-Review --------- Co-authored-by: Alexandre Catarino <AlexCatarino@users.noreply.github.com>
1 parent fe46e5e commit 020cf01

55 files changed

Lines changed: 718 additions & 739 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Algorithm.Python/AutoRegressiveIntegratedMovingAverageRegressionAlgorithm.py‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,26 @@
1919
# is sufficiently large (which would be due to the inclusion of the MA(1) term).
2020
# </summary>
2121
class AutoRegressiveIntegratedMovingAverageRegressionAlgorithm(QCAlgorithm):
22-
def initialize(self):
22+
def initialize(self) -> None:
2323
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
2424
self.set_start_date(2013, 1, 7)
2525
self.set_end_date(2013, 12, 11)
2626
self.settings.automatic_indicator_warm_up = True
2727
self.add_equity("SPY", Resolution.DAILY)
2828
self._arima = self.arima("SPY", 1, 1, 1, 50)
2929
self._ar = self.arima("SPY", 1, 1, 0, 50)
30+
self._last = None
3031

31-
def on_data(self, data):
32+
def on_data(self, data: Slice) -> None:
3233
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
3334
3435
Arguments:
3536
data: Slice object keyed by symbol containing the stock data
3637
'''
3738
if self._arima.is_ready:
3839
if abs(self._arima.current.value - self._ar.current.value) > 1:
39-
if self._arima.current.value > self.last:
40+
if self._arima.current.value > self._last:
4041
self.market_order("SPY", 1)
4142
else:
4243
self.market_order("SPY", -1)
43-
self.last = self._arima.current.value
44+
self._last = self._arima.current.value

‎Algorithm.Python/BasicTemplateOptionEquityStrategyAlgorithm.py‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,25 @@
2424
class BasicTemplateOptionEquityStrategyAlgorithm(QCAlgorithm):
2525
underlying_ticker = "GOOG"
2626

27-
def initialize(self):
27+
def initialize(self) -> None:
2828
self.set_start_date(2015, 12, 24)
2929
self.set_end_date(2015, 12, 24)
3030

3131
equity = self.add_equity(self.underlying_ticker)
3232
option = self.add_option(self.underlying_ticker)
33-
self.option_symbol = option.symbol
33+
self._option_symbol = option.symbol
3434

3535
# set our strike/expiry filter for this option chain
3636
option.set_filter(lambda u: (u.strikes(-2, +2)
3737
# Expiration method accepts TimeSpan objects or integer for days.
3838
# The following statements yield the same filtering criteria
3939
.expiration(0, 180)))
4040

41-
def on_data(self, slice):
42-
if self.portfolio.invested or not self.is_market_open(self.option_symbol): return
41+
def on_data(self, slice: Slice) -> None:
42+
if self.portfolio.invested or not self.is_market_open(self._option_symbol):
43+
return
4344

44-
chain = slice.option_chains.get_value(self.option_symbol)
45+
chain = slice.option_chains.get_value(self._option_symbol)
4546
if chain is None:
4647
return
4748

@@ -57,9 +58,9 @@ def on_data(self, slice):
5758
middle_strike = call_contracts[1].strike
5859
higher_strike = call_contracts[2].strike
5960

60-
option_strategy = OptionStrategies.call_butterfly(self.option_symbol, higher_strike, middle_strike, lower_strike, expiry)
61+
option_strategy = OptionStrategies.call_butterfly(self._option_symbol, higher_strike, middle_strike, lower_strike, expiry)
6162

6263
self.order(option_strategy, 10)
6364

64-
def on_order_event(self, order_event):
65+
def on_order_event(self, order_event: OrderEvent) -> None:
6566
self.log(str(order_event))

‎Algorithm.Python/Benchmarks/IndicatorRibbonBenchmark.py‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,25 +19,25 @@ class IndicatorRibbonBenchmark(QCAlgorithm):
1919
def initialize(self):
2020
self.set_start_date(2010, 1, 1) #Set Start Date
2121
self.set_end_date(2018, 1, 1) #Set End Date
22-
self.spy = self.add_equity("SPY", Resolution.MINUTE).symbol
22+
self._spy = self.add_equity("SPY", Resolution.MINUTE).symbol
2323
count = 50
2424
offset = 5
2525
period = 15
26-
self.ribbon = []
26+
self._ribbon = []
2727
# define our sma as the base of the ribbon
28-
self.sma = SimpleMovingAverage(period)
28+
self._sma = SimpleMovingAverage(period)
2929

3030
for x in range(count):
3131
# define our offset to the zero sma, these various offsets will create our 'displaced' ribbon
3232
delay = Delay(offset*(x+1))
3333
# define an indicator that takes the output of the sma and pipes it into our delay indicator
34-
delayed_sma = IndicatorExtensions.of(delay, self.sma)
34+
delayed_sma = IndicatorExtensions.of(delay, self._sma)
3535
# register our new 'delayed_sma' for automatic updates on a daily resolution
36-
self.register_indicator(self.spy, delayed_sma, Resolution.DAILY)
37-
self.ribbon.append(delayed_sma)
36+
self.register_indicator(self._spy, delayed_sma, Resolution.DAILY)
37+
self._ribbon.append(delayed_sma)
3838

3939
def on_data(self, data):
4040
# wait for our entire ribbon to be ready
41-
if not all(x.is_ready for x in self.ribbon): return
42-
for x in self.ribbon:
41+
if not all(x.is_ready for x in self._ribbon): return
42+
for x in self._ribbon:
4343
value = x.current.value

‎Algorithm.Python/BybitCustomDataCryptoRegressionAlgorithm.py‎

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111
# See the License for the specific language governing permissions and
1212
# limitations under the License.
1313

14+
from datetime import time
15+
import os
1416
from AlgorithmImports import *
15-
import datetime
1617

1718
### <summary>
1819
### Algorithm demonstrating and ensuring that Bybit crypto brokerage model works as expected with custom data types
1920
### </summary>
2021
class BybitCustomDataCryptoRegressionAlgorithm(QCAlgorithm):
2122

22-
def initialize(self):
23+
def initialize(self) -> None:
2324
self.set_start_date(2022, 12, 13)
2425
self.set_end_date(2022, 12, 13)
2526

@@ -29,42 +30,42 @@ def initialize(self):
2930
self.set_brokerage_model(BrokerageName.BYBIT, AccountType.CASH)
3031

3132
symbol = self.add_crypto("BTCUSDT").symbol
32-
self.btc_usdt = self.add_data(CustomCryptoData, symbol, Resolution.MINUTE).symbol
33+
self._btc_usdt = self.add_data(CustomCryptoData, symbol, Resolution.MINUTE).symbol
3334

3435
# create two moving averages
35-
self.fast = self.ema(self.btc_usdt, 30, Resolution.MINUTE)
36-
self.slow = self.ema(self.btc_usdt, 60, Resolution.MINUTE)
36+
self._fast = self.ema(self._btc_usdt, 30, Resolution.MINUTE)
37+
self._slow = self.ema(self._btc_usdt, 60, Resolution.MINUTE)
3738

38-
def on_data(self, data):
39-
if not self.slow.is_ready:
39+
def on_data(self, data: Slice) -> None:
40+
if not self._slow.is_ready:
4041
return
4142

42-
if self.fast.current.value > self.slow.current.value:
43+
if self._fast.current.value > self._slow.current.value:
4344
if self.transactions.orders_count == 0:
44-
self.buy(self.btc_usdt, 1)
45+
self.buy(self._btc_usdt, 1)
4546
else:
4647
if self.transactions.orders_count == 1:
47-
self.liquidate(self.btc_usdt)
48+
self.liquidate(self._btc_usdt)
4849

49-
def on_order_event(self, order_event):
50+
def on_order_event(self, order_event: OrderEvent) -> None:
5051
self.debug(f"{self.time} {order_event}")
5152

5253
class CustomCryptoData(PythonData):
53-
def get_source(self, config, date, is_live_mode):
54+
def get_source(self, config: SubscriptionDataConfig, date: datetime, is_live_mode: bool) -> SubscriptionDataSource:
5455
tick_type_string = Extensions.tick_type_to_lower(config.tick_type)
5556
formatted_date = date.strftime("%Y%m%d")
56-
source = os.path.join(Globals.DataFolder, "crypto", "bybit", "minute",
57+
source = os.path.join(Globals.data_folder, "crypto", "bybit", "minute",
5758
config.symbol.value.lower(), f"{formatted_date}_{tick_type_string}.zip")
5859

5960
return SubscriptionDataSource(source, SubscriptionTransportMedium.LOCAL_FILE, FileFormat.CSV)
6061

61-
def reader(self, config, line, date, is_live_mode):
62+
def reader(self, config: SubscriptionDataConfig, line: str, date: datetime, is_live_mode: bool) -> BaseData:
6263
csv = line.split(',')
6364

6465
data = CustomCryptoData()
6566
data.symbol = config.symbol
6667

67-
data_datetime = datetime.datetime.combine(date.date(), datetime.time()) + timedelta(milliseconds=int(csv[0]))
68+
data_datetime = datetime.combine(date.date(), time()) + timedelta(milliseconds=int(csv[0]))
6869
data.time = Extensions.convert_to(data_datetime, config.data_time_zone, config.exchange_time_zone)
6970
data.end_time = data.time + timedelta(minutes=1)
7071

‎Algorithm.Python/CallbackCommandRegressionAlgorithm.py‎

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@ class VoidCommand():
2222
parameters = {}
2323
targettime = None
2424

25-
def run(self, algo: QCAlgorithm) -> bool | None:
25+
def run(self, algo: IAlgorithm) -> bool:
2626
if not self.targettime or self.targettime != algo.time:
27-
return
27+
return False
2828
tag = self.parameters["tag"]
2929
algo.order(self.target[0], self.get_quantity(), tag=tag)
30+
return True
3031

3132
def get_quantity(self):
3233
return self.quantity
@@ -36,7 +37,7 @@ class BoolCommand(Command):
3637
array_test = []
3738
result = False
3839

39-
def run(self, algo: QCAlgorithm) -> bool | None:
40+
def run(self, algo: QCAlgorithm) -> bool:
4041
trade_ibm = self.my_custom_method()
4142
if trade_ibm:
4243
algo.debug(f"BoolCommand.run: {str(self)}")
@@ -96,13 +97,13 @@ def initialize(self):
9697

9798
# We need to create a project on QuantConnect to test the broadcast_command method
9899
# and use the project_id in the broadcast_command call
99-
self.project_id = 21805137;
100+
self.project_id = 21805137
100101

101102
# All live deployments receive the broadcasts below
102-
broadcast_result = self.broadcast_command(potential_command);
103-
broadcast_result2 = self.broadcast_command({ "symbol": "SPY", "parameters": { "quantity": 10 } });
103+
broadcast_result = self.broadcast_command(potential_command)
104+
broadcast_result2 = self.broadcast_command({ "symbol": "SPY", "parameters": { "quantity": 10 } })
104105

105-
def on_command(self, data):
106+
def on_command(self, data: object) -> bool:
106107
self.debug(f"on_command: {str(data)}")
107108
self.buy(data.symbol, data.parameters["quantity"])
108109
return True # False, None

‎Algorithm.Python/ClassicRangeConsolidatorAlgorithm.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
### Example algorithm of how to use ClassicRangeConsolidator
2020
### </summary>
2121
class ClassicRangeConsolidatorAlgorithm(RangeConsolidatorAlgorithm):
22-
def create_range_consolidator(self):
22+
def create_range_consolidator(self) -> ClassicRangeConsolidator:
2323
return ClassicRangeConsolidator(self.get_range())
2424

25-
def on_data_consolidated(self, sender, range_bar):
25+
def on_data_consolidated(self, sender: object, range_bar: RangeBar):
2626
super().on_data_consolidated(sender, range_bar)
2727

2828
if range_bar.volume == 0:

‎Algorithm.Python/ClassicRenkoConsolidatorAlgorithm.py‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323
class ClassicRenkoConsolidatorAlgorithm(QCAlgorithm):
2424
'''Demonstration of how to initialize and use the RenkoConsolidator'''
2525

26-
def initialize(self):
27-
26+
def initialize(self) -> None:
2827
self.set_start_date(2012, 1, 1)
2928
self.set_end_date(2013, 1, 1)
3029

@@ -48,11 +47,11 @@ def initialize(self):
4847

4948

5049
# We're doing our analysis in the on_renko_bar method, but the framework verifies that this method exists, so we define it.
51-
def on_data(self, data):
50+
def on_data(self, data: Slice) -> None:
5251
pass
5352

5453

55-
def handle_renko_close(self, sender, data):
54+
def handle_renko_close(self, sender: object, data: RenkoBar) -> None:
5655
'''This function is called by our renko_close consolidator defined in Initialize()
5756
Args:
5857
data: The new renko bar produced by the consolidator'''
@@ -62,7 +61,7 @@ def handle_renko_close(self, sender, data):
6261
self.log(f"CLOSE - {data.time} - {data.open} {data.close}")
6362

6463

65-
def handle_renko7_bar(self, sender, data):
64+
def handle_renko7_bar(self, sender: object, data: RenkoBar) -> None:
6665
'''This function is called by our renko7bar consolidator defined in Initialize()
6766
Args:
6867
data: The new renko bar produced by the consolidator'''

‎Algorithm.Python/CoarseFineOptionUniverseChainRegressionAlgorithm.py‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
### </summary>
2020
class CoarseFineOptionUniverseChainRegressionAlgorithm(QCAlgorithm):
2121

22-
def initialize(self):
22+
def initialize(self) -> None:
2323
'''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
2424

2525
self.set_start_date(2014,6,4)
@@ -41,27 +41,27 @@ def initialize(self):
4141

4242
self.add_universe_options(universe, self.option_filter_function)
4343

44-
def option_filter_function(self, universe):
44+
def option_filter_function(self, universe: OptionFilterUniverse) -> OptionFilterUniverse:
4545
universe.include_weeklys().front_month()
4646

47-
contracts: list[OptionUniverse] = list()
47+
contracts = list()
4848
for contract in universe:
4949
if len(contracts) == 5:
5050
break
5151
contracts.append(contract)
5252
return universe.contracts(contracts)
5353

54-
def coarse_selection_function(self, coarse):
54+
def coarse_selection_function(self, coarse: list[CoarseFundamental]) -> list[Symbol]:
5555
if self.time <= datetime(2014,6,5):
5656
return [ self._twx ]
5757
return [ self._aapl ]
5858

59-
def fine_selection_function(self, fine):
59+
def fine_selection_function(self, fine: list[FineFundamental]) -> list[Symbol]:
6060
if self.time <= datetime(2014,6,5):
6161
return [ self._twx ]
6262
return [ self._aapl ]
6363

64-
def on_data(self, data):
64+
def on_data(self, data: Slice) -> None:
6565
if self._changes == None or any(security.price == 0 for security in self._changes.added_securities):
6666
return
6767

@@ -83,12 +83,12 @@ def on_data(self, data):
8383
self._changes = None
8484

8585
# this event fires whenever we have changes to our universe
86-
def on_securities_changed(self, changes):
86+
def on_securities_changed(self, changes: SecurityChanges) -> None:
8787
if self._changes == None:
8888
self._changes = changes
8989
return
9090
self._changes = self._changes + changes
9191

92-
def on_end_of_algorithm(self):
92+
def on_end_of_algorithm(self) -> None:
9393
if self._option_count == 0:
9494
raise ValueError("Option universe chain did not add any option!")

0 commit comments

Comments
 (0)