| Overall Statistics |
|
Total Orders 19 Average Win 0.02% Average Loss -0.03% Compounding Annual Return -0.075% Drawdown 0.100% Expectancy -0.642 Start Equity 10000000 End Equity 9999344 Net Profit -0.007% Sharpe Ratio -0.641 Sortino Ratio -0.767 Probabilistic Sharpe Ratio 35.096% Loss Rate 78% Win Rate 22% Profit-Loss Ratio 0.61 Alpha -0.005 Beta 0.025 Annual Standard Deviation 0.005 Annual Variance 0 Information Ratio -0.464 Tracking Error 0.135 Treynor Ratio -0.121 Total Fees $19.00 Estimated Strategy Capacity $13000.00 Lowest Capacity Asset GOOCV 31K516AN36IVA|GOOCV VP83T1ZUHROL Portfolio Turnover 0.20% |
from AlgorithmImports import *
class USEquityOptionsUniverseAlgorithm(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.equity = self.add_equity("GOOG", data_normalization_mode=DataNormalizationMode.RAW).symbol
# Requesting option data and filter for the hedge candidates
option = self.add_option(self.equity)
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.equity),
self.time_rules.after_market_open(self.equity, 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.equity),
self.time_rules.before_market_close(self.equity, 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.equity].invested:
self.market_order(self.equity, 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