TradingViewのWebhookで株を自動発注|Node.jsで処理実装&ログ対応ガイド

TradingView × Node.js | Webhook で株を自動発注する方法 【ログ&バリデーション対応まで】

TradingView のアラート機能を使えば、特定のタイミングで Webhook 通知を送ることができます。 前回の記事では、Node.js 側でその通知を受信するところまで解説しました。

今回はいよいよ、その通知を kabu ステーション API の発注処理につなげて、実際に株を自動売買する仕組みを作っていきます。

📚 前提となる記事

✅ この記事でわかること

TradingView のアラート通知を使って、Node.js から株の発注処理を行う方法をステップ形式で解説します。

この記事を読み終えるころには、以下ができるようになります:

  • Webhook で株の発注を自動化する方法
  • 発注時のエラー内容をログで記録する仕組み
  • 不正な通知をブロックする簡易バリデーションの導入

🔧 今回の流れ

  1. すでにある send-order.js を再利用可能な関数形式にする
  2. Webhook サーバーから sendOrder() を呼び出して発注を行う

🏁 完成イメージ

TradingViewアラート
  ↓
Webhook通知              
  ↓
Node.js(バリデーション) → ログ記録
  ↓
kabuステAPIで発注

STEP1 | send-order.js を関数化して外部から呼び出せるようにする

まずは、これまで CLI(コマンド処理) 用に書いていた send-order.js を、モジュールとして再利用できる構成に変更します。

// send-order.js
const axios = require("axios");
const { config } = require("./config");
const { getToken } = require("./auth");
const { createOrderData } = require("./order-data.js");

async function sendOrder({ symbol, side, qty, cashMargin, price = 0 }) {
  try {
    const token = await getToken();
    const orderData = createOrderData({ symbol, side, qty, cashMargin, price });

    const res = await axios.post(
      `${config.baseUrl}/kabusapi/sendorder`,
      orderData,
      {
        headers: {
          "Content-Type": "application/json",
          "X-API-KEY": token,
        },
      }
    );

    console.log("✅ 注文成功:", res.data);
    return res.data;
  } catch (err) {
    if (err.response) {
      console.error("❌ APIエラー:", err.response.status, err.response.data);
    } else {
      console.error("❌ 通信エラー:", err.message);
    }
    throw err;
  }
}

module.exports = { sendOrder };
パラメータ 内容
symbol 銘柄コード(例:8306)
side 売買区分(1:売, 2:買)
qty 株数(例:100)
cashMargin 1=現物, 2=信用新規, 3=信用返済

STEP2 | Webhook を受信して、発注処理を流す

Webhook 通知を受け取って、createOrderData() で注文データを作り、sendOrder() で API に送信します。

// webhook.js
const express = require("express");
const { sendOrder } = require("./send-order");

const app = express();
app.use(express.json());

app.post("/webhook", async (req, res) => {
  const timestamp = new Date().toISOString();
  console.log(`[${timestamp}] Webhook受信:`, JSON.stringify(req.body));

  try {
    const { symbol, side, qty, cashMargin = 1, price = 0 } = req.body;

    const result = await sendOrder({ symbol, side, qty, cashMargin, price });

    console.log(`[${timestamp}] 注文成功:`, result);
    res.status(200).send("Order sent");
  } catch (err) {
    const errorInfo = err.response?.data || err.message || err;
    console.error(`[${timestamp}] 注文エラー:`, errorInfo);
    res.status(500).send("Order failed");
  }
});

app.listen(3000, () => {
  console.log("🚀 Webhook サーバー起動中(ポート 3000)");
});

STEP3 | TradingView の Webhook 通知から実際に発注する。

TradingView のアラートに以下のような JSON を設定:

{
  "symbol": "8306",
  "side": "2",
  "qty": 100,
  "cashMargin": 2
}
パラメータ 内容
symbol 銘柄コード(例:8306)
side 売買区分(1:売, 2:買)
qty 株数(例:100)
cashMargin 1=現物, 2=信用新規, 3=信用返済

✅ STEP3 まで完了!お疲れさまでした 🎉

これであなたの環境は、以下のように自動売買が可能な最低構成になりました 👇

Webhook受信
  ↓
発注データ作成
  ↓
kabuステAPIで注文実行

STEP4 |エラーログを追加して原因を“見える化”しよう

ここまででも特にエラー等がおこらない限りは、自動売買を運用できる状態です。

でも…このままでは「失敗したときの原因が見えません」。
システムを運用していくと、こんなトラブルに出くわします:

  • kabu ステーション API が起動していなかった
  • 通知内容が不完全だった
  • API トークンが期限切れになっていた

そのときにログがないと原因を突き止められません

✅ ログ付きの Webhook 受信処理(try-catch で記録)

app.post("/webhook", async (req, res) => {
  const timestamp = new Date().toISOString();
  console.log(`[${timestamp}] Webhook受信:`, JSON.stringify(req.body));

  try {
    const { symbol, side, qty, cashMargin = 1, price = 0 } = req.body;

    const orderData = createOrderData({ symbol, side, qty, cashMargin, price });
    const response = await sendOrder(orderData);

    console.log(`[${timestamp}] 注文成功:`, response);
    res.status(200).send("Order sent");
  } catch (err) {
    const errorInfo = err.response?.data || err.message || err;
    console.error(`[${timestamp}] 注文エラー:`, errorInfo);
    res.status(500).send("Order failed");
  }
});

🔎 ログがあると助かるケース

状況 問題 ログがあれば
発注できない API が失敗しても無反応 原因メッセージが残る
データが欠けてる symbol や qty が null 通知内容を検証できる
API トークン切れ 403 エラーで失敗 再認証が必要と気づける

STEP5 |バリデーションを追加して事故を未然に防ごう

ログがあるだけでは 「失敗の記録」はできても、

「失敗そのもの」を防ぐことはできません。

次は、発注前に「通知内容がおかしくないか」チェックする機能を追加します。

✅ 追加するチェック例

// 値のチェック
const validSides = ["1", "2"];
const validMargins = ["1", "2", "3"];

if (!symbol || !side || !qty) {
  console.error(`[${timestamp}] エラー: 必須項目が不足`);
  return res.status(400).send("Missing required fields");
}

if (!validSides.includes(String(side))) {
  console.error(`[${timestamp}] エラー: sideの値が不正`, side);
  return res.status(400).send("Invalid side value");
}

if (!validMargins.includes(String(cashMargin))) {
  console.error(`[${timestamp}] エラー: cashMarginの値が不正`, cashMargin);
  return res.status(400).send("Invalid cashMargin value");
}

💡 結果、こうなる

❌ おかしな注文 → 発注が通ってしまう → 損失の可能性
✅ おかしな注文 → バリデーションでブロック → エラーとして記録

✅ おわりに|これで安心して運用スタート!

  • STEP3 までで:Webhook 受信 → 自動発注ができる最小構成が完成
  • STEP4 で:トラブルが起きたときに気づけるログを追加
  • STEP5 で:トラブルそのものを減らせるバリデーションを追加

📢 次回予告| Slack 連携でスマホにリアルタイム通知!

次回の記事では、Slack 連携によるリアルタイム注文状況の通知の仕組みを解説します。

Slack 通知を導入することで:

  • いつどんな注文が発生したかをスマホで即確認可能
  • エラーログや異常発生時の通知もリアルタイム受信
  • 緊急時には売買処理の停止操作も Slack 経由で行える

といった運用の利便性と安全性が大幅にアップします。

ぜひ次回もご期待ください!