Obliczanie średniej kroczącej ważonej (weighted moving average)

0

Witam. Mam program, który dla danych w csv liczy mi średnią ruchomą (simple moving average) (używam dataframe) i później rysuje wykres. Czy może ktoś pomóc zrobić mi to samo, ale ze średnią ruchomą ważoną (weighted moving average)? Nie wyobrażam, jak napisać funkcję do jej obliczenia, bo tylko rozpoczęłam programować. Formuła jest:
WMA = ( Price n + Price(1) n-1 + ...+Price( n-1 ) 1) / ( n ( n + 1 ) / 2 ). (n = time period).

Dane w csv załączam.

Z góry dziękuję.

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as dates

#moving average
def mavg(data, N):
    cs = np.cumsum(np.insert(data, 0, 0))
    ma = (cs[N:] - cs[:-N]) / N
    return np.insert(ma, 0, np.repeat(0, N - 1))

#wczytywanie danych
data_pd = pd.read_csv('GS.csv')
format = '%m/%d/%Y'
data_pd['Date'] = pd.to_datetime(data_pd['Date'], format=format)
data_pd = data_pd.set_index(data_pd['Date'])
data_pd = data_pd.drop(columns=['Date'])

p1 = 5
data_pd['ma1'] = mavg(data_pd['Close'].values, p1)

#wykres
fig, ax = plt.subplots(1, 1, sharex=True, sharey=False)
ax.plot(data_pd.index[p1-1:],data_pd['ma1'][p1-1:], color = 'green')
date_formatter = dates.DateFormatter('%m/%d/%Y')
ax.xaxis.set_major_formatter(date_formatter)
ax.xaxis.set_major_locator(dates.MonthLocator(interval=12))
plt.setp(ax.xaxis.get_majorticklabels(), rotation=90, fontsize=7)
ax.set(title='GS data', ylabel='Close price', xlabel='Date')
fig.autofmt_xdate()
ax.autoscale_view()
ax.grid()
plt.show()
0

Pandas ma do tego prawie-że gotowce: rolling_mean (tylko sobie musisz ręcznie zrobić wagi), ewma (które jest ważone wykładniczo, więc tutaj musisz pozmieniać), w ostateczności rolling_apply (ogólna funkcja).

Numpy też coś ma dla Ciebie: average

1

Zgodnie z definicją z Wikipedii:

def average(data):
    """data[-1]: the most recent"""
    n = len(data)
    for i in range(n, 0, -1):
        data[i-1] = i * data[i-1]
    return sum(data) / ( (n * (n + 1)) / 2)

d = [4, 4.5, 5]

print(average(d)) # -> 4.66666

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0