API連携

バイナンスAPIをNode.jsで連携する方法|crypto署名とnode-binance-apiの実装

バイナンス Node.js API の完全実践ガイド。ネイティブ crypto モジュールでの署名、axios のカプセル化、公式・サードパーティSDKの比較、WebSocket 購読、TypeScript での実装、エラーハンドリングまで網羅。実行可能なコードサンプル付き。

バイナンスの Node.js API 連携における標準的な経路は、ネイティブの crypto モジュールを使用した HMAC-SHA256 署名の生成と axios によるリクエスト送信、あるいは node-binance-apibinance-api-node といったコミュニティライブラリの使用です。本記事では、ネイティブでのカプセル化、主要な SDK の比較、WebSocket 購読、TypeScript の型の4つのセクションに分けて完全なコードを提示します。これらはすべて npm install 後にそのまま実行可能です。まだバイナンスのアカウントをお持ちでない方は、バイナンス公式サイトで登録を完了させてください。初めての方は 無料登録 から口座を開設できます。

1. Node.js SDK 比較表

ライブラリ名 作者 週間ダウンロード数 特徴 推奨シーン
node-binance-api jaggedsoft 30k+ 機能が豊富、コールバック形式 スクリプトでの迅速な検証
binance-api-node Ashlar 50k+ Promiseベース、TypeScriptフレンドリー 本番環境の TypeScript
@binance/connector 公式 40k+ 軽量でシンプルなラップ 最新の API 更新への追従
ccxt コミュニティ 80k+ 複数の取引所に対応 取引所をまたぐクオンツ
自作 axios + crypto 究極のコントロール性 高頻度マーケットメイク

2. ネイティブ crypto 署名 + axios のカプセル化

プロジェクトの初期化

mkdir binance-node && cd binance-node
npm init -y
npm install axios dotenv

.env ファイルの設定:

BINANCE_API_KEY=your_key_here
BINANCE_SECRET_KEY=your_secret_here

核心となる署名のカプセル化

src/client.js:

const crypto = require('crypto');
const axios = require('axios');
require('dotenv').config();

const API_KEY = process.env.BINANCE_API_KEY;
const SECRET_KEY = process.env.BINANCE_SECRET_KEY;
const BASE_URL = 'https://api.binance.com';

function sign(params) {
  const query = new URLSearchParams(params).toString();
  return crypto
    .createHmac('sha256', SECRET_KEY)
    .update(query)
    .digest('hex');
}

async function request(method, path, params = {}, signed = false) {
  const headers = {};
  if (signed) {
    params.timestamp = Date.now();
    params.recvWindow = 5000;
    params.signature = sign(params);
    headers['X-MBX-APIKEY'] = API_KEY;
  }

  try {
    const config = {
      method,
      url: `${BASE_URL}${path}`,
      headers,
      timeout: 10000,
    };
    if (method === 'GET' || method === 'DELETE') {
      config.params = params;
    } else {
      config.data = new URLSearchParams(params).toString();
      config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    }
    const r = await axios(config);
    return r.data;
  } catch (err) {
    if (err.response) {
      const { code, msg } = err.response.data;
      throw new Error(`Binance ${code}: ${msg}`);
    }
    throw err;
  }
}

module.exports = { request, sign };

アカウントと相場の呼び出し

src/account.js:

const { request } = require('./client');

async function getAccount() {
  return request('GET', '/api/v3/account', {}, true);
}

async function getPrice(symbol) {
  const r = await request('GET', '/api/v3/ticker/price', { symbol });
  return parseFloat(r.price);
}

async function getDepth(symbol, limit = 20) {
  return request('GET', '/api/v3/depth', { symbol, limit });
}

async function placeLimitOrder(symbol, side, quantity, price) {
  return request('POST', '/api/v3/order', {
    symbol,
    side,
    type: 'LIMIT',
    timeInForce: 'GTC',
    quantity,
    price,
  }, true);
}

async function cancelOrder(symbol, orderId) {
  return request('DELETE', '/api/v3/order', { symbol, orderId }, true);
}

module.exports = { getAccount, getPrice, getDepth, placeLimitOrder, cancelOrder };

実行サンプル

index.js:

const { getAccount, getPrice, placeLimitOrder } = require('./src/account');

(async () => {
  try {
    const account = await getAccount();
    const nonZero = account.balances.filter(b => parseFloat(b.free) > 0);
    console.log('非ゼロ残高:');
    nonZero.forEach(b => console.log(`  ${b.asset}: ${b.free}`));

    const btc = await getPrice('BTCUSDT');
    console.log(`BTC 最新価格: $${btc}`);

    // 限価注文を出す(約定を避けるため現在価格の -10% でテスト)
    const testPrice = (btc * 0.9).toFixed(2);
    const order = await placeLimitOrder('BTCUSDT', 'BUY', '0.001', testPrice);
    console.log(`注文 ID ${order.orderId} が作成されました`);
  } catch (e) {
    console.error('失敗:', e.message);
  }
})();

実行:

node index.js

3. node-binance-api を使ったクイック実装

インストール

npm install node-binance-api

使用例

const Binance = require('node-binance-api');

const binance = new Binance().options({
  APIKEY: process.env.BINANCE_API_KEY,
  APISECRET: process.env.BINANCE_SECRET_KEY,
  useServerTime: true,  // サーバー時刻と自動同期
  recvWindow: 10000,
  test: false,  // true でテストネットを有効化
});

// 残高確認
binance.balance((error, balances) => {
  if (error) return console.error(error);
  Object.keys(balances).forEach(asset => {
    const available = parseFloat(balances[asset].available);
    if (available > 0) {
      console.log(`${asset}: ${available}`);
    }
  });
});

// 成行買い
binance.marketBuy('BTCUSDT', 0.001, (error, response) => {
  if (error) return console.error(error.body);
  console.log('成行買い成功:', response);
});

// 指値注文
binance.buy('BTCUSDT', 0.001, 60000, { type: 'LIMIT' }, (error, response) => {
  if (error) return console.error(error.body);
  console.log('指値注文が出されました:', response.orderId);
});

// Promise スタイル
(async () => {
  const ticker = await binance.prices('BTCUSDT');
  console.log('現在価格:', ticker.BTCUSDT);

  const candles = await binance.candlesticks('BTCUSDT', '1h', false, { limit: 100 });
  console.log('直近のローソク足数:', candles.length);
})();

4. binance-api-node (Promise / TypeScript)

インストール

npm install binance-api-node
npm install -D typescript @types/node

TypeScript サンプル

import Binance, { Binance as BinanceClient, OrderType, OrderSide } from 'binance-api-node';

const client: BinanceClient = Binance({
  apiKey: process.env.BINANCE_API_KEY!,
  apiSecret: process.env.BINANCE_SECRET_KEY!,
});

async function main() {
  // 自動型推論付き
  const time = await client.time();
  console.log('サーバー時間:', new Date(time));

  const account = await client.accountInfo();
  const nonZero = account.balances.filter(b => parseFloat(b.free) > 0);
  console.log(`${nonZero.length} 種類の資産を保有中`);

  const depth = await client.book({ symbol: 'BTCUSDT', limit: 20 });
  console.log(`买気配: ${depth.bids[0].price}, 売気配: ${depth.asks[0].price}`);

  // 型チェック付きの注文
  const order = await client.order({
    symbol: 'BTCUSDT',
    side: OrderSide.BUY,
    type: OrderType.LIMIT,
    timeInForce: 'GTC',
    quantity: '0.001',
    price: '60000.00',
  });
  console.log('注文 ID:', order.orderId);
}

main().catch(console.error);

5. WebSocket リアルタイム購読 (ws ライブラリ)

const WebSocket = require('ws');

function subscribeTickers(symbols) {
  const streams = symbols.map(s => `${s.toLowerCase()}@ticker`).join('/');
  const url = `wss://stream.binance.com:9443/stream?streams=${streams}`;

  function connect() {
    const ws = new WebSocket(url);

    ws.on('open', () => console.log(`${symbols.length} 個の通貨ペアを購読開始`));

    ws.on('message', (raw) => {
      const { stream, data } = JSON.parse(raw);
      console.log(`${data.s}: 最新価格 ${data.c}, 24h 変動率 ${data.P}%`);
    });

    ws.on('pong', () => console.log('pong 受信'));

    ws.on('close', () => {
      console.log('接続が切断されました。5秒後に再接続します。');
      setTimeout(connect, 5000);
    });

    ws.on('error', (err) => console.error('WS エラー:', err.message));

    // 3分ごとに ping を送信して接続を維持
    setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) ws.ping();
    }, 180000);
  }

  connect();
}

subscribeTickers(['BTCUSDT', 'ETHUSDT', 'BNBUSDT', 'SOLUSDT']);

6. 先物(Futures)API の Node.js 実装例

const crypto = require('crypto');
const axios = require('axios');

const FAPI = 'https://fapi.binance.com';

function signFutures(params, secret) {
  const query = new URLSearchParams(params).toString();
  return crypto.createHmac('sha256', secret).update(query).digest('hex');
}

async function futuresPlaceOrder(apiKey, secret, symbol, side, quantity, price) {
  const params = {
    symbol,
    side,
    type: 'LIMIT',
    timeInForce: 'GTC',
    quantity: quantity.toString(),
    price: price.toString(),
    timestamp: Date.now(),
  };
  params.signature = signFutures(params, secret);

  const r = await axios.post(
    `${FAPI}/fapi/v1/order`,
    new URLSearchParams(params).toString(),
    {
      headers: {
        'X-MBX-APIKEY': apiKey,
        'Content-Type': 'application/x-www-form-urlencoded',
      },
    }
  );
  return r.data;
}

async function futuresSetLeverage(apiKey, secret, symbol, leverage) {
  const params = { symbol, leverage, timestamp: Date.now() };
  params.signature = signFutures(params, secret);

  const r = await axios.post(
    `${FAPI}/fapi/v1/leverage`,
    new URLSearchParams(params).toString(),
    { headers: { 'X-MBX-APIKEY': apiKey } }
  );
  return r.data;
}

7. よくある質問 FAQ

Q1: Node.js の Date.now() の精度は十分ですか?

A: 十分です。Node.js の Date.now() はミリ秒精度のタイムスタンプ(13桁)を返します。バイナンス API はミリ秒単位を要求するため、完全に適合します。ただし、コンテナ環境ではホストマシンの時計が正確であることを確認してください(chronyd や systemd-timesyncd の使用を推奨)。

Q2: axios と node-fetch、バイナンス API にはどちらが適していますか?

A: axios はデフォルトの挙動が REST に適しています(自動 JSON パース、エラー再試行、コネクションプール)。node-fetch(Node 18+ のネイティブ fetch)はより軽量ですが、エラーハンドリングを手動で行う必要があります。高頻度取引では、axios よりも 30% ほどパフォーマンスが高い undici やネイティブの http.Agent を推奨します

Q3: TypeScript で as any を避けるにはどうすればよいですか?

A: 完全な型定義を備えた binance-api-node を使用するか、公式の OpenAPI 仕様に基づいて openapi-typescript で型を自動生成してください。request<any> のような汎用的なカプセル化は避けるべきです。

Q4: pm2 でデーモン化する際の注意点は?

A: WebSocket 接続が失われても Node のイベントループは終了しないため、pm2 は自動的に再起動しません。コード内で再接続ロジックを実装してください(第5セクション参照)。また、メモリリーク防止のために pm2 で max_memory_restart: '500M' を設定することをお勧めします。

Q5: Node.js でレート制限を行うには?

A: bottleneck ライブラリを使用してください:

const Bottleneck = require('bottleneck');
const limiter = new Bottleneck({
  minTime: 10,        // 最小 10ms 間隔
  maxConcurrent: 20,  // 最大 20 並列
});
const wrappedGet = limiter.wrap(axios.get);

Node.js での実装を確認したら、カテゴリナビ に戻り、「API連携」カテゴリから他言語の SDK チュートリアルをご覧ください。

引き続き閲覧

バイナンスの利用でまだ疑問がありますか?カテゴリページに戻って同じテーマの他のガイドを探しましょう。

カテゴリナビ

関連ガイド

バイナンスAPIの申請方法:APIキー取得と署名生成の完全ガイド 2026-04-14 バイナンス現物API(Spot API)の使い方:ゼロから最初の注文まで、実行可能なサンプルコード 2026-04-14 バイナンスの Futures と Spot API の違いは?エンドポイント・パラメータ・ウェイトの比較 2026-04-14 バイナンスAPIでIP制限を避けるには?レート制限とウェイト計算の仕組みを解説 2026-04-14