Quantopian's community platform is shutting down. Please read this post for more information and download your code.
Back to Community
errors on MACD histogram custom factor

Since MACD isn't a builtin for some reason, I'm having to make my own. I've tried a few examples, but none of them seem to work, or don't give me the flexibility I'm going to need to modify this later. I'm brand new to Quantopian and Python, so I don't know how to read and fix these errors I'm getting. Here's my code and the errors I'm getting:

Code:

class MACDHist(CustomFactor):  
    inputs = [USEquityPricing.close]  
    window_length = 28  
    def compute(self, today, asset_ids, out, values):  
        ema26 = EWMA.from_span(inputs = values, window_length=27, span=26)  
        ema12 = EWMA.from_span(inputs = values, window_length=13, span=12)  
        signal = EWMA.from_span(inputs = ema12[-10:] - ema26[-10:], window_length=9, span=9)  
        out[:] = (ema12[-1] - ema26[-1]) - signal[-1]  

Errors:
``` TypeErrorTraceback (most recent call last)
in ()
76 make_pipeline(),
77 start_date = now,
---> 78 end_date = now)
79
80 num_securities = pipeline_output.shape[0]

/build/src/qexec_repo/qexec/research/api.py in run_pipeline(pipeline, start_date, end_date, chunksize) 483 pipeline_engine,
484 equity_trading_days,
--> 485 holdout_manager,
486 )
487

/build/src/qexec_repo/qexec/research/_api.pyc in inner_run_pipeline(pipeline, start_date, end_date, chunksize, engine, equity_trading_days, holdout_manager) 734 adjusted_start_date,
735 adjusted_end_date,
--> 736 chunksize=chunksize,
737 )
738

/build/src/qexec_repo/zipline_repo/zipline/pipeline/engine.pyc in run_chunked_pipeline(self, pipeline, start_date, end_date, chunksize) 328 chunksize,
329 )
--> 330 chunks = [self.run_pipeline(pipeline, s, e) for s, e in ranges]
331
332 if len(chunks) == 1:

/build/src/qexec_repo/zipline_repo/zipline/pipeline/engine.pyc in run_pipeline(self, pipeline, start_date, end_date) 309 dates,
310 assets,
--> 311 initial_workspace,
312 )
313

/build/src/qexec_repo/zipline_repo/zipline/pipeline/engine.pyc in compute_chunk(self, graph, dates, assets, initial_workspace) 535 mask_dates,
536 assets,
--> 537 mask,
538 )
539 if term.ndim == 2:

/build/src/qexec_repo/zipline_repo/zipline/pipeline/mixins.pyc in _compute(self, windows, dates, assets, mask) 212 inputs = format_inputs(windows, inputs_mask)
213
--> 214 compute(date, masked_assets, out_row, *inputs, **params)
215 out[idx][out_mask] = out_row
216 return out

in compute(self, today, asset_ids, out, values)
42
43 def compute(self, today, asset_ids, out, values):
---> 44 ema26 = EWMA.from_span(inputs = values, window_length=27, span=26)
45 ema12 = EWMA.from_span(inputs = values, window_length=13, span=12)
46 signal = EWMA.from_span(inputs = ema12[-10:] - ema26[-10:], window_length=9, span=9)

/build/src/qexec_repo/zipline_repo/zipline/pipeline/factors/basic.py in from_span(cls, inputs, window_length, span, **kwargs) 197 @expect_types(span=Number)
198 def from_span(cls, inputs, window_length, span, **kwargs):
--> 199 """
200 Convenience constructor for passing decay_rate in terms of span.
201

/build/src/qexec_repo/zipline_repo/zipline/pipeline/factors/basic.pyc in from_span(cls, inputs, window_length, span, **kwargs) 237 window_length=window_length,
238 decay_rate=decay_rate,
--> 239 **kwargs
240 )
241

/build/src/qexec_repo/zipline_repo/zipline/pipeline/mixins.pyc in new(cls, inputs, outputs, window_length, mask, dtype, missing_value, ndim, **kwargs) 138 missing_value=missing_value,
139 ndim=ndim,
--> 140 **kwargs
141 )
142

/build/src/qexec_repo/zipline_repo/zipline/pipeline/term.pyc in new(cls, inputs, outputs, window_length, mask, *args, **kwargs) 488 mask=mask,
489 window_length=window_length,
--> 490 *args, **kwargs
491 )
492

/build/src/qexec_repo/zipline_repo/zipline/pipeline/term.pyc in new(cls, domain, dtype, missing_value, window_safe, ndim, *args, **kwargs) 119
120 try:
--> 121 return cls._term_cache[identity]
122 except KeyError:
123 new_instance = cls._term_cache[identity] = \

/usr/lib/python2.7/weakref.pyc in getitem(self, key) 75
76 def getitem(self, key):
---> 77 o = self.datakey
78 if o is None:
79 raise KeyError, key

TypeError: unhashable type: 'numpy.ndarray'
```

2 responses

@Vladimir

Thanks for the response, I'll give this a try. Using this and EWMA, I should be able to calculate the MACD_Histogram, right?
Also, can I use this function to get the trailing N days? I'm looking to use several days worth of MACD_Histogram to check for trends/momentum in the MACD_Histogram itself.

Thank you once again! I'll try this one out today. It looks like I can also change what talib.MACD returns to make custom factors for MACD and the signal line, which is nice.

Do you know what the bug in MovingAverageConverganceDiverganceSignal is? I found this code that looks like an implementation of it:
https://www.quantopian.com/posts/what-is-the-difference-between-talib-macd-and-built-in-factor-movingaverageconvergencedivergencesignal#5a2ae3c9246a1377691d1a61