from AlgorithmImports import *
import numpy as np
from collections import deque
class HKUSTIntradayMomentum(QCAlgorithm):
def initialize(self): # Исправлено: Initialize
self.SetStartDate(2023, 1, 1)
self.SetCash(1000000)
self.max_order_percentage = 0.3
symbol_list = [ 'AAPL', 'AMGN', 'AXP' ] #'BA', 'CAT', 'CRM',
#'CSCO', 'CVX', 'DIS', 'DOW', 'GS', 'HD', 'HON', 'INTC',
#'JNJ', 'JPM', 'KO', 'MCD', 'MMM', 'MRK', 'MSFT', 'NKE', 'PG', 'TRV',
#'UNH', 'V', 'VZ', 'WMT', "AAP", "ACHR", "ADMA", "AI", "ALAB",
#"APP", "AR", "ASTS", "AUR", "BE", "BILL", "BROS", "CART",
#"CELH", "CHWY", "CLSK", "CORZ", "CRDO", "CVNA", "ENPH", "ETSY",
#"FL", "GERN", "GME", "GO", "GSAT", "GT", "HIMS" ]
self.SetWarmUp(timedelta(100))
for symbol in symbol_list:
equity = self.add_equity( # Исправлено: AddEquity
symbol,
Resolution.MINUTE,
data_normalization_mode=DataNormalizationMode.TOTAL_RETURN
)
equity.SetMarginModel(PatternDayTradingMarginModel())
equity._vwap = self.VWAP(equity.Symbol)
equity._roc = self.ROCP(equity.Symbol, 1, Resolution.DAILY)
equity._vol = IndicatorExtensions.Of(StandardDeviation(7), equity._roc)
equity._deviation = AbsoluteDeviation('deviation', 60)
equity._previous_date = None
equity._open_price = None
equity._previous_close = None
equity._last_trade_date = None
equity._bars = deque(maxlen=2)
self.Consolidate(equity.Symbol, timedelta(minutes=30), self.consolidate_handler)
self.Schedule.On(
self.DateRules.EveryDay(symbol_list[0]),
self.TimeRules.BeforeMarketClose(symbol_list[0], 1), # Исправлено: TimeRules.BeforeMarketClose
self.end_of_day
)
def consolidate_handler(self, bar):
symbol = bar.Symbol
security = self.Securities[symbol]
current_date = bar.end_time.date()
security._bars.append(bar)
if current_date != security._previous_date:
security._previous_date = current_date
security._open_price = bar.Open
if len(security._bars) >= 2: # Исправлено: Проверка длины deque
security._previous_close = security._bars[-2].Close
else:
security._previous_close = None
security._deviation.update(bar)
if not security._vol.IsReady or security._previous_close is None or not security._deviation.IsReady or security._vwap.Current is None: # Исправлено: Проверка на None для VWAP
return
upper_bound = (max(security._open_price, security._previous_close) * (1 + security._deviation.Value))
lower_bound = (min(security._open_price, security._previous_close) * (1 - security._deviation.Value))
vwap_price = security._vwap.Current.Value
long_stop_price = max(vwap_price, upper_bound)
short_stop_price = min(vwap_price, lower_bound)
is_up_trend = bar.Close > vwap_price
is_down_trend = bar.Close < vwap_price
is_long = self.Portfolio[symbol].IsLong
is_short = self.Portfolio[symbol].IsShort
is_long_stopped_out = is_long and bar.Close <= long_stop_price
is_short_stopped_out = is_short and bar.Close >= short_stop_price
is_not_last_trade_date = security._last_trade_date != current_date
if self.IsWarmingUp: # Исправлено: IsWarmingUp
return
if is_long_stopped_out or is_short_stopped_out:
self.Liquidate(symbol)
if bar.Close > upper_bound and not is_long and is_up_trend and is_not_last_trade_date:
self.open_position(symbol, 1)
elif bar.Close < lower_bound and not is_short and is_down_trend and is_not_last_trade_date:
self.open_position(symbol, -1)
def open_position(self, symbol, direction):
security = self.Securities[symbol]
min_order_size = security.SymbolProperties.MinimumOrderSize # Исправлено: SymbolProperties
target_position_value = self.Portfolio.TotalPortfolioValue * self.max_order_percentage * direction
quantity = int(target_position_value / security.Close)
if direction > 0:
quantity = max(quantity, min_order_size)
else:
quantity = min(quantity, -min_order_size)
self.Debug(f"{symbol}: Target Value: {target_position_value}, Quantity: {quantity}, Close: {security.Close}, Min Order Size: {min_order_size}")
if quantity != 0:
self.SetHoldings(symbol, quantity) # Использование SetHoldings для внутридневной торговли
security._last_trade_date = self.Time.date()
def end_of_day(self):
self.Liquidate()
class AbsoluteDeviation(PythonIndicator):
def __init__(self, name, period):
super().__init__()
self.name = name
self.period = period
self.data = {}
self.ready = False
self.previous_data = None
self.open_price = None
def update(self, data: BaseData):
current_data = data.end_time.date()
if current_data != self.previous_data:
self.previous_data = current_data
self.open_price = data.open
current_time = data.end_time.time()
if current_time not in self.data:
self.data[current_time] = deque(maxlen=self.period)
self.data[current_time].append(
np.abs(data.close / self.open_price - 1)
)
if len(self.data[current_time]) == self.period:
self.ready = True
self.value = np.mean(self.data[current_time])
return len(self.data[current_time]) == self.period
Mia Alissi
Sources: Momentum And State Of Market Filters, Momentum Effect In Commodities Futures, Momentum Effect In Stocks, Opening Range Breakout for Stocks in Play, Momentum Effect In Country Equity Indexes
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
Dimitri
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!