Files
trade/data/exchanges/base_rest.ts
T
Rekey b4c7636731 添加 USDT-M 合约数据支持(配置层 + 清理多余字段)
- 配置层:env.yaml 新增 binance_futures API Key 段,validators + config 同步
- 清理 TradingPair 实体:删除 kline_interval、kline_intervals、kline_synthesis_enabled
- 删除 fetchKlines 系列函数的 interval 参数,硬编码为 1m
- 更新 SQL seed 数据、example、base_rest 接口、types 接口
- 新增 AGENTS/08-boundaries.md 执行纪律
- 新增 PLAN-add-futures-data.md 方案文档
2026-06-15 23:24:21 +08:00

108 lines
4.1 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.
// ============================================================
// base.ts — REST 客户端抽象基类
// ============================================================
// 各交易所适配器继承此类,复用 REST 请求限流、重试等通用逻辑。
// 子类通过注入各交易所原生 SDKbinance / okx / bybit ...
// 实现具体的数据拉取,无需依赖 ccxt。
//
// 子类只需实现:
// - fetchKlines() — 历史 K 线拉取(基于目标交易所 SDK)
// - fetchMarkets() — 交易对元数据拉取(用于自动注册交易对)
//
// WebSocket 实时行情由各适配器自行管理,不在此基类范围内。
// ============================================================
import { logger } from "../utils/logger";
import type { Kline, MarketInfo, RestClientConfig } from "../types";
import { DEFAULT_REST_CONFIG } from "../types/base";
// ============================================================
// 工具:异步 sleep
// ============================================================
/** 返回一个在 ms 毫秒后 resolve 的 Promise */
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
// ============================================================
// BaseRestClient
// ============================================================
export abstract class BaseRestClient {
/** 交易所标识(子类必须覆盖) */
abstract readonly exchange: string;
/** REST 客户端配置(可在子类构造函数中覆盖默认值) */
protected readonly config: RestClientConfig;
/** REST 请求节流 Mapkey → 上次请求时间戳) */
private lastRestFetch = new Map<string, number>();
// ============================================================
// 构造函数
// ============================================================
constructor(config: Partial<RestClientConfig> = {}) {
this.config = { ...DEFAULT_REST_CONFIG, ...config };
}
// ============================================================
// 限流工具
// ============================================================
/**
* 对同一 key 的 REST 请求进行冷却节流。
* 若距离上次请求不足 restRateLimitMs,自动等待剩余时间。
*
* @param key - 节流标识(如 `${symbol}:${interval}`
*/
protected async throttle(key: string): Promise<void> {
const lastFetch = this.lastRestFetch.get(key) ?? 0;
const elapsed = Date.now() - lastFetch;
if (elapsed < this.config.restRateLimitMs) {
const waitMs = this.config.restRateLimitMs - elapsed;
logger.debug(
{ exchange: this.exchange, key, waitMs },
`[${this.exchange}] REST 限流等待 ${waitMs}ms`,
);
await sleep(waitMs);
}
this.lastRestFetch.set(key, Date.now());
}
// ============================================================
// 抽象方法 —— 子类必须使用各自的交易所 SDK 实现
// ============================================================
/**
* 拉取 1m 历史 K 线数据(REST)。
*
* 子类负责:
* 1. 调用交易所原生 SDK 的 K 线接口
* 2. 将原始数据转换为本系统标准化 Kline 结构
* 3. 处理分页逻辑(若时间跨度超过单次请求上限)
*
* @param symbol - 交易对符号(如 BTCUSDT
* @param startTime - 起始时间(Unix ms
* @param endTime - 结束时间(Unix ms
* @param limit - 单次最大条数(默认取自 config.defaultLimit
*/
abstract fetchKlines(
symbol: string,
startTime: number,
endTime: number,
limit?: number,
): Promise<Kline[]>;
/**
* 获取交易所交易对信息(REST)。
*
* 子类负责调用交易所原生 SDK 的 /exchangeInfo 等价接口,
* 并转换为本系统标准化 MarketInfo 结构。
*/
abstract fetchMarkets(): Promise<MarketInfo[]>;
}
export default BaseRestClient;