backtest-monorepo-parallel is structured around a deliberate separation between the infrastructure layer (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/theonetrade/backtest-monorepo-parallel/llms.txt
Use this file to discover all available pages before exploring further.
@pro/core), the mode-dispatch layer (@pro/main), and the strategy layer (./content/). Infrastructure and mode dispatch are compiled by Rollup into CJS bundles and loaded at runtime. Strategy files are never bundled — @backtest-kit/cli loads them by path at evaluation time, by which point the entire DI container is already live on globalThis.core.
Directory Layout
The Two Packages
- @pro/core
- @pro/main
@pro/core is the shared infrastructure package. It is responsible for:- Dependency injection —
createActivator("pro")fromdi-kitproduces the{ init, inject, provide }triple used throughout the package. - Service registration —
provide.tsregisters every concrete class against its Symbol token. - IoC assembly —
lib/index.tscallsinject<T>(TYPES.x)for each service and collects them into theiocobject. - Global binding — after calling
init(),lib/index.tswritesglobalThis.core = ioc, making the container universally accessible. - Database layer —
CandleDbServicewraps a Mongoose model;BaseCRUD(upstream) providescreate / update / findById / findByFilter / findAll / iterate / paginatefor free. - Caching layer —
BaseMapwraps an ioredis client for O(1) string-keyed lookups with optional TTL. - Scraping and parsing —
ScraperServiceandParserServicefor HTML-based data collection. - Screen capture —
CryptoYodaScreenServicefor chart image capture.
The DI Runtime
Symbol Tokens
Every service is identified by a uniqueSymbol. All tokens are declared in packages/core/src/lib/core/types.ts:
The Activator
di.ts calls createActivator("pro") from di-kit to produce the three DI primitives used everywhere in @pro/core:
provide(token, factory)— registers a lazy factory for a given Symbol token.inject<T>(token)— returns a proxy that resolves the factory on first access.init()— eagerly resolves all registered providers, triggering any constructor side-effects.
Provider Registration
provide.ts maps every Symbol token to its concrete implementation factory. Because provide is lazy by default, service constructors run only when init() is called:
IoC Assembly and globalThis.core
lib/index.ts is the file that ties everything together. It imports provide.ts (side-effect — all factories are registered), calls inject<T>() for each service to build the ioc object, calls init() to resolve all factories, and then assigns ioc to globalThis.core:
The
declare global { var core: typeof ioc; } block is what makes
core.candleDbService and its peers type-safe in every file under
./content/ and ./config/ — no import required. TypeScript resolves
the type through tsconfig.json paths, which points @pro/core at the
rolled-up types.d.ts.Config Files
The three files under./config/ form the bootstrap layer that connects @backtest-kit/cli to the workspace packages.
alias.config.ts tells @backtest-kit/cli which built CJS bundles to load when it encounters require("@pro/core") or require("@pro/main") inside strategy files or config. It maps the package name to the Rollup output path at runtime — no bundler hooks, no module federation.
loader.config.ts is the async bootstrap function called by the CLI before it loads any strategy file. Importing @pro/core and @pro/main here triggers their side-effects (provider registration, init(), globalThis.core assignment, mode-dispatcher registration). The await waitForInit() call from @backtest-kit/mongo ensures MongoDB is connected before strategy evaluation begins.
setup.config.ts declares the adapter each backtest-kit subsystem should use for live versus backtest contexts. Live mode uses Mongo-backed Persist adapters for durability; backtest mode uses Memory or Local adapters to avoid disk I/O on transient state:
| Subsystem | Live adapter | Backtest adapter |
|---|---|---|
| Session | usePersist() (Mongo) | useLocal() (file) |
| Storage | usePersist() | useMemory() |
| Recent | usePersist() | useMemory() |
| Notification | usePersist() | useMemory() |
| Memory | usePersist() | useLocal() |
| State | usePersist() | useLocal() |
| Markdown | useDummy() | useDummy() |
| Log | useJsonl() | useJsonl() |
Compile-Time Types via tsconfig.json Paths
The root tsconfig.json maps the two package names to their rolled-up declaration files:
- Compile-time safety. Files under
./config/and./content/get full IntelliSense forimport { ioc } from "@pro/core"and forcore.*references, because TypeScript resolves those imports through the rolled-uptypes.d.tsrather than the sourceindex.ts. - No source dependency. Strategy files under
./content/are never part of the@pro/*build graph. Theincludearray covers only./configand./content, keeping the packages decoupled.
The Build Pipeline
Each package contains its ownrollup.config.ts (or equivalent). The root build script walks ./packages/* and runs npm run build in each:
build/index.cjs— the CommonJS bundle. This is whatconfig/alias.config.tspointsrequire("@pro/core")andrequire("@pro/main")at.types.d.ts— a single-file, rolled-up declaration bundle produced byrollup-plugin-dts. This is whattsconfig.jsonpathsresolves for type checking.
The Content Directory and Zero-Import Strategies
Strategy files under./content/ are the last piece. They are loaded exclusively by @backtest-kit/cli, which receives the path as a positional argument:
setup.config.tshas declared all adapters and calledsetup()from@backtest-kit/mongo.loader.config.tshas imported@pro/coreand@pro/main(triggeringglobalThis.coreassignment) and awaitedwaitForInit().alias.config.tshas registered the CJS bundle paths so that anyrequire("@pro/core")inside the strategy would also resolve correctly.
core.candleDbService.findByFilter(...) on its first line without any import statement. The type is available because tsconfig.json paths maps @pro/core to types.d.ts, which contains the declare global { var core: typeof ioc; } block from lib/index.ts.
Introduction
Read the performance benchmarks, feature overview, and the
explanation of all four runtime modes.
Quickstart
Follow the step-by-step guide to build the packages and run your
first parallel backtest.