One thing to consider is the original purpose for the pipeline construct. It's primary job is to reduce the data fetch time by minimizing the number of redundant database calls. If one were to simply create multiple instances of the pipeline object, this could also add multiple database fetches (which pipeline tries to optimize).
One approach is to create a single pipeline definition having all the factors and classifiers for all pipelines. Add the screens for each pipeline as columns but NOT as a screen (ie return all rows/securities). Then simply create separate dataframes for each separate pipeline. This has the net effect of having a single pipeline (for optimization) but ends up with separate filtered dataframes to use as outputs. Maybe code it something like this...
def make_pipeline():
"""
Create factors and classifiers for all pipes.
Add the final pipe screen as a column to the definition. Don't set a screen.
"""
mean_close_200 = SimpleMovingAverage(inputs=[USEquityPricing.close], window_length=200)
latest_close = USEquityPricing.close.latest
dollar_volume = AverageDollarVolume(window_length=30)
rsi= RSI()
a_filter = rsi < 30
b_filter = rsi > 70
return Pipeline(
columns={
'mean_close_200': mean_close_200,
'latest_close': latest_close,
'rsi': rsi,
'a_filter': a_filter,
'b_filter': b_filter,
},
)
def before_trading_start(context, data):
"""
Called every day before market open.
"""
# list the columns you want for 'pipe a' and include the filter
output_pipe_a = (pipeline_output('my_pipeline')
[['200_day_mean_close', 'rsi', 'a_filter']]
.copy()
.query('a_filter'))
# list the columns you want for 'pipe b' and include the filter
output_pipe_b = (pipeline_output('my_pipeline')
[['latest_close_price', 'rsi', 'b_filter']]
.copy()
.query('b_filter'))