The algo is importing the method risk_loading_pipeline
in line 11 (that's good). However, the algo then is redefining this method in line 71 (that's bad). Remove the following from your code.
def risk_loading_pipeline():
# Base universe set to the QTradableStocksUS
base_universe = QTradableStocksUS()
# Factor of yesterday's close price.
yesterday_close = USEquityPricing.close.latest
pipe = Pipeline(
columns={
'Symbol': my_dataset.symbol.latest,
'Action': my_dataset.action.latest,
'Price': my_dataset.price.latest,
'Date': my_dataset.asof_date.latest,
'Strength': my_dataset.strength.latest,
},
screen= (my_dataset.action.latest.notnull())
)
return pipe
That may fix the issue. Users here on the forum cannot run your algo 'as is' to test. It uses a self serve dataset which can only be accessed by you.
However, you should be able to troubleshoot. First, verify that the algo runs without any risk model code. Remove line 103. Generally don't manipulate the risk model dataframe.
Next, add the code for the risk model. There are really just four things to add when using the risk factors in optimization.
from quantopian.pipeline.experimental import risk_loading_pipeline
That is on line 11 and looks ok.
def initialize(context):
attach_pipeline(risk_loading_pipeline(), 'risk_loading_pipeline')
That was done in 'initialize' and looks ok.
def before_trading_start(context, data):
context.risk_loading_pipeline = pipeline_output('risk_loading_pipeline')
That was done in 'before_trading_start' and looks ok.
Finally, create any risk model constraints and then pass those constraints to the optimizer.
# create a constraint
constrain_sector_style_risk = opt.experimental.RiskModelExposure(
risk_model_loadings=context.risk_loading_pipeline,
version=opt.Newest,min_momentum=-0.9,max_momentum=0.9, min_value=-0.99, max_value = 0.99,min_real_estate=-0.99, max_real_estate=0.99
)
# add the constraint to the optimizer
algo.order_optimal_portfolio(objective=target_weights,
constraints=[constrain_pos_size,
constrain_sector_style_risk,
max_leverage,
dollar_neutral,
max_turnover,
]
)
That was done in rebalance and looks good too.
Those four (or five) steps should be all that are needed and shouldn't cause any errors.
You asked "I get the feeling that the target weights which are passed consist of no tickers once the function attempts to build a set of tickers which fit the risk metrics required." Yes, that can be an issue. Not only with the risk constraints but any constraints. The optimizer may not find a solution. If the optimizer cannot find a solution there are several methods to trouble shoot (https://www.quantopian.com/docs/api-reference/optimize-api-reference#quantopian.optimize.OptimizationResult). The easiest is to look at the logs. A error or warning will be printed if there is an optimize issue. Maybe put a 'try-except' block around algo.order_optimal_portfolio
and manually log any exceptions.