Overall Statistics |
Total Trades 4486 Average Win 4.20% Average Loss -3.36% Compounding Annual Return 268.850% Drawdown 56.700% Expectancy 0.121 Net Profit 36676.994% Sharpe Ratio 3.044 Probabilistic Sharpe Ratio 87.254% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.25 Alpha 2.826 Beta -0.18 Annual Standard Deviation 0.92 Annual Variance 0.847 Information Ratio 2.839 Tracking Error 0.939 Treynor Ratio -15.559 Total Fees $0.00 Estimated Strategy Capacity $910000.00 Lowest Capacity Asset WVVI R735QTJ8XC9X |
import pandas as pd from io import StringIO class ShortGappers(QCAlgorithm): estimated_capacity = None gapper_data = None premarket_high = {} traded_today = set() def Initialize(self): self.gapper_data = pd.read_csv(StringIO(self.Download("https://raw.githubusercontent.com/lieblius/financial-data/main/gappers.csv")), index_col='Date') self.estimated_capacity = int(self.GetParameter("estimated-capacity")) self.SetStartDate(2016, 10, 26) self.SetEndDate(2021, 5, 4) self.SetCash(1000) self.SetExecution(ImmediateExecutionModel()) self.UniverseSettings.Resolution = Resolution.Minute self.SetSecurityInitializer(self.CustomSecurityInitializer) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.At(15, 30) , self.ClosePositions) self.AddUniverseSelection(ScheduledUniverseSelectionModel( self.DateRules.EveryDay(), self.TimeRules.At(00, 00), self.SelectSymbols )) def CustomSecurityInitializer(self, security): security.SetDataNormalizationMode(DataNormalizationMode.Raw) security.SetFeeModel(ConstantFeeModel(0)) security.SetSlippageModel(ConstantSlippageModel(0)) security.SetFillModel(ImmediateFillModel()) def OnData(self, data): if 9 <= self.Time.hour < 12 : if self.Time.hour == 9 and self.Time.minute < 30: return for security in self.ActiveSecurities: equity = security.Value symbol = equity.Symbol symbol_string = symbol.Value if not equity.HasData: continue if equity.Invested: continue if symbol_string not in self.premarket_high: continue if symbol_string in self.traded_today: continue if symbol_string == 'BRPA': continue current_price = data[symbol].Close if current_price >= self.premarket_high[symbol_string]: continue quantity = (min(self.Portfolio.TotalPortfolioValue, self.estimated_capacity) / 4 / current_price) self.traded_today.add(symbol_string) self.MarketOrder(symbol, -quantity) self.StopMarketOrder(symbol, quantity, round(self.premarket_high[symbol_string], 2)) def ClosePositions(self): self.premarket_high = {} self.traded_today = set() self.Liquidate() self.Transactions.CancelOpenOrders() def SelectSymbols(self, dateTime): min_gap = float(self.GetParameter("min-gap-pct")) min_pmh_price = float(self.GetParameter("min-premarkethigh-price")) max_daily_trades = int(self.GetParameter("max-daily-trades")) symbols = [] date = str(dateTime.date()) if date in self.gapper_data.index: gappers = self.gapper_data.loc[date] gappers = self.gapper_data.loc[str(date)] if isinstance(gappers, pd.Series): symbol = gappers['Symbol'] if gappers['GAP%'] >= min_gap and gappers['Premarket High'] >= min_pmh_price:# \ # and gappers['Outstanding Shares'] <= 20000000 and gappers['Market Cap'] <= 20000000: self.premarket_high[symbol] = gappers['Premarket High'] symbols.append(Symbol.Create(symbol, SecurityType.Equity, Market.USA)) elif len(gappers) <= max_daily_trades: for i in range(len(gappers)): symbol = gappers.iloc[i]['Symbol'] if gappers.iloc[i]['GAP%'] >= min_gap and gappers.iloc[i]['Premarket High'] >= min_pmh_price:# \ # and gappers.iloc[i]['Outstanding Shares'] <= 20000000 and gappers.iloc[i]['Market Cap'] <= 20000000: self.premarket_high[symbol] = gappers.iloc[i]['Premarket High'] symbols.append(Symbol.Create(symbol, SecurityType.Equity, Market.USA)) else: top_list = [] for i in range(len(gappers)): symbol = gappers.iloc[i]['Symbol'] if gappers.iloc[i]['GAP%'] >= min_gap and gappers.iloc[i]['Premarket High'] >= min_pmh_price:# \ # and gappers.iloc[i]['Outstanding Shares'] <= 20000000 and gappers.iloc[i]['Market Cap'] <= 20000000: top_list.append(gappers.iloc[i]) top_list = sorted(top_list, key=lambda g: g['GAP%'], reverse=True)[:max_daily_trades] for gapper in top_list: symbol = gapper['Symbol'] self.premarket_high[symbol] = gapper['Premarket High'] symbols.append(Symbol.Create(symbol, SecurityType.Equity, Market.USA)) return symbols