| Overall Statistics |
|
Total Orders 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Start Equity 1000000 End Equity 1000000 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -1.781 Tracking Error 0.107 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
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