| Overall Statistics |
|
Total Orders 1496 Average Win 0.55% Average Loss -0.59% Compounding Annual Return 1.819% Drawdown 15.800% Expectancy 0.017 Start Equity 100000 End Equity 104643.6 Net Profit 4.644% Sharpe Ratio -0.258 Sortino Ratio -0.247 Probabilistic Sharpe Ratio 5.429% Loss Rate 47% Win Rate 53% Profit-Loss Ratio 0.94 Alpha -0.056 Beta 0.207 Annual Standard Deviation 0.13 Annual Variance 0.017 Information Ratio -0.865 Tracking Error 0.163 Treynor Ratio -0.163 Total Fees $3216.40 Estimated Strategy Capacity $120000000.00 Lowest Capacity Asset NQ YYFADOG4CO3L Portfolio Turnover 599.80% Drawdown Recovery 270 |
"""
NQ Baseline — Pure 8/20 MA Crossover
========================================
No HMM, no tensor, no gates. Every bull crossover → long 7 bars.
This exists to prove (or disprove) that the tensor adds value.
"""
from AlgorithmImports import *
import numpy as np
class NQBaseline(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2023, 6, 1)
self.SetEndDate(2026, 3, 4)
self.SetCash(100000)
self.nq = self.AddFuture(
Futures.Indices.NASDAQ100EMini,
Resolution.Minute,
dataNormalizationMode=DataNormalizationMode.Raw
)
self.nq.SetFilter(0, 90)
self.contract = None
# Parameters
self.MA_FAST = 8
self.MA_SLOW = 20
self.HOLD_BARS = 7
self.WARMUP_BARS = 6
self.RTH_START = time(9, 30)
self.RTH_END = time(15, 55)
self.NO_TRADE_AFTER = time(15, 0)
# State
self.close_buffer = []
self.bar_count = 0
self.current_session = None
self.open_trade = None
self.total_trades = 0
# 5-min accumulator
self.acc_open = None
self.acc_high = None
self.acc_low = None
self.acc_close = None
self.acc_vol = 0
self.acc_count = 0
def OnData(self, data):
# Get active contract
for chain in data.FutureChains:
contracts = sorted(
[c for c in chain.Value if c.OpenInterest > 0],
key=lambda c: c.OpenInterest, reverse=True
)
if contracts:
self.contract = contracts[0]
break
if self.contract is None:
return
bar = data.Bars.get(self.contract.Symbol)
if bar is None:
return
t = bar.EndTime.time()
d = bar.EndTime.date()
if t < self.RTH_START or t > self.RTH_END:
return
# Session reset
if d != self.current_session:
self.close_buffer = []
self.bar_count = 0
self.acc_count = 0
self.acc_vol = 0
self._close_position("session_end")
self.current_session = d
# Accumulate 5-min bars
if self.acc_count == 0:
self.acc_open = float(bar.Open)
self.acc_high = float(bar.High)
self.acc_low = float(bar.Low)
else:
self.acc_high = max(self.acc_high, float(bar.High))
self.acc_low = min(self.acc_low, float(bar.Low))
self.acc_close = float(bar.Close)
self.acc_vol += int(bar.Volume)
self.acc_count += 1
if self.acc_count >= 5:
self._on_5min(self.acc_close, bar.EndTime)
self.acc_count = 0
self.acc_vol = 0
def _on_5min(self, c, end_time):
self.bar_count += 1
if self.bar_count <= self.WARMUP_BARS:
self.close_buffer.append(c)
return
self.close_buffer.append(c)
# Check exit first
if self.open_trade is not None:
held = self.bar_count - self.open_trade["bar"]
if held >= self.HOLD_BARS:
self._close_position("fixed_hold")
# Check entry
if self.open_trade is None and end_time.time() < self.NO_TRADE_AFTER:
if self._bull_crossover():
self._enter(c, end_time)
def _bull_crossover(self):
buf = self.close_buffer
if len(buf) < self.MA_SLOW + 1:
return False
fast_now = np.mean(buf[-self.MA_FAST:])
slow_now = np.mean(buf[-self.MA_SLOW:])
fast_prev = np.mean(buf[-self.MA_FAST - 1:-1])
slow_prev = np.mean(buf[-self.MA_SLOW - 1:-1])
return (fast_now > slow_now) and (fast_prev <= slow_prev)
def _enter(self, price, end_time):
if self.contract is None:
return
self.MarketOrder(self.contract.Symbol, 1)
self.open_trade = {"bar": self.bar_count, "price": price}
self.total_trades += 1
self.Debug("ENTRY #{}: @ {:.2f} at {}".format(
self.total_trades, price, end_time))
def _close_position(self, reason):
if self.open_trade is None:
return
if not self.Portfolio.Invested:
self.open_trade = None
return
if self.contract and self.Portfolio[self.contract.Symbol].Invested:
pnl = self.Securities[self.contract.Symbol].Price - self.open_trade["price"]
self.Liquidate(self.contract.Symbol)
self.Debug("EXIT: {} | PnL={:+.2f}".format(reason, pnl))
self.open_trade = None
def OnEndOfAlgorithm(self):
self.Debug("=== BASELINE COMPLETE: {} trades ===".format(self.total_trades))