I'll certainly not be the first ever to say that python error messages aren't very helpful at times. This is perhaps one of those times.
The error NoneType' object has no attribute 'format'
stems from the following line
inputs=[RSI]
This should be
inputs=[RSI()]
In the first case one is passing the class RSI while in the second case, by adding the parenthesis, one is passing an instance of RSI. Custom factors expect instances.
However, once that is fixed there will still be another issue. The ExponentialWeightedMovingAverage
factor, like all factors, expects either a 'BoundColumn' or another factor as an input. In the following code, 'rsi' is an ndarray and not a BoundColumn or a factor.
def compute(self, today, assets, out, rsi):
rsi_ema = EMA(21, rsi)
out[:] = rsi_ema
What to do? How does one get the exponentially weighted moving average (ewma) of the RSI? One could fix the two custom factors (RSI_Score and EMA) and calculate it that way. However, one doesn't need to write custom factors. One can simply use the built in ones.
Remember that factors can accept either a 'BoundColumn' or another factor as an input. A 'BoundColumn' is something like USEquityPricing.close
or Fundamentals.current_assets
. A factor is, well, a factor. The only requirement for factors is they must be window_safe
(see the docs for more on that https://www.quantopian.com/docs/recipes/pipeline-recipes#recipe-custom-factor-into-custom-factor). So, to get the ewma of an RSI factor, simply pass the RSI factor to ExponentialWeightedMovingAverage
. Like this example
rsi = RSI()
rsi_ewma = ExponentialWeightedMovingAverage(inputs=[rsi], window_length=21, decay_rate=.5)
There are a couple of convenience methods one may want to use. First, ExponentialWeightedMovingAverage
can also be imported as EWMA
. This saves some typing and makes the code a bit shorter. Second, often one knows the ewma 'span' and not the decay rate. There is a class method from_span
which allows for the span to be inputted directly. There is an example in the documentation https://www.quantopian.com/docs/api-reference/pipeline-api-reference#quantopian.pipeline.factors.ExponentialWeightedMovingAverage
See the attached notebook. Again, one could write their own custom factor to do this, but in this case it's probably easier to use the built in ones.