میانگین متحرک نمایی دوگانه و سه گانه در پایتون — راهنمای گام به گام
در مطالب پیشین مجله فرادرس، به صورت گام به گام به پیاده سازی میانگین متحرک نمایی پرداختیم و مشاهده کردیم که از تأخیر کمتری نسبت به میانگین متحرک ساده دارد. در این مطلب میخواهیم به میانگین متحرک نمایی دوگانه (Double Exponential Moving Average - DEMA) و میانگین متحرک نمایی سهگانه (Triple Exponential Moving Average - TEMA) بپردازیم. در این نوع از میانگین متحرکها، مشکل تأخیر موجود در میانگین متحرک نمایی کمتر شده است.
میانگین متحرک نمایی دوگانه
اگر یک سری زمانی با نماد داشته باشیم، میتوانیم میانگین متحرک نمایی با طول بازه را بهصورت زیر تعریف کنیم:
حال میتوانیم میانگین متحرک دیگری روی محاسبه کنیم:
براساس تجربه میدانیم که نسبت به تأخیر دارد و نیز نسبت به دارای تأخیر دوچندان است. براساس این موضوع، میتوان تقریباً گفت که فاصله از مقداری که باید باشد (Target)، با فاصله از برابر است، یعنی:
در رابطه فوق، مقدار برابر با عددی است که در صورت نبود تأخیر آن را خواهیم داشت. حال پس از حل رابطه بهفرم زیر میرسیم:
به این ترتیب، میانگین متحرک نمایی دوگانه تعریف میشود:
به این ترتیب، فرمول نهایی حاصل میشود.
میانگین متحرک نمایی سه گانه
در این حالت نیز مشابه میانگین متحرک نمایی دوگانه تعریف میکنیم:
براساس آنچه گفته شد، تأخیر بین این موارد بهشکل زیر خواهد بود:
اگر یک تقریب بهصورت زیر داشته باشیم:
میتوان نوشت:
حال اگر مقدار را برحسب میانگین متحرک اول و دوم بنویسیم، خواهیم داشت:
اکنون میانگین متحرک نمایی سهگانه را تعریف میکنیم:
برای یادگیری برنامهنویسی با زبان پایتون، پیشنهاد میکنیم به مجموعه آموزشهای مقدماتی تا پیشرفته پایتون فرادرس مراجعه کنید که لینک آن در ادامه آورده شده است.
پیاده سازی میانگین متحرک نمایی دوگانه و سه گانه در پایتون
مباحث مربوط به تعریف میانگین متحرکها بیان شد. حال میتوانیم وارد محیط برنامهنویسی شده و کتابخانههای مورد نیاز را فراخوانی کنیم:
1import numpy as np
2import pandas as pd
3import yfinance as yf
4import matplotlib.pyplot as plt
این کتابخانهها بهترتیب برای موارد زیر استفاده خواهند شد:
- محاسبات برداری و کار با آرایهها
- کار با دیتافریمها و مجموعه داده
- دریافت آنلاین دادههای مربوط به قیمت نمادها
- رسم نمودار
حال، تنظیمات مربوط به نمودارها را بهصورت زیر وارد میکنیم:
1plt.style.use('ggplot')
سپس نماد مورد نظر را که قیمت نقره است را تعریف و تاریخچه قیمت برای یک سال بین ۲۰۲۱ تا ۲۰۲۲ دریافت میکنیم:
1Ticker = yf.Ticker('AG')
2DF = Ticker.history(interval='1d', start='2021-01-01', end='2022-01-01')
به این ترتیب، دیتافریم قیمت دریافت میشود. حال ۵ سطر اول مجموعه داده را مشاهده میکنیم:
1print(DF.head(5))
که خواهیم داشت:
Open High Low Close Volume Dividends Stock Splits Date 2020-12-31 13.644106 13.714025 13.314491 13.424362 5240600 0.0 0 2021-01-04 14.123548 14.543059 13.963733 14.223431 10227500 0.0 0 2021-01-05 14.273373 14.273373 13.793932 14.243408 8188200 0.0 0 2021-01-06 14.133536 14.223431 13.644106 14.213443 7572700 0.0 0 2021-01-07 14.093582 14.323315 13.783943 13.993699 5674700 0.0 0
به این ترتیب، داده حاصل میشود. حال ستون مربوط به قیمت Close را به شکل یک آرایه در میآوریم:
1S = DF['Close'].to_numpy()
برای رسم نمودار سری زمانی مینویسیم:
1plt.semilogy(S, lw=0.9, c='crimson')
2plt.title('Silver 1 Year Historical Price')
3plt.xlabel('Time (Day)')
4plt.ylabel('Price ($)')
5plt.show()
که شکل زیر را خواهیم داشت.
به این ترتیب، «نمودار نیمهلگاریتمی» (Semi-Logarithm) رسم میشود.
حال، کد مربوط به تابع میانگین متحرک نمایی را وارد کد میکنیم:
1def EMA(S:np.ndarray, L:int, r:float=1):
2 a = (1 + r) / (L + r)
3 nD0 = S.size
4 nD = nD0 - L + 1
5 M = np.zeros(nD)
6 M[0] = np.mean(S[:L])
7 for i in range(1, nD):
8 M[i] = a * S[i+L-1] + (1-a) * M[i-1]
9 return M
اکنون میتوانیم با استفاده از از این تابع، تابعی برای DEMA پیادهسازی کنیم. این تابع در ورودی سری زمانی اولیه و طول میانگینگیری را میگیرد:
1def DEMA(S:np.ndarray, L:int):
حال میتوانیم میانگین متحرکهای مراتب اول و دوم را محاسبه کنیم:
1def DEMA(S:np.ndarray, L:int):
2 E = EMA(S, L)
3 EoE = EMA(E, L)
حال میتوانیم اندازه خروجی را محاسبه کنیم که برابر با خواهد بود:
1def DEMA(S:np.ndarray, L:int):
2 E = EMA(S, L)
3 EoE = EMA(E, L)
4 nD = EoE.size
با توجه به اینکه طول آرایه بیشتر از است، از آرایه تنها عضو انتهایی را نگه میداریم:
1def DEMA(S:np.ndarray, L:int):
2 E = EMA(S, L)
3 EoE = EMA(E, L)
4 nD = EoE.size
5 E = E[-nD:]
حال میتوانیم خروجی را محاسبه کرده و برگردانیم:
1def DEMA(S:np.ndarray, L:int):
2 E = EMA(S, L)
3 EoE = EMA(E, L)
4 nD = EoE.size
5 E = E[-nD:]
6 dema = 2*E - EoE
7 return dema
به این ترتیب، تابع پیادهسازی میشود.
حال، میانگین متحرک نمایی و میانگین متحرک نمایی دوگانه سری را محاسبه میکنیم:
1ema = EMA(S, 15)
2dema = DEMA(S, 15)
حال روی نمودار هر دو را رسم میکنیم و نمایش میدهیم:
1T = np.arange(S.size)
2
3plt.semilogy(T, S, lw=0.9, c='crimson', label='Price')
4plt.semilogy(T[-ema.size:], ema, lw=0.9, c='teal', lable='EMA(15)')
5plt.semilogy(T[-dema.size:], dema, lw=0.9, c='k', lable='DEMA(15)')
6plt.title('Silver 1 Year Historical Price')
7plt.xlabel('Time (Day)')
8plt.ylabel('Price ($)')
9plt.legend()
10plt.show()
که شکل زیر را خواهیم داشت.
به این ترتیب، مشاهده میکنیم که میانگین متحرک نمایی سهگانه، رفتار بهتری دارد و سریعتر از میانگین متحرک نمایی ساده واکنش نشان میدهد. علاوه بر واکنش سریعتر، نقاط حمایت و مقاومت را بهتر و دقیقتر نشان میدهد.
حال تابعی دیگر برای پیادهسازی میانگین متحرک نمایی سهگانه ایجاد میکنیم:
1def TEMA(S:np.ndarray, L:int):
سپس میانگین متحرک نمایی مراتب اول، دوم و سوم را محاسبه میکنیم:
1def TEMA(S:np.ndarray, L:int):
2 E = EMA(S, L)
3 EoE = EMA(E, L)
4 EoEoE = EMA(EoE, L)
حال اندازه خروجی را محاسبه کرده، آرایههای و را اصلاح و خروجی را محاسبه میکنیم:
1def TEMA(S:np.ndarray, L:int):
2 E = EMA(S, L)
3 EoE = EMA(E, L)
4 EoEoE = EMA(EoE, L)
5 nD = EoEoE.size
6 E = E[-nD:]
7 EoE = EoE[-nD:]
8 tema = 3*E - 3*EoE + EoEoE
9 return tema
به این ترتیب، تابع پیادهسازی میشود. به شیوه مشابه از هر سه تابع خروجی میگیریم:
1ema = EMA(S, 15)
2dema = DEMA(S, 15)
3tema = TEMA(S, 15)
برای رسم نمودار مینویسیم:
1T = np.arange(S.size)
2
3plt.semilogy(T, S, lw=0.9, c='crimson', label='Price')
4plt.semilogy(T[-ema.size:], ema, lw=0.9, c='teal', label='EMA(15)')
5plt.semilogy(T[-dema.size:], dema, lw=0.9, c='k', label='DEMA(15)')
6plt.semilogy(T[-tema.size:], tema, lw=0.9, c='k', label='TEMA(15)')
7plt.title('Silver 1 Year Historical Price')
8plt.xlabel('Time (Day)')
9plt.ylabel('Price ($)')
10plt.legend()
11plt.show()
که در خروجی شکل زیر را خواهیم داشت.
مشاهده میکنیم که واکنش میانگین متحرک نمایی سهگانه نیز بهتر از میانگین متحرک نمایی دوگانه است.
جمعبندی
در این مطلب، میانگین متحرک نمایی دوگانه و سهگانه را بررسی و پیادهسازی کردیم.
برای مطالعه بیشتر، میتوان موارد زیر را بررسی کرد:
- نمودار قیمت، و و را رسم کرده و آنها را با هم مقایسه کنید.
- آیا میتوان میانگین متحرک نمایی سهگانه را به شیوهای دیگر نیز محاسبه کرد؟
- میانگین متحرک نمایی چهارگانه را پیادهسازی کنید.
- در های مختلف، نمودار مقایسه نهایی را رسم کرده و بهترین را پیدا کنید.
مطلبی که در بالا مطالعه کردید بخشی از مجموعه مطالب «آموزش پیادهسازی انواع میانگین های متحرک در پایتون» است. در ادامه، میتوانید فهرست این مطالب را ببینید:
- میانگین متحرک چیست ؟ + پیاده سازی Moving Average در پایتون
- پیاده سازی میانگین متحرک نمایی در پایتون — راهنمای گام به گام
- میانگین متحرک نمایی دوگانه و سه گانه در پایتون — راهنمای گام به گام(همین مطلب)
- میانگین متحرک وزن دار در پایتون — راهنمای گام به گام
- پیاده سازی میانگین متحرک هال در پایتون — راهنمای گام به گام