#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]