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])