前回の記事ではBigQueryで時系列データに移動平均を追加する方法を紹介しました。移動平均といえば株式のテクニカル分析でも使われる手法です。せっかくなので、移動平均を応用したものも含め、テクニカル分析で使われる代表的な手法をBigQueryのSQLで再現してみます。
事前準備
yfinanceで日経平均の株価データを取得し、BigQueryにロードします。yfinanceはYahoo Financeから株価データを取得できるPythonライブラリです。提供してくださっていることに感謝しつつ、今回は個人の学習目的なのでこちらを使わせていただきます。
import yfinance as yf
# 日経平均の株価を取得(2023/01/01 ~ 2024/12/31の2年分)
df = yf.download("^N225", start="2023-01-01", end="2024-12-31")
df = df.reset_index()
df.columns = ['date', 'close', 'high', 'low', 'open', 'volume']
df.to_csv("nikkei225.csv", index=False)
出力したCSVをBigQueryコンソールからアップロードします。今回は example_project.stock_data.nikkei225 として保存しました。
ゴールデンクロス・デッドクロス
短期移動平均と長期移動平均の2本の線を使った分析手法です。
- ゴールデンクロス: 短期移動平均が長期移動平均を下から上に抜ける → 一般的に上昇トレンドのサインとされる
- デッドクロス: 短期移動平均が長期移動平均を上から下に抜ける → 一般的に下降トレンドのサインとされる
SELECT
date,
close,
ROUND(AVG(close) OVER (ORDER BY date ROWS BETWEEN 6 PRECEDING AND CURRENT ROW)) AS ma_7d,
ROUND(AVG(close) OVER (ORDER BY date ROWS BETWEEN 24 PRECEDING AND CURRENT ROW)) AS ma_25d
FROM `example_project.stock_data.nikkei225`
ORDER BY date
ちなみにこのグラフは終値ベースの日次データです(ローソク足ではないので日足と呼んでいいのか怪しいところです)。
ボリンジャーバンド
移動平均を中心に、標準偏差の2倍を上下に加えたバンドを表示する手法です。一般的に、株価がバンドの外に出ると「買われすぎ」「売られすぎ」の判断材料になるとされています。
SELECT
date,
close,
ROUND(AVG(close) OVER w) AS ma_20d,
ROUND(AVG(close) OVER w + 2 * STDDEV(close) OVER w) AS upper_band,
ROUND(AVG(close) OVER w - 2 * STDDEV(close) OVER w) AS lower_band
FROM `example_project.stock_data.nikkei225`
WINDOW w AS (ORDER BY date ROWS BETWEEN 19 PRECEDING AND CURRENT ROW)
ORDER BY date
RSI(相対力指数)
一定期間の上昇幅と下落幅の比率から、買われすぎ・売られすぎを判断する指標です。0〜100の範囲で表され、一般的に70以上が買われすぎ、30以下が売られすぎとされています。
WITH price_changes AS (
SELECT
date,
close,
close - LAG(close) OVER (ORDER BY date) AS change
FROM `example_project.stock_data.nikkei225`
),
gains_losses AS (
SELECT
date,
close,
CASE WHEN change > 0 THEN change ELSE 0 END AS gain,
CASE WHEN change < 0 THEN ABS(change) ELSE 0 END AS loss
FROM price_changes
),
avg_gains_losses AS (
SELECT
date,
close,
AVG(gain) OVER (ORDER BY date ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS avg_gain,
AVG(loss) OVER (ORDER BY date ROWS BETWEEN 13 PRECEDING AND CURRENT ROW) AS avg_loss
FROM gains_losses
)
SELECT
date,
close,
ROUND(100 - (100 / (1 + SAFE_DIVIDE(avg_gain, avg_loss))), 2) AS rsi_14d
FROM avg_gains_losses
ORDER BY date
MACD
短期と長期の移動平均の差を見ることで、トレンドの方向と強さを判断する指標です。一般的に、MACDがシグナル線を上抜けると買いサイン、下抜けると売りサインとされています。
WITH moving_averages AS (
SELECT
date,
close,
AVG(close) OVER (ORDER BY date ROWS BETWEEN 11 PRECEDING AND CURRENT ROW) AS ma_12d,
AVG(close) OVER (ORDER BY date ROWS BETWEEN 25 PRECEDING AND CURRENT ROW) AS ma_26d
FROM `example_project.stock_data.nikkei225`
),
macd_line AS (
SELECT
date,
close,
ma_12d - ma_26d AS macd
FROM moving_averages
)
SELECT
date,
close,
ROUND(macd, 2) AS macd,
ROUND(AVG(macd) OVER (ORDER BY date ROWS BETWEEN 8 PRECEDING AND CURRENT ROW), 2) AS signal_line,
ROUND(macd - AVG(macd) OVER (ORDER BY date ROWS BETWEEN 8 PRECEDING AND CURRENT ROW), 2) AS histogram
FROM macd_line
ORDER BY date
出来高移動平均
出来高(取引された株の量)の移動平均を見ることで、市場の注目度のトレンドを把握できます。一般的に、株価上昇時に出来高も増えていれば、トレンドの信頼性が高いとされています。
SELECT
date,
close,
volume,
ROUND(AVG(volume) OVER (ORDER BY date ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)) AS volume_ma_5d,
ROUND(AVG(volume) OVER (ORDER BY date ROWS BETWEEN 24 PRECEDING AND CURRENT ROW)) AS volume_ma_25d
FROM `example_project.stock_data.nikkei225`
ORDER BY date
最後に
今回はウィンドウ関数でテクニカル分析の定番指標を再現してみました。BigQuery MLと組み合わせれば、もう少し面白い分析もできそうですね。
※本記事は特定の銘柄の売買を推奨するものではありません。投資判断はご自身の責任でお願いします。(念のため...)





