Quant Buffet放轻松,别过度思虑

期权到期周末交易策略

登录后收藏

回测表现

年化收益21.26%
贝塔0.008
索提诺比率-0.505
胜率55%

完整 Python 代码

from AlgorithmImports import *
class TradingOptionsDuringExpirationWeekends(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2011, 1, 1)
self.SetCash(100000)

self.symbol = self.AddEquity("SPY", Resolution.Minute).Symbol

# Next expiry date.
self.expiry_date = None

option = self.AddOption("SPY", Resolution.Minute)
option.SetFilter(-20, 20, 25, 35)
self.Schedule.On(self.DateRules.EveryDay(self.symbol), self.TimeRules.AfterMarketOpen(self.symbol, 1), self.Close)

def OnData(self, slice):
# Open new trades only on market close.
if not (self.Time.hour == 15 and self.Time.minute == 59):
    return

if self.expiry_date:
    if self.Time.date() < self.expiry_date.date(): 
        return
    
for i in slice.OptionChains:
    chains = i.Value
    if not self.Portfolio.Invested:
        puts = list(filter(lambda x: x.Right == OptionRight.Put, chains))
        if not puts: return
    
        underlying_price = self.Securities[self.symbol].Price
        expiries = [i.Expiry for i in puts]
        # Determine expiration date nearly one month.
        expiry = min(expiries, key=lambda x: abs((x.date()-self.Time.date()).days-30))
        strikes = [i.Strike for i in puts]
        # determine at-the-money strike
        strike = min(strikes, key=lambda x: abs(x-underlying_price))
        atm_put = [i for i in puts if i.Expiry == expiry and i.Strike == strike]
        if atm_put:
            if not self.expiry_date:
                self.expiry_date = atm_put[0].Expiry
                return
            
            options_q = int(self.Portfolio.MarginRemaining / (underlying_price * 100))
            if not (self.Time.month == 8 and self.Time.year == 2015):
                self.Sell(atm_put[0].Symbol, options_q)
                self.expiry_date = atm_put[0].Expiry
    
    if self.Portfolio.Invested:
        self.Liquidate(self.symbol)
        
def Close(self):
if self.Portfolio.Invested:
    self.Liquidate()