Overall Statistics |
Total Trades 375 Average Win 0.06% Average Loss -0.03% Compounding Annual Return 26.361% Drawdown 8.800% Expectancy 1.375 Net Profit 12.666% Sharpe Ratio 1.131 Probabilistic Sharpe Ratio 54.083% Loss Rate 18% Win Rate 82% Profit-Loss Ratio 1.90 Alpha 0.234 Beta -0.172 Annual Standard Deviation 0.181 Annual Variance 0.033 Information Ratio 0.146 Tracking Error 0.222 Treynor Ratio -1.187 Total Fees $375.59 |
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel class VentralModulatedThrustAssembly(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 7, 9) # Set Start Date self.SetCash(100000) # Set Strategy Cash self.SetUniverseSelection(SelectionModel()) self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1), 0.025, None)) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) class SelectionModel(FundamentalUniverseSelectionModel): def __init__(self, filterFineData = True, universeSettings = None, securityInitializer = None): super().__init__(filterFineData, universeSettings, securityInitializer) self.periodCheck = -1 self.coarse = dict() def SelectCoarse(self, algorithm, coarse): if algorithm.Time.year == self.periodCheck: return Universe.Unchanged self.coarse = {x.Symbol: x for x in coarse if x.HasFundamentalData and x.Volume > 0 and x.Price > 0} return [symbol for symbol,_ in self.coarse.items()] def SelectFine(self, algorithm, fine): DERatio = lambda x: x.OperationRatios.LongTermDebtEquityRatio.ThreeMonths fine = [x for x in fine if DERatio(x) and x.CompanyReference.CountryId == "USA" and (x.CompanyReference.PrimaryExchangeID in ["NYS", "NAS"]) and (algorithm.Time - x.SecurityReference.IPODate).days > 180 and x.EarningReports.BasicAverageShares.ThreeMonths * x.EarningReports.BasicEPS.TwelveMonths * x.ValuationRatios.PERatio > 1.52e8] if len(fine) == 0: return Universe.Unchanged self.periodCheck = algorithm.Time.year sortedByDEratio = sorted(fine, key=DERatio, reverse=False)[:50] symbols = [x.Symbol for x in sortedByDEratio] averages = dict() history = algorithm.History(symbols, 200, Resolution.Daily).close.unstack(0) for symbol in symbols: # Remove NaN: symbol does not have 200 daily data points df = history[symbol].dropna() if df.empty: continue mom = Momentum(126) for time, close in df.iteritems(): mom.Update(time, close) # Adds Momentum to dict only if it is ready if mom.IsReady: averages[symbol] = mom # Update with current data for symbol, mom in averages.items(): c = self.coarse.pop(symbol, None) mom.Update(c.EndTime, c.AdjustedPrice) sortedbyMomentum = sorted(averages.items(), key=lambda x: x[1], reverse=True) return [x[0] for x in sortedbyMomentum[:5]]