添加 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 方案文档
This commit is contained in:
Rekey
2026-06-15 23:24:21 +08:00
parent 6708abaf56
commit b4c7636731
13 changed files with 255 additions and 78 deletions
+11 -24
View File
@@ -1,4 +1,4 @@
import { MainClient, type Kline as BinanceRestKline } from "binance";
import { MainClient, type Kline as BinanceRestKline, CoinMClient } from "binance";
import { logger } from "../utils/logger";
import { exchange } from "../config";
@@ -48,7 +48,6 @@ export const KLINE_INTERVAL_MS: Record<KlineInterval, number> = {
function convertBinanceKline(
raw: BinanceRestKline,
symbol: string,
interval: KlineInterval,
): Kline {
const [
openTime,
@@ -68,7 +67,7 @@ function convertBinanceKline(
return {
exchange: "binance",
symbol,
interval,
interval: "1m",
openTime: openTime,
closeTime: closeTime,
open: String(open),
@@ -89,20 +88,18 @@ function convertBinanceKline(
// ============================================================
/**
* 通过 Binance 原生 SDK 拉取 UI K 线并转换为本系统 Kline。
* 通过 Binance 原生 SDK 拉取 1m K 线并转换为本系统 Kline。
*
* getUIKlines 与 getKlines 返回同构的 Kline[] 元组,
* getUIKlines 额外支持 timeZone 参数,适合按交易所时区对齐。
*
* @param symbol - 交易对(如 BTCUSDT
* @param interval - K 线周期
* @param startTime - 起始时间(Unix ms
* @param endTime - 结束时间(Unix ms),可选
* @param limit - 单次拉取条数,默认 500(最大 1000)
*/
async function fetchBinanceKlines(
symbol: string,
interval: KlineInterval,
startTime: number,
endTime?: number,
limit = 500,
@@ -119,15 +116,15 @@ async function fetchBinanceKlines(
const rawKlines = await client.getKlines({
symbol,
interval,
interval: "1m",
startTime,
endTime,
limit: safeLimit,
});
logger.info({
logger.debug({
symbol,
interval,
interval: "1m",
startTime,
endTime,
limit: safeLimit,
@@ -138,13 +135,7 @@ async function fetchBinanceKlines(
}
return filterConsecutive(
rawKlines.map((k, index) => {
// if (index === rawKlines.length - 1) {
// console.log(k);
// }
return convertBinanceKline(k, symbol, interval);
}),
interval,
rawKlines.map((k) => convertBinanceKline(k, symbol)),
);
}
@@ -165,10 +156,7 @@ async function fetchBinanceKlines(
* @param interval - K 线周期,用于查表获取 intervalMs
* @returns 从首条开始严格连续的最大前缀子序列;空数组无缺口时返回完整排序结果
*/
function filterConsecutive(klines: Kline[], interval: KlineInterval) {
// 查表获取当前 K 线周期对应的毫秒数
const intervalMs = KLINE_INTERVAL_MS[interval];
function filterConsecutive(klines: Kline[]) {
// 防御性排序:Binance API 不保证返回顺序,升序排列确保时间单调
const results = klines.sort((a: Kline, b: Kline) => {
return a.openTime - b.openTime;
@@ -222,19 +210,18 @@ export class Client extends BaseRestClient {
}
/**
* 拉取历史 K 线数据,返回标准化 Kline 数组。
* 拉取 1m 历史 K 线数据,返回标准化 Kline 数组。
*
* 根据交易所 ID 分发到各自的 SDK 拉取函数。
* K 线周期固定为 1m,高周期通过 TimescaleDB 连续聚合视图生成。
*
* @param symbol - 交易对符号(如 BTCUSDT
* @param interval - K 线周期
* @param startTime - 起始时间(Unix ms
* @param endTime - 结束时间(Unix ms),可选
* @param limit - 最大返回条数,默认取自 config.defaultLimit
*/
async fetchKlines(
symbol: string,
interval: KlineInterval,
startTime: number,
limit?: number,
endTime?: number,
@@ -242,7 +229,7 @@ export class Client extends BaseRestClient {
const effectiveLimit = limit ?? this.config.defaultLimit;
switch (this.exchange) {
case "binance":
return fetchBinanceKlines(symbol, interval, startTime, endTime, effectiveLimit);
return fetchBinanceKlines(symbol, startTime, endTime, effectiveLimit);
// TODO: 新增交易所在此添加 case
// case "okx":
// return fetchOkxKlines(symbol, interval, startTime, endTime, effectiveLimit);