Overall Statistics |
Total Trades 5 Average Win 0% Average Loss -5.85% Compounding Annual Return -57.320% Drawdown 12.800% Expectancy -1 Net Profit -7.193% Sharpe Ratio -1.333 Probabilistic Sharpe Ratio 15.753% Loss Rate 100% Win Rate 0% Profit-Loss Ratio 0 Alpha -0.422 Beta -0.073 Annual Standard Deviation 0.32 Annual Variance 0.102 Information Ratio -1.386 Tracking Error 0.353 Treynor Ratio 5.846 Total Fees $8.04 Estimated Strategy Capacity $340000.00 Lowest Capacity Asset ACOR TG2OFNO1HAHX |
#region imports from AlgorithmImports import * #endregion import datetime #import timedelta, time from datetime import datetime import math import time as t from AlgorithmImports import * from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel holidays = [2021-11-26, 2022-11-25, 2023-11-25, 2023-7-3] selected = [] """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Symbol Data """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" class SymbolData(object): def __init__(self, algorithm, symbol, criteriaDict): self.symbol = symbol self.symbolValue = symbol.Value self.algorithm = algorithm self.criteriaDict = criteriaDict self.highestTrailStopPrice = -1 self.tradeLock = False self.current = None self.smaDictionary = {} self.selectedSymbols = {} self.avg = {} self.BuyIn = {} class ErrorSubmission_TrailStop(QCAlgorithm): """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" Iniitalization """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" def Initialize(self): #-- Date Range self.SetStartDate(2021, 1, 1) # Set Start Date self.SetEndDate(2021, 2, 1) # Set End Date #-- Starting Equity self.SetCash(10000) # Set Strategy Cash # check if will be replaced self.UniverseSettings.Resolution = Resolution.Minute self.AddUniverse(self.CoarseFilterSelection, self.FineFilterSelection) self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x))) self.criteriaDict = {} self.averages = {} self.smavolume = {} self.purchased_options = [] self.symbolDict = {} self.symbolWithPositionDict = {} self.lock = {} self.SetWarmUp(200, Resolution.Minute) self.sm = {} self.smavol = {} self.BuyIn = {} """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" OnData """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" def OnSecuritiesChanged(self, changes): for security in changes.RemovedSecurities: if ((security.Symbol in self.symbolDict) and (security.Symbol not in self.symbolWithPositionDict) and (security.Symbol not in selected) and (security.Symbol not in self.purchased_options)): symbolData = self.symbolDict[security.Symbol] del self.symbolDict[security.Symbol] for security in changes.AddedSecurities: if security.Symbol not in self.symbolDict: #equity = self.AddEquity(security.Symbol.Value, Resolution.Minute, Market.USA) self.symbolDict[security.Symbol] = SymbolData(self,security.Symbol,self.criteriaDict) #equity.SetDataNormalizationMode(DataNormalizationMode.Raw) self.symbol = security.Symbol def TradeOptions(self, contracts, ticker): filtered_contracts = self.InitialFilter(ticker, contracts, -1, 1, 1, 15) if filtered_contracts == None: return elif len(filtered_contracts) > 0: expiry = sorted(filtered_contracts,key = lambda x: x.ID.Date, reverse=False)[0].ID.Date call = [i for i in filtered_contracts if i.ID.Date == expiry and i.ID.OptionRight == 0] call_contracts = sorted(call,key = lambda x: x.ID.StrikePrice) self.call = call_contracts[0] for i in filtered_contracts: if i.ID.Date == expiry and i.ID.OptionRight == 1 and i.ID.StrikePrice ==call_contracts[0].ID.StrikePrice: self.put = i self.AddOptionContract(self.call, Resolution.Minute) self.AddOptionContract(self.put, Resolution.Minute) self.purchased_options.append(self.symbol) self.Buy(self.call, 5) def InitialFilter(self, underlyingsymbol, symbol_list, min_strike_rank, max_strike_rank, min_expiry, max_expiry): contract_list = [i for i in symbol_list if min_expiry <= (i.ID.Date.date() - self.Time.date()).days < max_expiry] try : atm_strike = sorted(contract_list, key = lambda x: abs(x.ID.StrikePrice - self.Securities[underlyingsymbol].Price))[0].ID.StrikePrice strike_list = sorted(set([i.ID.StrikePrice for i in contract_list])) atm_strike_rank = strike_list.index(atm_strike) try: min_strike = strike_list[atm_strike_rank + min_strike_rank] max_strike = strike_list[atm_strike_rank + max_strike_rank] except: min_strike = strike_list[0] max_strike = strike_list[-1] filtered_contracts = [i for i in contract_list if i.ID.StrikePrice >= min_strike and i.ID.StrikePrice <= max_strike] except: filtered_contracts = None return filtered_contracts def OnData(self, data): if self.IsWarmingUp: return todaydate = datetime.today().strftime('%Y-%m-%d') for x in holidays: if x == todaydate: return for symbol in self.symbolDict: symbolData = self.symbolDict[symbol] symbolData.CurrentPrice = self.Securities[symbol].Price if len (self.symbolWithPositionDict) != 0: continue if len(selected) != 0: continue elif symbol not in selected and symbol not in self.lock: selected.append(symbol) self.BuyIn[symbol] = symbolData.CurrentPrice for symbol in selected: symbolData = self.symbolDict[symbol] symbolData.CurrentPrice = self.Securities[symbol].Price if not self.Portfolio[symbol].Invested: symbolData.BuyIn = symbolData.CurrentPrice symbolData.current = self.Time cash = self.Portfolio.Cash available = (cash *.5) purchase = math.floor(available / symbolData.CurrentPrice) locktime = self.Time contracts = self.OptionChainProvider.GetOptionContractList(symbol, self.Time.date()) if contracts: #self.Debug('contracts') #self.Debug(contracts) self.TradeOptions(contracts, symbol.Value) self.lock[symbol] = locktime self.MarketOrder(symbol, -purchase) self.symbolWithPositionDict[symbol] = SymbolData(self,symbol,self.criteriaDict) for symbol in list(self.symbolWithPositionDict): symbolData = self.symbolDict[symbol] if self.Securities[symbol].Price < symbolData.BuyIn * .85 or self.Securities[symbol].Price > symbolData.BuyIn * 1.1: # self.Securities[symbol].Price < symbolData.highestTrailStopPrice * .9 self.Liquidate(symbol) del self.symbolWithPositionDict[symbol] selected.remove(symbol) def CoarseFilterSelection(self, universe): filtering = [] universe = sorted(universe, key=lambda c: c.DollarVolume, reverse=True) universe = [c for c in universe] for coarse in universe: symbol = coarse.Symbol options = self.OptionChainProvider.GetOptionContractList(symbol, self.Time.date()) if len(options) == 0: continue if symbol not in self.averages: history = self.History(symbol, 30, Resolution.Daily) self.averages[symbol] = SelectionData(history) self.averages[symbol].update(self.Time, coarse.Volume) if self.averages[symbol].is_ready() and self.averages[symbol].aver.Current.Value > 500000: filtering.append(symbol) return filtering def FineFilterSelection(self, fine): sortedByShares = sorted(fine, key = lambda f: f.CompanyProfile.SharesOutstanding, reverse = True) universed = [f for f in sortedByShares if f.CompanyProfile.SharesOutstanding < 15000000 and f.MarketCap < 2000000000] return [x.Symbol for x in universed] class SelectionData(): def __init__(self, history): self.aver = SimpleMovingAverage(30) for bar in history.itertuples(): self.aver.Update(bar.Index[1], bar.close) def is_ready(self): return self.aver.IsReady def update(self, time, volume): self.aver.Update(time, volume)