| Overall Statistics |
|
Total Trades 1664 Average Win 0.00% Average Loss 0.00% Compounding Annual Return -0.436% Drawdown 0.700% Expectancy -0.544 Net Profit -0.438% Sharpe Ratio -0.733 Probabilistic Sharpe Ratio 1.936% Loss Rate 77% Win Rate 23% Profit-Loss Ratio 1.01 Alpha -0.003 Beta -0.001 Annual Standard Deviation 0.004 Annual Variance 0 Information Ratio -0.157 Tracking Error 0.128 Treynor Ratio 3.761 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset SPX W6IHW13YA7VY|SPX 31 |
# region imports
from AlgorithmImports import *
import typing
# endregion
def get_contract_by_delta(contracts: typing.List[OptionContract], delta) -> OptionContract:
contracts = sorted(contracts, key=lambda x: x.Strike)
contract = min(contracts, key=lambda x: abs(x.Greeks.Delta - delta))
return contract
class CryingFluorescentPinkCaribou(QCAlgorithm):
spx_symbol: Symbol
option_symbol: Symbol
def Initialize(self):
self.SetStartDate(2015, 1, 1)
self.SetEndDate(2016, 1, 1)
self.SetCash(int(50e6))
index = self.AddIndex('SPX', Resolution.Daily)
index.VolatilityModel = StandardDeviationOfReturnsVolatilityModel(30)
self.spx_symbol = index.Symbol
self.SetWarmup(30, Resolution.Daily)
option = self.AddIndexOption(self.spx_symbol, Resolution.Daily)
# ofu: OptionFilterUniverse
option.SetFilter(
lambda ofu: ofu.Strikes(10, 60).Expiration(0, 90).CallsOnly().OnlyApplyFilterAtMarketOpen()
)
option.PriceModel = OptionPriceModels.BlackScholes()
self.option_symbol = option.Symbol
def OnData(self, data: Slice):
if self.IsWarmingUp:
return
chain = data.OptionChains.get(self.option_symbol)
if not chain:
return
unique_expiry = list(set([s.Expiry for s in chain]))
for expiry in unique_expiry:
contracts = [s for s in chain if s.Right == OptionRight.Call and s.Expiry == expiry]
long_call = get_contract_by_delta(contracts, 0.30)
short_call = get_contract_by_delta(contracts, 0.20)
if long_call.Strike == short_call.Strike:
# Probably Greeks are not properly computed
# self.Debug(f"{self.Time}: {expiry} has wrong greeks. Skipping.")
continue
spread = OptionStrategies.BullCallSpread(self.option_symbol, long_call.Strike, short_call.Strike, expiry)
self.Buy(spread, 1)
self.log(long_call, short_call)
def log(self, long: OptionContract, short: OptionContract):
assert long.Expiry == short.Expiry
expiry = long.Expiry.strftime("%Y%m%d")
self.Debug(f"{self.Time} {expiry}C{long.Strike}/{short.Strike}")