| Overall Statistics |
|
Total Orders 111 Average Win 0.80% Average Loss -1.17% Compounding Annual Return 0.403% Drawdown 7.400% Expectancy -0.093 Start Equity 1000000 End Equity 1035301 Net Profit 3.530% Sharpe Ratio -0.712 Sortino Ratio -0.451 Probabilistic Sharpe Ratio 0.073% Loss Rate 46% Win Rate 54% Profit-Loss Ratio 0.68 Alpha -0.015 Beta -0.045 Annual Standard Deviation 0.027 Annual Variance 0.001 Information Ratio -0.644 Tracking Error 0.159 Treynor Ratio 0.427 Total Fees $0.00 Estimated Strategy Capacity $3600000.00 Lowest Capacity Asset SPX 32L3DOWEACQY6|SPX 31 Portfolio Turnover 0.03% |
# 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._vix = self.add_index('VIX')
self.settings.automatic_indicator_warm_up = True
self._std = self.std(self._vix.symbol, 90, resolution=Resolution.DAILY)
self._sma = self.sma(self._vix.symbol, 90, 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.month_start(self._spx.symbol), self.time_rules.after_market_open(self._spx.symbol, 30), self._trade)
def _trade(self):
self.plot('VIX', 'Value', self._vix.price)
self.plot('VIX', 'SMA', self._sma.current.value)
self.plot('VIX', 'SMA +1 STD', self._sma.current.value + self._std.current.value)
self.plot('VIX', 'SMA -1 STD', self._sma.current.value - self._std.current.value)
z_score = (self._vix.price - self._sma.current.value) / self._std.current.value
quantity = int(z_score)
if quantity == 0:
self.liquidate()
else:
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()