Files
trade/data/db/entities/kline.entity.ts
T
Rekey 85a0031a78 feat(data): 实现 Binance WebSocket 适配器与架构重构
- 新增 exchanges/ 模块:MarketDataFeed 统一接口、BaseExchangeAdapter 抽象基类、
  BinanceAdapter 完整实现(WebSocket + REST)
- WebSocket 层基于 binance 官方 SDK 的 WebsocketClient,自动多路复用与断线重连
- REST 层使用 MainClient(Spot),实现 fetchKlines 自动分页补拉 + fetchMarkets 元数据解析
- 数据标准化:Ticker/Trade/OrderBook/Kline 类型定义与 Binance 原生格式互转
- 引入 RxJS Subject 作为统一事件流管道,按 eventType 运行时路由分发
- 重构 config/:YAML 驱动配置加载 + 零依赖运行时校验(fail-fast)
- 重构 db/:TypeORM DataSource 配置 + TimescaleDB K 线 Hypertable 实体
- 新增 utils/logger.ts:Pino 结构化日志(开发环境 pino-pretty 彩色输出)
- 新增 env.yaml 作为 TS/Python 共享的统一环境配置源
- 删除旧版手写 SQL schema 与散落配置文件,收敛到 TypeORM 实体管理
- 安装 rxjs@7.8.2 依赖
2026-06-08 01:24:48 +08:00

139 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// ============================================================
// kline.entity.ts — TimescaleDB K 线 Hypertable 实体
// ============================================================
// 映射到 PostgreSQL klines 表(TimescaleDB hypertable)。
// 不继承 CommonBaseEntity — 使用 @timescaledb/typeorm 的
// @Hypertable / @TimeColumn 装饰器管理 TimescaleDB 特性。
//
// 关键 TimescaleDB 特性(由 @Hypertable 装饰器自动配置):
// - 自动按 time 列做时间分区(by_range
// - 列式压缩(compress),7 天后自动执行
// - 通过 ContinuousAggregate 生成高周期 K 线视图
//
// 注意:@timescaledb/typeorm v0.0.1 为实验版本,
// 不支持空间分区(partitioning_column)。
// 若需要空间分区,可通过 db/init-db/ 下的 SQL 脚本手动添加。
// ============================================================
import { Hypertable, TimeColumn } from "@timescaledb/typeorm";
import {
Entity,
PrimaryColumn,
Column,
Index,
CreateDateColumn,
UpdateDateColumn,
} from "typeorm";
/** K 线周期枚举 */
export type KlineInterval =
| "1m"
| "5m"
| "15m"
| "30m"
| "1h"
| "4h"
| "1d"
| "1w";
/**
* 1 分钟 K 线 Hypertable
*
* 存储交易所推送的 OHLCV 数据。写入使用 UPSERT
* ON CONFLICT DO UPDATE),已存在的 K 线只更新
* high/low/close/volume 增量。
*
* 高周期 K 线(5m+)通过 TimescaleDB 连续聚合视图
* 从 1m 表自动生成,无需单独建表。
*/
@Hypertable({
compression: {
compress: true,
compress_orderby: "time DESC",
compress_segmentby: "exchange, symbol, interval",
policy: {
schedule_interval: "365 days", // 365 天后自动压缩
},
},
})
@Index(["exchange", "symbol", "interval", "time"], { unique: true })
@Entity("klines")
export class Kline {
/** K 线开盘时间(UTC)— @timescaledb/typeorm 自动标记为时间分区列 */
@TimeColumn()
@PrimaryColumn("timestamptz")
time!: Date;
/** 交易所标识(binance / okx / bybit */
@Column("text")
exchange!: string;
/** 交易对符号(如 BTCUSDT */
@Column("text")
symbol!: string;
/** K 线周期(1m */
@Column("text")
interval!: KlineInterval;
// ============================================================
// OHLCV 价格数据(NUMERIC(20,8) 精度,与交易所对齐)
// ============================================================
/** 开盘价 */
@Column("numeric", { precision: 20, scale: 8 })
open!: number;
/** 最高价 */
@Column("numeric", { precision: 20, scale: 8 })
high!: number;
/** 最低价 */
@Column("numeric", { precision: 20, scale: 8 })
low!: number;
/** 收盘价 */
@Column("numeric", { precision: 20, scale: 8 })
close!: number;
/** 成交量(base 币种) */
@Column("numeric", { precision: 20, scale: 8 })
volume!: number;
// ============================================================
// 扩展字段(Binance 等交易所提供)
// ============================================================
/** 成交额(quote 币种) */
@Column("numeric", { precision: 20, scale: 8, nullable: true })
quote_volume?: number;
/** 主动买入成交量(base 币种) */
@Column("numeric", { precision: 20, scale: 8, nullable: true })
taker_buy_base_vol?: number;
/** 主动买入成交额(quote 币种) */
@Column("numeric", { precision: 20, scale: 8, nullable: true })
taker_buy_quote_vol?: number;
/** 成交笔数 */
@Column("integer", { nullable: true })
trade_count?: number;
/** K 线是否已关闭(true = 该周期 K 线不再变化) */
@Column("boolean", { default: true })
is_closed!: boolean;
// ============================================================
// 审计字段
// ============================================================
/** 记录首次写入时间 */
@CreateDateColumn({ type: "timestamptz", name: "created_at" })
createdAt!: Date;
/** 记录最后更新时间 */
@UpdateDateColumn({ type: "timestamptz", name: "updated_at" })
updatedAt!: Date;
}