* t status pep8 conversion * Minor tweaks and rebase * Various minor fixes --------- Co-authored-by: Martin Molinero <martin.molinero1@gmail.com>
This commit is contained in:
@@ -42,7 +42,7 @@ class AllShortableSymbolsCoarseSelectionRegressionAlgorithm(QCAlgorithm):
|
||||
self.set_start_date(2014, 3, 25)
|
||||
self.set_end_date(2014, 3, 29)
|
||||
self.set_cash(10000000)
|
||||
self.shortable_provider = RegressionTestShortableProvider();
|
||||
self.shortable_provider = RegressionTestShortableProvider()
|
||||
self.security = self.add_equity(self._spy)
|
||||
|
||||
self.add_universe(self.coarse_selection)
|
||||
@@ -86,7 +86,7 @@ class AllShortableSymbolsCoarseSelectionRegressionAlgorithm(QCAlgorithm):
|
||||
if len(missing) != expected_missing:
|
||||
raise Exception(f"Expected Symbols selected on {self.time.strftime('%Y%m%d')} to match expected Symbols, but the following Symbols were missing: {', '.join(list(map(lambda x:x.value, missing)))}")
|
||||
|
||||
self.coarse_selected[self.time] = True;
|
||||
self.coarse_selected[self.time] = True
|
||||
return selected_symbols
|
||||
|
||||
def on_end_of_algorithm(self):
|
||||
@@ -126,7 +126,7 @@ class RegressionTestShortableProvider(LocalDiskShortableProvider):
|
||||
|
||||
symbol = Symbol(SecurityIdentifier.generate_equity(ticker, Market.USA, mapping_resolve_date = localtime), ticker)
|
||||
quantity = int(csv[1])
|
||||
all_symbols[symbol] = quantity;
|
||||
all_symbols[symbol] = quantity
|
||||
|
||||
if len(all_symbols) > 0:
|
||||
return all_symbols
|
||||
|
||||
@@ -22,8 +22,8 @@ class BaseFrameworkRegressionAlgorithm(QCAlgorithm):
|
||||
self.set_start_date(2014, 6, 1)
|
||||
self.set_end_date(2014, 6, 30)
|
||||
|
||||
self.universe_settings.resolution = Resolution.HOUR;
|
||||
self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW;
|
||||
self.universe_settings.resolution = Resolution.HOUR
|
||||
self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW
|
||||
|
||||
symbols = [Symbol.create(ticker, SecurityType.EQUITY, Market.USA)
|
||||
for ticker in ["AAPL", "AIG", "BAC", "SPY"]]
|
||||
|
||||
@@ -29,9 +29,9 @@ class BrokerageModelAlgorithm(QCAlgorithm):
|
||||
self.add_equity("SPY", Resolution.SECOND)
|
||||
|
||||
# there's two ways to set your brokerage model. The easiest would be to call
|
||||
# SetBrokerageModel( BrokerageName ); // BrokerageName is an enum
|
||||
# SetBrokerageModel(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE);
|
||||
# SetBrokerageModel(BrokerageName.DEFAULT);
|
||||
# self.set_brokerage_model( BrokerageName ) # BrokerageName is an enum
|
||||
# self.set_brokerage_model(BrokerageName.INTERACTIVE_BROKERS_BROKERAGE)
|
||||
# self.set_brokerage_model(BrokerageName.DEFAULT)
|
||||
|
||||
# the other way is to call SetBrokerageModel( IBrokerageModel ) with your
|
||||
# own custom model. I've defined a simple extension to the default brokerage
|
||||
|
||||
@@ -29,7 +29,7 @@ class BybitCustomDataCryptoRegressionAlgorithm(QCAlgorithm):
|
||||
self.set_brokerage_model(BrokerageName.BYBIT, AccountType.CASH)
|
||||
|
||||
symbol = self.add_crypto("BTCUSDT").symbol
|
||||
self.btc_usdt = self.add_data(CustomCryptoData, symbol, Resolution.MINUTE).symbol;
|
||||
self.btc_usdt = self.add_data(CustomCryptoData, symbol, Resolution.MINUTE).symbol
|
||||
|
||||
# create two moving averages
|
||||
self.fast = self.ema(self.btc_usdt, 30, Resolution.MINUTE)
|
||||
@@ -47,7 +47,7 @@ class BybitCustomDataCryptoRegressionAlgorithm(QCAlgorithm):
|
||||
self.liquidate(self.btc_usdt)
|
||||
|
||||
def on_order_event(self, order_event):
|
||||
self.debug(f"{self.time} {order_event}");
|
||||
self.debug(f"{self.time} {order_event}")
|
||||
|
||||
class CustomCryptoData(PythonData):
|
||||
def get_source(self, config, date, is_live_mode):
|
||||
|
||||
@@ -44,8 +44,8 @@ class Collective2PortfolioSignalExportDemonstrationAlgorithm(QCAlgorithm):
|
||||
self.slow = self.ema("SPY", 100)
|
||||
|
||||
# Initialize these flags, to check when the ema indicators crosses between themselves
|
||||
self.ema_fast_is_not_set = True;
|
||||
self.ema_fast_was_above = False;
|
||||
self.ema_fast_is_not_set = True
|
||||
self.ema_fast_was_above = False
|
||||
|
||||
# Collective2 APIv4 KEY: This value is provided by Collective2 in their webpage in your account section (See https://collective2.com/account-info)
|
||||
# See API documentation at https://trade.collective2.com/c2-api
|
||||
@@ -80,7 +80,7 @@ class Collective2PortfolioSignalExportDemonstrationAlgorithm(QCAlgorithm):
|
||||
self.ema_fast_was_above = True
|
||||
else:
|
||||
self.ema_fast_was_above = False
|
||||
self.ema_fast_is_not_set = False;
|
||||
self.ema_fast_is_not_set = False
|
||||
|
||||
# Check whether ema fast and ema slow crosses. If they do, set holdings to SPY
|
||||
# or reduce its holdings, and send signals to Collective2 API from your Portfolio
|
||||
|
||||
@@ -50,8 +50,8 @@ class Collective2SignalExportDemonstrationAlgorithm(QCAlgorithm):
|
||||
self.slow = self.ema("SPY", 100)
|
||||
|
||||
# Initialize these flags, to check when the ema indicators crosses between themselves
|
||||
self.ema_fast_is_not_set = True;
|
||||
self.ema_fast_was_above = False;
|
||||
self.ema_fast_is_not_set = True
|
||||
self.ema_fast_was_above = False
|
||||
|
||||
# Set Collective2 export provider
|
||||
# Collective2 APIv4 KEY: This value is provided by Collective2 in your account section (See https://collective2.com/account-info)
|
||||
@@ -88,7 +88,7 @@ class Collective2SignalExportDemonstrationAlgorithm(QCAlgorithm):
|
||||
self.ema_fast_was_above = True
|
||||
else:
|
||||
self.ema_fast_was_above = False
|
||||
self.ema_fast_is_not_set = False;
|
||||
self.ema_fast_is_not_set = False
|
||||
|
||||
# Check whether ema fast and ema slow crosses. If they do, set holdings to SPY
|
||||
# or reduce its holdings, change its value in self.targets list and send signals
|
||||
|
||||
@@ -53,7 +53,7 @@ class ComboOrderTicketDemoAlgorithm(QCAlgorithm):
|
||||
quantities = [1, -2, 1]
|
||||
self._order_legs = []
|
||||
for i, contract in enumerate(call_contracts[:3]):
|
||||
leg = Leg.create(contract.symbol, quantities[i]);
|
||||
leg = Leg.create(contract.symbol, quantities[i])
|
||||
self._order_legs.append(leg)
|
||||
else:
|
||||
# COMBO MARKET ORDERS
|
||||
@@ -70,7 +70,7 @@ class ComboOrderTicketDemoAlgorithm(QCAlgorithm):
|
||||
|
||||
def combo_market_orders(self):
|
||||
if len(self._open_market_orders) != 0 or self._order_legs is None:
|
||||
return;
|
||||
return
|
||||
|
||||
self.log("Submitting combo market orders")
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ class CustomPartialFillModel(FillModel):
|
||||
return partial_fills
|
||||
|
||||
for kvp, fill in zip(sorted(parameters.securities_for_orders, key=lambda x: x.key.id), fills):
|
||||
order = kvp.key;
|
||||
order = kvp.key
|
||||
|
||||
absolute_remaining = self.absolute_remaining_by_order_id.get(order.id, order.absolute_quantity)
|
||||
|
||||
@@ -108,11 +108,11 @@ class CustomPartialFillModel(FillModel):
|
||||
return partial_fills
|
||||
|
||||
def combo_limit_fill(self, order, parameters):
|
||||
fills = super().combo_limit_fill(order, parameters);
|
||||
fills = super().combo_limit_fill(order, parameters)
|
||||
partial_fills = self.fill_orders_partially(parameters, fills, 20)
|
||||
return partial_fills
|
||||
|
||||
def combo_leg_limit_fill(self, order, parameters):
|
||||
fills = super().combo_leg_limit_fill(order, parameters);
|
||||
fills = super().combo_leg_limit_fill(order, parameters)
|
||||
partial_fills = self.fill_orders_partially(parameters, fills, 10)
|
||||
return partial_fills
|
||||
|
||||
@@ -18,8 +18,8 @@ from AlgorithmImports import *
|
||||
### </summary>
|
||||
class CompleteOrderTagUpdateAlgorithm(QCAlgorithm):
|
||||
|
||||
tag_after_fill = "This is the tag set after order was filled.";
|
||||
tag_after_canceled = "This is the tag set after order was canceled.";
|
||||
tag_after_fill = "This is the tag set after order was filled."
|
||||
tag_after_canceled = "This is the tag set after order was canceled."
|
||||
|
||||
def initialize(self) -> None:
|
||||
self.set_start_date(2013,10, 7)
|
||||
|
||||
@@ -32,8 +32,8 @@ class CustomBrokerageModelRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
def on_data(self, slice):
|
||||
if not self.portfolio.invested:
|
||||
self.market_order("SPY", 100.0);
|
||||
self.aig_ticket = self.market_order("AIG", 100.0);
|
||||
self.market_order("SPY", 100.0)
|
||||
self.aig_ticket = self.market_order("AIG", 100.0)
|
||||
|
||||
def on_order_event(self, order_event):
|
||||
spy_ticket = self.transactions.get_order_ticket(order_event.order_id)
|
||||
|
||||
@@ -62,4 +62,4 @@ class CustomBuyingPowerModel(BuyingPowerModel):
|
||||
# Override this as well because the base implementation calls GetMaintenanceMargin (overridden)
|
||||
# because in C# it wouldn't resolve the overridden Python method
|
||||
def get_reserved_buying_power_for_position(self, parameters):
|
||||
return parameters.result_in_account_currency(0);
|
||||
return parameters.result_in_account_currency(0)
|
||||
|
||||
@@ -31,14 +31,14 @@ class CustomDataBenchmarkRegressionAlgorithm(QCAlgorithm):
|
||||
self.set_holdings("SPY", 1)
|
||||
|
||||
def on_end_of_algorithm(self):
|
||||
security_benchmark = self.benchmark;
|
||||
security_benchmark = self.benchmark
|
||||
if security_benchmark.security.price == 0:
|
||||
raise Exception("Security benchmark price was not expected to be zero")
|
||||
|
||||
class ExampleCustomData(PythonData):
|
||||
|
||||
def get_source(self, config, date, is_live):
|
||||
source = "https://www.dl.dropboxusercontent.com/s/d83xvd7mm9fzpk0/path_to_my_csv_data.csv?dl=0";
|
||||
source = "https://www.dl.dropboxusercontent.com/s/d83xvd7mm9fzpk0/path_to_my_csv_data.csv?dl=0"
|
||||
return SubscriptionDataSource(source, SubscriptionTransportMedium.REMOTE_FILE)
|
||||
|
||||
def reader(self, config, line, date, is_live):
|
||||
|
||||
@@ -43,7 +43,7 @@ class CustomSettlementModelRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
class CustomSettlementModel:
|
||||
def apply_funds(self, parameters):
|
||||
self.currency = parameters.cash_amount.currency;
|
||||
self.currency = parameters.cash_amount.currency
|
||||
self.amount = parameters.cash_amount.amount
|
||||
parameters.portfolio.cash_book[self.currency].add_amount(self.amount)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ from AlgorithmImports import *
|
||||
class CustomShortableProviderRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
def initialize(self):
|
||||
self.set_cash(10000000);
|
||||
self.set_cash(10000000)
|
||||
self.set_start_date(2013,10,4)
|
||||
self.set_end_date(2013,10,6)
|
||||
self.spy = self.add_security(SecurityType.EQUITY, "SPY", Resolution.DAILY)
|
||||
|
||||
@@ -127,10 +127,10 @@ class ETFConstituentUniverseFrameworkRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
historical_data = self.history(universe, 1)
|
||||
if len(historical_data) != 1:
|
||||
raise ValueError(f"Unexpected history count {len(historical_data)}! Expected 1");
|
||||
raise ValueError(f"Unexpected history count {len(historical_data)}! Expected 1")
|
||||
for universe_data_collection in historical_data:
|
||||
if len(universe_data_collection) < 200:
|
||||
raise ValueError(f"Unexpected universe DataCollection count {len(universe_data_collection)}! Expected > 200");
|
||||
raise ValueError(f"Unexpected universe DataCollection count {len(universe_data_collection)}! Expected > 200")
|
||||
|
||||
### <summary>
|
||||
### Filters ETF constituents
|
||||
|
||||
@@ -37,10 +37,10 @@ class IndicatorWarmupAlgorithm(QCAlgorithm):
|
||||
|
||||
self.__sd = { }
|
||||
for security in self.securities:
|
||||
self.__sd[security.key] = self.symbol_data(security.key, self)
|
||||
self.__sd[security.key] = self.SymbolData(security.key, self)
|
||||
|
||||
# we want to warm up our algorithm
|
||||
self.set_warmup(self.symbol_data.required_bars_warmup)
|
||||
self.set_warmup(self.SymbolData.REQUIRED_BARS_WARMUP)
|
||||
|
||||
def on_data(self, data):
|
||||
'''on_data event is the primary entry point for your algorithm. Each new data point will be pumped in here.
|
||||
@@ -68,10 +68,10 @@ class IndicatorWarmupAlgorithm(QCAlgorithm):
|
||||
return time.second == 0
|
||||
|
||||
class SymbolData:
|
||||
RequiredBarsWarmup = 40
|
||||
PercentTolerance = 0.001
|
||||
PercentGlobalStopLoss = 0.01
|
||||
LotSize = 10
|
||||
REQUIRED_BARS_WARMUP = 40
|
||||
PERCENT_TOLERANCE = 0.001
|
||||
PERCENT_GLOBAL_STOP_LOSS = 0.01
|
||||
LOT_SIZE = 10
|
||||
|
||||
def __init__(self, symbol, algorithm):
|
||||
self.symbol = symbol
|
||||
@@ -92,7 +92,7 @@ class IndicatorWarmupAlgorithm(QCAlgorithm):
|
||||
def update(self):
|
||||
self.is_ready = self.close.is_ready and self._adx.is_ready and self._ema.is_ready and self._macd.is_ready
|
||||
|
||||
tolerance = 1 - self.percent_tolerance
|
||||
tolerance = 1 - self.PERCENT_TOLERANCE
|
||||
self.is_uptrend = self._macd.signal.current.value > self._macd.current.value * tolerance and\
|
||||
self._ema.current.value > self.close.current.value * tolerance
|
||||
|
||||
@@ -111,10 +111,10 @@ class IndicatorWarmupAlgorithm(QCAlgorithm):
|
||||
|
||||
if self.is_uptrend:
|
||||
# 100 order lots
|
||||
qty = self.lot_size
|
||||
qty = self.LOT_SIZE
|
||||
limit = self.security.low
|
||||
elif self.is_downtrend:
|
||||
qty = -self.lot_size
|
||||
qty = -self.LOT_SIZE
|
||||
limit = self.security.high
|
||||
|
||||
if qty != 0:
|
||||
@@ -126,7 +126,7 @@ class IndicatorWarmupAlgorithm(QCAlgorithm):
|
||||
|
||||
limit = 0
|
||||
qty = self.security.holdings.quantity
|
||||
exit_tolerance = 1 + 2 * self.percent_tolerance
|
||||
exit_tolerance = 1 + 2 * self.PERCENT_TOLERANCE
|
||||
if self.security.holdings.is_long and self.close.current.value * exit_tolerance < self._ema.current.value:
|
||||
limit = self.security.high
|
||||
elif self.security.holdings.is_short and self.close.current.value > self._ema.current.value * exit_tolerance:
|
||||
@@ -142,8 +142,8 @@ class IndicatorWarmupAlgorithm(QCAlgorithm):
|
||||
|
||||
# if we just finished entering, place a stop loss as well
|
||||
if self.security.invested:
|
||||
stop = fill.fill_price*(1 - self.percent_global_stop_loss) if self.security.holdings.is_long \
|
||||
else fill.fill_price*(1 + self.percent_global_stop_loss)
|
||||
stop = fill.fill_price*(1 - self.PERCENT_GLOBAL_STOP_LOSS) if self.security.holdings.is_long \
|
||||
else fill.fill_price*(1 + self.PERCENT_GLOBAL_STOP_LOSS)
|
||||
|
||||
self.__current_stop_loss = self.__algorithm.stop_market_order(self.symbol, -qty, stop, "StopLoss at: {0}".format(stop))
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ class LimitIfTouchedRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
new_quantity = int(self._request.quantity - self._negative)
|
||||
self._request.update_quantity(new_quantity, f"LIT - Quantity: {new_quantity}")
|
||||
self._request.update_trigger_price(Extensions.round_to_significant_digits(self._request.get(OrderField.TRIGGER_PRICE), 5));
|
||||
self._request.update_trigger_price(Extensions.round_to_significant_digits(self._request.get(OrderField.TRIGGER_PRICE), 5))
|
||||
|
||||
def on_order_event(self, order_event):
|
||||
if order_event.status == OrderStatus.FILLED:
|
||||
|
||||
@@ -78,7 +78,7 @@ class CustomImpliedVolatility(ImpliedVolatility):
|
||||
# we demonstate put-call parity calculation here, but note that it is not suitable for American options
|
||||
def f(self, vol: float, time_till_expiry: float) -> float:
|
||||
call_black_price = OptionGreekIndicatorsHelper.BlackTheoreticalPrice(
|
||||
vol, UnderlyingPrice.Current.Value, Strike, timeTillExpiry, RiskFreeRate.Current.Value, DividendYield.Current.Value, OptionRight.Call);
|
||||
vol, UnderlyingPrice.Current.Value, Strike, timeTillExpiry, RiskFreeRate.Current.Value, DividendYield.Current.Value, OptionRight.Call)
|
||||
put_black_price = OptionGreekIndicatorsHelper.BlackTheoreticalPrice(
|
||||
vol, UnderlyingPrice.Current.Value, Strike, timeTillExpiry, RiskFreeRate.Current.Value, DividendYield.Current.Value, OptionRight.Put);
|
||||
vol, UnderlyingPrice.Current.Value, Strike, timeTillExpiry, RiskFreeRate.Current.Value, DividendYield.Current.Value, OptionRight.Put)
|
||||
return Price.Current.Value + OppositePrice.Current.Value - call_black_price - put_black_price
|
||||
|
||||
@@ -19,109 +19,109 @@ from AlgorithmImports import *
|
||||
class PythonDictionaryFeatureRegressionAlgorithm(QCAlgorithm):
|
||||
'''Example algorithm showing that Slice, Securities and Portfolio behave as a Python Dictionary'''
|
||||
|
||||
def Initialize(self):
|
||||
def initialize(self):
|
||||
|
||||
self.SetStartDate(2013,10, 7) #Set Start Date
|
||||
self.SetEndDate(2013,10,11) #Set End Date
|
||||
self.SetCash(100000) #Set Strategy Cash
|
||||
self.set_start_date(2013,10, 7) #Set Start Date
|
||||
self.set_end_date(2013,10,11) #Set End Date
|
||||
self.set_cash(100000) #Set Strategy Cash
|
||||
|
||||
self.spySymbol = self.AddEquity("SPY").Symbol
|
||||
self.ibmSymbol = self.AddEquity("IBM").Symbol
|
||||
self.aigSymbol = self.AddEquity("AIG").Symbol
|
||||
self.aaplSymbol = Symbol.Create("AAPL", SecurityType.Equity, Market.USA)
|
||||
self.spy_symbol = self.add_equity("SPY").symbol
|
||||
self.ibm_symbol = self.add_equity("IBM").symbol
|
||||
self.aig_symbol = self.add_equity("AIG").symbol
|
||||
self.aapl_symbol = Symbol.create("AAPL", SecurityType.EQUITY, Market.USA)
|
||||
|
||||
dateRules = self.DateRules.On(2013, 10, 7)
|
||||
self.Schedule.On(dateRules, self.TimeRules.At(13, 0), self.TestSecuritiesDictionary)
|
||||
self.Schedule.On(dateRules, self.TimeRules.At(14, 0), self.TestPortfolioDictionary)
|
||||
self.Schedule.On(dateRules, self.TimeRules.At(15, 0), self.TestSliceDictionary)
|
||||
date_rules = self.date_rules.on(2013, 10, 7)
|
||||
self.schedule.on(date_rules, self.time_rules.at(13, 0), self.test_securities_dictionary)
|
||||
self.schedule.on(date_rules, self.time_rules.at(14, 0), self.test_portfolio_dictionary)
|
||||
self.schedule.on(date_rules, self.time_rules.at(15, 0), self.test_slice_dictionary)
|
||||
|
||||
def TestSliceDictionary(self):
|
||||
slice = self.CurrentSlice
|
||||
def test_slice_dictionary(self):
|
||||
slice = self.current_slice
|
||||
|
||||
symbols = ', '.join([f'{x}' for x in slice.keys()])
|
||||
sliceData = ', '.join([f'{x}' for x in slice.values()])
|
||||
sliceBars = ', '.join([f'{x}' for x in slice.Bars.values()])
|
||||
slice_data = ', '.join([f'{x}' for x in slice.values()])
|
||||
slice_bars = ', '.join([f'{x}' for x in slice.bars.values()])
|
||||
|
||||
if "SPY" not in slice:
|
||||
raise Exception('SPY (string) is not in Slice')
|
||||
|
||||
if self.spySymbol not in slice:
|
||||
if self.spy_symbol not in slice:
|
||||
raise Exception('SPY (Symbol) is not in Slice')
|
||||
|
||||
spy = slice.get(self.spySymbol)
|
||||
spy = slice.get(self.spy_symbol)
|
||||
if spy is None:
|
||||
raise Exception('SPY is not in Slice')
|
||||
|
||||
for symbol, bar in slice.Bars.items():
|
||||
self.Plot(symbol, 'Price', bar.Close)
|
||||
for symbol, bar in slice.bars.items():
|
||||
self.plot(symbol, 'Price', bar.close)
|
||||
|
||||
|
||||
def TestSecuritiesDictionary(self):
|
||||
symbols = ', '.join([f'{x}' for x in self.Securities.keys()])
|
||||
leverages = ', '.join([str(x.GetLastData()) for x in self.Securities.values()])
|
||||
def test_securities_dictionary(self):
|
||||
symbols = ', '.join([f'{x}' for x in self.securities.keys()])
|
||||
leverages = ', '.join([str(x.get_last_data()) for x in self.securities.values()])
|
||||
|
||||
if "IBM" not in self.Securities:
|
||||
if "IBM" not in self.securities:
|
||||
raise Exception('IBM (string) is not in Securities')
|
||||
|
||||
if self.ibmSymbol not in self.Securities:
|
||||
if self.ibm_symbol not in self.securities:
|
||||
raise Exception('IBM (Symbol) is not in Securities')
|
||||
|
||||
ibm = self.Securities.get(self.ibmSymbol)
|
||||
ibm = self.securities.get(self.ibm_symbol)
|
||||
if ibm is None:
|
||||
raise Exception('ibm is None')
|
||||
|
||||
aapl = self.Securities.get(self.aaplSymbol)
|
||||
aapl = self.securities.get(self.aapl_symbol)
|
||||
if aapl is not None:
|
||||
raise Exception('aapl is not None')
|
||||
|
||||
for symbol, security in self.Securities.items():
|
||||
self.Plot(symbol, 'Price', security.Price)
|
||||
for symbol, security in self.securities.items():
|
||||
self.plot(symbol, 'Price', security.price)
|
||||
|
||||
def TestPortfolioDictionary(self):
|
||||
symbols = ', '.join([f'{x}' for x in self.Portfolio.keys()])
|
||||
leverages = ', '.join([f'{x.Symbol}: {x.Leverage}' for x in self.Portfolio.values()])
|
||||
def test_portfolio_dictionary(self):
|
||||
symbols = ', '.join([f'{x}' for x in self.portfolio.keys()])
|
||||
leverages = ', '.join([f'{x.symbol}: {x.leverage}' for x in self.portfolio.values()])
|
||||
|
||||
if "AIG" not in self.Securities:
|
||||
if "AIG" not in self.securities:
|
||||
raise Exception('AIG (string) is not in Portfolio')
|
||||
|
||||
if self.aigSymbol not in self.Securities:
|
||||
if self.aig_symbol not in self.securities:
|
||||
raise Exception('AIG (Symbol) is not in Portfolio')
|
||||
|
||||
aig = self.Portfolio.get(self.aigSymbol)
|
||||
aig = self.portfolio.get(self.aig_symbol)
|
||||
if aig is None:
|
||||
raise Exception('aig is None')
|
||||
|
||||
aapl = self.Portfolio.get(self.aaplSymbol)
|
||||
aapl = self.portfolio.get(self.aapl_symbol)
|
||||
if aapl is not None:
|
||||
raise Exception('aapl is not None')
|
||||
|
||||
for symbol, holdings in self.Portfolio.items():
|
||||
msg = f'{symbol}: {holdings.Leverage}'
|
||||
for symbol, holdings in self.portfolio.items():
|
||||
msg = f'{symbol}: {holdings.leverage}'
|
||||
|
||||
def OnEndOfAlgorithm(self):
|
||||
def on_end_of_algorithm(self):
|
||||
|
||||
portfolioCopy = self.Portfolio.copy()
|
||||
portfolio_copy = self.portfolio.copy()
|
||||
try:
|
||||
self.Portfolio.clear() # Throws exception
|
||||
self.portfolio.clear() # Throws exception
|
||||
except Exception as e:
|
||||
self.Debug(e)
|
||||
self.debug(e)
|
||||
|
||||
bar = self.Securities.pop("SPY")
|
||||
length = len(self.Securities)
|
||||
bar = self.securities.pop("SPY")
|
||||
length = len(self.securities)
|
||||
if length != 2:
|
||||
raise Exception(f'After popping SPY, Securities should have 2 elements, {length} found')
|
||||
|
||||
securitiesCopy = self.Securities.copy()
|
||||
self.Securities.clear() # Does not throw
|
||||
securities_copy = self.securities.copy()
|
||||
self.securities.clear() # Does not throw
|
||||
|
||||
|
||||
def OnData(self, data):
|
||||
'''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
|
||||
def on_data(self, data):
|
||||
'''on_data 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 not self.Portfolio.Invested:
|
||||
self.SetHoldings("SPY", 1/3)
|
||||
self.SetHoldings("IBM", 1/3)
|
||||
self.SetHoldings("AIG", 1/3)
|
||||
if not self.portfolio.invested:
|
||||
self.set_holdings("SPY", 1/3)
|
||||
self.set_holdings("IBM", 1/3)
|
||||
self.set_holdings("AIG", 1/3)
|
||||
|
||||
@@ -17,24 +17,24 @@ import torch.nn.functional as F
|
||||
|
||||
class PytorchNeuralNetworkAlgorithm(QCAlgorithm):
|
||||
|
||||
def Initialize(self):
|
||||
self.SetStartDate(2013, 10, 7) # Set Start Date
|
||||
self.SetEndDate(2013, 10, 8) # Set End Date
|
||||
def initialize(self):
|
||||
self.set_start_date(2013, 10, 7) # Set Start Date
|
||||
self.set_end_date(2013, 10, 8) # Set End Date
|
||||
|
||||
self.SetCash(100000) # Set Strategy Cash
|
||||
self.set_cash(100000) # Set Strategy Cash
|
||||
|
||||
# add symbol
|
||||
spy = self.AddEquity("SPY", Resolution.Minute)
|
||||
self.symbols = [spy.Symbol] # using a list can extend to condition for multiple symbols
|
||||
spy = self.add_equity("SPY", Resolution.MINUTE)
|
||||
self._symbols = [spy.symbol] # using a list can extend to condition for multiple symbols
|
||||
|
||||
self.lookback = 30 # days of historical data (look back)
|
||||
|
||||
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 28), self.NetTrain) # train the NN
|
||||
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), self.Trade)
|
||||
self.schedule.on(self.date_rules.every_day("SPY"), self.time_rules.after_market_open("SPY", 28), self.net_train) # train the NN
|
||||
self.schedule.on(self.date_rules.every_day("SPY"), self.time_rules.after_market_open("SPY", 30), self.trade)
|
||||
|
||||
def NetTrain(self):
|
||||
def net_train(self):
|
||||
# Daily historical data is used to train the machine learning model
|
||||
history = self.History(self.symbols, self.lookback + 1, Resolution.Daily)
|
||||
history = self.history(self._symbols, self.lookback + 1, Resolution.DAILY)
|
||||
|
||||
# dicts that store prices for training
|
||||
self.prices_x = {}
|
||||
@@ -44,13 +44,13 @@ class PytorchNeuralNetworkAlgorithm(QCAlgorithm):
|
||||
self.sell_prices = {}
|
||||
self.buy_prices = {}
|
||||
|
||||
for symbol in self.symbols:
|
||||
for symbol in self._symbols:
|
||||
if not history.empty:
|
||||
# x: preditors; y: response
|
||||
self.prices_x[symbol] = list(history.loc[symbol.Value]['open'])[:-1]
|
||||
self.prices_y[symbol] = list(history.loc[symbol.Value]['open'])[1:]
|
||||
self.prices_x[symbol] = list(history.loc[symbol.value]['open'])[:-1]
|
||||
self.prices_y[symbol] = list(history.loc[symbol.value]['open'])[1:]
|
||||
|
||||
for symbol in self.symbols:
|
||||
for symbol in self._symbols:
|
||||
# if this symbol has historical data
|
||||
if symbol in self.prices_x:
|
||||
|
||||
@@ -79,17 +79,17 @@ class PytorchNeuralNetworkAlgorithm(QCAlgorithm):
|
||||
self.buy_prices[symbol] = net(y)[-1] + np.std(y.data.numpy())
|
||||
self.sell_prices[symbol] = net(y)[-1] - np.std(y.data.numpy())
|
||||
|
||||
def Trade(self):
|
||||
def trade(self):
|
||||
'''
|
||||
Enter or exit positions based on relationship of the open price of the current bar and the prices defined by the machine learning model.
|
||||
Liquidate if the open price is below the sell price and buy if the open price is above the buy price
|
||||
'''
|
||||
for holding in self.Portfolio.Values:
|
||||
if self.CurrentSlice[holding.Symbol].Open < self.sell_prices[holding.Symbol] and holding.Invested:
|
||||
self.Liquidate(holding.Symbol)
|
||||
for holding in self.portfolio.values():
|
||||
if self.current_slice[holding.symbol].open < self.sell_prices[holding.symbol] and holding.invested:
|
||||
self.liquidate(holding.symbol)
|
||||
|
||||
if self.CurrentSlice[holding.Symbol].Open > self.buy_prices[holding.Symbol] and not holding.Invested:
|
||||
self.SetHoldings(holding.Symbol, 1 / len(self.symbols))
|
||||
if self.current_slice[holding.symbol].open > self.buy_prices[holding.symbol] and not holding.invested:
|
||||
self.set_holdings(holding.symbol, 1 / len(self._symbols))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -19,17 +19,17 @@ from AlgorithmImports import *
|
||||
class QuitAfterInitializationRegressionAlgorithm(QCAlgorithm):
|
||||
'''Basic template algorithm simply initializes the date range and cash'''
|
||||
|
||||
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) #Set Start Date
|
||||
self.SetEndDate(2013,10,11) #Set End Date
|
||||
self.SetCash(100000) #Set Strategy Cash
|
||||
self.set_start_date(2013,10, 7) #Set Start Date
|
||||
self.set_end_date(2013,10,11) #Set End Date
|
||||
self.set_cash(100000) #Set Strategy Cash
|
||||
|
||||
self.AddEquity("SPY", Resolution.Daily)
|
||||
self.add_equity("SPY", Resolution.DAILY)
|
||||
self._stopped = False
|
||||
|
||||
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:
|
||||
@@ -38,4 +38,4 @@ class QuitAfterInitializationRegressionAlgorithm(QCAlgorithm):
|
||||
if self._stopped:
|
||||
raise ValueError("Algorithm should of stopped!")
|
||||
self._stopped = True
|
||||
self.Quit()
|
||||
self.quit()
|
||||
|
||||
@@ -19,17 +19,17 @@ from AlgorithmImports import *
|
||||
class QuitInInitializationRegressionAlgorithm(QCAlgorithm):
|
||||
'''Basic template algorithm simply initializes the date range and cash'''
|
||||
|
||||
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) #Set Start Date
|
||||
self.SetEndDate(2013,10,11) #Set End Date
|
||||
self.SetCash(100000) #Set Strategy Cash
|
||||
self.set_start_date(2013,10, 7) #Set Start Date
|
||||
self.set_end_date(2013,10,11) #Set End Date
|
||||
self.set_cash(100000) #Set Strategy Cash
|
||||
|
||||
self.AddEquity("SPY", Resolution.Daily)
|
||||
self.Quit()
|
||||
self.add_equity("SPY", Resolution.DAILY)
|
||||
self.quit()
|
||||
|
||||
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:
|
||||
|
||||
@@ -16,7 +16,7 @@ from QuantConnect.Data.Auxiliary import *
|
||||
from QuantConnect.Lean.Engine.DataFeeds import DefaultDataProvider
|
||||
|
||||
_ticker = "GOOGL"
|
||||
_expectedRawPrices = [ 1157.93, 1158.72,
|
||||
_expected_raw_prices = [ 1157.93, 1158.72,
|
||||
1131.97, 1114.28, 1120.15, 1114.51, 1134.89, 567.55, 571.50, 545.25, 540.63 ]
|
||||
|
||||
# <summary>
|
||||
@@ -27,40 +27,40 @@ _expectedRawPrices = [ 1157.93, 1158.72,
|
||||
# <meta name="tag" content="regression test" />
|
||||
class RawDataRegressionAlgorithm(QCAlgorithm):
|
||||
|
||||
def Initialize(self):
|
||||
self.SetStartDate(2014, 3, 25)
|
||||
self.SetEndDate(2014, 4, 7)
|
||||
self.SetCash(100000)
|
||||
def initialize(self):
|
||||
self.set_start_date(2014, 3, 25)
|
||||
self.set_end_date(2014, 4, 7)
|
||||
self.set_cash(100000)
|
||||
|
||||
# Set our DataNormalizationMode to raw
|
||||
self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw
|
||||
self._googl = self.AddEquity(_ticker, Resolution.Daily).Symbol
|
||||
self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW
|
||||
self._googl = self.add_equity(_ticker, Resolution.DAILY).symbol
|
||||
|
||||
# Get our factor file for this regression
|
||||
dataProvider = DefaultDataProvider()
|
||||
mapFileProvider = LocalDiskMapFileProvider()
|
||||
mapFileProvider.Initialize(dataProvider)
|
||||
factorFileProvider = LocalDiskFactorFileProvider()
|
||||
factorFileProvider.Initialize(mapFileProvider, dataProvider)
|
||||
data_provider = DefaultDataProvider()
|
||||
map_file_provider = LocalDiskMapFileProvider()
|
||||
map_file_provider.initialize(data_provider)
|
||||
factor_file_provider = LocalDiskFactorFileProvider()
|
||||
factor_file_provider.initialize(map_file_provider, data_provider)
|
||||
|
||||
# Get our factor file for this regression
|
||||
self._factorFile = factorFileProvider.Get(self._googl)
|
||||
self._factor_file = factor_file_provider.get(self._googl)
|
||||
|
||||
|
||||
def OnData(self, data):
|
||||
if not self.Portfolio.Invested:
|
||||
self.SetHoldings(self._googl, 1)
|
||||
def on_data(self, data):
|
||||
if not self.portfolio.invested:
|
||||
self.set_holdings(self._googl, 1)
|
||||
|
||||
if data.Bars.ContainsKey(self._googl):
|
||||
googlData = data.Bars[self._googl]
|
||||
if data.bars.contains_key(self._googl):
|
||||
googl_data = data.bars[self._googl]
|
||||
|
||||
# Assert our volume matches what we expected
|
||||
expectedRawPrice = _expectedRawPrices.pop(0)
|
||||
if expectedRawPrice != googlData.Close:
|
||||
expected_raw_price = _expected_raw_prices.pop(0)
|
||||
if expected_raw_price != googl_data.close:
|
||||
# Our values don't match lets try and give a reason why
|
||||
dayFactor = self._factorFile.GetPriceScaleFactor(googlData.Time)
|
||||
probableRawPrice = googlData.Close / dayFactor # Undo adjustment
|
||||
day_factor = self._factor_file.get_price_scale_factor(googl_data.time)
|
||||
probable_raw_price = googl_data.close / day_factor # Undo adjustment
|
||||
|
||||
raise Exception("Close price was incorrect; it appears to be the adjusted value"
|
||||
if expectedRawPrice == probableRawPrice else
|
||||
if expected_raw_price == probable_raw_price else
|
||||
"Close price was incorrect; Data may have changed.")
|
||||
|
||||
@@ -22,52 +22,52 @@ from AlgorithmImports import *
|
||||
### <meta name="tag" content="fine universes" />
|
||||
class RawPricesCoarseUniverseAlgorithm(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.'''
|
||||
|
||||
# what resolution should the data *added* to the universe be?
|
||||
self.UniverseSettings.Resolution = Resolution.Daily
|
||||
self.universe_settings.resolution = Resolution.DAILY
|
||||
|
||||
self.SetStartDate(2014,1,1) #Set Start Date
|
||||
self.SetEndDate(2015,1,1) #Set End Date
|
||||
self.SetCash(50000) #Set Strategy Cash
|
||||
self.set_start_date(2014,1,1) #Set Start Date
|
||||
self.set_end_date(2015,1,1) #Set End Date
|
||||
self.set_cash(50000) #Set Strategy Cash
|
||||
|
||||
# Set the security initializer with the characteristics defined in CustomSecurityInitializer
|
||||
self.SetSecurityInitializer(self.CustomSecurityInitializer)
|
||||
self.set_security_initializer(self.custom_security_initializer)
|
||||
|
||||
# this add universe method accepts a single parameter that is a function that
|
||||
# accepts an IEnumerable<CoarseFundamental> and returns IEnumerable<Symbol>
|
||||
self.AddUniverse(self.CoarseSelectionFunction)
|
||||
self.add_universe(self.coarse_selection_function)
|
||||
|
||||
self.__numberOfSymbols = 5
|
||||
self.__number_of_symbols = 5
|
||||
|
||||
def CustomSecurityInitializer(self, security):
|
||||
def custom_security_initializer(self, security):
|
||||
'''Initialize the security with raw prices and zero fees
|
||||
Args:
|
||||
security: Security which characteristics we want to change'''
|
||||
security.SetDataNormalizationMode(DataNormalizationMode.Raw)
|
||||
security.SetFeeModel(ConstantFeeModel(0))
|
||||
security.set_data_normalization_mode(DataNormalizationMode.RAW)
|
||||
security.set_fee_model(ConstantFeeModel(0))
|
||||
|
||||
# sort the data by daily dollar volume and take the top 'NumberOfSymbols'
|
||||
def CoarseSelectionFunction(self, coarse):
|
||||
def coarse_selection_function(self, coarse):
|
||||
# sort descending by daily dollar volume
|
||||
sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
|
||||
sorted_by_dollar_volume = sorted(coarse, key=lambda x: x.dollar_volume, reverse=True)
|
||||
|
||||
# return the symbol objects of the top entries from our sorted collection
|
||||
return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ]
|
||||
return [ x.symbol for x in sorted_by_dollar_volume[:self.__number_of_symbols] ]
|
||||
|
||||
|
||||
# this event fires whenever we have changes to our universe
|
||||
def OnSecuritiesChanged(self, changes):
|
||||
def on_securities_changed(self, changes):
|
||||
# liquidate removed securities
|
||||
for security in changes.RemovedSecurities:
|
||||
if security.Invested:
|
||||
self.Liquidate(security.Symbol)
|
||||
for security in changes.removed_securities:
|
||||
if security.invested:
|
||||
self.liquidate(security.symbol)
|
||||
|
||||
# we want 20% allocation in each security in our universe
|
||||
for security in changes.AddedSecurities:
|
||||
self.SetHoldings(security.Symbol, 0.2)
|
||||
for security in changes.added_securities:
|
||||
self.set_holdings(security.symbol, 0.2)
|
||||
|
||||
def OnOrderEvent(self, orderEvent):
|
||||
if orderEvent.Status == OrderStatus.Filled:
|
||||
self.Log(f"OnOrderEvent({self.UtcTime}):: {orderEvent}")
|
||||
def on_order_event(self, order_event):
|
||||
if order_event.status == OrderStatus.FILLED:
|
||||
self.log(f"OnOrderEvent({self.utc_time}):: {order_event}")
|
||||
|
||||
@@ -23,39 +23,39 @@ from AlgorithmImports import *
|
||||
### <meta name="tag" content="fine universes" />
|
||||
class RawPricesUniverseRegressionAlgorithm(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.'''
|
||||
|
||||
# what resolution should the data *added* to the universe be?
|
||||
self.UniverseSettings.Resolution = Resolution.Daily
|
||||
self.universe_settings.resolution = Resolution.DAILY
|
||||
|
||||
# Use raw prices
|
||||
self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw
|
||||
self.universe_settings.data_normalization_mode = DataNormalizationMode.RAW
|
||||
|
||||
self.SetStartDate(2014,3,24) #Set Start Date
|
||||
self.SetEndDate(2014,4,7) #Set End Date
|
||||
self.SetCash(50000) #Set Strategy Cash
|
||||
self.set_start_date(2014,3,24) #Set Start Date
|
||||
self.set_end_date(2014,4,7) #Set End Date
|
||||
self.set_cash(50000) #Set Strategy Cash
|
||||
|
||||
# Set the security initializer with zero fees
|
||||
self.SetSecurityInitializer(lambda x: x.SetFeeModel(ConstantFeeModel(0)))
|
||||
self.set_security_initializer(lambda x: x.set_fee_model(ConstantFeeModel(0)))
|
||||
|
||||
self.AddUniverse("MyUniverse", Resolution.Daily, self.SelectionFunction)
|
||||
self.add_universe("MyUniverse", Resolution.DAILY, self.selection_function)
|
||||
|
||||
|
||||
def SelectionFunction(self, dateTime):
|
||||
if dateTime.day % 2 == 0:
|
||||
def selection_function(self, date_time):
|
||||
if date_time.day % 2 == 0:
|
||||
return ["SPY", "IWM", "QQQ"]
|
||||
else:
|
||||
return ["AIG", "BAC", "IBM"]
|
||||
|
||||
|
||||
# this event fires whenever we have changes to our universe
|
||||
def OnSecuritiesChanged(self, changes):
|
||||
def on_securities_changed(self, changes):
|
||||
# liquidate removed securities
|
||||
for security in changes.RemovedSecurities:
|
||||
if security.Invested:
|
||||
self.Liquidate(security.Symbol)
|
||||
for security in changes.removed_securities:
|
||||
if security.invested:
|
||||
self.liquidate(security.symbol)
|
||||
|
||||
# we want 20% allocation in each security in our universe
|
||||
for security in changes.AddedSecurities:
|
||||
self.SetHoldings(security.Symbol, 0.2)
|
||||
for security in changes.added_securities:
|
||||
self.set_holdings(security.symbol, 0.2)
|
||||
|
||||
@@ -22,37 +22,37 @@ from AlgorithmImports import *
|
||||
### <meta name="tag" content="plotting indicators" />
|
||||
class RegressionChannelAlgorithm(QCAlgorithm):
|
||||
|
||||
def Initialize(self):
|
||||
def initialize(self):
|
||||
|
||||
self.SetCash(100000)
|
||||
self.SetStartDate(2009,1,1)
|
||||
self.SetEndDate(2015,1,1)
|
||||
self.set_cash(100000)
|
||||
self.set_start_date(2009,1,1)
|
||||
self.set_end_date(2015,1,1)
|
||||
|
||||
equity = self.AddEquity("SPY", Resolution.Minute)
|
||||
self._spy = equity.Symbol
|
||||
self._holdings = equity.Holdings
|
||||
self._rc = self.RC(self._spy, 30, 2, Resolution.Daily)
|
||||
equity = self.add_equity("SPY", Resolution.MINUTE)
|
||||
self._spy = equity.symbol
|
||||
self._holdings = equity.holdings
|
||||
self._rc = self.rc(self._spy, 30, 2, Resolution.DAILY)
|
||||
|
||||
stockPlot = Chart("Trade Plot")
|
||||
stockPlot.AddSeries(Series("Buy", SeriesType.Scatter, 0))
|
||||
stockPlot.AddSeries(Series("Sell", SeriesType.Scatter, 0))
|
||||
stockPlot.AddSeries(Series("UpperChannel", SeriesType.Line, 0))
|
||||
stockPlot.AddSeries(Series("LowerChannel", SeriesType.Line, 0))
|
||||
stockPlot.AddSeries(Series("Regression", SeriesType.Line, 0))
|
||||
self.AddChart(stockPlot)
|
||||
stock_plot = Chart("Trade Plot")
|
||||
stock_plot.add_series(Series("Buy", SeriesType.SCATTER, 0))
|
||||
stock_plot.add_series(Series("Sell", SeriesType.SCATTER, 0))
|
||||
stock_plot.add_series(Series("UpperChannel", SeriesType.LINE, 0))
|
||||
stock_plot.add_series(Series("LowerChannel", SeriesType.LINE, 0))
|
||||
stock_plot.add_series(Series("Regression", SeriesType.LINE, 0))
|
||||
self.add_chart(stock_plot)
|
||||
|
||||
def OnData(self, data):
|
||||
if (not self._rc.IsReady) or (not data.ContainsKey(self._spy)): return
|
||||
def on_data(self, data):
|
||||
if (not self._rc.is_ready) or (not data.contains_key(self._spy)): return
|
||||
if data[self._spy] is None: return
|
||||
value = data[self._spy].Value
|
||||
if self._holdings.Quantity <= 0 and value < self._rc.LowerChannel.Current.Value:
|
||||
self.SetHoldings(self._spy, 1)
|
||||
self.Plot("Trade Plot", "Buy", value)
|
||||
if self._holdings.Quantity >= 0 and value > self._rc.UpperChannel.Current.Value:
|
||||
self.SetHoldings(self._spy, -1)
|
||||
self.Plot("Trade Plot", "Sell", value)
|
||||
value = data[self._spy].value
|
||||
if self._holdings.quantity <= 0 and value < self._rc.lower_channel.current.value:
|
||||
self.set_holdings(self._spy, 1)
|
||||
self.plot("Trade Plot", "Buy", value)
|
||||
if self._holdings.quantity >= 0 and value > self._rc.upper_channel.current.value:
|
||||
self.set_holdings(self._spy, -1)
|
||||
self.plot("Trade Plot", "Sell", value)
|
||||
|
||||
def OnEndOfDay(self, symbol):
|
||||
self.Plot("Trade Plot", "UpperChannel", self._rc.UpperChannel.Current.Value)
|
||||
self.Plot("Trade Plot", "LowerChannel", self._rc.LowerChannel.Current.Value)
|
||||
self.Plot("Trade Plot", "Regression", self._rc.LinearRegression.Current.Value)
|
||||
def on_end_of_day(self, symbol):
|
||||
self.plot("Trade Plot", "UpperChannel", self._rc.upper_channel.current.value)
|
||||
self.plot("Trade Plot", "LowerChannel", self._rc.lower_channel.current.value)
|
||||
self.plot("Trade Plot", "Regression", self._rc.linear_regression.current.value)
|
||||
|
||||
@@ -17,14 +17,14 @@ from Portfolio.RiskParityPortfolioConstructionModel import *
|
||||
class RiakParityPortfolioAlgorithm(QCAlgorithm):
|
||||
'''Example algorithm of using RiskParityPortfolioConstructionModel'''
|
||||
|
||||
def Initialize(self):
|
||||
self.SetStartDate(2021, 2, 21) # Set Start Date
|
||||
self.SetEndDate(2021, 3, 30)
|
||||
self.SetCash(100000) # Set Strategy Cash
|
||||
self.SetSecurityInitializer(lambda security: security.SetMarketPrice(self.GetLastKnownPrice(security)))
|
||||
def initialize(self):
|
||||
self.set_start_date(2021, 2, 21) # Set Start Date
|
||||
self.set_end_date(2021, 3, 30)
|
||||
self.set_cash(100000) # Set Strategy Cash
|
||||
self.set_security_initializer(lambda security: security.set_market_price(self.get_last_known_price(security)))
|
||||
|
||||
self.AddEquity("SPY", Resolution.Daily)
|
||||
self.AddEquity("AAPL", Resolution.Daily)
|
||||
self.add_equity("SPY", Resolution.DAILY)
|
||||
self.add_equity("AAPL", Resolution.DAILY)
|
||||
|
||||
self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1)))
|
||||
self.SetPortfolioConstruction(RiskParityPortfolioConstructionModel())
|
||||
self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1)))
|
||||
self.set_portfolio_construction(RiskParityPortfolioConstructionModel())
|
||||
@@ -16,46 +16,46 @@ from queue import Queue
|
||||
|
||||
class ScheduledQueuingAlgorithm(QCAlgorithm):
|
||||
|
||||
def Initialize(self):
|
||||
self.SetStartDate(2020, 9, 1)
|
||||
self.SetEndDate(2020, 9, 2)
|
||||
self.SetCash(100000)
|
||||
def initialize(self):
|
||||
self.set_start_date(2020, 9, 1)
|
||||
self.set_end_date(2020, 9, 2)
|
||||
self.set_cash(100000)
|
||||
|
||||
self.__numberOfSymbols = 2000
|
||||
self.__numberOfSymbolsFine = 1000
|
||||
self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction, None, None))
|
||||
self.__number_of_symbols = 2000
|
||||
self.__number_of_symbols_fine = 1000
|
||||
self.set_universe_selection(FineFundamentalUniverseSelectionModel(self.coarse_selection_function, self.fine_selection_function, None))
|
||||
|
||||
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
|
||||
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
|
||||
|
||||
self.SetExecution(ImmediateExecutionModel())
|
||||
self.set_execution(ImmediateExecutionModel())
|
||||
|
||||
self.queue = Queue()
|
||||
self.dequeue_size = 100
|
||||
|
||||
self.AddEquity("SPY", Resolution.Minute)
|
||||
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(0, 0), self.FillQueue)
|
||||
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.Every(timedelta(minutes=60)), self.TakeFromQueue)
|
||||
self.add_equity("SPY", Resolution.MINUTE)
|
||||
self.schedule.on(self.date_rules.every_day("SPY"), self.time_rules.at(0, 0), self.fill_queue)
|
||||
self.schedule.on(self.date_rules.every_day("SPY"), self.time_rules.every(timedelta(minutes=60)), self.take_from_queue)
|
||||
|
||||
def CoarseSelectionFunction(self, coarse):
|
||||
has_fundamentals = [security for security in coarse if security.HasFundamentalData]
|
||||
sorted_by_dollar_volume = sorted(has_fundamentals, key=lambda x: x.DollarVolume, reverse=True)
|
||||
return [ x.Symbol for x in sorted_by_dollar_volume[:self.__numberOfSymbols] ]
|
||||
def coarse_selection_function(self, coarse):
|
||||
has_fundamentals = [security for security in coarse if security.has_fundamental_data]
|
||||
sorted_by_dollar_volume = sorted(has_fundamentals, key=lambda x: x.dollar_volume, reverse=True)
|
||||
return [ x.symbol for x in sorted_by_dollar_volume[:self.__number_of_symbols] ]
|
||||
|
||||
def FineSelectionFunction(self, fine):
|
||||
sorted_by_pe_ratio = sorted(fine, key=lambda x: x.ValuationRatios.PERatio, reverse=True)
|
||||
return [ x.Symbol for x in sorted_by_pe_ratio[:self.__numberOfSymbolsFine] ]
|
||||
def fine_selection_function(self, fine):
|
||||
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] ]
|
||||
|
||||
def FillQueue(self):
|
||||
securities = [security for security in self.ActiveSecurities.Values if security.Fundamentals is not None]
|
||||
def fill_queue(self):
|
||||
securities = [security for security in self.active_securities.values() if security.fundamentals is not None]
|
||||
|
||||
# Fill queue with symbols sorted by PE ratio (decreasing order)
|
||||
self.queue.queue.clear()
|
||||
sorted_by_pe_ratio = sorted(securities, key=lambda x: x.Fundamentals.ValuationRatios.PERatio, reverse=True)
|
||||
sorted_by_pe_ratio = sorted(securities, key=lambda x: x.fundamentals.valuation_ratios.pe_ratio, reverse=True)
|
||||
for security in sorted_by_pe_ratio:
|
||||
self.queue.put(security.Symbol)
|
||||
self.queue.put(security.symbol)
|
||||
|
||||
def TakeFromQueue(self):
|
||||
def take_from_queue(self):
|
||||
symbols = [self.queue.get() for _ in range(min(self.dequeue_size, self.queue.qsize()))]
|
||||
self.History(symbols, 10, Resolution.Daily)
|
||||
self.history(symbols, 10, Resolution.DAILY)
|
||||
|
||||
self.Log(f"Symbols at {self.Time}: {[str(symbol) for symbol in symbols]}")
|
||||
self.log(f"Symbols at {self.time}: {[str(symbol) for symbol in symbols]}")
|
||||
|
||||
@@ -25,28 +25,28 @@ class SectorExposureRiskFrameworkAlgorithm(QCAlgorithm):
|
||||
'''This example algorithm defines its own custom coarse/fine fundamental selection model
|
||||
### with equally weighted portfolio and a maximum sector exposure.'''
|
||||
|
||||
def Initialize(self):
|
||||
def initialize(self):
|
||||
|
||||
# Set requested data resolution
|
||||
self.UniverseSettings.Resolution = Resolution.Daily
|
||||
self.universe_settings.resolution = Resolution.DAILY
|
||||
|
||||
self.SetStartDate(2014, 3, 25)
|
||||
self.SetEndDate(2014, 4, 7)
|
||||
self.SetCash(100000)
|
||||
self.set_start_date(2014, 3, 25)
|
||||
self.set_end_date(2014, 4, 7)
|
||||
self.set_cash(100000)
|
||||
|
||||
# set algorithm framework models
|
||||
self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine))
|
||||
self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1)))
|
||||
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
|
||||
self.SetRiskManagement(MaximumSectorExposureRiskManagementModel())
|
||||
self.set_universe_selection(FineFundamentalUniverseSelectionModel(self.select_coarse, self.select_fine))
|
||||
self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1)))
|
||||
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel())
|
||||
self.set_risk_management(MaximumSectorExposureRiskManagementModel())
|
||||
|
||||
def OnOrderEvent(self, orderEvent):
|
||||
if orderEvent.Status == OrderStatus.Filled:
|
||||
self.Debug(f"Order event: {orderEvent}. Holding value: {self.Securities[orderEvent.Symbol].Holdings.AbsoluteHoldingsValue}")
|
||||
def on_order_event(self, order_event):
|
||||
if order_event.status == OrderStatus.FILLED:
|
||||
self.debug(f"Order event: {order_event}. Holding value: {self.securities[order_event.symbol].holdings.absolute_holdings_value}")
|
||||
|
||||
def SelectCoarse(self, coarse):
|
||||
tickers = ["AAPL", "AIG", "IBM"] if self.Time.date() < date(2014, 4, 1) else [ "GOOG", "BAC", "SPY" ]
|
||||
return [Symbol.Create(x, SecurityType.Equity, Market.USA) for x in tickers]
|
||||
def select_coarse(self, coarse):
|
||||
tickers = ["AAPL", "AIG", "IBM"] if self.time.date() < date(2014, 4, 1) else [ "GOOG", "BAC", "SPY" ]
|
||||
return [Symbol.create(x, SecurityType.EQUITY, Market.USA) for x in tickers]
|
||||
|
||||
def SelectFine(self, fine):
|
||||
return [f.Symbol for f in fine]
|
||||
def select_fine(self, fine):
|
||||
return [f.symbol for f in fine]
|
||||
|
||||
@@ -21,28 +21,28 @@ class SectorWeightingFrameworkAlgorithm(QCAlgorithm):
|
||||
'''This example algorithm defines its own custom coarse/fine fundamental selection model
|
||||
with sector weighted portfolio.'''
|
||||
|
||||
def Initialize(self):
|
||||
def initialize(self):
|
||||
|
||||
# Set requested data resolution
|
||||
self.UniverseSettings.Resolution = Resolution.Daily
|
||||
self.universe_settings.resolution = Resolution.DAILY
|
||||
|
||||
self.SetStartDate(2014, 4, 2)
|
||||
self.SetEndDate(2014, 4, 6)
|
||||
self.SetCash(100000)
|
||||
self.set_start_date(2014, 4, 2)
|
||||
self.set_end_date(2014, 4, 6)
|
||||
self.set_cash(100000)
|
||||
|
||||
# set algorithm framework models
|
||||
self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine))
|
||||
self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1)))
|
||||
self.SetPortfolioConstruction(SectorWeightingPortfolioConstructionModel())
|
||||
self.set_universe_selection(FineFundamentalUniverseSelectionModel(self.select_coarse, self.select_fine))
|
||||
self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1)))
|
||||
self.set_portfolio_construction(SectorWeightingPortfolioConstructionModel())
|
||||
|
||||
def OnOrderEvent(self, orderEvent):
|
||||
if orderEvent.Status == OrderStatus.Filled:
|
||||
self.Debug(f"Order event: {orderEvent}. Holding value: {self.Securities[orderEvent.Symbol].Holdings.AbsoluteHoldingsValue}")
|
||||
def on_order_event(self, order_event):
|
||||
if order_event.status == OrderStatus.FILLED:
|
||||
self.debug(f"Order event: {order_event}. Holding value: {self.securities[order_event.symbol].holdings.absolute_holdings_value}")
|
||||
|
||||
def SelectCoarse(self, coarse):
|
||||
def select_coarse(self, coarse):
|
||||
# IndustryTemplateCode of AAPL, IBM and GOOG is N, AIG is I, BAC is B. SPY have no fundamentals
|
||||
tickers = ["AAPL", "AIG", "IBM"] if self.Time.date() < date(2014, 4, 4) else [ "GOOG", "BAC", "SPY" ]
|
||||
return [Symbol.Create(x, SecurityType.Equity, Market.USA) for x in tickers]
|
||||
tickers = ["AAPL", "AIG", "IBM"] if self.time.date() < date(2014, 4, 4) else [ "GOOG", "BAC", "SPY" ]
|
||||
return [Symbol.create(x, SecurityType.EQUITY, Market.USA) for x in tickers]
|
||||
|
||||
def SelectFine(self, fine):
|
||||
return [f.Symbol for f in fine]
|
||||
def select_fine(self, fine):
|
||||
return [f.symbol for f in fine]
|
||||
|
||||
@@ -15,9 +15,9 @@ from AlgorithmImports import *
|
||||
from CustomSettlementModelRegressionAlgorithm import CustomSettlementModel, CustomSettlementModelRegressionAlgorithm
|
||||
|
||||
### <summary>
|
||||
### Regression algorithm to test we can specify a custom settlement model using Security.SetSettlementModel() method
|
||||
### Regression algorithm to test we can specify a custom settlement model using Security.set_settlement_model() method
|
||||
### (without a custom brokerage model)
|
||||
### </summary>
|
||||
class SetCustomSettlementModelRegressionAlgorithm(CustomSettlementModelRegressionAlgorithm):
|
||||
def SetSettlementModel(self, security):
|
||||
security.SetSettlementModel(CustomSettlementModel())
|
||||
def set_settlement_model(self, security):
|
||||
security.set_settlement_model(CustomSettlementModel())
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ from SetHoldingsMultipleTargetsRegressionAlgorithm import SetHoldingsMultipleTar
|
||||
### Regression algorithm testing GH feature 3790, using SetHoldings with a collection of targets
|
||||
### which will be ordered by margin impact before being executed, with the objective of avoiding any
|
||||
### margin errors
|
||||
### Asserts that liquidateExistingHoldings equal false does not close positions inadvertedly (GH 7008)
|
||||
### Asserts that liquidate_existing_holdings equal false does not close positions inadvertedly (GH 7008)
|
||||
### </summary>
|
||||
class SetHoldingsLiquidateExistingHoldingsMultipleTargetsRegressionAlgorithm(SetHoldingsMultipleTargetsRegressionAlgorithm):
|
||||
def on_data(self, data):
|
||||
|
||||
@@ -16,29 +16,29 @@ import talib
|
||||
|
||||
class CalibratedResistanceAtmosphericScrubbers(QCAlgorithm):
|
||||
|
||||
def Initialize(self):
|
||||
self.SetStartDate(2020, 1, 2)
|
||||
self.SetEndDate(2020, 1, 6)
|
||||
self.SetCash(100000)
|
||||
self.AddEquity("SPY", Resolution.Hour)
|
||||
def initialize(self):
|
||||
self.set_start_date(2020, 1, 2)
|
||||
self.set_end_date(2020, 1, 6)
|
||||
self.set_cash(100000)
|
||||
self.add_equity("SPY", Resolution.HOUR)
|
||||
|
||||
self.rolling_window = pd.DataFrame()
|
||||
self.dema_period = 3
|
||||
self.sma_period = 3
|
||||
self.wma_period = 3
|
||||
self.window_size = self.dema_period * 2
|
||||
self.SetWarmUp(self.window_size)
|
||||
self.set_warm_up(self.window_size)
|
||||
|
||||
def OnData(self, data):
|
||||
if "SPY" not in data.Bars:
|
||||
def on_data(self, data):
|
||||
if "SPY" not in data.bars:
|
||||
return
|
||||
|
||||
close = data["SPY"].Close
|
||||
close = data["SPY"].close
|
||||
|
||||
if self.IsWarmingUp:
|
||||
if self.is_warming_up:
|
||||
# Add latest close to rolling window
|
||||
row = pd.DataFrame({"close": [close]}, index=[data.Time])
|
||||
self.rolling_window = self.rolling_window.append(row).iloc[-self.window_size:]
|
||||
row = pd.DataFrame({"close": [close]}, index=[data.time])
|
||||
self.rolling_window = pd.concat([self.rolling_window, row]).iloc[-self.window_size:]
|
||||
|
||||
# If we have enough closing data to start calculating indicators...
|
||||
if self.rolling_window.shape[0] == self.window_size:
|
||||
@@ -57,11 +57,11 @@ class CalibratedResistanceAtmosphericScrubbers(QCAlgorithm):
|
||||
"DEMA" : talib.DEMA(closes, self.dema_period)[-1],
|
||||
"EMA" : talib.EMA(closes, self.sma_period)[-1],
|
||||
"WMA" : talib.WMA(closes, self.wma_period)[-1]},
|
||||
index=[data.Time])
|
||||
index=[data.time])
|
||||
|
||||
self.rolling_window = self.rolling_window.append(row).iloc[-self.window_size:]
|
||||
self.rolling_window = pd.concat([self.rolling_window, row]).iloc[-self.window_size:]
|
||||
|
||||
|
||||
def OnEndOfAlgorithm(self):
|
||||
self.Log(f"\nRolling Window:\n{self.rolling_window.to_string()}\n")
|
||||
self.Log(f"\nLatest Values:\n{self.rolling_window.iloc[-1].to_string()}\n")
|
||||
def on_end_of_algorithm(self):
|
||||
self.log(f"\nRolling Window:\n{self.rolling_window.to_string()}\n")
|
||||
self.log(f"\nLatest Values:\n{self.rolling_window.iloc[-1].to_string()}\n")
|
||||
|
||||
Reference in New Issue
Block a user