Overall Statistics |
Total Orders 3297 Average Win 0.28% Average Loss -0.38% Compounding Annual Return 8.539% Drawdown 41.700% Expectancy 0.105 Start Equity 50000 End Equity 99001.76 Net Profit 98.004% Sharpe Ratio 0.361 Sortino Ratio 0.426 Probabilistic Sharpe Ratio 1.712% Loss Rate 36% Win Rate 64% Profit-Loss Ratio 0.74 Alpha -0.043 Beta 1.085 Annual Standard Deviation 0.182 Annual Variance 0.033 Information Ratio -0.342 Tracking Error 0.1 Treynor Ratio 0.061 Total Fees $4492.70 Estimated Strategy Capacity $2100000.00 Lowest Capacity Asset TTD WE3561IA1KKL Portfolio Turnover 4.53% |
# region imports from AlgorithmImports import * # endregion class StockSelectionStrategyBasedOnFundamentalFactorsAlgorithm(QCAlgorithm): def initialize(self): self.set_start_date(2009, 1, 2) self.set_end_date(2017, 5, 2) self.set_cash(50000) self._current_month = -1 self._coarse_count = 300 self._fine_count = 10 self.add_universe(self._coarse_selection_function, self._fine_selection_function) self.set_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(30))) self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel(lambda _: None)) def _coarse_selection_function(self, coarse): if self._current_month == self.time.month: return Universe.UNCHANGED self._current_month = self.time.month sorted_by_dollar_volume = sorted([x for x in coarse if x.has_fundamental_data], key=lambda x: x.dollar_volume, reverse=True)[:self._coarse_count] return [i.symbol for i in sorted_by_dollar_volume] def _fine_selection_function(self, fine): fine = [x for x in fine if x.earning_reports.total_dividend_per_share.three_months and x.valuation_ratios.price_change_1m and x.valuation_ratios.book_value_per_share and x.valuation_ratios.fcf_yield] sorted_by_factor1 = sorted(fine, key=lambda x: x.earning_reports.total_dividend_per_share.three_months, reverse=True) sorted_by_factor2 = sorted(fine, key=lambda x: x.valuation_ratios.price_change_1m, reverse=False) sorted_by_factor3 = sorted(fine, key=lambda x: x.valuation_ratios.book_value_per_share, reverse=True) sorted_by_factor4 = sorted(fine, key=lambda x: x.valuation_ratios.fcf_yield, reverse=True) stock_dict = {} for rank1, ele in enumerate(sorted_by_factor1): rank2 = sorted_by_factor2.index(ele) rank3 = sorted_by_factor3.index(ele) rank4 = sorted_by_factor4.index(ele) stock_dict[ele] = rank1 + rank2 + rank3 + rank4 sorted_stock = sorted(stock_dict.items(), key=lambda d:d[1], reverse=True)[:self._fine_count] return [x[0].symbol for x in sorted_stock]