MarketDataCenterTerminal加密货币外汇期货全球股指美股港股日股A 股

通过 API 集成 — 5 步演练

真实拉数据 + 代码片段。把你的 api key 填上面,每步底下的 fetch / WebSocket 代码直接复制到自己项目。

1

列出可见市场

GET /v1/markets · 首屏渲染市场 Tab

未运行
代码(复制即用)
fetch
const apiKey = "mdc_live_xxx";

const res = await fetch("/api/v1/markets", {
  headers: { Authorization: `Bearer ${apiKey}` },
});
const markets = await res.json();
// markets: Array<{ code, label, emoji, count, subMarkets? }>
真实数据
点击右上"运行"调用 API,结果会显示在这里
2

拉某市场热门榜

GET /v1/popular · 含 lastPrice / changePct / marketCap / volume24h

未运行
代码(复制即用)
fetch
const res = await fetch(
  "/api/v1/popular?market=us&limit=10",
  { headers: { Authorization: `Bearer ${apiKey}` } },
);
const rows = await res.json();
// rows: Array<{
//   rank, symbol, name, lastPrice, changePct,
//   marketCap, volume24h, logoUrl
// }>
真实数据
点击右上"运行"调用 API,结果会显示在这里
3

按关键字搜标的

GET /v1/symbols?q=... · 做搜索框 / 实例选择器

未运行
代码(复制即用)
fetch
const res = await fetch(
  "/api/v1/symbols?q=apple&limit=8",
  { headers: { Authorization: `Bearer ${apiKey}` } },
);
const symbols = await res.json();
// symbols: Array<{ symbol, name, market, assetType, marketCap, volume24h, logoUrl }>
真实数据
点击右上"运行"调用 API,结果会显示在这里
4

拉历史 K 线

GET /v1/kline · OHLCV 数组,直接喂图表库

未运行
代码(复制即用)
fetch
const res = await fetch(
  "/api/v1/kline?symbol=AAPL.US&tf=1d&limit=60",
  { headers: { Authorization: `Bearer ${apiKey}` } },
);
const { candles } = await res.json();
// candles: [{ timestamp, open, high, low, close, volume, preClose, increase, ratio }, ...]
// timestamp 为秒级时间戳,按 timestamp 升序,最后一根可能未收盘
// 直接喂 lightweight-charts / klinecharts
真实数据
点击右上"运行"调用 API,结果会显示在这里
5

WebSocket 订阅实时报价

WS /v1/stream · 订阅 topic 收 quote / bar 推送

未运行
代码(复制即用)
websocket
// ───── 基础连接 + 订阅 ─────
const apiKey = "mdc_live_xxx";
const ws = new WebSocket(`/api/v1/stream?api_key=${encodeURIComponent(apiKey)}`);
ws.onopen = () => {
  ws.send(JSON.stringify({ action: "subscribe", topics: ["BTCUSDT:quote"] }));
};

// 心跳:每 30s 发 ping,避免空闲 5min 被踢
setInterval(() => ws.readyState === 1 && ws.send('{"action":"ping"}'), 30000);

// ───── K 线图 + 实时价格条 同步推荐写法 ─────
// 同时订 SYMBOL:quote (高频) + SYMBOL:<tf> (画图),用 lastBarSeen 桥接:
let lastBarSeen = null;
const bucketStartTs = (ts, tf) => {
  // ts 为秒级时间戳。这里简化版(tf='1m')
  const TF_SEC = { '1m':60, '5m':300, '1h':3600, '1d':86400 };
  return Math.floor(ts / TF_SEC[tf]) * TF_SEC[tf];
};

ws.onmessage = (ev) => {
  const msg = JSON.parse(ev.data);

  if (msg.type === "quote") {
    // 顶部价格条:高频更新 (~100ms/条)
    setPrice(msg.lastPrice);
    setChangePct(msg.changePct);

    // K 线最右那根活跃 bar:用 lastPrice 同步 c,扩展 h/l —— 跟价格条永远一致
    const ts = bucketStartTs(msg.ts, currentTf);
    if (lastBarSeen && lastBarSeen.ts === ts) {
      lastBarSeen = {
        ...lastBarSeen,
        c: msg.lastPrice,
        h: Math.max(lastBarSeen.h, msg.lastPrice),
        l: Math.min(lastBarSeen.l, msg.lastPrice),
      };
    } else {
      lastBarSeen = { ts, o: msg.lastPrice, h: msg.lastPrice, l: msg.lastPrice, c: msg.lastPrice, v: 0 };
    }
    chart.update(lastBarSeen);  // lightweight-charts / klinecharts
  }

  if (msg.type === "bar") {
    // bar 推送:完整 OHLV 覆盖,记录 ref 让下一条 quote 能扩展 h/l
    lastBarSeen = { ts: msg.ts, o: msg.o, h: msg.h, l: msg.l, c: msg.c, v: msg.v };
    chart.update(lastBarSeen);
  }

  if (msg.type === "error") {
    // 按 code switch,不要按 message 文本判断
    switch (msg.code) {
      case "AUTH_REQUIRED":   /* 先 auth 或连接时带 api_key */ break;
      case "AUTH_INVALID":    /* 重新拿 api_key */ break;
      case "INVALID_JSON":    /* 检查序列化 */ break;
      case "INVALID_MESSAGE": /* 检查 action 字段 */ break;
      default:                console.error(msg);
    }
  }
};
真实数据
○ 未连接0 条推送
等待推送数据…
API 完整字段说明 → admin /api-explorer · 5 个步骤的源码: apps/web/app/integration/page.tsx