Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
Having Difficulty with MACD and Custom Factors in the Notebook Pipeline

Briefly, what I'm trying to do right now is create a pipeline with two columns (latest close price and talib.MACD histogram value), for all stocks that pass a screen (has not been set yet) for a period of time. I was originally using the built in MovingAverageConvergenceDivergenceSignal factor, but haven't really figured out what its output is (as it doesn't agree with any of the three talib.MACD values).

Here's my pipeline:

def make_pipeline():

    lastclose = USEquityPricing.close.latest  
    myFactor = myMACD()  
    return Pipeline(  
        columns={  
            'close': lastclose,  
            'my MACD': myFactor  
        }  
    )  

...and here's that custom MACD factor:

class myMACD(CustomFactor):  
    # Default inputs  
    inputs = [USEquityPricing.close]  
    window_length = 27

    # Compute  
    def compute(self, today, assets, out, close):  

        macd, signal, hist = talib.MACD(close[:], fastperiod=12, slowperiod=26, signalperiod=9)  
        out[:] = hist[-1]  

...and when I call it:

result = run_pipeline(make_pipeline(), '2017-01-01', '2017-07-03')  
result  

... the "macd, signal, hist = talib.MACD(close[:],..." line keeps throwing the error "AssertionError: real has wrong dimensions." I'm very new to custom factors, and really don't know exactly what all the inputs are or what types they are. I've figured out that "out[:] = assets" will return the id of the stock, and that "out[:] = close[-1]" will return the last price (same as the other column). But I don't know exactly what combination of assets and close will let me run the MACD line.

I'd really appreciate any guidence. Thanks in advance.

3 responses

The talib functions expect a 1 dimensioned series as their input. In this case 'close' is a 2 dimensioned numpy array which is indexed by date and has all the assets as columns. The error is simply stating that the 'close' parameter is expecting a single dimensioned series and has the wrong dimensions (ie a lot more than 1). Maybe look at the talib documentation https://mrjbq7.github.io/ta-lib/func.html .

Take a look at this post for details on how to implement the talib functions within a custom factor https://www.quantopian.com/posts/using-ta-lib-functions-in-pipeline .

Good luck.

Dan,

Thank you! I think I've got it now. I'll attach my new notebook (copied from the notebook in the example you gave me) for anyone else having similar issues.
There are still a couple peculiarities with the code. For awhile the code would run, but I would get a completely empty pipeline returned. I couldn't figure out what was wrong until I started messing with the " window_length" of the custom function. This turned up some interesting results:

When the window_length is less than 34, the pipeline is completely empty.

When the window_length is greater than or equal to 34 and less than the number of days in the entire pipeline time period, the pipeline fills with data, but the value I'm looking for (macd_hist) is different than what the talib function returns outside of the pipeline.

When the window_length is equal to the number of days the pipeline is constructed for (in this case, 127, which was found manually. I'm wondering what the best way is to dynamically find this within the pipeline to pass to the custom factor class), then the macd_hist values are equal to the values found outside the pipeline.

I'm really not sure what's going on behind the scenes with the window length, or why the number 34 is the minimal value for filling the pipeline (considering talib.MACD uses 26, 12, and 9 day periods).

Regardless, it seems to be working now. Thank you for your help!

I think it's because calculating one MACD needs 26 days, and the signal line is 9 EMA of MACDs, so 26+9 would be 35. Thus under 34 there wouldn't be enough data.
I do notice that the value is different for different window_length which is super weird, this is driving me crazy... I can't believe you found the number manually!