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.
NoneType' object has no attribute 'format' stems from the following line
This should be
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
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.