Overall Statistics |
Total Orders 9 Average Win 0% Average Loss -0.01% Compounding Annual Return -1.125% Drawdown 0.200% Expectancy -1 Start Equity 10000000 End Equity 9990076 Net Profit -0.099% Sharpe Ratio -2.204 Sortino Ratio -1.988 Probabilistic Sharpe Ratio 16.122% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.012 Beta 0.03 Annual Standard Deviation 0.005 Annual Variance 0 Information Ratio -0.514 Tracking Error 0.132 Treynor Ratio -0.347 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset SPX 31 Portfolio Turnover 0.42% |
from AlgorithmImports import * class IndexOptionsUniverseAlgorithm(QCAlgorithm): def initialize(self) -> None: self.set_start_date(2021, 1, 1) self.set_end_date(2021, 2, 1) self.set_cash(10000000) # Asynchronous can use computational resources efficiently self.universe_settings.asynchronous = True # Subscribe to the underlying for the underlying position # Set the data normalization mode to raw for strike price comparability self.index = self.add_index("SPX").symbol # Requesting option data and filter for the hedge candidates option = self.add_index_option(self.index) option.set_filter(self.option_filter) self.option_symbol = option.symbol # Set scheduled event to buy a hedge option contract at market open to eliminate the intra-day movement self.schedule.on( self.date_rules.every_day(self.index), self.time_rules.after_market_open(self.index, 1), self.buy_hedge_contract ) # Set a scheduled event to sell the hedge contract before market close, since we want to earn from inter-day movement # Leave 2 minutes contingency to fill self.schedule.on( self.date_rules.every_day(self.index), self.time_rules.before_market_close(self.index, 2), self.sell_hedge_contract ) self.hedge = None def option_filter(self, universe: OptionFilterUniverse) -> OptionFilterUniverse: # Select the contracts with delta very close to -1 and high open interest # This can effectively hedge most of the price change of the underlying and ensure the liquidity # Make sure the contract is expiring close for its tradbility return universe.include_weeklys().puts_only().expiration(2, 7).delta(-1, -0.95).open_interest(10, 1000) def buy_hedge_contract(self) -> None: chain = self.current_slice.option_chains.get(self.option_symbol) if chain: # Order the underlying if not hold, the order size should match the option contract # Order only if option chain data ready for hedging if not self.portfolio[self.index].invested: self.market_order(self.index, self.securities[self.option_symbol].symbol_properties.contract_multiplier) # Get the contract with delta closest to -1 (lowest possible delta) contract = sorted(chain, key=lambda x: x.greeks.delta)[0] self.hedge = contract.symbol # Buy 1 deep ITM put with delta close to -1 to eliminate the intraday movement self.market_order(self.hedge, 1) def sell_hedge_contract(self) -> None: # Check if any hedge contract position, if so, liquidate before market close to expose to underlying overnight movement if self.hedge: self.liquidate(self.hedge) self.hedge = None