Files
trade/data/types/base.ts
T
Rekey 5e385547c7 refactor(data): 重构交易所适配器,修复 Kline 实体复合主键
- 废弃旧 adapter 体系 (base/binance/types.ts),新增 base_rest/rest.ts
  基于 Binance 官方 SDK 实现 REST K 线拉取
- Kline 实体改为四列复合主键 (exchange/symbol/interval/time),
  修复单列 time PK 导致的跨 symbol 写入冲突
- 新增 filterConsecutive():K 线连续性过滤,首缺口截断策略
- 新增 service/kline.ts:批量 UPSERT K 线入库
- 新增 types/ 共享类型定义、example/ 示例、run/ 运行脚本
2026-06-08 18:18:16 +08:00

291 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// types.ts — 统一行情数据类型定义与 MarketDataFeed 接口
// ============================================================
// 所有交易所适配器共享的数据结构和接口契约。
// 适配器负责将交易所原生数据格式转换为以下标准化类型。
//
// 设计原则:
// - 字段语义与 Binance/OKX/Bybit 通用概念对齐
// - 时间戳统一使用 Unix 毫秒(number),便于排序和计算
// - 价格/数量使用 number 类型(JavaScript 64-bit float),
// 对精度敏感场景(如 orderbook 快照)保留原始字符串
// ============================================================
import type { Observable } from "rxjs";
import type { KlineInterval } from "./kline";
// ============================================================
// 标准化行情数据结构
// ============================================================
/** 24 小时滚动 Ticker 统计 */
export interface Ticker {
/** 交易所标识 */
exchange: string;
/** 交易对符号(大写,如 BTCUSDT) */
symbol: string;
/** 最新成交价 */
lastPrice: number;
/** 24h 开盘价 */
openPrice: number;
/** 24h 最高价 */
highPrice: number;
/** 24h 最低价 */
lowPrice: number;
/** 24h 成交量(base 币种) */
volume: number;
/** 24h 成交额(quote 币种) */
quoteVolume: number;
/** 24h 价格变化 */
priceChange: number;
/** 24h 价格变化百分比(0.05 = 5% */
priceChangePercent: number;
/** 买一价 */
bidPrice: number;
/** 买一量 */
bidQty: number;
/** 卖一价 */
askPrice: number;
/** 卖一量 */
askQty: number;
/** 事件发生时间(Unix ms */
eventTime: number;
/** 交易所收盘时间(Unix ms,用于判断 K 线是否闭合) */
closeTime: number;
}
/** 逐笔成交 */
export interface Trade {
/** 交易所标识 */
exchange: string;
/** 交易对符号 */
symbol: string;
/** 成交价 */
price: number;
/** 成交数量(base 币种) */
amount: number;
/** 成交额(quote 币种 = price × amount */
quoteAmount: number;
/** 成交时间(Unix ms */
timestamp: number;
/** 买方是否为挂单方(true = 主动卖出 / taker sell */
isBuyerMaker: boolean;
/** 交易所成交 ID(可能为字符串,如 Binance tradeId 为 bigint */
tradeId: string;
}
/** 订单簿深度快照 */
export interface OrderBook {
/** 交易所标识 */
exchange: string;
/** 交易对符号 */
symbol: string;
/** 买单列表 [[price, qty], ...],按价格降序(买一在前) */
bids: [number, number][];
/** 卖单列表 [[price, qty], ...],按价格升序(卖一在前) */
asks: [number, number][];
/** 上次更新 ID */
lastUpdateId: number;
/** 事件发生时间(Unix ms */
eventTime: number;
}
/** 标准化 K 线(OHLCV */
export interface Kline {
/** 交易所标识 */
exchange: string;
/** 交易对符号 */
symbol: string;
/** K 线周期 */
interval: KlineInterval;
/** 开盘时间(Unix ms */
openTime: number;
/** 收盘时间(Unix ms */
closeTime: number;
/** 开盘价 */
open: string;
/** 最高价 */
high: string;
/** 最低价 */
low: string;
/** 收盘价 */
close: string;
/** 成交量(base 币种) */
volume: string;
/** 成交额(quote 币种) */
quoteVolume: string;
/** 主动买入成交量(base 币种) */
takerBuyBaseVol: string;
/** 主动买入成交额(quote 币种) */
takerBuyQuoteVol: string;
/** 成交笔数 */
tradeCount: string;
/** 该 K 线是否已关闭(不再更新) */
isClosed: boolean;
}
/** K 线增量更新(仅推送最新一根 OHLCV 变化) */
export interface KlineDelta {
exchange: string;
symbol: string;
interval: KlineInterval;
openTime: number;
closeTime: number;
open: number;
high: number;
low: number;
close: number;
volume: number;
isClosed: boolean;
}
// ============================================================
// WebSocket 连接状态
// ============================================================
/** 连接状态枚举 */
export type ConnectionState =
| "disconnected"
| "connecting"
| "connected"
| "error";
// ============================================================
// REST 客户端配置
// ============================================================
/** REST 客户端通用配置(各交易所 SDK 共用) */
export interface RestClientConfig {
/** REST API 请求冷却时间(毫秒),默认 200 */
restRateLimitMs: number;
/** 单次请求默认拉取条数 */
defaultLimit: number;
}
/** 默认 REST 客户端配置 */
export const DEFAULT_REST_CONFIG: RestClientConfig = {
restRateLimitMs: 200,
defaultLimit: 500,
};
// ============================================================
// 适配器配置(含 WebSocket 重连)
// ============================================================
/** 交易所适配器完整配置(REST + WebSocket */
export interface AdapterConfig extends RestClientConfig {
/** 指数退避重连基数(毫秒),默认 3000 */
reconnectBaseDelayMs: number;
/** 最大重连次数,默认 10 */
maxReconnectAttempts: number;
}
/** 默认适配器配置 */
export const DEFAULT_ADAPTER_CONFIG: AdapterConfig = {
...DEFAULT_REST_CONFIG,
reconnectBaseDelayMs: 3000,
maxReconnectAttempts: 10,
};
// ============================================================
// MarketDataFeed 接口 —— 所有交易所适配器必须实现
// ============================================================
/**
* 统一行情数据源接口。
*
* 每个交易所适配器实现此接口,向上层管道暴露标准化数据流。
* 使用 RxJS Observable 作为统一推送机制,pipeline 层可自由
* 组合、过滤、分流各交易所数据。
*/
export interface MarketDataFeed {
/** 交易所标识(如 "binance" */
readonly exchange: string;
/** 当前连接状态 */
readonly connectionState: ConnectionState;
/** 建立 WebSocket 连接 */
connect(): Promise<void>;
/** 断开连接 */
disconnect(): Promise<void>;
/**
* 订阅 24h 滚动 Ticker 流。
* 每笔成交触发推送(Binance: <symbol>@ticker)。
*/
subscribeTicker(symbols: string[]): Observable<Ticker>;
/**
* 订阅逐笔成交流。
* 实时推送每笔撮合成交(Binance: <symbol>@trade)。
*/
subscribeTrade(symbols: string[]): Observable<Trade>;
/**
* 订阅订单簿深度。
* depth 参数指定档位(如 5/10/20),默认 20。
*/
subscribeOrderbook(symbol: string, depth?: number): Observable<OrderBook>;
/**
* REST 拉取历史 K 线(用于补齐缺失数据或回测)。
*
* @param symbol - 交易对符号
* @param interval - K 线周期
* @param startTime - 起始时间(Unix ms
* @param endTime - 结束时间(Unix ms
* @param limit - 最大返回条数(默认 500)
* @returns 标准化 K 线数组,按时间升序
*/
fetchKlines(
symbol: string,
interval: KlineInterval,
startTime: number,
endTime: number,
limit?: number,
): Promise<Kline[]>;
/**
* 获取交易所交易对信息(用于自动注册到 trading_pairs 表)。
* 返回标准化后的交易对元数据。
*/
fetchMarkets(): Promise<MarketInfo[]>;
}
/** 交易对元信息(从交易所 REST API 获取) */
export interface MarketInfo {
symbol: string;
baseAsset: string;
quoteAsset: string;
pricePrecision: number;
quantityPrecision: number;
minQty?: number;
stepSize?: number;
minNotional?: number;
}
// ============================================================
// 工具类型
// ============================================================
/** Binance WebSocket 原始 K 线数据(kline 事件中的 k 字段) */
export interface BinanceRawKline {
t: number; // K 线开始时间
T: number; // K 线结束时间
s: string; // 交易对
i: string; // 周期
o: string; // 开盘价
h: string; // 最高价
l: string; // 最低价
c: string; // 收盘价
v: string; // 成交量
n: number; // 成交笔数
x: boolean; // 是否已关闭
q: string; // 成交额
V: string; // 主动买入成交量
Q: string; // 主动买入成交额
}