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:
@@ -0,0 +1,77 @@
|
||||
import { logger } from "../utils/logger";
|
||||
import { AppDataSource } from "../db/data-source";
|
||||
import { Exchange } from "../db/entities/exchange.entity";
|
||||
import { TradingPair } from "../db/entities/trading-pair.entity";
|
||||
|
||||
interface PairSeed {
|
||||
symbol: string;
|
||||
baseAsset: string;
|
||||
quoteAsset: string;
|
||||
}
|
||||
|
||||
const PAIRS: PairSeed[] = [
|
||||
{ symbol: "BTCUSDT", baseAsset: "BTC", quoteAsset: "USDT" },
|
||||
{ symbol: "ETHUSDT", baseAsset: "ETH", quoteAsset: "USDT" },
|
||||
];
|
||||
|
||||
async function run(): Promise<void> {
|
||||
logger.info("Seeding trading pairs...");
|
||||
|
||||
const exchangeRepo = AppDataSource.getRepository(Exchange);
|
||||
const pairRepo = AppDataSource.getRepository(TradingPair);
|
||||
|
||||
// 1. 确保 binance 交易所存在
|
||||
let exchange = await exchangeRepo.findOne({ where: { name: "binance" } });
|
||||
if (!exchange) {
|
||||
exchange = exchangeRepo.create({
|
||||
name: "binance",
|
||||
label: "Binance",
|
||||
enabled: true,
|
||||
});
|
||||
await exchangeRepo.save(exchange);
|
||||
logger.info("Created exchange: binance");
|
||||
} else {
|
||||
logger.info("Exchange already exists: binance");
|
||||
}
|
||||
|
||||
// 2. 逐个插入交易对(跳过已存在的)
|
||||
let created = 0;
|
||||
let skipped = 0;
|
||||
|
||||
for (const seed of PAIRS) {
|
||||
const existing = await pairRepo.findOne({
|
||||
where: {
|
||||
exchange: { id: exchange.id },
|
||||
symbol: seed.symbol,
|
||||
},
|
||||
});
|
||||
|
||||
if (existing) {
|
||||
logger.info({ symbol: seed.symbol }, "Trading pair already exists, skipping");
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const pair = pairRepo.create({
|
||||
exchange,
|
||||
symbol: seed.symbol,
|
||||
base_asset: seed.baseAsset,
|
||||
quote_asset: seed.quoteAsset,
|
||||
active: true,
|
||||
kline_synthesis_enabled: true,
|
||||
});
|
||||
|
||||
await pairRepo.save(pair);
|
||||
created++;
|
||||
logger.info({ symbol: seed.symbol, id: pair.id }, "Created trading pair");
|
||||
}
|
||||
|
||||
logger.info({ created, skipped, total: PAIRS.length }, "Seeding complete");
|
||||
await AppDataSource.destroy();
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
run().catch((err) => {
|
||||
logger.error({ err }, "Seeding failed");
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user