Overall Statistics |
Total Trades 3908 Average Win 0.08% Average Loss -0.06% Compounding Annual Return 16.414% Drawdown 31.900% Expectancy 0.776 Net Profit 113.987% Sharpe Ratio 0.637 Probabilistic Sharpe Ratio 14.063% Loss Rate 28% Win Rate 72% Profit-Loss Ratio 1.46 Alpha 0.025 Beta 1.049 Annual Standard Deviation 0.209 Annual Variance 0.044 Information Ratio 0.262 Tracking Error 0.116 Treynor Ratio 0.127 Total Fees $3967.87 Estimated Strategy Capacity $120000.00 Lowest Capacity Asset FORTY R735QTJ8XC9X |
# g score investing updated from AlgorithmImports import * import statistics as stat from collections import deque class DynamicCalibratedGearbox(QCAlgorithm): def Initialize(self): self.tech_ROA_key = 'TECH_ROA' self.SetStartDate(2017, 6, 1) self.SetEndDate(2022, 6, 1) self.SetCash(100000) self.SetBrokerageModel(AlphaStreamsBrokerageModel()) self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(days=31))) self.SetExecution(ImmediateExecutionModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time:None)) self.AddUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseFilter, self.FineFilter)) self.UniverseSettings.Resolution = Resolution.Daily self.curr_month = -1 self.tech_ROA = {} self.symbols = None self.quarters = 0 self.SetWarmUp(756, Resolution.Daily) def CoarseFilter(self, coarse): if self.curr_month == self.Time.month: return Universe.Unchanged self.curr_month = self.Time.month if self.Time.month % 3 != 1: return Universe.Unchanged self.quarters += 1 return [c.Symbol for c in coarse if c.HasFundamentalData] def FineFilter(self, fine): tech_securities = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology and f.OperationRatios.ROA.ThreeMonths] for security in tech_securities: symbol = security.Symbol if symbol not in self.tech_ROA: self.tech_ROA[symbol] = deque(maxlen=12) self.tech_ROA[symbol].append(security.OperationRatios.ROA.ThreeMonths) if self.Time.month != 4 or (self.quarters < 12 ): return Universe.Unchanged tech_securities = [x for x in tech_securities if x.OperationRatios.ROA.OneYear and x.FinancialStatements.CashFlowStatement.OperatingCashFlow.TwelveMonths and x.FinancialStatements.BalanceSheet.TotalAssets.TwelveMonths and x.FinancialStatements.IncomeStatement.ResearchAndDevelopment.TwelveMonths and x.FinancialStatements.CashFlowStatement.CapExReported.TwelveMonths and x.FinancialStatements.IncomeStatement.SellingGeneralAndAdministration.TwelveMonths and x.MarketCap] tech_VARROA = {symbol:stat.variance(ROA) for symbol, ROA in self.tech_ROA.items() if len(ROA) == ROA.maxlen} if len(tech_VARROA) < 2: return Universe.Unchanged tech_VARROA_median = stat.median(tech_VARROA.values()) tech_ROA1Y = {x.Symbol:x.OperationRatios.ROA.OneYear for x in tech_securities} tech_ROA1Y_median = stat.median(tech_ROA1Y.values()) tech_CFROA = {x.Symbol: ( x.FinancialStatements.CashFlowStatement.OperatingCashFlow.TwelveMonths / x.FinancialStatements.BalanceSheet.TotalAssets.TwelveMonths ) for x in tech_securities} tech_CFROA_median = stat.median(tech_CFROA.values()) tech_RD2MktCap = {x.Symbol: ( x.FinancialStatements.IncomeStatement.ResearchAndDevelopment.TwelveMonths / x.MarketCap ) for x in tech_securities} tech_RD2MktCap_median = stat.median(tech_RD2MktCap.values()) tech_CaPex2MktCap = {x.Symbol: ( x.FinancialStatements.CashFlowStatement.CapExReported.TwelveMonths / x.MarketCap ) for x in tech_securities} tech_CaPex2MktCap_median = stat.median(tech_CaPex2MktCap.values()) tech_Ad2MktCap = {x.Symbol: ( x.FinancialStatements.IncomeStatement.SellingGeneralAndAdministration.TwelveMonths / x.MarketCap ) for x in tech_securities} tech_Ad2MktCap_median = stat.median(tech_Ad2MktCap.values()) has_book = [f for f in fine if f.FinancialStatements.BalanceSheet.NetTangibleAssets.TwelveMonths and f.MarketCap] sorted_by_BM = sorted(has_book, key=lambda x: x.FinancialStatements.BalanceSheet.NetTangibleAssets.TwelveMonths / x.MarketCap)[:len(has_book)//4] tech_symbols = [f.Symbol for f in sorted_by_BM if f in tech_securities] ratioDicts_medians = [(tech_ROA1Y, tech_ROA1Y_median), (tech_CFROA, tech_CFROA_median), (tech_RD2MktCap, tech_RD2MktCap_median), (tech_CaPex2MktCap, tech_CaPex2MktCap_median), (tech_Ad2MktCap, tech_Ad2MktCap_median)] def compute_g_score(symbol): g_score = 0 if tech_CFROA[symbol] > tech_ROA1Y[symbol]: g_score += 1 if symbol in tech_VARROA and tech_VARROA[symbol] < tech_VARROA_median: g_score += 1 for ratio_dict, median in ratioDicts_medians: if symbol in ratio_dict and ratio_dict[symbol] > median: g_score += 1 return g_score g_scores = {symbol:compute_g_score(symbol) for symbol in tech_symbols} return [symbol for symbol, g_score in g_scores.items() if g_score >= 5]