| Overall Statistics |
|
Total Orders 409 Average Win 0.75% Average Loss -0.48% Compounding Annual Return 40.373% Drawdown 50.700% Expectancy 1.253 Start Equity 100000 End Equity 571287.91 Net Profit 471.288% Sharpe Ratio 1.013 Sortino Ratio 1.262 Probabilistic Sharpe Ratio 49.628% Loss Rate 12% Win Rate 88% Profit-Loss Ratio 1.56 Alpha 0.148 Beta 1.609 Annual Standard Deviation 0.272 Annual Variance 0.074 Information Ratio 1.132 Tracking Error 0.173 Treynor Ratio 0.171 Total Fees $421.39 Estimated Strategy Capacity $0 Lowest Capacity Asset NVDA RHM8UTD8DT2D Portfolio Turnover 0.26% Drawdown Recovery 514 |
#region imports
from AlgorithmImports import *
#endregion
class AIBasketStrategy(QCAlgorithm):
def Initialize(self):
# 1. Setup: Last 5 Years
self.SetStartDate(2020, 11, 10)
self.SetEndDate(2026, 1, 1)
self.SetCash(100000)
# 2. Define the "AI Basket"
# We manually select the leaders to ensure purity of the theme
self.tickers = [
"NVDA", # GPU King
"AMD", # GPU Challenger
"TSM", # The Foundry (makes the chips)
"AVGO", # Broadcom (Custom AI chips & Networking)
"MSFT", # OpenAI / Cloud
"GOOGL",# Gemini / DeepMind
"META", # LLaMA / Meta AI
"PLTR" # AI Data Foundry
]
self.symbols = []
for ticker in self.tickers:
# Add equity and set resolution to Daily (sufficient for rebalancing)
symbol = self.AddEquity(ticker, Resolution.Daily).Symbol
self.symbols.append(symbol)
# 3. Schedule Rebalancing (First trading day of every month)
# This keeps the portfolio strictly equal-weighted
self.Schedule.On(
self.DateRules.MonthStart("NVDA"),
self.TimeRules.AfterMarketOpen("NVDA", 30),
self.Rebalance
)
# 4. Realistic Settings
self.SetSecurityInitializer(lambda x: x.SetFeeModel(ConstantFeeModel(1.0)))
self.SetBenchmark("SPY") # Compare against S&P 500
def Rebalance(self):
# Calculate target weight (100% / 8 stocks = 12.5% each)
# We check if stock has data to avoid errors (e.g. if one was delisted or halted)
valid_symbols = [s for s in self.symbols if self.Securities[s].Price > 0]
if len(valid_symbols) == 0: return
weight = 1.0 / len(valid_symbols)
# Execute Trades
for symbol in valid_symbols:
self.SetHoldings(symbol, weight)
def OnData(self, data):
# We don't need trade logic here because the Scheduler handles it.
pass