SQLを使って株にテクニカル指標を出す① 単純移動平均線 / ボリンジャーバンド
株のテクニカル指標をまとめる
色々なテクニカル指標があるので、改めて勉強の意味もあり
MACDやRSI、移動平均などなどのテクニカル指標の計算式をSQLで行ってみます。
今回の環境はPostgres 15.2を利用しています。
今回参照するデータは2023年の日経平均を利用します。
利用するデータは こちらにSQLを準備
2023年分の情報を出すのに2022年のデータが必要ですので入れています。
5日、25日、75日の単純移動平均を出す。
SELECT * FROM (
SELECT
date,
close,
ROUND(AVG(close) OVER (ORDER BY date ASC ROWS BETWEEN 4 PRECEDING AND current ROW), 2) as _5moving_average,
ROUND(AVG(close) OVER (ORDER BY date ASC ROWS BETWEEN 24 PRECEDING AND current ROW), 2) as _25moving_average,
ROUND(AVG(close) OVER (ORDER BY date ASC ROWS BETWEEN 74 PRECEDING AND current ROW), 2) as _75moving_average
FROM
nikkei225
ORDER BY
date DESC) AS T1 WHERE date >= '2023-01-01';
単純移動平均線は自分の終値と計算する日数分の過去を平均する方法ですのでシンプルなWINDOW関数でできます。 WINDOW関数の部分でBETWEEN部分で必要な日数の-1日をする必要があるのが注意点となります。
RSIの計算
SELECT
date,
ROUND(CASE WHEN a + b > 0 THEN a / (a + b) ELSE 0 END * 100, 2) AS rsi9,
ROUND(CASE WHEN c + d > 0 THEN c / (c + d) ELSE 0 END * 100, 2) AS rsi14
FROM (
SELECT
date,
ABS(SUM(CASE WHEN close > 0 THEN close ELSE 0 END) OVER w2 / 9) AS a,
ABS(SUM(CASE WHEN close > 0 THEN 0 ELSE close END) OVER w2 / 9) AS b,
ABS(SUM(CASE WHEN close > 0 THEN close ELSE 0 END) OVER w3 / 14) AS c,
ABS(SUM(CASE WHEN close > 0 THEN 0 ELSE close END) OVER w3 / 14) AS d
FROM (
SELECT
date, close - last_value(close) OVER w1 AS close
FROM
nikkei225
WINDOW
w1 AS (ORDER BY date DESC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)
) AS S1
WINDOW w2 AS (ORDER BY date DESC ROWS BETWEEN 0 PRECEDING AND 8 FOLLOWING),
w3 AS (ORDER BY date DESC ROWS BETWEEN 0 PRECEDING AND 13 FOLLOWING)
) AS T2;
RSIの計算方法は以下のような形となる ① RS=(n日間の終値の上昇幅の平均)÷(n日間の終値の下落幅の平均) ② RSI= 100 - (100 ÷ (RS+1)) これをSQLで表現するとサブクエリを用いて行い複雑化していくことになるがしょうがないです。
ボリンジャーバンドの±1〜3σを計算
SELECT
date,
ROUND(_25moving_average, 2) AS ma,
ROUND(_25moving_average + _25stddev, 2) AS plus1sigma,
ROUND(_25moving_average - _25stddev, 2) AS minus1sigma,
ROUND(_25moving_average + _25stddev * 2, 2) AS plus2sigma,
ROUND(_25moving_average - _25stddev * 2, 2) AS minus2sigma,
ROUND(_25moving_average + _25stddev * 3, 2) AS plus3sigma,
ROUND(_25moving_average - _25stddev * 3, 2) AS minus3sigma
FROM (
SELECT
date,
STDDEV_POP(close) OVER w _25stddev,
AVG(close) OVER w as _25moving_average
FROM
nikkei225
WINDOW
w AS (ORDER BY date ASC ROWS BETWEEN 24 PRECEDING AND current ROW)
ORDER BY
date DESC) AS T1;
ボリンジャーバンドは、移動平均と標準偏差の計算で求められるのでSQLとしては結構シンプルだと思います。 ただ、標準偏差を求める際に、母標準偏差を基準に計算するためSTDDEV_POP関数を利用しています。
まとめ
3指標をまとめましたがSQLとしてはまだ計算しやすいところをまとめました。 指数移動平均や、加重移動平均などのWITH句を駆使する感じもできないか模索中ですのでできたら上げます。