I'm computing technical indicators on a rolling basis to avoid any look-ahead bias, for example, for model training and back-testing. To that end I would like to compute the indicator ForceIndexIndicator
using the TA Python project. However this needs two inputs instead of one: close and volume, and I can't get hold of both on my rolling - apply pipeline:
import pandas as pd
import ta
...
df.columns = ['close', 'volume']
df['force_index_close'] = (
df.rolling(window=window)
.apply(
lambda x: ta.volume.ForceIndexIndicator(
close=x['close'],
volume=x['volume'],
window=13,
fillna=True)
.force_index().iloc[-1]))
I get the error KeyError: 'close'
because apply gets one column at a time and not both simultaneously as needed.
I found two ways to do it, but one of them using numba and rolling method='table'
doesn't work because numba is a bit obscure and doesn't understand the outside context of the callback function.
However, the solution based on this answer works perfectly:
df['force_index_close'] = df['close'].rolling(window=window).\
apply(args=(df['volume'],),
func=lambda close, dfv: ta.volume.ForceIndexIndicator(close=close, volume=dfv.loc[close.index], window=13, fillna=True).force_index().iloc[-1])
print(df['force_index_close'])
df['force_index_close'].plot()
this is what's happening:
close
, otherwise the apply is computed twice, i.e. once per columnargs
with the series made of the other column volume
, if your use-case would require additional columns then they could be injected here into the applyvolume
series to align to the close
index