Here's an update. This seems to work pretty well:
def factor_pipeline():
factors = make_factors()
sectors = [101,102,103,104,205,206,207,308,309,310,311]
market_cap = factset.Fundamentals.mkt_val.latest
pipeline_columns = {}
for k,f in enumerate(factors):
for s in sectors:
universe = market_cap.percentile_between(0,33, mask = QTradableStocksUS() & Sector().eq(s))
pipeline_columns['alpha_sc_'+str(k)+'_'+str(s)] = f(mask=universe)
universe = market_cap.percentile_between(33,66, mask = QTradableStocksUS() & Sector().eq(s))
pipeline_columns['alpha_mc_'+str(k)+'_'+str(s)] = f(mask=universe)
universe = market_cap.percentile_between(66,100, mask = QTradableStocksUS() & Sector().eq(s))
pipeline_columns['alpha_lc_'+str(k)+'_'+str(s)] = f(mask=universe)
pipe = Pipeline(columns = pipeline_columns,
screen = QTradableStocksUS())
return pipe
There's a nice, detailed factor construction recipe here, by the way:
Step-by-step guide to Vanguard’s factor construction
https://advisors.vanguard.com/iwe/pdf/FASFMTH.pdf
No complex "optimangler" required.