You could write a small CustomFactor to accomplish this. Something like this..
class UniverseSize(CustomFactor):
inputs = [USEquityPricing.close]
window_length = 1
def compute(self, today, assets, out, securities):
out[:] = len(assets)
That would result in a factor with the same value for all securities and that value would be the number off assets passed to the factor. If no mask is set when instantiating the factor, then this would be all assets in the Q database. If a mask is supplied, it would be a subset defined by the mask.
You may be better off putting all your logic into a single custom factor where you can use this length within if statements etc to branch depending upon size.
However, as a philosophical point, I'd argue that maybe this type of logic isn't appropriate inside the pipeline definition. The fundamental purpose of the pipeline is to fetch data. Fundamentally, the pipeline definition is simply to specify what data to fetch. The fact that you can do some simple logic within the definition doesn't mean you must.
I'm a proponent of separating the data from the logic. Define all the data (ie the columns) you need within the pipeline definition. Fetch that data each day in the 'before_trading_start'. That data is returned in a neat powerful pandas dataframe using the 'pipline_output' method. Then perform whatever logic your algo requires using that data at that time. You can then slice and dice and add and subtract columns from the returned dataframe using the many pandas methods which typically give much more flexibility than the factor and filter methods.