東証銘柄の株価を取得してGoogleスプレッドシートを更新する
まず結論
個人用の集計表で東証銘柄の価格を更新するなら、Node.js から yahoo-finance2 を呼び、Sheets API へまとめて書き込む方法があります。ただし Yahoo Finance の API は非公式です。売買判断や業務システムには、契約条件と品質保証が明確な J-Quants API や JPX の有償データを選びます。
この記事の例は、Node.js 22 以降、yahoo-finance2 4 系、Google Sheets API v4 を前提にします。導入時は利用するバージョンの README と型定義を確認してください。
import YahooFinance from "yahoo-finance2";
import { google } from "googleapis";
const yahooFinance = new YahooFinance();
const quote = await yahooFinance.quote("7203.T");
console.log(quote.regularMarketPrice);
使う場面
この構成が向くのは、次の条件です。
- 個人用の資産集計など、多少の遅延や欠損を許容できる
- API の変更時に自分で追随できる
- 価格を売買執行や顧客向け表示へ直接使わない
スプレッドシート内で完結させたい場合は GOOGLEFINANCE も候補ですが、公式ヘルプは多くの海外市場を対象外としています。対象銘柄で取得できるか先に試してください。
構文と設定項目
| 項目 | 例 | 補足 |
|---|---|---|
| 東証のシンボル | 7203.T |
Yahoo Finance形式 |
| スプレッドシートID | URL中のID | 環境変数で渡す |
| 書き込み範囲 | Prices!A2:C |
行数に合わせて終端を組み立てる |
| 認証 | Application Default Credentials またはサービスアカウント | 対象シートを共有し、Sheets APIを有効にする |
| 実行環境 | Node.js 22 以降 |
yahoo-finance2 4 系を利用する |
API キーや認証 JSON をソースコードへ埋め込まず、実行環境のシークレットとして管理します。
サービスアカウントを使う場合は、Google Cloud で Sheets API を有効にし、サービスアカウントのメールアドレスを対象スプレッドシートへ共有します。SPREADSHEET_ID と認証情報の場所は環境変数などで渡し、認証 JSON をリポジトリへ追加しません。
実装例
次は Node.js で複数銘柄を取得し、値を一括更新する骨格です。再試行の回数や間隔は、データの鮮度と API の利用制限に合わせて決めてください。
import YahooFinance from "yahoo-finance2";
import { google } from "googleapis";
const symbols = ["7203.T", "6758.T"];
const yahooFinance = new YahooFinance();
async function loadRows(): Promise<(string | number | null)[][]> {
return Promise.all(
symbols.map(async (symbol) => {
const quote = await yahooFinance.quote(symbol);
return [
symbol,
quote.regularMarketPrice ?? null,
quote.regularMarketTime?.toISOString() ?? null,
];
}),
);
}
async function updateSheet(): Promise<void> {
const spreadsheetId = process.env.SPREADSHEET_ID;
if (!spreadsheetId) {
throw new Error("SPREADSHEET_ID is required");
}
const auth = new google.auth.GoogleAuth({
scopes: ["https://www.googleapis.com/auth/spreadsheets"],
});
const sheets = google.sheets({ version: "v4", auth });
const values = await loadRows();
// 1件でも価格を取得できなければ、前回値を残したまま更新しない
if (values.length === 0 || values.some(([, price]) => typeof price !== "number")) {
throw new Error("A quote did not contain a numeric price");
}
await sheets.spreadsheets.values.update({
spreadsheetId,
range: `Prices!A2:C${values.length + 1}`,
valueInputOption: "RAW",
requestBody: { values },
});
}
try {
await updateSheet();
} catch (error) {
console.error("価格の取得またはスプレッドシートの更新に失敗しました", error);
process.exitCode = 1;
}
loadRows() は Promise.all で全銘柄の取得が終わるまで待ち、取得処理または価格の検証に失敗した場合は values.update を呼びません。そのため、取得失敗時に前回の値を消さずに済みます。コード例は認証情報を用いた実行確認をしていないため、まずコピーした検証用スプレッドシートで試してください。
つまずきやすい点
非公式APIを安定したデータソースとみなす
yahoo-finance2 自身が、Yahoo との提携がない非公式ライブラリだと明記しています。レスポンス変更、利用制限、欠損を前提にします。
セルを1件ずつ更新する
API 呼び出し回数が増え、遅くなります。2 次元配列を作って spreadsheets.values.update でまとめて書き込みます。
価格だけを保存する
取得時刻、通貨、取引所を一緒に持たないと、後から値の意味を確認できません。少なくとも取得時刻を保存します。
エラー時に前回値を消す
取得失敗と価格 0 を区別します。前回値を残す場合も、最終成功時刻とエラー状態を別列で示します。上の例では、取得または検証に失敗した時点で更新処理を止め、標準エラー出力へ記録します。
関連する機能
まとめ
試作や個人集計なら、非公式 API と Sheets API の組み合わせは手軽です。用途が重要になるほど、データの契約、時刻、欠損時の扱いを先に決め、公式または有償のデータソースへ切り替えます。
Discussion