SQLを使って株にテクニカル指標を出す③ 指数移動平均

SQLを使って株にテクニカル指標を出す③ 指数移動平均

Twitter LINEで送る Facebook はてなブログ

株のテクニカル指標をまとめる

SQLを使って株にテクニカル指標を出す②に続き3個目 今回は、EMA(Exponential Moving Average)指数平滑移動平均線計算を解説 EMAはMACDなどにも利用されているため重要な計算となりますがいろいろ試した結果でききました。

参照するデータは前回同様、2023年の日経平均を利用します。
  利用するデータは こちらにSQLを準備 2023年分の情報を出すのに2022年のデータが必要ですので入れています。

指数平滑移動平均の数式

指数移動平均の計算には数列の一種の、漸化式の知識が必要で数Bに習う内容です。

初項:n日分の移動平均値
2項名以降:前項 + (2 / (n日 + 1)) * (当日の値 - 前項)

具体的な数値をベースに計算を行います。 以下のようなcsvファイルを基準に5日の指数移動平均を算出するものとします。

日付,値
2024/01/01,1
2024/01/02,2
2024/01/03,4
2024/01/04,8
2024/01/05,16
2024/01/06,32
2024/01/07,64
2024/01/08,128
2024/01/09,256

具体的な項を求めると以下が計算式になります。

1項目(2024/01/05): (1 + 2 + 4 + 8 + 16) / 5 = 6.20
2項目(2024/01/06): 6.20 + (2 / (1 + 5)) * (32 - 6.20) = 14.80
3項目(2024/01/07): 14.80 + (2 / (1 + 5)) * (64 - 14.80) = 31.20
4項目(2024/01/08): 31.20 + (2 / (1 + 5)) * (128 - 31.20) = 63.47 
5項目(2024/01/09): 63.47 + (2 / (1 + 5)) * (256 - 63.47) = 127.64 

上記の漸化式で指数移動平均の求め方になります。 前項の値を参照する漸化式では初項をどこから始めるかで 若干の値のずれが発生するためその点は考慮が必要です。

指数平滑移動平均をSQLで求める

SQL自体は以下のようなSQLとなります。 WITH RECURIVEを複数用いての計算となります。 今回は、5日分で指数平滑移動平均を求めることとします。

WITH RECURSIVE wr_select_ema(i, date, close, exponent) AS (
SELECT
    i,
    date,
    close,
    exponent
FROM 
(SELECT
    ROW_NUMBER() OVER (ORDER BY date) AS i,
    date,
    close AS close,
    ROUND(AVG(close) OVER w, 10) AS exponent	
FROM
    nikkei225
WINDOW
    w AS (ORDER BY date ASC ROWS BETWEEN 4 PRECEDING AND current ROW)
) AS T1 WHERE date >= '2022-01-11'
),
wr_calc_ema AS  (
    SELECT 
        i,
        date,
        close,
        exponent
    FROM
        wr_select_ema
    WHERE
        i = 5
UNION ALL
    SELECT 
        T2.i,
        T2.date,
        T2.close,
        ROUND(T1.exponent + (0.333333333333333) * (T2.close-T1.exponent), 10) AS exponent
    FROM
        wr_calc_ema AS T1, wr_select_ema AS T2
    WHERE
        T1.i + 1 = T2.i
)

SELECT * FROM wr_calc_ema;

1つ目のwr_select_emaでは、単純移動平均を求めています。 これは初項を算出するためと自分がn番目の値を付与するための準備用SQLとなります。

2つ目のwr_calc_emaが本体で、 「i = 5」となっている部分は5日分の移動平均が集まるのが5となる為です。
漸化式的なSQLは「UNON ALL」以降となり「exponent」の計算がそこに該当します。
WHERE部分の「T1.i + 1 = T2.i」では前項の値を参照するために利用している部分になります
1点、原因を突き止めていない部分で「0.333333333333333」を「(2 / (1 + 5))」と数式化すると正しく計算ができませんでした。 このSQLを利用すると指数移動平均が1回で必要な日数分求められるので便利と思います。

まとめ

今回は1つの式ですが、思っている以上に苦労しました。
漸化式自体をSQL求めるよりプログラムを組んだ方がこれは楽な領域とおおもえるので
労力には合っていないなという感が終わった時の感想になってしましました。
とはいえこれでMACDなどの値も出せるので幅は広がりました。