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.197
Tracking Error
0.156
Treynor Ratio
0
Total Fees
$0.00
import numpy as np  
import pandas as pd
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")

from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Data import *
from datetime import timedelta
from System.Collections.Generic import List
from QuantConnect.Data.UniverseSelection import *
class QualityMomentumModel(QCAlgorithm):

    
    def __init__(self):
        
        # Set target number of securities to hold   
        self.TARGET_SECURITIES = 5
        
    

        
        
         #trend following filter
        self.TF_LOOKBACK = 200  
        self.TF_CURRENT_LOOKBACK = 20
        self.TF_up = 0
        
        #determining momentum
        self.MOMENTUM_LOOKBACK_DAYS = 126 #how many days to lookback  
        self.MOMENTUM_SKIP_DAYS = 10  #how many days to skip
        self.overall_lookback = (self.MOMENTUM_LOOKBACK_DAYS + self.MOMENTUM_SKIP_DAYS)
        
    def Initialize(self):
        self.SetStartDate(2010, 1, 1)  # Set Start Date
        self.SetEndDate(2010, 2, 1)
        self.SetCash(1000)  # Set Strategy Cash
        self.spy = self.AddEquity("SPY", Resolution.Minute) #add SPY to use for trends


        #schedule function for making trades
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.AfterMarketOpen("SPY", 30), Action(self.trade))
        self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 30), Action(self.trade))

    
        #50 Day moving average of SPY
        self.spy_ma_fast = self.SMA("SPY", 50)
        #200 Day moving average of SPY
        self.spy_ma_slow = self.SMA("SPY", 200)
    
        self.trend_up = self.spy_ma_fast >= self.spy_ma_slow
        
        if self.spy_ma_fast >= self.spy_ma_slow:
            self.TF_up = 1

        self.UniverseSettings.Resolution = Resolution.Minute #update the universe every minute    
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverse(self.CoarseSelectionFunction, self.FineSelectionFunction)
    
    
    def CoarseSelectionFunction(self, coarse):
        '''Drop securities which have no fundamental data or have too low prices.
        Select those with highest by dollar volume'''
        
        
    
        selected = [x for x in coarse if (x.HasFundamentalData) 
                    and (float(x.Price) > 20)]
        

        filtered = sorted(selected, key=lambda x: x.DollarVolume, reverse=True)
        return [x.Symbol for x in filtered[:2000]]
            

    def FineSelectionFunction(self, fine):
        if self.TF_up == 1:
            quality = [x for x in fine if x.ValuationRatios.FCFYield
                                      and x.ValuationRatios.CashReturn
                                      and x.OperationRatios.ROIC
                                      and x.OperationRatios.LongTermDebtEquityRatio.NineMonths
                                      and x.ValuationRatios.CashReturn
                                      and x.ValuationRatios.FCFYield
                                      and x.OperationRatios.ROIC
                                      and x.OperationRatios.LongTermDebtEquityRatio]
                                      
            self.Plot("Stocks", "Len", len(quality))
    
            self.returns_overall = sorted(quality,
                key = lambda f: f.OperationRatios.RevenueGrowth.overall_lookback)
            
            self.returns_recent = sorted(quality,
                key = lambda f: f.OperationRatios.RevenueGrowth.MOMENTUM_SKIP_DAYS)
            
            self.momentum = sorted(quality,
                key = lambda f: self.returns_overall -
                            self.returns_recent)
 
            self.top_quality = sorted(quality,
                key = lambda f: f.OperationRatios.ROE.OneMonth)
            
            TQ2 = [x[0] for x in self.top_quality]
            self.stocks_to_hold = [x.symbol for x in TQ2[:self.TARGET_SECURITIES]]
            
            return self.stocks_to_hold

    

    def trade(self):
        
        for i in self.Portfolio.Values:
            if (i.Invested) and (i not in self.stocks_to_hold):
                self.Liquidate(i.Symbol)
                
        for i in self.stocks_to_hold:
            self.SetHoldings(i, 1.0 / self.TARGET_SECURITIES )