Overall Statistics
This strategy resolves around working with fundamentals and finding the best companies based on
- Free Cash Flow Yield 
- ROC value (Price Index)

It combines both of these values in necessary percentage to find the top 30 companies to invest in
All companies will have equal weightage

from QuantConnect import Resolution, Extensions
from QuantConnect.Algorithm.Framework.Alphas import *
from QuantConnect.Algorithm.Framework.Portfolio import *
from itertools import groupby
from datetime import datetime, timedelta
class TheStrongOnes(QCAlgorithm):

        1.Decide on Universe (possibly Dollar volume)
        2.Sort the companies by ROC (12 monhts and then 6 monhts)
        3.Start with 1000 companies
        4.Take top 20% of the companies based on ROC
        5.Calculate the free cash flow yield for these 200 companies
        6.Sort high to Low and take the top 30 out of final 40
        7.Equal investment on all companies"

        1. Coarse selection -  Find all with stocks with Fundamental data and price greater than $10 - DONE
        2. Fine selection - Find all stocks with Marketcap greater than 100M - DONE
        3. Check if we can run Insights generator on a monthly basis and do not run if it is not one month - NO NEED
        3.1 Calculate ROC from 1000 copmpanies and get 20% sorted high to low - DONE
        3.2 Calculate free cash flow on 200 companies now and find the top 30 out of it - DONE
        3.3 Generate Insghts Group for these 30 companies - NOT NEEDED
        4. Add Portfolio Construction to Equal weight to buy all these 30 companies - DONE
        5. Rebalance should happen automatically every month based on Insights group or may be Universe selection itself
    def Initialize(self):
        self.SetStartDate(2012, 1, 1) 
        self.SetEndDate(2012, 2, 15)
        self.UniverseSettings.Resolution = Resolution.Daily
        self.Settings.RebalancePortfolioOnSecurityChanges = True
        self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter)
        self.SetPortfolioConstruction( EqualWeightingPortfolioConstructionModel() )
        self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1)))
        self.numberOfSymbolsCoarse = 20
        self.numberOfSymbolsFine = 10
        self.current = self.Time - timedelta(31)
    def CoarseSelectionFilter(self, coarse):
        if (self.Time - self.current).days <= 30:
            return Universe.Unchanged
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)   # sort descending by daily dollar volume
        return [ x.Symbol for x in sortedByDollarVolume if x.Price > 10 and x.HasFundamentalData][:self.numberOfSymbolsCoarse]  # return the symbol objects of the top entries from our sorted collection
    def FineSelectionFilter(self, fine): 
        if (self.Time - self.current).days <= 30:
            return Universe.Unchanged
        market_cap = {}
        # Calculate the market cap and add the "MarketCap" property to fine universe object
        for i in fine:
            market_cap[i] = (i.EarningReports.BasicAverageShares.ThreeMonths * i.EarningReports.BasicEPS.TwelveMonths * i.ValuationRatios.PERatio)

        filtered = [x for x in fine if market_cap[x] > 0]

        marketCapFilter = sorted(filtered, key=lambda x: market_cap[x])

        # marketCapFilter = [x for x in fine if x.Marketcap > 10000000]
        sortedByCashReturn = sorted(marketCapFilter, key=lambda x: x.ValuationRatios.CashReturn, reverse=True)[:200] 
        sortedByROIC = sorted(sortedByCashReturn, key=lambda x: x.OperationRatios.ROIC.OneYear)[:40]
        self.Debug('sortedByROIC -->'+ str(len(sortedByROIC)))
        return [ x.Symbol for x in sortedByROIC]

    def OnData(self, CoarseSelectionFilter):
        if not self.Portfolio.Invested:
            self.current = self.Time