Overall Statistics
#region imports
from AlgorithmImports import *
#endregion
#https://www.quantconnect.com/tutorials/strategy-library/capm-alpha-ranking-strategy-on-dow-30-companies

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

import numpy as np

class EmotionalBlueLion(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2023, 6, 1)   # Set Start Date
        self.SetEndDate(2025, 4, 15)     # Set End Date
        self.SetCash(1000000)             # Set Strategy Cash       
        
        
        
        self.subset =  ['AGG',
                        'IWM',
                        'IAU', 
                        'COMT',
                        'USMV',
                        'DGRO', 
                        'QUAL', 
                        'DVY', 
                        'MTUM',
                        'VLUE', 
                        'EFAV',
                        'EEMV', 
                        'IDV',
                        'IQLT', 
                        'IYW',
                        'IGF', 
                        'IYH']
         
        # Our Symbols
        self.symbols = [self.AddEquity(ticker).Symbol for ticker in self.subset ] 
        
        # Our reference
        self.reference = self.AddEquity("SPY").Symbol
        self.AddEquity("SPY", Resolution.Daily)

        # Other Parameters
        self.lookback = 10
        self.SetWarmup(20)
        self.counter = 0
       
        
    def OnData(self,data):
        self.counter += 1
        
        self.Debug(f"Counter : {self.counter}")
        
        if self.IsWarmingUp: 
            return
        
        if self.counter % 10 == 0:
            
            history = self.History(
            self.symbols + [self.reference], 
            self.lookback,
            Resolution.Daily).close.unstack(level=0)
            
            symbols = self.SelectSymbols(history)

           
            for holdings in self.Portfolio.Values:
                symbol = holdings.Symbol
            if symbol not in symbols and holdings.Invested:
                self.Liquidate(symbol)

           
            for symbol in symbols:
                self.SetHoldings(symbol, 0.2)
   


    def SelectSymbols(self, history):
        
        alphas = dict()

       
        reference = history[self.reference].pct_change().dropna()

        
        for symbol in self.symbols:
            
            # Get the security returns
            returns = history[symbol].pct_change().dropna()
            bla = np.vstack([reference, np.ones(len(returns))]).T

            # Simple linear regression function in Numpy
            result = np.linalg.lstsq(bla , returns)
            alphas[symbol] = result[0][0]

        # Select symbols with the highest intercept/alpha to the reference
        selected = sorted(alphas.items(), key=lambda x: x[1], reverse=True)[:5]
        return [x[0] for x in selected]