| Overall Statistics |
|
Total Orders 2350 Average Win 0.28% Average Loss -0.29% Compounding Annual Return 0.636% Drawdown 8.700% Expectancy 0.012 Start Equity 100000 End Equity 103097.5 Net Profit 3.098% Sharpe Ratio -0.384 Sortino Ratio -0.44 Probabilistic Sharpe Ratio 0.954% Loss Rate 49% Win Rate 51% Profit-Loss Ratio 0.97 Alpha -0.023 Beta 0.035 Annual Standard Deviation 0.052 Annual Variance 0.003 Information Ratio -0.63 Tracking Error 0.178 Treynor Ratio -0.573 Total Fees $5052.50 Estimated Strategy Capacity $140000000.00 Lowest Capacity Asset NQ YOGVNNAOI1OH Portfolio Turnover 368.83% |
from AlgorithmImports import *
class DailyNQFutures(QCAlgorithm):
def Initialize(self):
# Set the start and end dates for the backtest
self.SetStartDate(2020, 1, 1)
#self.SetEndDate(2024, 10, 1)
# Set the initial cash balance for the algorithm
self.SetCash(100000)
# Add the Nasdaq 100 E-mini futures contract to trade
futureNQ = self.AddFuture(Futures.Indices.NASDAQ100EMini, Resolution.Minute)
# Filter to select contracts that expire within 90 days from today
futureNQ.SetFilter(timedelta(0), timedelta(90))
# Initialize the contract symbol to None (will be updated later)
self.contractSymbol = None
# Set the parameters for the SMA periods
self.sma_5min_period = 7 # 5-minute SMA period
self.sma_30min_period = 21 # 30-minute SMA period
# Define the indicators (will be set up later)
self.sma_5min = None
self.sma_30min = None
# Schedule the daily buy/sell event (check for weekdays and market open inside methods)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 54), Action(self.TradeNQ))
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 59), Action(self.SellNQ))
def OnData(self, slice):
# Iterate through future contracts in the slice (market data for the current time step)
for chain in slice.FutureChains:
contracts = list(chain.Value)
if len(contracts) > 0:
# Sort the contracts by expiration date
nearest_contract = sorted(contracts, key=lambda x: x.Expiry)[0]
# Check if the current contract is expiring in less than 4 days
if nearest_contract.Expiry - self.Time < timedelta(days=4):
# Ensure there is a next contract available
if len(contracts) > 1:
next_contract = sorted(contracts, key=lambda x: x.Expiry)[1]
if self.contractSymbol != next_contract.Symbol:
self.contractSymbol = next_contract.Symbol
self.SetupIndicators(self.contractSymbol)
self.Debug(f"Rolled to new contract: {self.contractSymbol}, Expiration: {next_contract.Expiry}")
else:
# If not rolling, just track the nearest contract
if self.contractSymbol != nearest_contract.Symbol:
self.contractSymbol = nearest_contract.Symbol
self.SetupIndicators(self.contractSymbol)
def SetupIndicators(self, symbol):
# Set up the 5-minute and 30-minute SMA indicators for the given contract symbol
self.sma_5min = self.SMA(symbol, self.sma_5min_period, Resolution.Minute)
self.sma_30min = self.SMA(symbol, self.sma_30min_period, Resolution.Minute)
def TradeNQ(self):
# Only trade if it's a weekday, the market is open, and we have a contract symbol
if self.Time.weekday() < 5: # 0 = Monday, 4 = Friday
if self.contractSymbol and self.IsMarketOpen(self.contractSymbol):
# Make sure both SMAs are ready (i.e., enough data points are available)
if self.sma_5min.IsReady and self.sma_30min.IsReady:
# Check current invested position
current_position = self.Portfolio[self.contractSymbol].Quantity
# Long if 5-minute SMA is above the 30-minute SMA (bullish signal)
if self.sma_5min.Current.Value > self.sma_30min.Current.Value:
if current_position <= 0: # If not already long, buy
self.MarketOrder(self.contractSymbol, 1) # Buy 1 contract
self.Debug(f"Bought 1 contract at {self.Time}, 5-min SMA: {self.sma_5min.Current.Value}, 30-min SMA: {self.sma_30min.Current.Value}")
# Short if 5-minute SMA is below the 30-minute SMA (bearish signal)
elif self.sma_5min.Current.Value < self.sma_30min.Current.Value:
if current_position >= 0: # If not already short, sell
self.MarketOrder(self.contractSymbol, -1) # Short 1 contract
self.Debug(f"Shorted 1 contract at {self.Time}, 5-min SMA: {self.sma_5min.Current.Value}, 30-min SMA: {self.sma_30min.Current.Value}")
def SellNQ(self):
# Only liquidate if it's a weekday, the market is open, and we have a contract symbol
if self.Time.weekday() < 5: # 0 = Monday, 4 = Friday
if self.contractSymbol and self.IsMarketOpen(self.contractSymbol):
if self.Portfolio[self.contractSymbol].Invested:
self.Liquidate(self.contractSymbol)
self.Debug(f"Liquidated position at {self.Time}")
def IsMarketOpen(self, symbol):
# Check if the market for the given symbol is open at the current time
exchange = self.Securities[symbol].Exchange
return exchange.DateTimeIsOpen(self.Time)