一:指數移動平均線的計算
EMA 通過加權乘數賦予最新價格更多權重。 這個乘數應用於最后一個價格,因此它比其他數據點占移動平均線更大的部分。EMA 是通過采用最近的價格(我們將其稱為“時間 t 的價格”) 減去前一個時間段 (EMA_{t-1})。 此差異由您將 EMA 設置為 (N) 並加回到 EMA_{t-1}的時間段數加權。在數學上,我們可以這樣寫:

你可能已經注意到上面的等式有一個小問題,它是如何開始的? 它參考了最后一個時期的 EMA,所以如果你進行第一次計算,它參考的是什么? 這通常可以通過替換簡單移動平均線 (SMA) 來初始化計算來延緩,這樣您就可以在第一次之后的所有時間段構建 EMA。
讓我們通過導入我們的包,用 Python 中的一個簡單示例來展示它是如何工作的。
import numpy as np import pandas as pd import yfinance as yf import matplotlib.pyplot as plt
從這里開始,我們將構建兩個函數來協同工作並計算我們的指標。 第一個函數將是我們上面概述的公式的簡單實現:
def _calcEMA(P, last_ema, N):
return (P - last_ema) * (2 / (N + 1)) + last_ema
第二個函數將計算我們所有數據的 EMA,首先使用 SMA 對其進行初始化,然后迭代我們的數據以使用我們的 SMA 列中的值更新每個后續條目,或者調用我們上面定義的 _calcEMA 函數來處理大於 N的值。
def calcEMA(data, N):
# Initialize series
data['SMA_' + str(N)] = data['Close'].rolling(N).mean()
ema = np.zeros(len(data))
for i, _row in enumerate(data.iterrows()):
row = _row[1]
if i < N:
ema[i] += row['SMA_' + str(N)]
else:
ema[i] += _calcEMA(row['Close'], ema[i-1], N)
data['EMA_' + str(N)] = ema.copy()
return data
現在,讓我們獲取一些數據,看看它是如何工作的。 我們將拉出比回測更短的時間段,並比較 EMA 和 SMA 的 10、50 和 100 天。
ticker = 'GM'
yfObj = yf.Ticker(ticker)
data = yfObj.history(ticker, start='2018-01-01', end='2020-12-31')
N = [10, 50, 100]
_ = [calcEMA(data, n) for n in N]
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
fig, ax = plt.subplots(figsize=(18, 8))
ax.plot(data['Close'], label='Close')
for i, n in enumerate(N, 1):
ax.plot(data[f'EMA_{n}'], label=f'EMA-{n}', color=colors[i])
ax.plot(data[f'SMA_{n}'], label=f'SMA-{n}', color=colors[i], linestyle=':')
ax.legend()
ax.set_title(f'EMA and Closing Price Comparison for {ticker}')
plt.show()
二:現在來看一下我們系統的實現思路 歷史數據+當日實時數據 滾動計算,將結果數據實時寫入數據庫...
看一下日志(獲取完實時行情數據后調用python開始計算):

看一下python計算的界面...

可以指定計算的日期,默認是當日(由於我們系統只在股市開盤工日(9:30-11:30及13:00-15:00)調用python計算,所以python就不用判斷工作時間了)。
以下只是作一個測試:

