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/ 运行脚本
112 lines
3.7 KiB
TypeScript
112 lines
3.7 KiB
TypeScript
// ============================================================
|
||
// trading-pair.entity.ts — 交易对配置实体
|
||
// ============================================================
|
||
// 映射到 PostgreSQL trading_pairs 表,存储各交易所的交易对元信息。
|
||
// 数据模块启动时从该表读取 active=true 的交易对列表,
|
||
// 决定 WebSocket 订阅范围和 K 线合成范围。
|
||
//
|
||
// 继承 CommonBaseEntity:id (UUID) / created_at / updated_at
|
||
//
|
||
// 与 TimescaleDB klines 表的关系:
|
||
// klines.symbol → trading_pairs.symbol(逻辑外键,不做 DB 级约束)
|
||
// klines.exchange → exchanges.name(逻辑外键)
|
||
// ============================================================
|
||
|
||
import {
|
||
Entity,
|
||
Column,
|
||
ManyToOne,
|
||
JoinColumn,
|
||
Index,
|
||
} from "typeorm";
|
||
import { Exchange } from "./exchange.entity";
|
||
import { CommonBaseEntity } from "./common.entity";
|
||
|
||
import type { KlineInterval } from '../../types';
|
||
|
||
@Entity("trading_pairs")
|
||
@Index(["exchange", "symbol"], { unique: true }) // 同一交易所下 symbol 唯一
|
||
@Index(["active"]) // 按激活状态快速筛选
|
||
export class TradingPair extends CommonBaseEntity {
|
||
/** 所属交易所 */
|
||
@ManyToOne(() => Exchange, { nullable: false })
|
||
@JoinColumn({ name: "exchange_id" })
|
||
exchange!: Exchange;
|
||
|
||
/** 交易对符号(如 BTCUSDT / ETHUSDT) */
|
||
@Column("varchar", { length: 20 })
|
||
symbol!: string;
|
||
|
||
/** 基础币种(如 BTC) */
|
||
@Column("varchar", { length: 10 })
|
||
base_asset!: string;
|
||
|
||
/** 计价币种(如 USDT) */
|
||
@Column("varchar", { length: 10 })
|
||
quote_asset!: string;
|
||
|
||
/** 价格精度(小数位数) */
|
||
@Column("integer", { default: 10 })
|
||
price_precision!: number;
|
||
|
||
/** 数量精度(小数位数) */
|
||
@Column("integer", { default: 10 })
|
||
quantity_precision!: number;
|
||
|
||
/** 最小下单量 */
|
||
@Column("numeric", { precision: 32, scale: 8, nullable: true })
|
||
min_qty?: number;
|
||
|
||
/** 下单步长(数量增量) */
|
||
@Column("numeric", { precision: 32, scale: 8, nullable: true })
|
||
step_size?: number;
|
||
|
||
/** 最小名义价值(USDT) */
|
||
@Column("numeric", { precision: 32, scale: 8, nullable: true })
|
||
min_notional?: number;
|
||
|
||
/** 是否激活数据订阅(false 时不采集该交易对行情) */
|
||
@Column("boolean", { default: true })
|
||
active!: boolean;
|
||
|
||
/** 是否启用 K 线合成(false 时仅采集原始行情,不合成) */
|
||
@Column("boolean", { default: true })
|
||
kline_synthesis_enabled!: boolean;
|
||
|
||
/** K 线时间周期 */
|
||
@Column("varchar", { length: 100, default: "1m" })
|
||
kline_interval!: KlineInterval;
|
||
|
||
/** K 线合成周期列表(逗号分隔,如 "1m,5m,15m,1h,4h,1d") */
|
||
@Column("varchar", { length: 100, default: "1m,5m,15m,1h,4h,1d" })
|
||
kline_intervals!: string;
|
||
|
||
/**
|
||
* 历史 K 线最后补全时间(UTC)。
|
||
* 记录最近一次 REST 补拉 K 线的结束时间戳,
|
||
* 下次启动时从此时间点继续补全,避免重复拉取。
|
||
*
|
||
* 默认值为 Unix 0(1970-01-01T00:00:00.000Z),
|
||
* 新交易对从 epoch 起始时间开始全量补拉,
|
||
* 补全后更新为实际拉取到的最后时间。
|
||
*/
|
||
@Column("timestamptz", { default: () => "to_timestamp(0)" })
|
||
last_backfill_time!: Date;
|
||
|
||
/** 备注 */
|
||
@Column("text", { nullable: true })
|
||
notes?: string;
|
||
|
||
// ============================================================
|
||
// 工具方法
|
||
// ============================================================
|
||
|
||
/** 解析 kline_intervals 为周期数组 */
|
||
getIntervals(): string[] {
|
||
return this.kline_intervals
|
||
.split(",")
|
||
.map((s) => s.trim())
|
||
.filter(Boolean);
|
||
}
|
||
}
|