| Overall Statistics |
|
Total Trades 6001 Average Win 0.18% Average Loss -0.18% Compounding Annual Return 12.393% Drawdown 29.100% Expectancy 0.173 Net Profit 164.850% Sharpe Ratio 0.594 Probabilistic Sharpe Ratio 8.188% Loss Rate 41% Win Rate 59% Profit-Loss Ratio 0.99 Alpha -0.027 Beta 1.143 Annual Standard Deviation 0.205 Annual Variance 0.042 Information Ratio -0.076 Tracking Error 0.107 Treynor Ratio 0.106 Total Fees $7691.89 |
from math import ceil,floor
class CoarseFineFundamentalComboAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2009,1,2) # Set Start Date
self.SetEndDate(2017,5,2) # Set End Date
self.SetCash(50000) # Set Strategy Cash
self.AddUniverseSelection(
FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction)
)
self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(30)))
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time:None))
self.AddEquity("SPY")
self.numberOfSymbols = 300
self.numberOfSymbolsFine = 10
self.num_portfolios = 6
self.curr_month = self.Time.month
def CoarseSelectionFunction(self, coarse):
if self.curr_month == self.Time.month:
return Universe.Unchanged
self.curr_month = self.Time.month
CoarseWithFundamental = [x for x in coarse if x.HasFundamentalData]
sortedByDollarVolume = sorted(CoarseWithFundamental, key=lambda x: x.DollarVolume, reverse=True)
top = sortedByDollarVolume[:self.numberOfSymbols]
return [i.Symbol for i in top]
def FineSelectionFunction(self, fine):
filtered_fine = [x for x in fine if x.EarningReports.TotalDividendPerShare.ThreeMonths
and x.ValuationRatios.PriceChange1M
and x.ValuationRatios.BookValuePerShare
and x.ValuationRatios.FCFYield]
sortedByfactor1 = sorted(filtered_fine, key=lambda x: x.EarningReports.TotalDividendPerShare.ThreeMonths, reverse=True)
sortedByfactor2 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.PriceChange1M, reverse=False)
sortedByfactor3 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.BookValuePerShare, reverse=True)
sortedByfactor4 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.FCFYield, reverse=True)
num_stocks = floor(len(filtered_fine)/self.num_portfolios)
stock_dict = {}
for i,ele in enumerate(sortedByfactor1):
rank1 = i
rank2 = sortedByfactor2.index(ele)
rank3 = sortedByfactor3.index(ele)
rank4 = sortedByfactor4.index(ele)
score = [ceil(rank1/num_stocks),
ceil(rank2/num_stocks),
ceil(rank3/num_stocks),
ceil(rank4/num_stocks)]
score = sum(score)
stock_dict[ele] = score
#self.Log("score" + str(score))
self.sorted_stock = sorted(stock_dict.items(), key=lambda d:d[1],reverse=True)
sorted_symbol = [self.sorted_stock[i][0] for i in range(len(self.sorted_stock))]
topFine = sorted_symbol[:self.numberOfSymbolsFine]
return [i.Symbol for i in topFine]