| Overall Statistics |
|
Total Orders 136 Average Win 0.10% Average Loss -0.11% Compounding Annual Return -2.288% Drawdown 1.700% Expectancy -0.159 Start Equity 1000000 End Equity 988465.95 Net Profit -1.153% Sharpe Ratio -4.945 Sortino Ratio -4.024 Probabilistic Sharpe Ratio 3.810% Loss Rate 56% Win Rate 44% Profit-Loss Ratio 0.91 Alpha -0.073 Beta 0.013 Annual Standard Deviation 0.014 Annual Variance 0 Information Ratio -2.717 Tracking Error 0.089 Treynor Ratio -5.523 Total Fees $392.82 Estimated Strategy Capacity $170000000.00 Lowest Capacity Asset TSLA UNU3P8Y3WFAD Portfolio Turnover 7.40% |
from AlgorithmImports import *
from collections import deque
class FadingTheGapUniverse(QCAlgorithm):
def initialize(self):
self.set_start_date(2024, 1, 1) # <------- CHANGE PARAMETER
self.set_end_date(2024, 7, 1) # <------- CHANGE PARAMETER
self.set_cash(1_000_000) # <------- CHANGE PARAMETER
self.spy = Symbol.create('SPY', SecurityType.EQUITY, Market.USA)
self.add_universe(self.coarse_filter)
self.stocks = []
self.window = {}
self.volatility = {}
self.schedule.on(self.date_rules.every_day(self.spy),
self.time_rules.before_market_close(self.spy, 10),
self.closing_bar)
self.schedule.on(self.date_rules.every_day(self.spy),
self.time_rules.after_market_open(self.spy, 10),
self.opening_bar)
self.schedule.on(self.date_rules.every_day(self.spy),
self.time_rules.before_market_close(self.spy, 1),
self.close_positions)
def coarse_filter(self, coarse): # <------- CHANGE PARAMETER
filtered = [x for x in coarse if x.price > 10 and x.dollar_volume > 1e6]
return [x.Symbol for x in sorted(filtered, key=lambda x: x.dollar_volume, reverse=True)[:10]]
def on_securities_changed(self, changes):
for added in changes.added_securities:
self.window[added.Symbol] = deque(maxlen=5) # <------- CHANGE PARAMETER
self.volatility[added.Symbol] = StandardDeviation(60) # <------- CHANGE PARAMETER
self.add_equity(added.Symbol, Resolution.MINUTE)
self.stocks.append(added.Symbol)
for removed in changes.removed_securities:
if removed.Symbol in self.stocks:
self.liquidate(removed.Symbol)
self.stocks.remove(removed.Symbol)
if removed.Symbol in self.window:
del self.window[removed.Symbol]
if removed.Symbol in self.volatility:
del self.volatility[removed.Symbol]
def on_data(self, data):
for symbol in self.stocks:
if symbol in data and data[symbol] is not None:
self.volatility[symbol].update(self.time, data[symbol].close)
if len(self.window[symbol]) == 5: # <------- CHANGE PARAMETER w/ DeQ
self.window[symbol].append(data[symbol])
def opening_bar(self):
self.log(f"Opening bar triggered at {self.time}")
for symbol in self.stocks:
if symbol in self.current_slice.bars:
self.window[symbol].append(self.current_slice[symbol])
if not self.volatility[symbol].is_ready:
continue
delta = self.window[symbol][0].open - self.window[symbol][1].close
deviations = delta / self.volatility[symbol].current.value
if deviations < -1: # <------- CHANGE PARAMETER
self.set_holdings(symbol, 0.1) # <------- CHANGE PARAMETER
def close_positions(self):
self.log(f"Closing positions at {self.time}")
self.liquidate()
def closing_bar(self):
self.log(f"Closing bar triggered at {self.time}")
for symbol in self.stocks:
if symbol in self.current_slice.bars:
self.window[symbol].append(self.current_slice[symbol])