• #GAS
  • #Gemini
  • #株式投資
  • #自動化
  • #LINE通知

GAS×Geminiで最強の「米国株&市場センチメント」自動分析ツールを作った話(と、ハマったポイント全まとめ)

米国株の個別銘柄のターゲットプライスと、市場全体のセンチメント(Fear & Greed Index等)を毎日自動で収集・分析し、スマホ(LINE)にチャート付きで通知するシステムを構築しました。

Google Apps Script (GAS) をベースに、生成AI(Gemini API)による画像解析や、Chart.jsを使ったリッチなダッシュボード化など、盛りだくさんの内容です。

開発中に直面した「リアルなエラー」や「ハマりポイント」も備忘録として残しておきます。

🛠 作ったものの構成

  1. 個別銘柄ターゲットプライス管理
    • Yahoo Finance(非公式API)から30〜100銘柄以上の目標株価・現在値をスクレイピング。
    • GASの「6分の壁」を超えるための自動リレー実行機能。
    • Webアプリ化したスプレッドシートで、スマホから見れるリッチなチャート表示。
  2. 市場センチメント分析 (Fear & Greed / NAAIM)
    • APIFlash でCNN等のサイトをスクリーンショット撮影。
    • Gemini 2.5 Flash (Googleの生成AI) に画像を読ませて、指数数値をOCR的に抽出。
    • 抽出結果をスプレッドシートに蓄積し、LINEに通知。
    • チャート背景に「恐怖〜強欲」の色分けゾーンを表示。

🚧 開発中の「つまずきポイント」と解決策

ここが一番重要です。理論上は簡単そうに見えても、実際に手を動かすと細かいエラーに遭遇しました。

1. GASの実行時間制限(6分の壁)問題

課題: 監視する銘柄数が30〜40件を超えると、処理時間が6分(無料アカウントの上限)を超えてしまい、途中でスクリプトが強制終了してしまう。

❌ 最初の失敗: 単純に関数を分割して fetchData1(); fetchData2(); と続けて書いたが、1回の実行時間はリセットされないため、結局タイムアウトした。

✅ 解決策: 「自分自身を予約する」リレー方式 4分30秒経過した時点で処理を中断し、進捗(何件目まで終わったか)を保存。その後、ScriptApp.newTrigger を使って「1分後に続きを実行してね」と予約して終了する実装に変更しました。

余談: 後で気づきましたが、私は Google Workspace(有料)アカウントだったので制限は30分あり、実はこの対策は不要でした。しかし、銘柄数が数百件になっても動く堅牢な設計になりました。

2. ライブラリのエラー(URL間違い)

エラー内容:スクリプトで使用されるライブラリ ... へのアクセス権がないか、ライブラリが削除されました。

原因: Webアプリとしてデプロイした後、開くべき「WebアプリのURL(.../exec)」ではなく、間違って**「ライブラリとしての共有URL」**や、別の管理画面のリンクをクリックしてしまっていた。

✅ 解決策: 「デプロイ」ボタンを押した直後に表示される ウェブアプリ: https://script.google.com/.../exec というURLを正しくコピーして開くことで解決。

3. Webアプリの権限設定(友人が見れない!)

課題: 作ったチャート画面のURLを友人に共有したが、「アクセス権がありません」と言われて見てもらえない。

✅ 解決策: デプロイの設定を以下のように変更しました。

  • 次のユーザーとして実行: 「自分 (Me)」 ← ここが重要!自分の権限でデータを取りに行く
  • アクセスできるユーザー: 「全員 (Anyone)」

4. HTMLファイル名の大文字・小文字トラップ

エラー内容:Exception: 「Index」という HTML ファイルは見つかりませんでした。

原因: GASのエディタ上でファイル名を index.html(小文字)で作っていたのに、スクリプト側で HtmlService.createHtmlOutputFromFile('Index')(大文字)と呼び出していた。

✅ 解決策: プログラミングにおいて大文字と小文字は別物。ファイル名を合わせることで解決。

5. APIFlashがJSONを返してくれない

エラー内容:SyntaxError: Unexpected token '', "PNG..." is not valid JSON

原因: スクリーンショットAPIを叩いた際、レスポンスとして「画像のURL(JSON)」が欲しかったのに、設定漏れで「画像バイナリそのもの(PNG)」が返ってきてしまい、JSON.parse で爆発した。

✅ 解決策: APIのリクエストURL末尾に &response_type=json を追加。


📊 こだわりのUI実装

1. Fear & Greed チャートの背景色分け

単なる折れ線グラフでは味気ないので、Chart.jsのプラグイン機能を使って背景に色を塗りました。

  • 0-25: 🟥 Extreme Fear
  • 50-75: 🟩 Greed といった具合にゾーン分けすることで、今の相場がどの位置にいるか一目で分かります。

2. Webアプリのナビゲーション

銘柄切り替えボタンをポチポチ押すのが面倒だったので、以下の機能を追加しました。

  • ←前へ 次へ→ ボタン の設置
  • キーボードの矢印キー での切り替え対応

🚀 まとめ

今回の開発で、「スクレイピング × 生成AI画像解析 × Webアプリ化」 というGASのフルコースを体験しました。

特に、「APIがないサイト(Fear & Greed Index等)でも、スクショを撮ってGeminiに画像解析させれば数値化できる」 という手法は、あらゆるデータ収集に応用できる強力なテクニックです。

毎朝、LINEに「推移グラフはこちら」というリンク付きでレポートが届くようになり、相場チェックが劇的に快適になりました。