Overall Statistics
Total Trades
1587
Average Win
0.33%
Average Loss
-0.28%
Compounding Annual Return
14.649%
Drawdown
22.000%
Expectancy
0.161
Net Profit
50.868%
Sharpe Ratio
0.934
Probabilistic Sharpe Ratio
45.043%
Loss Rate
47%
Win Rate
53%
Profit-Loss Ratio
1.20
Alpha
0.125
Beta
-0.036
Annual Standard Deviation
0.129
Annual Variance
0.017
Information Ratio
0.024
Tracking Error
0.176
Treynor Ratio
-3.331
Total Fees
$3189.72
import talib

from Selection.EmaCrossUniverseSelectionModel import EmaCrossUniverseSelectionModel

class ModulatedOptimizedProcessor(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2016, 11, 30)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        self.SetBenchmark("SPY")
        #self.UniverseSettings.Resolution = Resolution.Daily
        self.UniverseSettings.Leverage = 1
        
        fastPeriod = 10
        slowPeriod = 30
        count = 10
        #self.SetUniverseSelection(EmaCrossUniverseSelectionModel(fastPeriod, slowPeriod, count))
        #self.AddUniverse(self.Universe.Index.QC500)
        self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)

    def CoarseSelectionFunction(self, coarse):
        sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True)
        filtered = [ x.Symbol for x in sortedByDollarVolume if x.HasFundamentalData ]
        return filtered[:50]

    def FineSelectionFunction(self, fine):

        filtered_fine = [x for x in fine if x.EarningReports.TotalDividendPerShare.ThreeMonths > 0
                                            and x.ValuationRatios.PriceChange1M > 0
                                            and x.ValuationRatios.BookValuePerShare
                                            and x.ValuationRatios.PERatio < 18
                                            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)
        
        sortedByPeRatio = sorted(filtered_fine, key=lambda x: x.ValuationRatios.PERatio, reverse=False)
        stocks = [ x.Symbol for x in sortedByPeRatio[:50] ]
        
        return stocks


    def OnData(self, data):
        '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
            Arguments:
                data: Slice object keyed by symbol containing the stock data
        '''

        # if we have no changes, do nothing
        if self._changes is None: return

        # liquidate removed securities
        for security in self._changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol)

        # we want 10% allocation in each security in our universe
        for security in self._changes.AddedSecurities:
            self.SetHoldings(security.Symbol, 0.15)

        self._changes = None
        #self.next_rebalance = Expiry.EndOfMonth(self.Time)


    # this event fires whenever we have changes to our universe
    def OnSecuritiesChanged(self, changes):
        self._changes = changes
        # if not self.Portfolio.Invested:
        #    self.SetHoldings("SPY", 1)