Back to Community
ExponentialWeightedMovingAverage inside CustomFactors

Hi, I am trying to run the following code

class PairTrades(CustomFactor):  
    inputs = [Returns(window_length=YYY), EWMA([USEquityPricing.close], window_length=ZZZ,  
                                              decay_rate=np.exp(np.log(0.5) / 10))]  
    window_length = XXX  

but I keep getting the following error for various values of XXX, YYY, ZZZ

NonWindowSafeInput: Can't compute windowed expression PairTrades((Returns((USEquityPricing.close::float64,), window_length=20), ExponentialWeightedMovingAverage((USEquityPricing.close::float64,), window_length=20)), window_length=400) with windowed input ExponentialWeightedMovingAverage((USEquityPricing.close::float64,), window_length=20).

can someone please explain how these 3 numbers are linked to each other ?

Thanks

Loading notebook preview...
Notebook previews are currently unavailable.
4 responses

I am also getting NonWindowSafeInput. Did you find a solution for this?

NonWindowSafeInput happened when one of the dependent factor runs into is not window_safe.

In this case, ExponentialWeightedMovingAverage.window_safe is false, and therefore cannot be wrapped into a CustomFactor.

According to https://github.com/quantopian/zipline/blob/master/zipline/errors.py#L422

    Raised when a Pipeline API term that is not deemed window safe is specified  
    as an input to another windowed term.  
    This is an error because it's generally not safe to compose windowed  
    functions on split/dividend adjusted data.  

In some cases you can window_safe transformation that makes the input factor window_safe (e.g. .rank()) - but in this specific case I'm not quiet sure that you can wrap that around a CustomFactor

If anybody find a better solution would love to learn also.

I created custom factors and if one of the default input factors was giving me trouble I set its window_safe property to True.

Here's an example of a Custom Factor that works for me.

class MarketCap(CustomFactor):  
    window_safe = True # Avoid NonWindowSafeInput Error  
    mcap = morningstar.valuation.market_cap.latest  
    mcap.window_safe = True #Manually set the window_safe property. Factor fails without this.  
    inputs = [mcap]  
    window_length = 1  
    def compute(self, today, asset_ids, out, values):  
        out[:] = values  

Great example Tariq. I applied it in the below way to fill NaN values to be able to do some calculations.

class FillNa(CustomFactor):  
    # Returns value of input x trading days ago where x is the window_length  
    # Both the inputs and window_length must be specified as there are no defaults  
    window_safe = True  # Avoid NonWindowSafeInput Error  
    net_inc_lat = cash_flow_statement.net_income.latest  
    net_inc_lat.window_safe = True  
    cf_ops_lat = cash_flow_statement.cash_flow_from_continuing_operating_activities.latest  
    cf_ops_lat.window_safe = True  
    total_assets = balance_sheet.total_assets.latest  
    total_assets.window_safe = True  
    cash_equiv_lat = balance_sheet.cash_and_cash_equivalents.latest  
    cash_equiv_lat.window_safe = True  
    total_debt_lat = balance_sheet.total_debt.latest  
    total_debt_lat.window_safe = True  
    min_interest_lat = balance_sheet.minority_interest.latest  
    min_interest_lat.window_safe = True  
    pref_stock_lat = balance_sheet.preferred_stock.latest  
    pref_stock_lat.window_safe = True  
    common_stock_lat = balance_sheet.common_stock.latest  
    common_stock_lat.window_safe = True  

    def compute(self, today, assets, out, inputs):  
        out[:] = pd.DataFrame(inputs).fillna(0)