@ backtest- kit/ pg (英语)
PostgreSQL + Redis 持久性用于 反测试- kit。将默认文件存储换为生产后端——耐用、可查询、原子,O(1)缓存读取——在 一个
setup()呼叫和零战略代码更改。 。 。 .

📚 文档 • 妇女 参考执行情况 • 妇女 GitHub 图像
npm install @backtest-kit/pg backtest-kit typeorm pg ioredis reflect-metadata
import { setup } from '@backtest-kit/pg';
setup(); // reads connection settings from env; call once before any trading operation
那个单调重播 16个 反测试孩子的 IPersist*Instance 对PostgreSQL(真相来源)与Redis O(1)的合同读取缓存。 你的策略代码不变.
为什么
单节原子错觉. 在一个孤独的Postgres节点上,所有货币都通过行锁和MVCC进行内部仲裁,所以即使是草率的 write 之后为 单独 SELECT 看起来是正确的——读取击中了刚刚承诺的进程。 添加读取的复制品和幻觉断裂:后续 SELECT 能够被引导到尚未收到承诺的Aync复制品,默默地还原已停滞的数据. 这个软件包为Pgpool调制了每个操作,以挤出最大吞吐量,同时剪除不必要的锁. 返回的行种子为 Redis- first id 缓存:每读 O(1).
Pgpool-II粉丝读取负载横跨集群. 背向点火 数千个上下文键读取每秒平行符号 写作仍然在初级上进行序列化(其中原子更新保留了读后-写作的保证),而读后-重度的热道尺度与您添加的每一个复制件水平地进行.
上至~4×快于MongoDB适配器. 模拟一分钟的市场数据成本 35至40分钟 通过单节点的MongoDB适配器,但仅限 ~10 毫秒(每秒) 通过这个 Postgres + Pgpool 集群——复制品吸收了读取的扇出,否则会瓶颈出一个单一的节点. 您的策略代码不会改变; 只有时钟时间通过后台测试才会改变.
- 🗄️ PostgreSQL 后端软件 全部16个
IPersist*Instance与TypeORM公司执行的合同. - ⚡ O(1)通过Redis读取 一个
GET+1个主键取出,热道上没有B树扫描. - 🔒 原子写 —— 说
INSERT … ON CONFLICT DO UPDATE … RETURNING *保证无种族的后写. - 🛡️ 头部保护 ——影响决策的适配器存储模拟
when。 。 。 . - 🪦 软删除 测量/间隔/内存
removed旗帜而不是被删除(审计线索). - 🔌 零战略变化 - 降级
setup()进入您的入口; 其他一切保持不变.
配置
明确参数和环境变量
import { setup } from '@backtest-kit/pg';
setup({
CC_POSTGRES_CONNECTION_STRING: 'postgres://backtest:secret@postgres:5432/mydb',
CC_REDIS_HOST: 'redis', CC_REDIS_PORT: 6379, CC_REDIS_PASSWORD: 'secret',
});
| 变量 | 默认 | 说明 |
|---|---|---|
CC_POSTGRES_CONNECTION_STRING | postgres://backtest:mysecurepassword@localhost:5432/backtest-pro | PostgreSQL 连接字符串 |
CC_REDIS_HOST | 127.0.0.1 | Redis 主机 |
CC_REDIS_PORT | 6379 | Redis 端口 |
CC_REDIS_USER | (空虚) | Redis 用户名 |
CC_REDIS_PASSWORD | (空虚) | 重写密码 |
转至的值 setup() 编号 : setConfig() 永远优于地狱之地 在CLI内部,放 setup() 内 config/setup.config.ts ——当存在时, CLI 跳过其默认的文件适应器注册和您的配置本身的持久性.
API 参考
| 导出 | 说明 |
|---|---|
setup(config?) | 配置 财务报告和审定财务报表 在一个呼叫中登记所有16个适配器。 何时读取 config 省略. |
install() | 仅登记适配器——当配置已经通过 setConfig/env. (原始内容存档于2018-09-26). |
setConfig(config) | 运行时覆盖单个连接参数. |
getConfig() | 当前合并配置( env + 任何) setConfig (原始内容存档于2017-03-25). overse. |
setLogger(logger) | 用您自己的执行替换内部记录器 . |
getPostgres() | 连接的类型ORM DataSource (懒惰的单子). |
getRedis() | 相接的ioredis实例(lazy singleton). |
16个适配器
每个适配器在后试-吻上覆盖一个持久性槽. 独特的索引是存储引擎上的复合键PostgreSQL执行.
| 适配器 | 图表 | 独一无二的索引 |
|---|---|---|
| 蜡烛 | candle-items | exchangeName + symbol + interval + timestamp |
| 信号 | signal-items | symbol + strategyName + exchangeName |
| 战略 | strategy-items | symbol + strategyName + exchangeName |
| 时间表 | schedule-items | symbol + strategyName + exchangeName |
| 风险 | risk-items | riskName + exchangeName |
| 部分 | partial-items | symbol + strategyName + exchangeName + signalId |
| 断面 | breakeven-items | symbol + strategyName + exchangeName + signalId |
| 存储 | storage-items | backtest + signalId |
| 通知 | notification-items | backtest + notificationId |
| 日志 | log-items | entryId |
| 措施 | measure-items | bucket + entryKey |
| 间隔 | interval-items | bucket + entryKey |
| 内存 | memory-items | signalId + bucketName + memoryId |
| 近期 | recent-items | symbol + strategyName + exchangeName + frameName + backtest |
| 状态 | state-items | signalId + bucketName |
| 预算 | budget-items | strategyName + exchangeName + frameName + backtest + name |
| 会议 | session-items | strategyName + exchangeName + frameName |
写语义——不可变能,可变能,可变能,可软去除
- 蜡烛是永恒的 ——先写胜;后写同
(exchangeName, symbol, interval, timestamp)被默默忽略 通过一个不开放DO UPDATE从未触及过 OHLCV 列(历史的 OHLCV 从未改变). - 其他人都会用
DO UPDATE SET payload = EXCLUDED.payload——每个写入取代了以前的值. - 度量/ 中间/ 内存软删除 —— 说
removeMeasureData编号 :removeIntervalData编号 :removeMemoryData设定removed = true而不是删除; 在removed = false保持完整的审计线索.
如何运作
O(1) 读取—— DbService + 缓存服务每个域
每个域有两层:a 服务 (后SQL)和a 缓存服务 (瑞地语). 上下文密钥的读取状态 id 首先,一个命中是两个 O(1) 行动,一个错落到一个索引 findOne 和回填雷迪斯.
read signal for (BTCUSDT, my_strategy, binance)
├─ Redis GET → hit → Postgres findByFilter({ id }) ← O(1) + O(1)
└─ Redis GET → miss → Postgres findByFilter(filter) → Redis SET → return
在每次写完Redis条目后,都会在同一通电话中刷新,所以写到时读总是会点击缓存.
原子弹写作——无种族读后写作
反测试- kit 需要一次 write*Data() 返回,下一个 read*Data() 看到了新的价值。 每个字都是一个 INSERT … ON CONFLICT … RETURNING 圆通:
const { raw } = await repo
.createQueryBuilder()
.insert()
.values({ symbol, strategyName, exchangeName, payload })
.orUpdate(["payload"], ["symbol", "strategyName", "exchangeName"])
.returning("*")
.execute();
await signalCacheService.setSignalId(raw[0]);
冲突目标匹配独特的复合索引,所以PostgreSQL序列化了存储引擎上任何同时插入的重复——输家取下 DO UPDATE 分支而不是抛出;返回的行被直接写到Redis上,使得下一个读取了O(1)的新数据.
DB 层的面向偏移保护
数据影响决策的适配器(风险、部分、断层、最近、状态、预算、会话、记忆、间隔)存储 when: bigint 模拟时间戳以毫秒表示——与有效载荷并列,因此,反测试-基特可以验证没有读取返回数据 未来 模拟时间. 措施豁免 因为它缓存了 LLM / 外部- API 响应, 其中的外观- ahead 偏差没有意义 .
内部架构( 完整源图)
图层文件( F)
公众表面 —— 说 functions/setup.ts (单位:千美元)setup编号 :install编号 :setLogger, (中文(简体) ), config/params.ts (单位:千美元)setConfig编号 :getConfig, (中文(简体) ), index.ts 再出口+ getPostgres编号 :getRedis。 。 。 .
适配类 (单位:千美元)classes/Persist*Instance.ts,17)——各执行一回试-吻 IPersist*Instance dbService: 合同和代表 PersistCandleInstance, (中文(简体) ), PersistSignalInstance, (中文(简体) ), PersistStrategyInstance, (中文(简体) ), PersistScheduleInstance, (中文(简体) ), PersistRiskInstance, (中文(简体) ), PersistPartialInstance, (中文(简体) ), PersistBreakevenInstance, (中文(简体) ), PersistStorageInstance, (中文(简体) ), PersistNotificationInstance, (中文(简体) ), PersistLogInstance, (中文(简体) ), PersistMeasureInstance, (中文(简体) ), PersistIntervalInstance, (中文(简体) ), PersistMemoryInstance, (中文(简体) ), PersistRecentInstance, (中文(简体) ), PersistStateInstance, (中文(简体) ), PersistBudgetInstance, (中文(简体) ), PersistSessionInstance。 。 。 .
服务层 (单位:千美元)lib/services/:
base/—— 说PostgresService(懒惰型ORM)DataSource, (中文(简体) ),RedisService(懒驴),LoggerService。 。 。 .db/一个*DbService每个域:TypeORM实体计划、独特的化合物指数和INSERT … ON CONFLICT … RETURNING上调逻辑.cache/一个*CacheService每个领域(CandleCacheService, (中文(简体) ),SignalCacheService, (中文(简体) ),BreakevenCacheService, (中文(简体) ),IntervalCacheService, (中文(简体) ),LogCacheService, (中文(简体) ),MeasureCacheService, (中文(简体) ),MemoryCacheService, (中文(简体) ),NotificationCacheService, (中文(简体) ),PartialCacheService, (中文(简体) ),RecentCacheService,...):雷迪丝ido(1)取景图.
共享原始物 (单位:千美元)lib/common/(b) —— BaseCRUD (每一次DbService再利用的上升/读取/删除模式)和 BaseMap (Redis键映射模式每一次缓存服务回用).
DI 配置 —— 说 lib/core/{di,provide,types}.ts (IoC集装箱接线Db/Cache/基地服务), lib/index.ts (集装箱靴子), config/{postgres,redis,params}.ts (连接建设者+合并参数), interfaces/Logger.interface.ts。 。 。 .
* 贡献
叉/ PR 打开 GitHub 图像。 。 。 .
许可证
麻省理工学院 特立奥尔斯基平板电脑