Overall Statistics |
Total Trades 4538 Average Win 3.29% Average Loss -2.67% Compounding Annual Return 206.229% Drawdown 56.000% Expectancy 0.121 Net Profit 15743.732% Sharpe Ratio 2.472 Probabilistic Sharpe Ratio 81.594% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 1.23 Alpha 2.086 Beta -0.252 Annual Standard Deviation 0.83 Annual Variance 0.688 Information Ratio 2.246 Tracking Error 0.853 Treynor Ratio -8.138 Total Fees $0.00 Estimated Strategy Capacity $340000.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(25000) 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': # There is a bug in data for this symbol continue current_price = data[symbol].Close if current_price >= self.premarket_high[symbol_string]: continue quantity = int((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