Overall Statistics |
Total Orders 466 Average Win 0.27% Average Loss -0.20% Compounding Annual Return 0.899% Drawdown 8.000% Expectancy 0.121 Start Equity 1000000 End Equity 1080199 Net Profit 8.020% Sharpe Ratio -0.533 Sortino Ratio -0.287 Probabilistic Sharpe Ratio 0.364% Loss Rate 53% Win Rate 47% Profit-Loss Ratio 1.36 Alpha -0.025 Beta 0.106 Annual Standard Deviation 0.029 Annual Variance 0.001 Information Ratio -0.735 Tracking Error 0.136 Treynor Ratio -0.147 Total Fees $0.00 Estimated Strategy Capacity $10000.00 Lowest Capacity Asset SPX 32L3DOV2BROMM|SPX 31 Portfolio Turnover 0.11% |
# region imports from AlgorithmImports import * # endregion class VolatilityTradingOptionAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2016, 1, 1) self.set_cash(1_000_000) self.settings.automatic_indicator_warm_up = True self._vix = self.add_index('VIX') self._vix.std = self.std(self._vix.symbol, 24*21, resolution=Resolution.DAILY) self._vix.sma = self.sma(self._vix.symbol, 24*21, resolution=Resolution.DAILY) self._spx = self.add_index_option('SPX') self._spx.set_filter(lambda universe: universe.straddle(30)) self.schedule.on(self.date_rules.every_day(self._spx.symbol), self.time_rules.after_market_open(self._spx.symbol, 30), self._trade) def _trade(self): z_score = (self._vix.price - self._vix.sma.current.value) / self._vix.std.current.value quantity = -int(z_score) if quantity == 0: self.liquidate() elif not self.portfolio.invested: chain = self.current_slice.option_chains.get(self._spx.symbol, None) if not chain: return chain = [c for c in chain if c.expiry > self.time] expiry = min([x.expiry for x in chain]) strike = sorted([c for c in chain if c.expiry == expiry], key=lambda x: abs(x.strike - self._spx.price))[0].strike strategy = OptionStrategies.straddle(self._spx.symbol, strike, expiry) self.order(strategy, quantity) def on_order_event(self, order_event): if order_event.status == OrderStatus.FILLED and order_event.is_assignment: self.liquidate()