5e385547c7
- 废弃旧 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/ 运行脚本
78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
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);
|
|
});
|