Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
-1.057
Tracking Error
0.115
Treynor Ratio
0
Total Fees
$0.00
'''
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):

    '''
    ROUGH GUIDELINES
        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"

    ROUGH TRY FOR QUANTCONNECT GUIDANCE
        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, 12, 29)
        self.SetCash(10000)
        self.UniverseSettings.Resolution = Resolution.Daily
        self.Settings.RebalancePortfolioOnSecurityChanges = True
        self.AddUniverse(self.CoarseSelectionFilter, self.FineSelectionFilter)
        self.SetPortfolioConstruction( EqualWeightingPortfolioConstructionModel() )
        self.numberOfSymbolsCoarse = 2000
        self.numberOfSymbolsFine = 1000
        self.current = self.Time
        
    def CoarseSelectionFilter(self, coarse):
        # if self.year == self.Time.year:
        #     return self.symbols
        if (self.Time - self.current).days != 30:
            return []
        else:
            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): 
        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)

        marketCapFilter = sorted([x for x in fine if market_cap[x] > 0], 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