SQLでRSIを計算する

SQLでRSIを計算する

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

株のテクニカル指標「Relative Strength Index」とは?

RSIは「Relative Strength Index」の略です。 細かい事を知らなくても各証券会社のアプリなどでは、自動で計算できます。 実際には、この数値が70を超えていれば買われすぎなので売りのシグナル 30を下回っていれば買いのシグナルと判断することが多いです。

また、50を基準に上下すると売買のタイミングという考え方もあります。

RSIは何を基準に計算される?

RSIには、上昇率の平均と下落率の平均を利用し、上昇と下落の比率を意味する形になります。 RSIが100になるには、毎日前日の終値より今日の終値が上昇することで100になります。 反対に0になるには、毎日前日の終値より今日の終値が下落することで0になります。 日々、相場は上下し特定のセクターなどに資金が流入するとセクターのRSIを見て判断の材料にも使えます。

RSIの計算式

一般的には9日、14日などが証券会社などで採用されています。 9日の場合 RSI = 1 - (9日の上昇率の平均) / (9日の上昇率の平均 + 9日の下落率の平均)

日付価格
2021-05-2829149.41
2021-05-2728549.01
2021-05-2628642.19
2021-05-2528553.98
2021-05-2428364.61
2021-05-2128317.83
2021-05-2028098.25
2021-05-1928044.45
2021-05-1828406.84
2021-05-1727824.83
ある株価を10日分することで9日分の前日との差が計算できるので計算すると「79.6」となります。

SQLを利用した計算

環境バージョン
OSmac OS 10.15.3
DBPostgreSQL 10.5
-- テーブルの作製
CREATE TABLE stocks2 (
    id SERIAL,
    code VARCHAR(4),
    date date,
    price NUMERIC(19, 6)
);
-- データの作製
INSERT INTO stocks2(date, code, price) VALUES ('2021-05-28', '0001', 29149.41), ('2021-05-27', '0001', 28549.01), ('2021-05-26', '0001', 28642.19), ('2021-05-25', '0001', 28553.98), ('2021-05-24', '0001', 28364.61), ('2021-05-21', '0001', 28317.83), ('2021-05-20', '0001', 28098.25), ('2021-05-19', '0001', 28044.45), ('2021-05-18', '0001', 28406.84), ('2021-05-17', '0001', 27824.83);

Step1. 前日との差分を出すSQL.

SELECT code, date, price - last_value(price) OVER w AS price FROM stocks2 WINDOW w AS (PARTITION BY code ORDER BY date DESC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING);
 code |    date    |    price    
------+------------+-------------
 0001 | 2021-05-28 |  600.400000
 0001 | 2021-05-27 |  -93.180000
 0001 | 2021-05-26 |   88.210000
 0001 | 2021-05-25 |  189.370000
 0001 | 2021-05-24 |   46.780000
 0001 | 2021-05-21 |  219.580000
 0001 | 2021-05-20 |   53.800000
 0001 | 2021-05-19 | -362.390000
 0001 | 2021-05-18 |  582.010000
 0001 | 2021-05-17 |    0.000000
(10 rows)

Window関数を利用して差分を抽出。

Step2. RSIの実計算SQL

SELECT code, date, a, b, CASE WHEN a + b > 0 THEN a / (a + b) ELSE 0 END AS rsi, diff AS diff FROM (SELECT code, date, ABS(SUM(CASE WHEN price > 0 THEN price ELSE 0 END) OVER w2 / 9) AS a, ABS(SUM(CASE WHEN price > 0 THEN 0 ELSE price END) OVER w2 / 9) AS b, count(date) OVER w2 AS count, price AS diff FROM (SELECT code, date, price - last_value(price) OVER w AS price FROM stocks2 WINDOW w AS (PARTITION BY code ORDER BY date DESC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)) AS T1 WINDOW w2 AS (PARTITION BY code ORDER BY date DESC ROWS BETWEEN 0 PRECEDING AND 8 FOLLOWING) ) AS S1 WHERE count = 9 AND date = '2021-05-28';
 code |    date    |          a           |          b          |          rsi           |    diff    
------+------------+----------------------+---------------------+------------------------+------------
 0001 | 2021-05-28 | 197.7944444444444444 | 50.6188888888888889 | 0.79623119174136296130 | 600.400000
(1 row)

またも、Window関数と、ゼロ除算数のケースを組み込む事で対応。 割り算の「9」や「8」の部分を所定の日数にすることで任意のRSIの計算も可能になります。

※この計算SQLには1点問題点があります。上昇する日と下落する日にちがそれぞれ1回以上必要になります。 ご注意ください。

【免責事項】

本ブログの内容において、正当性を保証するものではありません。
本ブログを利用して損失を被った場合でも一切の責任を負いません。
期限付き内容を含でおり、ご自身で問題ないことを確認してください。
最終的な決定は、ご自身の判断(自己責任)でお願い致します。