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

📚 文档 • 妇女 参考执行情况 • 妇女 GitHub 图像
npm install @backtest-kit/mongo backtest-kit mongoose ioredis
import { setup } from '@backtest-kit/mongo';
setup(); // reads connection settings from env; call once before any trading operation
那个单调重播 16个 反测试孩子的 IPersist*Instance 与Redis O(1)签订的反对MongoDB(真相来源)的合同改为缓存。 你的策略代码不变.
为什么
文件存储在第一天是完美的,在你做数千个按上下文键的一天中,一个瓶颈每秒读取平行符号. 此套件在不触摸策略逻辑的情况下将持久性移到 MongoDB : 每个读取符都先被 Redis- first for the Mongo _id (两个O(1)跳,每个写作都是一个原子) findOneAndUpdate 更新(已保证读后写,同时复制被唯一索引拒绝),以及数据驱动决定的适配器存储模拟时间戳 搜索前端保护即使在数据库内也能执行。 。 。 .
- 🗄️ 蒙戈DB 后端 全部16个
IPersist*Instance与Mongoose执行的合同. - ⚡ O(1)通过Redis读取 一个
GET+一个findById热路没有B树扫描. - 🔒 原子写 —— 说
findOneAndUpdate({ upsert:true, new:true })保证无种族的后写. - 🛡️ 头部保护 ——影响决策的适配器存储模拟
when。 。 。 . - 🪦 软删除 测量/间隔/内存
removed旗帜而不是被删除(审计线索). - 🔌 零战略变化 - 降级
setup()进入您的入口; 其他一切保持不变.
配置
明确参数和环境变量
import { setup } from '@backtest-kit/mongo';
setup({
CC_MONGO_CONNECTION_STRING: 'mongodb://mongo:27017/mydb',
CC_REDIS_HOST: 'redis', CC_REDIS_PORT: 6379, CC_REDIS_PASSWORD: 'secret',
});
| 变量 | 默认 | 说明 |
|---|---|---|
CC_MONGO_CONNECTION_STRING | mongodb://localhost:27017/backtest-kit?wtimeoutMS=15000 | MongoDB 连接字符串 |
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) | 用您自己的执行替换内部记录器 . |
getMongo() | 相通的Mongoose实例(懒惰的单子). |
getRedis() | 相接的ioredis实例(lazy singleton). |
16个适配器
每个适配器在后试-吻上覆盖一个持久性槽. 独特的索引是存储引擎上的复合键MongoDB执行.
| 适配器 | 收藏 | 独一无二的索引 |
|---|---|---|
| 蜡烛 | candle-items | 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 |
写语义——不可变能,可变能,可变能,可软去除
- 蜡烛是永恒的 ——先写胜;后写同
(symbol, interval, timestamp)被默默忽略通过$setOnInsert(历史的OHLCV从未改变). - 其他人都会用
$set——每个写入取代了以前的值. - 度量/ 中间/ 内存软删除 —— 说
removeMeasureData编号 :removeIntervalData编号 :removeMemoryData设定removed: true而不是删除; 在removed: false保持完整的审计线索.
如何运作
O(1) 读取—— DbService + 缓存服务每个域
每个域有两层:a 服务 (蒙戈DB)和一个 缓存服务 (瑞地语). 上下文密钥的读取状态要求 Redis 为 Mongo 读取 _id 首先,一个命中是两个 O(1) 行动,一个错落到一个索引 findOne 和回填雷迪斯.
read signal for (BTCUSDT, my_strategy, binance)
├─ Redis GET → hit → Mongo findById(_id) ← O(1) + O(1)
└─ Redis GET → miss → Mongo findOne(filter) → Redis SET → return
在每次写完Redis条目后,都会在同一通电话中刷新,所以写到时读总是会点击缓存.
原子弹写作——无种族读后写作
反测试- kit 需要一次 write*Data() 返回,下一个 read*Data() 看到了新的价值。 每个字都是一个 findOneAndUpdate 圆通:
const document = await SignalModel.findOneAndUpdate(
{ symbol, strategyName, exchangeName },
{ $set: { payload } },
{ upsert: true, new: true, setDefaultsOnInsert: true },
);
await signalCacheService.setSignalId(readTransform(document.toJSON()));
过滤器匹配了独特的复合索引,因此MongoDB拒绝存储引擎中任何同时插入的重复;返回的文档被直接写到Redis上,使得下一次读取O(1)在新鲜数据上.
DB 层的面向偏移保护
数据影响决策的适配器(风险、部分、断层、最近、状态、预算、会话、记忆、间隔)存储 when: Number 模拟时间戳以毫秒表示——与有效载荷并列,因此,反测试-基特可以验证没有读取返回数据 未来 模拟时间. 措施豁免 因为它缓存了 LLM / 外部- API 响应, 其中的外观- ahead 偏差没有意义 .
内部架构( 完整源图)
图层文件( F)
公众表面 —— 说 functions/setup.ts (单位:千美元)setup编号 :install编号 :setConfig编号 :getConfig编号 :setLogger, (中文(简体) ), index.ts 再出口+ getMongo编号 :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/—— 说MongoService(懒绵羊连接),RedisService(懒驴),LoggerService。 。 。 .db/一个*DbService每个域:Mongoose模型、计划、独特的复合指数和findOneAndUpdate上调逻辑.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/{mongo,redis,params}.ts (连接建设者+合并参数), interfaces/Logger.interface.ts。 。 。 .
* 贡献
叉/ PR 打开 GitHub 图像。 。 。 .
许可证
麻省理工学院 特立奥尔斯基平板电脑