I have been having problems using multiple Alphas with Black Litterman in python. I have tried to create a small python minimal example to showcase the issues.
ValueError : shapes (1, 4) and (1, 1) not aligned: 4 (dim 1) != 1 (dim 0)
Is the current error with the attached code, with the imports fixed.
Attached a backtest just to share code. Note the main.py does not properly import the Alphas with magnitudes modified, so the backtest mistakenly runs (it actually should error out immediately in the Cloud IDE).
I also receive a different error in another Black Litterman project that goes like this:
Runtime Error: It is not possible to cast a non-finite floating-point value (NaN) as decimal. Please review math operations and verify the result is valid. (Parameter 'input') in PortfolioTarget.cs:line 61 (Open Stacktrace)
Running similar code, but without an additional QC500 universe, gives this:
Runtime Error: An item with the same key has already been added. Key: 1/18/2018 2:52:00 PM in ReturnsSymbolData.cs:line 49 (Open Stacktrace)
The main of that other project is set up something like this:
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Risk.MaximumDrawdownPercentPerSecurity import MaximumDrawdownPercentPerSecurity
from Selection.QC500UniverseSelectionModel import QC500UniverseSelectionModel
from WIPExecution import WIPExecution
from StochasticRSI import StochasticRSI
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
from CustomUniverse import QC10UniverseSelectionModel
from StochasticRSIAlphaModel import StochasticRSIAlphaModel
from NeuralNetworkAlpha import NeuralNetworkAlpha
from EmaCrossAlphaModelMagnitude import EmaCrossAlphaModelMagnitude
from MacdAlphaModelMagnitude import MacdAlphaModelMagnitude
class ExecutionModelRefactor(QCAlgorithm):
def Initialize(self):
self.RISK_FREE_RATE = float(self.GetParameter("RISK_FREE_RATE"))
self.DELTA = float(self.GetParameter("DELTA"))
self.TAU = float(self.GetParameter("TAU"))
self.SetStartDate(2018,1,1); # Set Start Date
self.SetCash(100000) # Set Strategy Cash
################# CHUNGUS ALGS #################
self.AddAlpha(MacdAlphaModelMagnitude(120, 260, 90, MovingAverageType.TripleExponential, Resolution.Minute, bounceThresholdPercent = 0.025))
self.AddAlpha(EmaCrossAlphaModelMagnitude(50, 200, Resolution.Minute))
################# CHUNGUS ALGS #################
self.SetExecution(WIPExecution())
self.SetPortfolioConstruction(BlackLittermanOptimizationPortfolioConstructionModel(delta=2.5, tau=0.05, risk_free_rate=0.00,portfolioBias=PortfolioBias.Long))
self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.05))
self.UniverseSettings.Resolution = Resolution.Minute
symbols = [
Symbol.Create("SPY", SecurityType.Equity, Market.USA),
Symbol.Create("UVXY", SecurityType.Equity, Market.USA),
Symbol.Create("GLD", SecurityType.Equity, Market.USA),
Symbol.Create("TLT", SecurityType.Equity, Market.USA),
Symbol.Create("SOXL", SecurityType.Equity, Market.USA),
Symbol.Create("QQQ", SecurityType.Equity, Market.USA),
Symbol.Create("NVDA", SecurityType.Equity, Market.USA),
Symbol.Create("AMD", SecurityType.Equity, Market.USA),
Symbol.Create("INTC", SecurityType.Equity, Market.USA),
Symbol.Create("USO", SecurityType.Equity, Market.USA),
Symbol.Create("IEF", SecurityType.Equity, Market.USA),
Symbol.Create("SHY", SecurityType.Equity, Market.USA),
Symbol.Create("SH", SecurityType.Equity, Market.USA)
]
self.AddUniverseSelection(ManualUniverseSelectionModel(symbols))
#self.AddUniverseSelection(QC10UniverseSelectionModel())
self.SetWarmUp(14, Resolution.Daily)
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 self.IsWarmingUp: #or not any([self.base_stoch_minutely, self.base_stoch_hourly, self.base_stoch_daily]):# or not self.base_stoch_minutely or not self.base_stoch_hourly or not self.base_stoch_daily:
return
## Print delisting warnings and notifications
for universe in self.UniverseManager.Values:
for symbol in universe.Members.Keys:
symbol_str = str(symbol)
if data.Delistings.ContainsKey(symbol):
delisting = data.Delistings[symbol]
## Log the delisting warning type
self.Log(delisting.ToString())
if delisting.Type == 0:
self.Log(symbol_str + ' will be delisted EOD')
if delisting.Type == 1:
self.Log(symbol_str + ' delisted')
## Log old and new symbol, and change to new symbol upon symbol change
if data.SymbolChangedEvents.ContainsKey(symbol):
self.Log("Old symbol: {0}, New symbol: {1}".format(data.SymbolChangedEvents[symbol].OldSymbol,data.SymbolChangedEvents[symbol].NewSymbol))
#self.base_security = str(data.SymbolChangedEvents[STOCK_BASE].NewSymbol)
## Log split information and update history
if data.Splits.ContainsKey(symbol):
split_stock = data.Splits[symbol]
if split_stock.Type == 0:
self.Log(symbol_str + ' stock will split next trading day')
if split_stock.Type == 1:
self.Log("Split type: {0}, Split factor: {1}, Reference price: {2}".format(split_stock.Type, split_stock.SplitFactor, split_stock.ReferencePrice))
Ross Wendt
I may have fixed the blocking bugs. 😊
Things I learned:
Feel free to use my crappy, probably bug-ridden code to explore. I know the backtest looks bad. My goal was just doing a bug free run with two different Alphas. I think I succeded, finally!
Ross Wendt
Upon further testing, points 3 and 4 seems can be relaxed substantially. I am not sure under what conditions Black Litterman will break if you do not do them, but I was able to do a backtest without enforcing those in a separate project.
Ross Wendt
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!