Overall Statistics |
Total Trades 12 Average Win 9.02% Average Loss -8.32% Compounding Annual Return -4.730% Drawdown 0.600% Expectancy 0.042 Net Profit -0.420% Sharpe Ratio -2.055 Probabilistic Sharpe Ratio 17.302% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.08 Alpha -0.283 Beta 0.023 Annual Standard Deviation 0.025 Annual Variance 0.001 Information Ratio -15.772 Tracking Error 0.63 Treynor Ratio -2.188 Total Fees $12.00 Estimated Strategy Capacity $760000.00 |
#Need to change the liquidate to later in the day #Same goes for when this is executed from datetime import timedelta from clr import AddReference AddReference("System") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Common") from System import * from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Securities.Option import OptionPriceModels from QuantConnect.Data.UniverseSelection import * class BasicTemplateOptionsAlgorithm(QCAlgorithm): contracts = 1 shortDelta = .18 longDelta = .15 def Initialize(self): self.SetStartDate(2021, 1, 1) self.SetEndDate(2021, 2, 1) self.SetCash(100000) self.symbol = "TSLA" self.expiry = self.Time equity = self.AddEquity(self.symbol, Resolution.Minute) option = self.AddOption(self.symbol, Resolution.Minute) option.SetFilter(-20, 20, timedelta(30), timedelta(60)) # self.MaximumOrderValue = 20000 # use the underlying equity as the benchmark self.SetBenchmark(equity.Symbol) self.SetWarmUp(35, Resolution.Daily) def OnData(self, slice): if(self.IsWarmingUp): return self.TradeOptions(slice) def TradeOptions(self, slice): days_to_expiry = (self.expiry-self.Time).days if self.Portfolio.Invested and days_to_expiry <=20: self.Liquidate() profit2 = sum([x.UnrealizedProfitPercent for x in self.Portfolio.Values if x.Type == SecurityType.Option]) self.Log(profit2) if self.Portfolio.Invested and profit2 >= .5: self.Liquidate() if not self.Portfolio.Invested and self.Time.hour != 0 and self.Time.minute != 0: shortCall = None longCall = None shortPut = None longPut = None for i in slice.OptionChains: chain = [x for x in i.Value if x.ImpliedVolatility < 50] contract_list = [x for x in chain] # if there is no optionchain or no contracts in this optionchain, pass the instance if (slice.OptionChains.Count == 0) or (len(contract_list) == 0): return # sorted optionchain by expiration date and choose the furthest date self.expiry = sorted(chain, key = lambda x: x.Expiry)[-1].Expiry # filter call and put options from the contracts call = [i for i in chain if i.Right == 0 and i.Expiry == self.expiry] put = [i for i in chain if i.Right == 1 and i.Expiry == self.expiry] # sort calls by strike prices in ascending order call_contracts = sorted(call, key = lambda x: x.Strike) # sort puts by strike prices in descending order put_contracts = sorted(put, key = lambda x: x.Strike, reverse=True) if len(call_contracts) == 0 or len(put_contracts) == 0 : continue # loop from low strike to high for call in call_contracts: self.Log("call=" + str(call.Greeks.Delta)) if((shortCall is None) and (call.Greeks.Delta <= self.shortDelta)): shortCall = call elif((longCall is None) and (call.Greeks.Delta <= self.longDelta)): longCall = call break # stop for loop # loop from high strike to low for put in put_contracts: self.Log("put=" + str(put.Greeks.Delta)) if((shortPut is None) and (put.Greeks.Delta >= -self.shortDelta)): shortPut = put elif((longPut is None) and (put.Greeks.Delta >= -self.longDelta)): longPut = put break # stop for loop if((longCall is not None) and (shortCall is not None) and (longPut is not None) and (shortPut is not None)): break if((longCall is None) or (shortCall is None) or (longPut is None) or (shortPut is None)): return self.Log(str(longCall.Greeks.Delta)) self.Log(str(shortCall.Greeks.Delta)) self.Log(str(shortPut.Greeks.Delta)) self.Log(str(longPut.Greeks.Delta)) # trade the options self.Buy(longCall.Symbol, self.contracts) self.Sell(shortCall.Symbol, self.contracts) self.Sell(shortPut.Symbol, self.contracts) self.Buy(longPut.Symbol, self.contracts)