| 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]