برنامه نویسی و طراحی سایت

پیاده سازی میانگین متحرک نمایی در پایتون — راهنمای گام به گام

پیاده سازی میانگین متحرک نمایی در پایتون — راهنمای گام به گام

در آموزش‌های قبلی مجله تم آف، با پیاده‌سازی میانگین متحرک ساده در پایتون آشنا شدیم و به برخی از نقاط ضعف آن اشاره کردیم. در این آموزش، به میانگین متحرک نمایی (Exponential Moving Average) یا EMA خواهیم پرداخت. در این روشِ میانگین‌گیری، برخلاف روش ساده، با تمامی داده‌ها به یک شکل برخورد نمی‌کنیم و به داده‌های جدیدتر، وزن زیادی قائل می‌شویم. این ویژگی باعث می‌شود تا تأخیر کمتری در رفتار آن وجود داشته باشد. در ادامه، به پیاده سازی میانگین متحرک نمایی در پایتون می‌پردازیم.

فهرست مطالب این نوشته
میانگین متحرک نمایی چیست؟

پیاده‌سازی میانگین متحرک نمایی در پایتون

جمع‌بندی

faradars mobile

میانگین متحرک نمایی چیست؟

اگر یک سری زمانی به شکل زیر داشته باشیم:

$$ large X =left{x_{1}, x_{2} ldots x_{n}right} $$

یک میانگین متحرک نمایی با طول $$L$$ به شکل زیر محاسبه می‌شود:

$$ large begin{aligned}
&M_{L}=frac{1}{L} sum_{i=1}^{L} x_{i}\
&M_{t}=alpha cdot x_{t}+(1-alpha) cdot M_{t-1} quad L
end{aligned} $$

به این ترتیب، مقدار در هر زمان با توجه به زمان‌های قبلی محاسبه می‌شود.

آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average
فیلم آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average در تم آف

کلیک کنید

به سادگی می‌توانیم وزن مربوط به هر روز را به شکل زیر محاسبه کنیم:

$$ large begin{aligned}
&W_{t}=alpha\
&W_{t-1}=alpha cdot(1-alpha)\
&W_{t-2}=alpha cdot(1-alpha)^{2}\
&vdots \
&W_{t-infty}=alpha cdot(1-alpha)^{infty}=0
end{aligned} $$

که مجموع وزن‌ها به صورت زیر خواهد بود:

$$ large begin{align}
text { Sum } & =sum_{i=0}^{infty} W_{t-i}=sum_{i=0}^{infty} alpha cdot(1-alpha)^{i}=alpha sum_{i=0}^{infty}(1-alpha)^{i}=alpha cdotleft(frac{1}{1-(1-alpha)}right) \
& =alpha cdotleft(frac{1}{alpha}right)=1
end{align} $$

بنابراین اثبات می‌شود که مجموع وزن‌ها برابر $$1$$ است.

آموزش اندیکاتور همگرایی – واگرایی میانگین متحرک MACD
فیلم آموزش اندیکاتور همگرایی – واگرایی میانگین متحرک MACD در تم آف

کلیک کنید

ضریب $$alpha$$ میزان حساسیت بر داده‌های جدید را تعیین می‌کند. اگر $$alpha = 0 $$، مقدار میانگین متحرک همواره ثابت خواهد بود و اگر $$alpha = 1 $$، مقدار میانگین متحرک همواره برابر آخرین مقدار سیگنال خواهد بود.

معمولاً به منظور محاسبه میانگین متحرک نمایی با طول $$L$$ از رابطه زیر استفاده می‌کنیم:

$$ large alpha =frac {1 +r } { L + r}$$

که در این رابطه اغلب حالت $$r=1$$ در نظر گرفته می‌شود. با افزایش $$r$$ وزن مربوط به روز‌های اخیر افزایش می‌یابد.

آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم
فیلم آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم در تم آف

کلیک کنید

برای یادگیری برنامه‌نویسی با زبان پایتون، پیشنهاد می‌کنیم به مجموعه آموزش‌های مقدماتی تا پیشرفته پایتون تم آف مراجعه کنید که لینک آن در ادامه آورده شده است.

پیاده‌سازی میانگین متحرک نمایی در پایتون

برای پیاده‌سازی میانگین متحرک نمایی، وارد محیط برنامه‌نویسی شده و کتابخانه‌های مورد نیاز را فراخوانی می‌کنیم:

import numpy as np
import matplotlib.pyplot as plt

این دو کتابخانه برای کار با آرایه و مصورسازی استفاده خواهند شد.

آموزش تحلیل و پیش بینی سری های زمانی
فیلم آموزش تحلیل و پیش بینی سری های زمانی در تم آف

کلیک کنید

حال Style مربوط به نمودارها را نیز تنظیم می‌کنیم:

plt.style.use('ggplot')

حال یک مجموعه داده مصنوعی به شکل زیر تولید می‌کنیم:

N = 200 # Signal Size
T = np.linspace(0, 80, num=N) # Time
S = 5*np.sin(8 + T/7) - 3*np.sin(5 + T/5) + 2*np.sin(3 + T/3) - np.sin(2 + T/2)

برای بررسی نمودار سیگنال ایجاد شده، یک Line Plot ایجاد می‌کنیم:

plt.plot(T, S, ls='-', lw=1, marker='o', ms=2, label='Signal')
plt.axhline(lw=1.2, c='k')
plt.axvline(lw=1.2, c='k')
plt.xlabel('T')
plt.ylabel('Value')
plt.legend()
plt.show()

که در خروجی فوق نمودار زیرحاصل می‌شود.

نمودار در پایتون

حال برای پیاده‌سازی میانگین متحرک نمایی، ابتدا یک تابع ایجاد می‌کنیم و در ورودی سیگنال، طول بازه و مقدار $$r$$ را دریافت می‌کنیم:

def EMA(S:np.ndarray, L:int, r:float=1):

حال مقدار $$alpha$$ را محاسبه می‌کنیم:

def EMA(S:np.ndarray, L:int, r:float=1):
    a = (1 + r) / (L + r)

توجه داشته باشید که چون غالباً حالت $$r=1$$ استفاده می‌شود، مقدار پیش‌فرض برای این ورودی تعریف شده است.

آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average
فیلم آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average در تم آف

کلیک کنید

حال ابتدا اندازه سیگنال را تعیین کرده و سپس اندازه میانگین متحرک حاصل را محاسبه می‌کنیم:

def EMA(S:np.ndarray, L:int, r:float=1):
    a = (1 + r) / (L + r)
    nD0 = S.size
    nD = nD0 - L + 1

حال یک آرایه خالی برای ذخیره مقادیر میانگین متحرک ایجاد می‌کنیم:

def EMA(S:np.ndarray, L:int, r:float=1):
    a = (1 + r) / (L + r)
    nD0 = S.size
    nD = nD0 - L + 1
    M = np.zeros(nD)

حال اولین مقدار را به صورت میانگین معمولی از $$L$$ داده ابتدایی محاسبه می‌کنیم:

def EMA(S:np.ndarray, L:int, r:float=1):
    a = (1 + r) / (L + r)
    nD0 = S.size
    nD = nD0 - L + 1
    M = np.zeros(nD)
    M[0] = np.mean(S[:L])

حال می‌توانیم سایر مقادیر را داخل یک حلقه با استفاده از رابطه بازگشتی محاسبه کنیم:

def EMA(S:np.ndarray, L:int, r:float=1):
    a = (1 + r) / (L + r)
    nD0 = S.size
    nD = nD0 - L + 1
    M = np.zeros(nD)
    M[0] = np.mean(S[:L])
    for i in range(1, nD):
        M[i] = a*S[i+L-1] + (1-a)*M[i-1]
    return M

به این ترتیب، مقادیر بعدی محاسبه، در آرایه $$M$$ ذخیره و در خروجی برگردانده می‌شوند.

آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم
فیلم آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم در تم آف

کلیک کنید

برای استفاده از تابع به صورت زیر عمل می‌کنیم:

M = EMA(S, 5)

برای مشاهده رفتار میانگین متحرک حاصل، به شکل زیر نموداری رسم می‌کنیم:

plt.plot(T, S, ls='-', lw=1, marker='o', ms=2, label='Signal')
plt.plot(T[-M.size:], M, ls='-', lw=0.9, c='teal', label='EMA(5)')
plt.axhline(lw=1.2, c='k')
plt.axvline(lw=1.2, c='k')
plt.xlabel('T')
plt.ylabel('Value')
plt.legend()
plt.show()

توجه داشته باشید که طول آرایه $$M$$ کوتاه‌تر از $$T$$ است. به همین دلیل، برای رسم نمودار باید تعدادی از اعضای ابتدایی آرایه $$T$$ حذف شود.

آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average
فیلم آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average در تم آف

کلیک کنید

پس از اجرا، نمودار زیر نمایش داده می‌شود.

رسم میانگین نمایی در پایتون

به این ترتیب، مشاهده می‌کنیم که تابع نوشته‌ شده به خوبی عملکرد خود را نشان می‌دهد.

آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم
فیلم آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم در تم آف

کلیک کنید

با افزایش مقدار $$L$$، تأخیر افزایش و در کنار آن، اعتبار نیز افزایش می‌یابد.

میانگین نمایی در پایتون

به این ترتیب، اثر $$L$$ مشهود است.

آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average
فیلم آموزش میانگین متحرک – تحلیل تکنیکال در بورس و سرمایه گذاری در بازارهای مالی با Moving Average در تم آف

کلیک کنید

برای بررسی اثر $$r$$ نیز به شکل زیر عمل می‌کنیم:

M1 = EMA(S, 7, r=-0.90)
M2 = EMA(S, 7, r=0)
M3 = EMA(S, 7, r=+3)

plt.plot(T, S, ls='-', lw=1, marker='o', ms=2, label='Signal')
plt.plot(T[-M1.size:], M1, ls='-', lw=0.9, c='teal', label='EMA(5, r=-0.90)')
plt.plot(T[-M2.size:], M2, ls='-', lw=0.9, c='crimson', label='EMA(5, r=0)')
plt.plot(T[-M3.size:], M3, ls='-', lw=0.9, c='lime', label='EMA(5, r=+3)')
plt.axhline(lw=1.2, c='k')
plt.axvline(lw=1.2, c='k')
plt.xlabel('T')
plt.ylabel('Value')
plt.legend()
plt.show()

که نمودار زیر برای کد فوق حاصل خواهد شد.

میانگین متحرک نمایی در پایتون

به این ترتیب، مشاهده می‌کنیم که در حالت $$r=-0.9$$ مقدار تأخیر به شدت افزایش یافته است. حالت‌های $$r=0$$ و $$r= 3 $$ هر دو از شرایط مناسبی برخوردار هستند و هر کدام بسته به نیاز می‌توانند استفاده شوند. تنظیم دو پارامتر $$L$$ و $$r$$ می‌تواند میانگین متحرک نمایی متناسب با نیاز ما را ایجاد کند.

آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم
فیلم آموزش پیاده سازی اندیکاتورهای تکنیکال با پایتون Python – بخش یکم در تم آف

کلیک کنید

حال برای مقایسه رفتار میانگین متحرک نمایی و میانگین متحرک ساده، تابع نوشته‌ شده برای میانگین متحرک ساده را وارد کد می‌کنیم:

def SMA(S:np.ndarray, L:int):
    nD0 = S.size
    nD = nD0 - L + 1
    M = np.zeros(nD)
    for i in range(nD):
        M[i] = np.mean(S[i:i + L])
    return M

حال هر دو میانگین متحرک را در طول $$L=15$$ محاسبه می‌کنیم:

sma = SMA(S, 15)
ema = EMA(S, 15)

و برای رسم نمودار مناسب می‌نویسیم:

plt.plot(T, S, ls='-', lw=1, marker='o', ms=2, label='Signal')
plt.plot(T[-sma.size:], sma, ls='-', lw=0.9, c='teal', label='SMA(15)')
plt.plot(T[-ema.size:], ema, ls='-', lw=0.9, c='lime', label='EMA(15)')
plt.axhline(lw=1.2, c='k')
plt.axvline(lw=1.2, c='k')
plt.xlabel('T')
plt.ylabel('Value')
plt.legend()
plt.show()

که در نهایت نمودار مورد نظر حاصل می‌شود.

پیاده سازی میانگین متحرک نمایی در پایتون

به این ترتیب، مشاهده می‌کنیم که میانگین متحرک نمایی زودتر از میانگین متحرک ساده به تغییرات روند واکنش می‌دهد.

جمع‌بندی

در این آموزش، میانگین متحرک نمایی در پایتون را مورد بررسی قرار دادیم. برای مطالعه بیشتر می‌توان موارد زیر را بررسی کرد:

  1. حذف روند از سیگنال (Detrending) با استفاده از میانگین متحرک نمایی
  2. بررسی اختلاف بین دو میانگین متحرک نمایی با طول‌های متفاوت و ارتباط آن با رفتار سیگنال
  3. آموزش دادن یک مدل خودهمبسته (Autoregressive) روی سیگنال و میانگین متحرک حاصل از آن و مقایسه دقت‌ها
  4. پیدا کردن روش‌هایی که می‌توان تأخیر میانگین متحرک نمایی را بیشتر از مقدار موجود کاهش داد

مطلبی که در بالا مطالعه کردید بخشی از مجموعه مطالب «آموزش پیاده‌سازی انواع میانگین های متحرک‌ در پایتون» است. در ادامه، می‌توانید فهرست این مطالب را ببینید:

  • میانگین متحرک چیست؟ + پیاده سازی Moving Average در پایتون
  • پیاده سازی میانگین متحرک نمایی در پایتون — راهنمای گام به گام(همین مطلب)
  • میانگین متحرک نمایی دوگانه و سه گانه در پایتون — راهنمای گام به گام
  • میانگین متحرک وزن دار در پایتون — راهنمای گام به گام
  • پیاده سازی میانگین متحرک هال در پایتون — راهنمای گام به گام

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.