市场数据概览 (Market Data Overview)
ZTDX 提供全面的市场数据 API,所有市场数据接口都是公开的,无需身份验证即可访问。
数据类型
实时数据
| 数据类型 | 更新频率 | 接口 | WebSocket |
|---|---|---|---|
| Ticker (行情) | 实时 | /api/v1/ticker/:symbol | ✅ |
| Orderbook (订单簿) | 实时 | /api/v1/orderbook/:symbol | ✅ |
| Trades (最新成交) | 实时 | /api/v1/trades/:symbol | ✅ |
| Index Price (指数价格) | 10秒 | /api/v1/index-price/:symbol | ❌ |
| Mark Price (标记价格) | 10秒 | /api/v1/mark-price/:symbol | ❌ |
历史数据
| 数据类型 | 时间范围 | 接口 | WebSocket |
|---|---|---|---|
| Klines (K线) | 不限 | /api/v1/klines/:symbol | ✅ |
| Historical Trades | 30天 | /api/v1/trades/:symbol/history | ❌ |
| Funding Rate History | 不限 | /api/v1/funding-rate/history | ❌ |
市场信息
| 数据类型 | 更新频率 | 接口 |
|---|---|---|
| Markets (交易对列表) | 静态 | /api/v1/markets |
| Market Config | 静态 | /api/v1/markets/:symbol/config |
| Insurance Fund | 10分钟 | /api/v1/insurance-fund/:symbol |
数据架构
价格体系
ZTDX 使用多层价格机制确保公平和稳定:
graph TD
A[CEX价格源] --> B[指数价格 Index Price]
B --> C[标记价格 Mark Price]
C --> D[清算价格计算]
C --> E[资金费率计算]
F[订单簿] --> G[最新成交价 Last Price]
G --> H[行情展示]
1. 指数价格 (Index Price)
从多个中心化交易所聚合计算的价格,用作参考:
指数价格 = Σ(交易所价格 × 权重) / Σ权重
示例 (BTCUSDT):
Binance: 65000 (权重: 40%)
Coinbase: 65100 (权重: 30%)
OKX: 64950 (权重: 30%)
指数价格 = (65000×0.4 + 65100×0.3 + 64950×0.3) / 1.0 = 65015
2. 标记价格 (Mark Price)
用于计算未实现盈亏和清算价格:
标记价格 = 指数价格 × (1 + 基差率)
基差率 = EMA(最新成交价 - 指数价格, 周期=8小时)
为什么使用标记价格?
- 防止操纵:避免短期价格波动导致不公平清算
- 平滑机制:使用指数价格平滑市场异常
- 保护用户:减少因流动性不足导致的意外清算
3. 最新成交价 (Last Price)
实际交易发生的价格,用于:
- 行情展示
- 限价单触发判断
- 用户界面展示
API 端点概览
1. 交易对列表
获取所有支持的交易对及其配置。
GET /api/v1/markets
响应示例:
{
"markets": [
{
"symbol": "BTCUSDT",
"base_currency": "BTC",
"quote_currency": "USDT",
"status": "trading",
"min_order_size": "0.001",
"max_order_size": "100.0",
"price_precision": 2,
"amount_precision": 8,
"max_leverage": 50,
"maintenance_margin_rate": "0.005"
}
]
}
2. 24小时行情
获取交易对的24小时统计数据。
GET /api/v1/ticker/:symbol
响应示例:
{
"symbol": "BTCUSDT",
"last_price": "65000.00",
"bid_price": "64995.00",
"ask_price": "65005.00",
"high_24h": "66000.00",
"low_24h": "64000.00",
"volume_24h": "1234.56",
"quote_volume_24h": "80125000.00",
"price_change_24h": "1500.00",
"price_change_percent_24h": "2.36",
"open_interest": "50000.00",
"funding_rate": "0.0001",
"next_funding_time": 1704067200,
"index_price": "65015.00",
"mark_price": "65010.00"
}
3. 订单簿深度
获取买卖盘深度数据。
GET /api/v1/orderbook/:symbol?depth=20
响应示例:
{
"symbol": "BTCUSDT",
"bids": [
["64995.00", "1.5"],
["64990.00", "2.3"]
],
"asks": [
["65005.00", "1.2"],
["65010.00", "3.1"]
],
"timestamp": 1704067200000
}
4. 最新成交
获取最近的成交记录。
GET /api/v1/trades/:symbol?limit=50
响应示例:
{
"symbol": "BTCUSDT",
"trades": [
{
"id": "12345678",
"price": "65000.00",
"amount": "0.1",
"side": "buy",
"timestamp": 1704067200000
}
]
}
5. K线数据
获取历史K线数据。
GET /api/v1/klines/:symbol?period=1h&limit=100
支持的周期: 1m, 5m, 15m, 1h, 4h, D, W, M
响应示例:
{
"symbol": "BTCUSDT",
"period": "1h",
"klines": [
{
"timestamp": 1704067200000,
"open": "65000.00",
"high": "65500.00",
"low": "64800.00",
"close": "65200.00",
"volume": "100.5",
"quote_volume": "6520000.00"
}
]
}
数据质量
数据来源
| 数据类型 | 来源 | 验证机制 |
|---|---|---|
| 交易数据 | 内部撮合引擎 | 实时生成 |
| 指数价格 | CEX聚合 | 多源验证 |
| K线数据 | 实时聚合 | 历史回填 |
数据精度
| 项目 | 精度 |
|---|---|
| 价格 | 小数点后 2-8 位 |
| 数量 | 小数点后 8 位 |
| 时间戳 | 毫秒级 |
| 百分比 | 小数点后 2 位 |
延迟保证
| 接口类型 | 延迟 |
|---|---|
| REST API | < 50ms (P99) |
| WebSocket 推送 | < 10ms |
| 指数价格更新 | 10秒 |
| 标记价格更新 | 10秒 |
WebSocket 订阅
所有实时数据都支持 WebSocket 订阅,获取更低延迟的数据推送。
订阅Ticker
ws.send(JSON.stringify({
action: 'subscribe',
channel: 'ticker',
symbol: 'BTCUSDT'
}));
订阅订单簿
ws.send(JSON.stringify({
action: 'subscribe',
channel: 'orderbook',
symbol: 'BTCUSDT',
depth: 20
}));
订阅K线
ws.send(JSON.stringify({
action: 'subscribe',
channel: 'klines',
symbol: 'BTCUSDT',
period: '1m'
}));
使用示例
JavaScript
// 获取多个交易对的行情
async function getMultipleTickers(symbols) {
const tickers = await Promise.all(
symbols.map(symbol =>
fetch(`/api/v1/ticker/${symbol}`).then(r => r.json())
)
);
return tickers.map(ticker => ({
symbol: ticker.symbol,
price: ticker.last_price,
change24h: ticker.price_change_percent_24h
}));
}
// 使用
const tickers = await getMultipleTickers(['BTCUSDT', 'ETHUSDT', 'SOLUSDT']);
console.log(tickers);
Python
import requests
def get_market_overview():
# 获取所有市场
markets = requests.get('/api/v1/markets').json()['markets']
# 获取每个市场的行情
tickers = []
for market in markets:
ticker = requests.get(f"/api/v1/ticker/{market['symbol']}").json()
tickers.append({
'symbol': market['symbol'],
'price': float(ticker['last_price']),
'change_24h': float(ticker['price_change_percent_24h']),
'volume_24h': float(ticker['volume_24h'])
})
# 按成交量排序
tickers.sort(key=lambda x: x['volume_24h'], reverse=True)
return tickers
# 使用
top_markets = get_market_overview()[:5]
for ticker in top_markets:
print(f"{ticker['symbol']}: ${ticker['price']} ({ticker['change_24h']:+.2f}%)")
数据可视化
TradingView 集成
ZTDX 提供 TradingView 兼容的数据格式:
// TradingView Datafeed 示例
const datafeed = {
onReady: (callback) => {
callback({
supported_resolutions: ['1', '5', '15', '60', '240', 'D', 'W', 'M'],
supports_marks: false,
supports_timescale_marks: false
});
},
getBars: async (symbolInfo, resolution, periodParams, onResult, onError) => {
const period = resolutionMap[resolution]; // '1' -> '1m'
const klines = await fetch(
`/api/v1/klines/${symbolInfo.name}?period=${period}&limit=300`
).then(r => r.json());
const bars = klines.klines.map(k => ({
time: k.timestamp,
open: parseFloat(k.open),
high: parseFloat(k.high),
low: parseFloat(k.low),
close: parseFloat(k.close),
volume: parseFloat(k.volume)
}));
onResult(bars, { noData: false });
}
};
频率限制
| 接口类型 | 限制 | 窗口期 |
|---|---|---|
| 公开接口 | 100 次/分钟 | IP 级别 |
| WebSocket 连接 | 10 个/IP | 无限期 |
| WebSocket 订阅 | 50 个/连接 | 无限期 |
超过限制将返回 429 Too Many Requests
最佳实践
1. 使用 WebSocket 而非轮询
// ❌ 不推荐:轮询
setInterval(() => {
fetch('/api/v1/ticker/BTCUSDT').then(updateUI);
}, 1000);
// ✅ 推荐:WebSocket
ws.subscribe('ticker', 'BTCUSDT');
ws.on('ticker', updateUI);
2. 批量获取数据
// ❌ 不推荐:多次请求
for (const symbol of symbols) {
const ticker = await getTicker(symbol);
}
// ✅ 推荐:并行请求
const tickers = await Promise.all(
symbols.map(symbol => getTicker(symbol))
);
3. 缓存静态数据
// 市场配置很少变化,可以缓存
const marketsCache = new Map();
async function getMarketConfig(symbol) {
if (!marketsCache.has(symbol)) {
const config = await fetch(`/api/v1/markets/${symbol}/config`)
.then(r => r.json());
marketsCache.set(symbol, config);
}
return marketsCache.get(symbol);
}
4. 处理时间戳
// K线时间戳对齐到周期开始
function alignTimestamp(timestamp, period) {
const ms = {
'1m': 60000,
'5m': 300000,
'15m': 900000,
'1h': 3600000,
'4h': 14400000,
'D': 86400000
}[period];
return Math.floor(timestamp / ms) * ms;
}
数据完整性
历史数据回填
ZTDX 确保历史数据的完整性:
- ✅ K线数据定期从Binance等CEX回填
- ✅ 缺失数据自动修复
- ✅ 数据异常检测和修正
数据验证
// 验证K线数据
function validateKline(kline) {
return (
kline.high >= kline.low &&
kline.high >= kline.open &&
kline.high >= kline.close &&
kline.low <= kline.open &&
kline.low <= kline.close &&
parseFloat(kline.volume) >= 0
);
}