Overall Statistics Total Trades1285Average Win0.68%Average Loss-0.58%Compounding Annual Return17.827%Drawdown35.100%Expectancy0.197Net Profit98.100%Sharpe Ratio0.787Loss Rate45%Win Rate55%Profit-Loss Ratio1.18Alpha0.168Beta-0.127Annual Standard Deviation0.194Annual Variance0.038Information Ratio0.148Tracking Error0.232Treynor Ratio-1.209Total Fees\$3004.30
```from System.Collections.Generic import List
from QuantConnect.Data.UniverseSelection import *
import operator
from math import ceil,floor

class CoarseFineFundamentalComboAlgorithm(QCAlgorithm):
'''In this algorithm we demonstrate how to define a universe as a combination of use the coarse fundamental data and fine fundamental data'''
def Initialize(self):

self.SetStartDate(2013,01,02)  #Set Start Date
self.SetEndDate(2017,03,02)    #Set End Date
self.SetCash(50000)            #Set Strategy Cash
self.flag1 = 1
self.flag2 = 0
self.flag3 = 0

self.UniverseSettings.Resolution = Resolution.Daily

# this add universe method accepts two parameters:
# - coarse selection function: accepts an IEnumerable<CoarseFundamental> and returns an IEnumerable<Symbol>
# - fine selection function: accepts an IEnumerable<FineFundamental> and returns an IEnumerable<Symbol>
self.__numberOfSymbols = 200
self.__numberOfSymbolsFine = 15
self.num_portfolios = 7

self._changes = SecurityChanges.None
self.Schedule.On(self.DateRules.MonthStart("SPY"), self.TimeRules.AfterMarketOpen("SPY"), Action(self.Rebalancing))

# sort the data by daily dollar volume and take the top 'NumberOfSymbols'
def CoarseSelectionFunction(self, coarse):
if self.flag1:
CoarseWithFundamental = [x for x in coarse if x.HasFundamentalData]
sortedByDollarVolume = sorted(CoarseWithFundamental, key=lambda x: x.Volume, reverse=True)
# return the symbol objects of the top entries from our sorted collection
top = sortedByDollarVolume[:self.__numberOfSymbols]
# we need to return only the symbol objects
list = List[Symbol]()
for x in top:
return list
else:
return(List[Symbol]())

def FineSelectionFunction(self, fine):
if self.flag1:
self.flag1 = 0
self.flag2 = 1

filtered_fine = [x for x in fine if x.ValuationRatios.PERatio
and x.ValuationRatios.PriceChange1M
and x.ValuationRatios.BookValuePerShare]

sortedByfactor1 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False)
sortedByfactor2 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.PriceChange1M, reverse=False)
sortedByfactor3 = sorted(filtered_fine, key=lambda x: x.ValuationRatios.BookValuePerShare, reverse=True)
num_stocks = floor(len(filtered_fine)/self.num_portfolios)*self.num_portfolios

stock_dict = {}

for i,ele in enumerate(sortedByfactor1):
rank1 = i
rank2 = sortedByfactor2.index(ele)
rank3 = sortedByfactor3.index(ele)
score = [ceil(rank1/num_stocks),ceil(rank2/num_stocks),ceil(rank3/num_stocks)]
score = sum(score)
stock_dict[ele] = 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 xrange(len(self.sorted_stock))]
# take the top entries from our sorted collection
topFine = sorted_symbol[:self.__numberOfSymbolsFine]
list = List[Symbol]()
for x in topFine:
self.flag3 = self.flag3 + 1

return list
else:
return (List[Symbol]())

def OnData(self, data):
if self.flag3 > 0:
if self.flag2 == 1:
self.flag2 = 0

# if we have no changes, do nothing
if self._changes == SecurityChanges.None: return
# liquidate removed securities
for security in self._changes.RemovedSecurities:
if security.Invested:
self.Liquidate(security.Symbol)