| Overall Statistics |
|
Total Orders 211 Average Win 1.97% Average Loss -0.96% Compounding Annual Return 16.520% Drawdown 16.800% Expectancy 0.770 Start Equity 100000 End Equity 214755.08 Net Profit 114.755% Sharpe Ratio 1.048 Sortino Ratio 1.111 Probabilistic Sharpe Ratio 67.144% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 2.05 Alpha 0.066 Beta 0.48 Annual Standard Deviation 0.095 Annual Variance 0.009 Information Ratio 0.319 Tracking Error 0.097 Treynor Ratio 0.207 Total Fees $4101.07 Estimated Strategy Capacity $21000000.00 Lowest Capacity Asset IGW S6BDJ8ONH2ZP Portfolio Turnover 3.49% Drawdown Recovery 434 |
from AlgorithmImports import *
import numpy as np
class SharpeGodTierFinal(QCAlgorithm):
"""
STRATEGY: Sharpe God Tier Final
TYPE: Trend-Following Mean Reversion Hybrid
CORE LOGIC:
1. Trend Filter: Only trade assets above their 200-day Moving Average.
2. Entry Timing: Buy on a pullback (RSI < 45).
3. Volatility Scaling: Scale position size down when market volatility (SPY) is high.
4. Exit Logic: Exit on extreme strength (RSI > 75) or a 2.5x ATR Trailing Stop.
"""
def Initialize(self):
# --- Backtest Configuration ---
#self.SetStartDate(2016, 1, 1)
self.SetEndDate(2020, 1, 1)
self.set_start_date(self.end_date - timedelta(5*365))
self.SetCash(100_000)
# --- Strategy Parameters ---
self.max_positions = 3 # Quality over Quantity (Concentrated Alpha)
self.rsi_entry = 45 # Pullback threshold
self.rsi_exit = 75 # Overbought exit threshold
# --- Asset Selection ---
# Diversified across Tech, Finance, Health, and Gold
self.assets = {
"QQQ": "Tech", "SOXX": "Tech", "NVDA": "Tech",
"XLF": "Finance", "XLV": "Health", "GLD": "Gold"
}
self.symbols = [self.AddEquity(t, Resolution.Daily).Symbol for t in self.assets.keys()]
# --- Market Regime Filter (Volatility Proxy) ---
# We use SPY Standard Deviation to detect "Market Stress"
self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol
self.spy_std = self.STD(self.spy, 10, Resolution.Daily)
# --- Indicator Setup ---
self.data = {}
for s in self.symbols:
self.data[s] = {
"rsi": self.RSI(s, 14, MovingAverageType.Wilders, Resolution.Daily),
"sma_200": self.SMA(s, 200, Resolution.Daily),
"atr": self.ATR(s, 14, MovingAverageType.Wilders, Resolution.Daily),
"hwm": 0 # High Water Mark for trailing stops
}
self.SetWarmUp(200) # Ensure indicators (especially SMA 200) are ready
def OnData(self, data: Slice):
# 1. Validation & Warmup
if self.IsWarmingUp or not self.spy_std.IsReady:
return
invested_symbols = [s for s in self.symbols if self.Portfolio[s].Invested]
# 2. MARKET VOLATILITY SCALE
# If current SPY volatility (10-day STD) is > 1.5% of price, we are in a High Vol regime.
is_high_vol = self.spy_std.Current.Value > (self.Securities[self.spy].Price * 0.015)
for s in self.symbols:
if not data.Bars.ContainsKey(s): continue
d = self.data[s]
price = self.Securities[s].Price
rsi_val = d["rsi"].Current.Value
# --- SURGICAL EXIT LOGIC ---
if self.Portfolio[s].Invested:
# Update High Water Mark for Trailing Stop
d["hwm"] = max(d["hwm"], price)
# Exit A: Sell into strength (Profit Taking)
if rsi_val > self.rsi_exit:
self.Liquidate(s, f"RSI Exit at {rsi_val:.2f}")
# Exit B: Volatility-adjusted Trailing Stop
elif price < (d["hwm"] - (d['atr'].Current.Value * 2.5)):
self.Liquidate(s, "Trailing Stop Triggered")
continue # Move to next symbol; cannot enter if already invested
# --- CONCENTRATED ENTRY LOGIC ---
# Don't open new positions if we've hit our concentration limit
if len(invested_symbols) >= self.max_positions:
continue
# Condition 1: Long-term Trend is Bullish (Above SMA 200)
# Condition 2: Short-term Mean Reversion (RSI < 45)
if price > d["sma_200"].Current.Value and rsi_val < self.rsi_entry:
# SIZING: Risk-Off in high volatility (1%), Risk-On in calm markets (3%)
risk_per_trade = 0.01 if is_high_vol else 0.03
atr = d["atr"].Current.Value
if atr == 0: continue
# Calculate Quantity based on ATR risk distance
# Stop is technically 3x ATR, risk is dollar amount of portfolio
quantity = (self.Portfolio.TotalPortfolioValue * risk_per_trade) / (atr * 3)
# Weight calculation (capped at 33% of portfolio to maintain diversification)
weight = min(0.33, (quantity * price) / self.Portfolio.TotalPortfolioValue)
self.SetHoldings(s, weight)
d["hwm"] = price # Reset HWM for the new trade
invested_symbols.append(s)