Giampaolo Levorato
Giampaolo Levorato

Reputation: 1622

Inverse formula of exponential moving average (ewm) in pandas

I have created this pandas dataframe

import pandas as pd

ds = {'col1' : [1,2,3,4,3,3,2,2,2,4,5,6,7,5,4,3,2,2,4,5,12]}
df = pd.DataFrame(data=ds)

The dataset looks like this:

display(df)

    col1
0     1
1     2
2     3
3     4
4     3
5     3
6     2
7     2
8     2
9     4
10    5
11    6
12    7
13    5
14    4
15    3
16    2
17    2
18    4
19    5
20   12

I now calculate the 3-period Exponential Moving Average as follows:

time_window = 3
df['ema3'] = df['col1'].ewm(com=time_window - 1,
                        min_periods=time_window).mean()

The resulting dataframe looks like this:

    col1    ema3
0   1        NaN
1   2        NaN
2   3   2.263158
3   4   2.984615
4   3   2.990521
5   3   2.993985
6   2   2.642059
7   2   2.419350
8   2   2.275833
9   4   2.860698
10  5   3.582139
11  6   4.394353
12  7   5.267388
13  5   5.177952
14  4   4.784403
15  3   4.188695
16  2   3.458389
17  2   2.971930
18  4   3.314775
19  5   3.876685
20  12  6.585000

Question: what value for col1 would return an EMA of 8.12 at record 21?

    col1    ema3
0   1        NaN
1   2        NaN
2   3   2.263158
3   4   2.984615
4   3   2.990521
5   3   2.993985
6   2   2.642059
7   2   2.419350
8   2   2.275833
9   4   2.860698
10  5   3.582139
11  6   4.394353
12  7   5.267388
13  5   5.177952
14  4   4.784403
15  3   4.188695
16  2   3.458389
17  2   2.971930
18  4   3.314775
19  5   3.876685
20  12  6.585000
21  ??  8.120000

Is there a formula that inverts the ewm and gives a value for col1 such that the EMA at record 21 is 8.12000? I don't want to iterate numerous values. I am asking if anyone knows a formula (that I can code in python) for that.

Thanks!

Upvotes: 1

Views: 100

Answers (1)

mozway
mozway

Reputation: 262224

An exponentially weighted moving average is defined as following:

EWMA(t) = a * value(t) + (1-a) * EWMA(t-1)

In your case, you want value(t) and you know that EWMA(t) = 8.12 and EWMA(t-1) = 6.585, and a = 1/(1+com). You can thus solve:

com = time_window - 1
a = 1/(1+com) # 0.333
x = (8.12 - (1-a)*6.585) / a

Output: 11.189999999999996

Verification (not with an exact precision):

     col1      ema3
0    1.00       NaN
1    2.00       NaN
2    3.00  2.263158
3    4.00  2.984615
4    3.00  2.990521
5    3.00  2.993985
6    2.00  2.642059
7    2.00  2.419350
8    2.00  2.275833
9    4.00  2.860698
10   5.00  3.582139
11   6.00  4.394353
12   7.00  5.267388
13   5.00  5.177952
14   4.00  4.784403
15   3.00  4.188695
16   2.00  3.458389
17   2.00  2.971930
18   4.00  3.314775
19   5.00  3.876685
20  12.00  6.585000
21  11.19  8.120205

Upvotes: 1

Related Questions