backtest-kit 15.4.0 → 15.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -753,6 +753,12 @@ PostgreSQL + Redis O(1) cache via TypeORM. All 15 persistence contracts, atomic
753
753
  npm install @backtest-kit/pg backtest-kit typeorm pg ioredis reflect-metadata
754
754
  ```
755
755
 
756
+ ### `@backtest-kit/minio` — [npm](https://www.npmjs.com/package/@backtest-kit/minio)
757
+ MinIO (S3) source-of-truth + Redis time-ordered index. Listings in O(limit), zero schema management. Zero strategy changes.
758
+ ```bash
759
+ npm install @backtest-kit/minio backtest-kit minio ioredis
760
+ ```
761
+
756
762
  ### `@backtest-kit/ollama` — [npm](https://www.npmjs.com/package/@backtest-kit/ollama)
757
763
  Universal LLM adapter: 10+ providers, structured output, token rotation, fallback chains, trading-context injection.
758
764
  ```bash
@@ -781,6 +787,7 @@ Real, runnable templates — not slideware. And worth naming the concern directl
781
787
  - **[backtest-ollama-crontab](https://github.com/backtest-kit/backtest-ollama-crontab)** — a local Ollama (`gpt-oss` quantized) as a per-signal risk gate plus a 15-minute crontab ingesting any public Telegram channel; the *same code* re-polls live and bulk-prepares in backtest. Documented result: **+52.22% → +68.90%** with the LLM gate on.
782
788
  - **[backtest-kit-redis-mongo-docker](https://github.com/backtest-kit/backtest-kit-redis-mongo-docker)** — production persistence: all 15 adapters on Mongo+Redis, atomic read-after-write, `docker-compose` one-command deploy.
783
789
  - **[backtest-kit-redis-postgres-pgpool-docker](https://github.com/backtest-kit/backtest-kit-redis-postgres-pgpool-docker)** — backtest-kit persistence on PostgreSQL (Pgpool-II) + Redis cache, with atomic upserts and a replica cluster.
790
+ - **[backtest-kit-minio-s3-docker](https://github.com/backtest-kit/backtest-kit-minio-s3-docker)** — persistence on MinIO (S3) with deterministic keys, S3-grade durability
784
791
  - **[backtest-kit-skills](https://github.com/backtest-kit/backtest-kit-skills)** — a Claude Code skill + Mintlify docs: describe a strategy in plain language, get working TypeScript with every schema registration wired. `npx skills add https://github.com/backtest-kit/backtest-kit-skills`
785
792
  - **[uzse-backtest-app](https://github.com/backtest-kit/uzse-backtest-app)** — Pine Script on regional exchanges that aren't on TradingView (UZSE, MSE, DSE…): download raw trades, build candles, feed them through a custom Mongo exchange adapter.
786
793
  - **[backtest-kit-docs](https://github.com/backtest-kit/backtest-kit-docs)** — Architecture handbook and knowledge base: explains the engine's design, AI workflows, production patterns, and quantitative trading concepts beyond the API.
package/build/index.cjs CHANGED
@@ -1597,6 +1597,9 @@ class PersistRiskInstance {
1597
1597
  async readPositionData(_when) {
1598
1598
  if (await this._storage.hasValue(PersistRiskInstance.STORAGE_KEY)) {
1599
1599
  const riskData = await this._storage.readValue(PersistRiskInstance.STORAGE_KEY);
1600
+ if (!riskData) {
1601
+ return [];
1602
+ }
1600
1603
  // JSON serializes Infinity as null, so an eternal-hold position
1601
1604
  // (minuteEstimatedTime: Infinity) reads back as null — restore it.
1602
1605
  for (const [, position] of riskData) {
@@ -2004,6 +2007,12 @@ class PersistStrategyInstance {
2004
2007
  async readStrategyData() {
2005
2008
  if (await this._storage.hasValue(PersistStrategyInstance.STORAGE_KEY)) {
2006
2009
  const strategyData = await this._storage.readValue(PersistStrategyInstance.STORAGE_KEY);
2010
+ // writeStrategyData(null) stores a literal null under the key, so an
2011
+ // existing key does not imply an object (mirrors the signalRow/scheduledRow
2012
+ // guards in readSignalData/readScheduleData).
2013
+ if (!strategyData) {
2014
+ return null;
2015
+ }
2007
2016
  // JSON serializes Infinity as null, so an eternal-hold signal
2008
2017
  // (minuteEstimatedTime: Infinity) reads back as null — restore it.
2009
2018
  for (const signal of [strategyData.closedSignal, strategyData.cancelledSignal, strategyData.activatedSignal, strategyData.takeProfitSignal, strategyData.stopLossSignal]) {
package/build/index.mjs CHANGED
@@ -1577,6 +1577,9 @@ class PersistRiskInstance {
1577
1577
  async readPositionData(_when) {
1578
1578
  if (await this._storage.hasValue(PersistRiskInstance.STORAGE_KEY)) {
1579
1579
  const riskData = await this._storage.readValue(PersistRiskInstance.STORAGE_KEY);
1580
+ if (!riskData) {
1581
+ return [];
1582
+ }
1580
1583
  // JSON serializes Infinity as null, so an eternal-hold position
1581
1584
  // (minuteEstimatedTime: Infinity) reads back as null — restore it.
1582
1585
  for (const [, position] of riskData) {
@@ -1984,6 +1987,12 @@ class PersistStrategyInstance {
1984
1987
  async readStrategyData() {
1985
1988
  if (await this._storage.hasValue(PersistStrategyInstance.STORAGE_KEY)) {
1986
1989
  const strategyData = await this._storage.readValue(PersistStrategyInstance.STORAGE_KEY);
1990
+ // writeStrategyData(null) stores a literal null under the key, so an
1991
+ // existing key does not imply an object (mirrors the signalRow/scheduledRow
1992
+ // guards in readSignalData/readScheduleData).
1993
+ if (!strategyData) {
1994
+ return null;
1995
+ }
1987
1996
  // JSON serializes Infinity as null, so an eternal-hold signal
1988
1997
  // (minuteEstimatedTime: Infinity) reads back as null — restore it.
1989
1998
  for (const signal of [strategyData.closedSignal, strategyData.cancelledSignal, strategyData.activatedSignal, strategyData.takeProfitSignal, strategyData.stopLossSignal]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "backtest-kit",
3
- "version": "15.4.0",
3
+ "version": "15.5.0",
4
4
  "description": "A TypeScript library for trading system backtest",
5
5
  "author": {
6
6
  "name": "Petr Tripolsky",