| Overall Statistics |
|
Total Orders 1 Average Win 0% Average Loss 0% Compounding Annual Return 6.171% Drawdown 10.000% Expectancy 0 Start Equity 10000 End Equity 13490.03 Net Profit 34.900% Sharpe Ratio 0.131 Sortino Ratio 0.132 Probabilistic Sharpe Ratio 27.777% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.008 Beta 0.203 Annual Standard Deviation 0.055 Annual Variance 0.003 Information Ratio -0.533 Tracking Error 0.123 Treynor Ratio 0.036 Total Fees $1.00 Estimated Strategy Capacity $25000000.00 Lowest Capacity Asset NVDA RHM8UTD8DT2D Portfolio Turnover 0.00% Drawdown Recovery 548 |
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data.Market import TradeBar
from datetime import datetime, timedelta
# List of approximate NVDA earnings report dates from 2021-2025 (QC compatible format)
# Note: In a real QC algo, you might automate fetching this data.
EARNINGS_DATES = [
datetime(2021, 2, 24).date(), datetime(2021, 5, 26).date(),
datetime(2021, 8, 18).date(), datetime(2021, 11, 17).date(),
datetime(2022, 2, 16).date(), datetime(2022, 5, 25).date(),
datetime(2022, 8, 24).date(), datetime(2022, 11, 16).date(),
datetime(2023, 2, 22).date(), datetime(2023, 5, 24).date(),
datetime(2023, 8, 23).date(), datetime(2023, 11, 21).date(),
datetime(2024, 2, 21).date(), datetime(2024, 5, 22).date(),
datetime(2024, 8, 28).date(), datetime(2024, 11, 19).date(),
datetime(2025, 2, 26).date(), datetime(2025, 5, 21).date(),
datetime(2025, 8, 27).date(), datetime(2025, 11, 19).date()
]
class NVDAGapQC(QCAlgorithm):
def initialize(self):
# Set backtest time frame (5 years)
self.set_start_date(2021, 1, 1)
self.set_end_date(2025, 12, 31)
self.set_cash(10000)
# Request daily data for NVDA
self.nvda = self.add_equity("NVDA", Resolution.MINUTE)
self.nvda_symbol = self.nvda.symbol
# Set commission model (QC default is 0 for Equity, adjust as needed)
self.set_security_initializer(lambda security: security.set_fee_model(ConstantFeeModel(0)))
self.entry_price = 0
self.stop_loss_price = 0
self.target_price = 0
self.gap_threshold = 0.01
self.base_risk_pct = 0.01 # Targeting sub-10% DD with 0.5% risk/trade
def on_data(self, slice):
# Only trade on NVDA
if self.nvda_symbol not in slice.bars:
return
# Check for trade execution if an order is pending
if self.portfolio.invested:
return
# --- Earnings Filter Check ---
current_date = self.time.date()
if current_date in EARNINGS_DATES or (current_date - timedelta(days=1)) in EARNINGS_DATES:
return # Skip trading near earnings
# --- Gap Calculation ---
# Need previous day's close price (QuantConnect History call)
history = self.history(self.nvda_symbol, 2, Resolution.DAILY)
if len(history) < 2:
return
prev_close = history.iloc[-2]['close']
curr_open = slice.bars[self.nvda_symbol].open
gap_percent = (curr_open - prev_close) / prev_close
is_monday = self.time.weekday() == 0 # Monday is 0
if is_monday and abs(gap_percent) > self.gap_threshold:
# --- Dynamic Position Sizing (Low DD) ---
# QC requires different DD monitoring via PerformanceMetrics
# For simplicity here, we use fixed risk
# Simplified Sizing: Risk 0.5% of equity, assume $5 average stop loss
cash = self.portfolio.cash
risk_amount = cash * self.base_risk_pct
size = int(risk_amount / 5) # Uses $5 stop distance approximation
if size == 0: return
# --- Trade Execution ---
if gap_percent < 0: # Gap Down (Buy for fill)
# Enter Long (Market order), set Stop Loss and Take Profit targets
self.debug(f"Monday Gap Down detected. Entering Long {size} shares.")
self.market_order(self.nvda_symbol, size)
# In QC, OCO orders need separate methods or manual management in OnData
elif gap_percent > 0: # Gap Up (Sell/Short for fill)
self.debug(f"Monday Gap Up detected. Entering Short {size} shares.")
self.market_order(self.nvda_symbol, -size)
def on_order_event(self, order_event):
# Handle order confirmations/fills here if complex OCO logic is needed
pass
def on_end_of_algorithm(self):
# Calculate final Sharpe ratio and other metrics
self.log(f"Algorithm finished.")
# QC automatically generates performance reports with Sharpe Ratio, Drawdown etc.