Overall Statistics |
Total Trades 446 Average Win 0.20% Average Loss -0.29% Compounding Annual Return -24.983% Drawdown 7.100% Expectancy -0.072 Net Profit -5.834% Sharpe Ratio -3.465 Loss Rate 45% Win Rate 55% Profit-Loss Ratio 0.68 Alpha -0.246 Beta 0.152 Annual Standard Deviation 0.065 Annual Variance 0.004 Information Ratio -2.904 Tracking Error 0.126 Treynor Ratio -1.471 Total Fees $426.00 |
from clr import AddReference from QuantConnect.Securities.Option import OptionPriceModels import decimal as d AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Data import * from QuantConnect.Algorithm import * import numpy as np from datetime import timedelta class My1(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 6, 1) self.SetEndDate(2019, 8, 15) self.SetCash(25000) self.date = None # add the underlying asset self.stock= "SPY" self.equity = self.AddEquity(self.stock, Resolution.Minute) self.equity.SetDataNormalizationMode(DataNormalizationMode.Raw) option = self.AddOption(self.stock) option.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(-5, +5).Expiration(timedelta(0), timedelta(7))) # for greeks and pricer (needs some warmup) - https://github.com/QuantConnect/Lean/blob/21cd972e99f70f007ce689bdaeeafe3cb4ea9c77/Common/Securities/Option/OptionPriceModels.cs#L81 option.PriceModel = OptionPriceModels.CrankNicolsonFD() # both European & American, automatically # this is needed for Greeks calcs self.SetWarmUp(TimeSpan.FromDays(3)) # timedelta(7) self.contract = str() self.contractsAdded = set() self.delta_treshold = 0.1 self.Delta = 0.0 def OnData(self, data): if self.Time.date != self.date: self.date = self.Time.date for chain in data.OptionChains.Values: # sort contracts to find at the money (ATM) contract with the farthest expiration contracts = sorted(sorted(chain, key = lambda x: abs(chain.Underlying.Price - x.Strike)), \ key = lambda x: x.Expiry, reverse=True) expiry = sorted(contracts,key = lambda x: x.Expiry, reverse=True)[0].Expiry #self.Debug("best expiry is" + str(expiry)) calls = [i for i in contracts if i.Expiry == expiry and i.Right == 0 and i.Strike > chain.Underlying.Price] # sorted the contracts according to their strike prices call_contracts = sorted(calls,key = lambda x: x.Strike) if len(call_contracts) == 0: continue # choose the deep OTM call option self.call = call_contracts[0] # select the put options which have the same expiration date with the call option puts = [i for i in contracts if i.Expiry == expiry and i.Right == 1 and i.Strike < chain.Underlying.Price] # sort the put options by strike price put_contracts = sorted(puts, key = lambda x: x.Strike) # choose the deep OTM put option self.put = put_contracts[-1] if not self.Portfolio.Invested: #self.Transactions.CancelOpenOrders("SPY") self.Debug("------------------------------- price is " + str(self.Securities[self.stock].Close)) self.Debug("Trade: Call " + str(self.call.Strike) + " " + str(self.call.Expiry)) self.Debug("Trade: Put " + str(self.put.Strike) + " " + str(self.put.Expiry)) self.Buy(self.call.Symbol ,1) self.Buy(self.put.Symbol ,1) #self.StopMarketOrder(self.stock, 50, self.call.Strike) #self.StopMarketOrder(self.stock, -50, self.put.Strike) else: #if self.Time.minute == 59: self.get_greeks(data) self.doDeltaHedge() def doDeltaHedge(self): fut = self.Portfolio[self.stock].Quantity #self.Debug("+++ time: "+ str(self.Time) +" delta is " + str(self.Delta) + " fut pos: " + str(fut)) if abs(self.Delta) > self.delta_treshold: needfut = round(self.Delta*-100) self.MarketOrder(self.stock,needfut) self.Debug(str(self.Time) + " delta_hedging: self.Delta {} add fut contracts: {}" .format(self.Delta, needfut)) def get_greeks(self, slice): sumdelta = 0.00 symbols = set() for sym in self.Portfolio: symbols.add(sym.Value.Symbol) opt = self.Securities[sym.Value.Symbol] for kvp in slice.OptionChains: chain = kvp.Value # option contracts for each 'subscribed' symbol/key traded_contracts = filter(lambda x: x.Symbol in symbols, chain) #if not traded_contracts: self.Log("No traded cointracts"); return deltas = [i.Greeks.Delta*self.Portfolio[i.Symbol].Quantity for i in traded_contracts] sumdelta=sum(deltas) futpos = self.Portfolio[self.stock].Quantity self.Delta=sumdelta + futpos/100