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/ 运行脚本
This commit is contained in:
Rekey
2026-06-08 18:18:16 +08:00
parent 85a0031a78
commit 5e385547c7
16 changed files with 829 additions and 1043 deletions
+44
View File
@@ -0,0 +1,44 @@
import { logger } from "../utils/logger";
import { getAllPairs, updatePairLastBackfillTime } from '../service/pair';
import { upsertOrUpdateKlines } from "../service/kline";
import { Client } from '../exchanges/rest';
function getNowMinuteMS() {
const minuteMS = 1000 * 60;
return Math.floor(Date.now() / minuteMS) * minuteMS
}
const allPairs = await getAllPairs();
for (const pair of allPairs) {
const client = new Client("binance");
let lastBackfillTime = pair.last_backfill_time.getTime();
try {
while (lastBackfillTime < getNowMinuteMS()) {
console.log('lastBackfillTime', lastBackfillTime);
const klines = await client.fetchKlines(
pair.symbol,
pair.kline_interval,
lastBackfillTime,
500
);
console.log(`拉取到 ${klines.length} 条 K 线`);
if (klines.length > 0) {
await upsertOrUpdateKlines(klines);
const lastK = klines[klines.length - 1];
if (lastK) {
await updatePairLastBackfillTime(lastK?.symbol, new Date(lastK.openTime));
if (lastBackfillTime === lastK.openTime) {
break;
}
lastBackfillTime = lastK.openTime;
}
}
await new Promise((resolve) => {
setTimeout(resolve, Math.random() * 1000);
});
}
} catch (err) {
console.error("拉取失败:", err);
}
}