Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
[Help Request] Min/Max functions not working as expected in pipeline

In the attached backtest, on line 47 I am trying to find max(0, current_liabilities-current_assets). However I see in the debugger that I am consistently getting negative excess cash when I expect positive values or 0.

Does anyone have insight into this or have a suggestion of what I should do?

2 responses

The problem is with the 'max' method. Factors can only be manipulated with a small set of methods and operators (see the list here https://www.quantopian.com/help#quantopian_pipeline_factors_Factor ). Remember that when defining factors one is really just defining the data which pipeline should fetch. The factors aren't the data. They are simply the definitions. One can't use a method like 'max' which expects numbers.

However, not to worry. Any calculations that prove too cumbersome to define inside the pipeline can always be done once the pipeline runs. The pipeline output is a pandas dataframe. Do any calculations one wants to do with that dataframe.

So, take the calculations out of the pipeline definition. Commented out here.

    # Can't use the 'max' method with factor objects  
    # Do this calc after the pipeline runs  
    # e = max(0, current_liabilities-current_assets)  
    # pipe.add(e, "e")  
    # excess_cash = cash-e  
    # pipe.add(excess_cash, "excess_cash")  
    #total_ev = market_cap+debt_value-excess_cash  
    # total_ev = excess_cash/(market_cap+debt_value)  
    # pipe.add(total_ev, "equity_value")  

Once the pipeline runs, simply add any new columns and/or calculations to the returned dataframe.

def before_trading_start(context,data):  
    context.output = pipeline_output('ev')  
    # Add other columns to the output dataframe  
    # Do the calculations we want  
    context.output['e'] = (context.output.liabilities - context.output.assets).clip(lower=0)  
    context.output['excess_cash'] = context.output.cash - context.output.e  
    context.output['total_ev'] = context.output.excess_cash / (context.output.market_cap + context.output.debt_value)  

I used the '.clip' method to ensure that e is never negative. Maybe could be done with a 'max' method but this was just personal preference.

See attached backtest.

Thanks Dan.