Overall Statistics
Total Trades
3
Average Win
0%
Average Loss
0%
Compounding Annual Return
17.059%
Drawdown
2.500%
Expectancy
0
Net Profit
3.495%
Sharpe Ratio
1.913
Probabilistic Sharpe Ratio
66.305%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0.044
Beta
0.462
Annual Standard Deviation
0.067
Annual Variance
0.005
Information Ratio
-0.735
Tracking Error
0.075
Treynor Ratio
0.279
Total Fees
$19.75
Estimated Strategy Capacity
$23000000.00
Lowest Capacity Asset
SPY WLF0Z3N5TUH2|SPY R735QTJ8XC9X
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from datetime import timedelta
from QuantConnect.Securities.Option import OptionPriceModels

class DCAintoLEAPs(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2016, 6, 1)
        self.SetEndDate(2016, 8, 20)
        self.SetWarmUp(90, Resolution.Daily)
        self.UniverseSettings.SetLeverage = 1
        self.num_buys = 24
        self.amt_per_txn = 500000//24

        self.SetCash(500000)
        self.AddEquity("SPY", Resolution.Daily)

        option = self.AddOption("SPY")
        option.PriceModel = OptionPriceModels.CrankNicolsonFD()
        self.option_symbol = option.Symbol
        # set our strike/expiry filter for this option chain
        option.SetFilter(self.UniverseFunc)

        # use the underlying equity as the benchmark
        self.SetBenchmark("SPY")
        
        self.contracts = None
        
        self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 10), self.OnDataTrade)
        self.Schedule.On(self.DateRules.WeekStart("SPY"), self.TimeRules.AfterMarketOpen("SPY", 10), self.sell_expiring)


    def UniverseFunc(self, universe):
        return universe.IncludeWeeklys().Strikes(-100, 100).Expiration(timedelta(380), timedelta(445))


    def OnData(self,slice):
        if not (self.Time.hour == 9 and self.Time.minute == 38): return
        for kvp in slice.OptionChains:
            if kvp.Key != self.option_symbol: continue
            chain = kvp.Value
            chain = [x for x in chain if x.Right == OptionRight.Call]
            contracts = sorted(chain, key = lambda x: abs(x.Greeks.Delta-0.4))
            self.Plot("Delta", "Calls", contracts[0].Greeks.Delta)
            self.Plot("Options", "Calls", len(chain))
            
            
            
            closest_expiry_beyond_1y = sorted(chain,key = lambda x: x.Expiry)[0].Expiry
            chain = [x for x in chain if x.Expiry == closest_expiry_beyond_1y]
            contracts = sorted(chain, key = lambda x: abs(x.Greeks.Delta-0.4))
            x = contracts[0]
            
            self.Plot("Delta", "Calls + Latest Expiry", x.Greeks.Delta)
            self.Plot("Options", "Calls + Latest Expiry", len(chain))
            
            #columns=['idx', 'type(call 0, put 1)', 'strike', 'expiry', 'ask price', 'bid price', 'delta', x.Symbol.Value, x.Right,float(x.Strike),x.Expiry,float(x.BidPrice),float(x.AskPrice),float(x.Greeks.Delta)]
            #self.Log(str(columns))
            self.contracts = contracts
            
    def sell_expiring(self):
            # Sell calls that are expiring within a week
            leaps = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
            for x in leaps:
                if (self.Securities[x].Expiry.date() - self.Time.date()).days <= 14:
                    self.Liquidate(x)
        
    def OnDataTrade(self):
            # Buy calls
            if len(self.contracts) == 0: pass
            symbol = self.contracts[0].Symbol
            self.MarketOrder(symbol, (self.amt_per_txn/100)//self.contracts[0].AskPrice)


    def OnOrderEvent(self, orderEvent):
        self.Log(str(orderEvent))