tradelab 1.3.0 → 1.3.1
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/CHANGELOG.md +6 -0
- package/README.md +7 -6
- package/bin/tradelab.js +1 -1
- package/dist/cjs/live.cjs +1 -1
- package/docs/README.md +6 -4
- package/docs/api-reference.md +15 -1
- package/docs/data-reporting-cli.md +9 -0
- package/docs/mcp.md +3 -3
- package/docs/research.md +15 -0
- package/package.json +1 -1
- package/src/live/session.js +5 -5
- package/src/mcp/tools.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.3.1] - 2026-06-28
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Documentation refresh: the README now leads with the agent-native MCP story, and the reference docs cover `summarize`, `createResearchStore` and the agent research loop, `attachNotifier`, multi-symbol sessions, exposure caps, and `tradelab run`.
|
|
13
|
+
|
|
8
14
|
## [1.3.0] - 2026-06-27
|
|
9
15
|
|
|
10
16
|
### Added
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
<img src="https://i.imgur.com/HGvvQbq.png" width="420" alt="tradelab logo" />
|
|
3
3
|
|
|
4
|
-
<p><strong>
|
|
4
|
+
<p><strong>An agent-native Node.js trading engine: research, backtest, and trade live through one signal contract.</strong></p>
|
|
5
5
|
|
|
6
6
|
[](https://www.npmjs.com/package/tradelab)
|
|
7
7
|
[](https://github.com/ishsharm0/tradelab)
|
|
@@ -13,17 +13,18 @@
|
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
-
A Node.js toolkit for testing, validating, and operating trading strategies.
|
|
16
|
+
A Node.js toolkit for testing, validating, and operating trading strategies, built so humans and AI agents work from the same primitives.
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
One `signal()` contract runs across research and execution:
|
|
19
19
|
|
|
20
20
|
- run candle or tick backtests
|
|
21
21
|
- model slippage, commissions, borrow, carry, and funding
|
|
22
22
|
- validate parameters with walk-forward tests and research statistics
|
|
23
23
|
- combine multiple systems into a shared-capital portfolio
|
|
24
|
-
- move the same strategy into paper or live execution
|
|
24
|
+
- move the same strategy into paper or live execution, single or multi-symbol
|
|
25
25
|
- export reports, metrics, and trade ledgers
|
|
26
|
-
|
|
26
|
+
|
|
27
|
+
**Agent-native.** The `tradelab-mcp` server exposes 25 tools over stdio, so an AI agent can run the whole loop itself: pull data, run and score backtests, track hypotheses across runs with built-in overfitting guards, then open a paper or live session and place risk-sized bracket orders behind a kill-switch. Agents get the same depth a quant does, not a thin read-only wrapper. See [docs/mcp.md](docs/mcp.md).
|
|
27
28
|
|
|
28
29
|
```bash
|
|
29
30
|
npm install tradelab
|
|
@@ -270,7 +271,7 @@ Add `--dashboard --dashboardPort 4317` to open a local Server-Sent Events dashbo
|
|
|
270
271
|
|
|
271
272
|
## MCP Server
|
|
272
273
|
|
|
273
|
-
`tradelab-mcp` exposes
|
|
274
|
+
`tradelab-mcp` exposes 25 tools over stdio to any MCP-capable agent (Claude Desktop, Cursor, and similar). They cover the full loop an agent needs to work a strategy end to end: research it, validate it, track the search, then trade it. See [docs/mcp.md](docs/mcp.md) for the full tool reference and agent trading guide.
|
|
274
275
|
|
|
275
276
|
**Research tools:** `list_strategies`, `fetch_candles`, `run_backtest`, `walk_forward`, `analyze_robustness`, `optimize_strategy`, `compare_strategies`, `candle_stats`
|
|
276
277
|
|
package/bin/tradelab.js
CHANGED
|
@@ -271,7 +271,7 @@ async function loadWalkForwardStrategy(strategyArg, args) {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
function printHelp() {
|
|
274
|
-
console.log(`tradelab
|
|
274
|
+
console.log(`tradelab: agent-native trading engine for Node.js
|
|
275
275
|
|
|
276
276
|
Usage: tradelab <command> [options]
|
|
277
277
|
|
package/dist/cjs/live.cjs
CHANGED
|
@@ -3666,7 +3666,7 @@ var TradingSession = class _TradingSession {
|
|
|
3666
3666
|
}
|
|
3667
3667
|
return order;
|
|
3668
3668
|
}
|
|
3669
|
-
// Sync event handler
|
|
3669
|
+
// Sync event handler; fire-and-forget async OCO work via a stored promise
|
|
3670
3670
|
_onBrokerFillSync(order) {
|
|
3671
3671
|
this._record("order:filled", this._withMeta(order));
|
|
3672
3672
|
for (const [sym, staged] of this._pendingBrackets) {
|
package/docs/README.md
CHANGED
|
@@ -11,8 +11,8 @@ Use this page to choose the right guide. If you are new to tradelab, read the fi
|
|
|
11
11
|
## Reference
|
|
12
12
|
|
|
13
13
|
- [API reference](api-reference.md) - public exports by module.
|
|
14
|
-
- [Research tools](research.md) - Monte Carlo, deflated Sharpe, PBO, and
|
|
15
|
-
- [MCP server](mcp.md) - `tradelab-mcp` setup and tool
|
|
14
|
+
- [Research tools](research.md) - Monte Carlo, deflated Sharpe, PBO, CPCV, and the agent research loop.
|
|
15
|
+
- [MCP server](mcp.md) - `tradelab-mcp` setup and the 25-tool reference for AI agents.
|
|
16
16
|
- [Strategy examples](examples.md) - complete strategy patterns you can adapt.
|
|
17
17
|
|
|
18
18
|
## Common Paths
|
|
@@ -26,17 +26,19 @@ Use this page to choose the right guide. If you are new to tradelab, read the fi
|
|
|
26
26
|
| Test parameter stability | [Backtesting](backtest-engine.md#walk-forward-validation) |
|
|
27
27
|
| Run a local paper session | [Live trading](live-trading.md) |
|
|
28
28
|
| Connect an MCP client | [MCP server](mcp.md) |
|
|
29
|
+
| Let an AI agent research and trade | [MCP server](mcp.md) |
|
|
29
30
|
| Check exact function names | [API reference](api-reference.md) |
|
|
30
31
|
|
|
31
32
|
## Package Scope
|
|
32
33
|
|
|
33
|
-
tradelab is built for strategy research and operational dry-runs:
|
|
34
|
+
tradelab is built for strategy research and operational dry-runs, by humans and AI agents alike:
|
|
34
35
|
|
|
35
36
|
- candle and tick backtests
|
|
36
37
|
- shared-capital portfolio simulation
|
|
37
38
|
- realistic cost assumptions
|
|
38
39
|
- walk-forward validation and overfitting checks
|
|
39
|
-
- paper and live execution through broker adapters
|
|
40
|
+
- single and multi-symbol paper and live execution through broker adapters
|
|
41
|
+
- a 25-tool MCP server so an agent can research, validate, and trade end to end
|
|
40
42
|
- local reports and machine-readable exports
|
|
41
43
|
|
|
42
44
|
It is not an exchange simulator. It does not try to model full market depth, queue priority, latency, or venue-specific microstructure.
|
package/docs/api-reference.md
CHANGED
|
@@ -108,6 +108,7 @@ registerStrategy("my-strategy", {
|
|
|
108
108
|
| `exportTradesCsv(trades, options)` | Write a trade or position CSV ledger |
|
|
109
109
|
| `exportMetricsJSON(options)` | Write machine-readable metrics JSON |
|
|
110
110
|
| `exportBacktestArtifacts(options)` | Write HTML, CSV, and JSON artifacts together |
|
|
111
|
+
| `summarize(metrics, options)` | Render metrics into one plain-English paragraph |
|
|
111
112
|
|
|
112
113
|
### Research
|
|
113
114
|
|
|
@@ -127,6 +128,8 @@ import { research } from "tradelab";
|
|
|
127
128
|
| `research.normalPpf(p)` | Standard normal inverse CDF |
|
|
128
129
|
| `research.moments(values)` | Mean, standard deviation, skew, kurtosis |
|
|
129
130
|
|
|
131
|
+
For the agent research loop, `createResearchStore({ dir })` returns a file-backed `{ open, log, recall, close }` store for tracking strategy hypotheses, their metrics, and overfitting verdicts across runs. The MCP `research_*` tools wrap it.
|
|
132
|
+
|
|
130
133
|
### Indicators And Helpers
|
|
131
134
|
|
|
132
135
|
| Export | Summary |
|
|
@@ -184,6 +187,17 @@ import { LiveEngine, PaperEngine, createDashboardServer } from "tradelab/live";
|
|
|
184
187
|
| `PaperEngine` | In-process broker simulator |
|
|
185
188
|
| `createPaperEngine(options)` | Factory for `PaperEngine` |
|
|
186
189
|
|
|
190
|
+
### Sessions And Notifications
|
|
191
|
+
|
|
192
|
+
| Export | Summary |
|
|
193
|
+
| --------------------------------- | ----------------------------------------------------------- |
|
|
194
|
+
| `TradingSession` | One account, one or many symbols, with risk-sized brackets |
|
|
195
|
+
| `SessionManager` | Create and track sessions; gates live mode |
|
|
196
|
+
| `createSessionManager(options)` | Factory for `SessionManager` |
|
|
197
|
+
| `attachNotifier(session, options)`| Fire a callback or webhook on fills, risk halts, drawdown |
|
|
198
|
+
|
|
199
|
+
`SessionManager.create({ symbols: ["BTC", "ETH"] })` opens a multi-symbol portfolio session; pass a single `symbol` for the original behavior. Per-symbol calls take a `symbol` argument (`pushBar(bar, symbol)`, `placeOrder({ symbol })`). Portfolio-level `RiskManager` options `maxGrossExposurePct` and `maxNetExposurePct` (default 0, off) reject orders that would breach the cap.
|
|
200
|
+
|
|
187
201
|
### Broker Adapters
|
|
188
202
|
|
|
189
203
|
| Export | Summary |
|
|
@@ -287,7 +301,7 @@ import { createServer, startStdioServer } from "tradelab/mcp";
|
|
|
287
301
|
| `createServer()` | Build an MCP server with tradelab tools |
|
|
288
302
|
| `startStdioServer()` | Start the MCP server on stdio |
|
|
289
303
|
|
|
290
|
-
See [mcp.md](mcp.md) for client configuration and tool payload examples.
|
|
304
|
+
The server exposes 25 tools: 8 research, 4 research-loop (`research_open`, `research_log`, `research_recall`, `research_close`), and 13 live-trading (sessions, orders, brackets, kill-switch). See [mcp.md](mcp.md) for client configuration and tool payload examples.
|
|
291
305
|
|
|
292
306
|
## Types
|
|
293
307
|
|
|
@@ -198,6 +198,15 @@ tradelab walk-forward \
|
|
|
198
198
|
|
|
199
199
|
You can pass `--strategy ./strategy.mjs` for local modules that export `signalFactory(params, args)` and either `parameterSets` or `createParameterSets(args)`.
|
|
200
200
|
|
|
201
|
+
### Run a Preset
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
tradelab run ema-cross --source yahoo --symbol SPY --period 1y
|
|
205
|
+
tradelab run rsi-reversion --source csv --csvPath ./btc.csv --params '{"period":14,"oversold":25}'
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
`tradelab run <preset>` backtests a named built-in strategy and prints a plain-English summary of the result. Use `--params` to override the preset defaults. Run `tradelab run` with an unknown name to see the available presets.
|
|
209
|
+
|
|
201
210
|
### Live and Paper
|
|
202
211
|
|
|
203
212
|
```bash
|
package/docs/mcp.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
## Safety
|
|
8
8
|
|
|
9
|
-
**Paper is the default and always safe.** Every session is paper unless you explicitly request live mode. Live mode requires all three gates simultaneously
|
|
9
|
+
**Paper is the default and always safe.** Every session is paper unless you explicitly request live mode. Live mode requires all three gates simultaneously. If any is missing the call throws and nothing is created:
|
|
10
10
|
|
|
11
11
|
1. Environment variable `TRADELAB_ALLOW_LIVE=true` must be set in the server process.
|
|
12
12
|
2. The `create_session` call must include `confirmLive: true`.
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
|
|
15
15
|
Every session also enforces:
|
|
16
16
|
|
|
17
|
-
- `maxDailyLossPct
|
|
18
|
-
- `halt_all
|
|
17
|
+
- `maxDailyLossPct`: if realized day PnL drops below this percentage of starting equity, all new `place_order` calls are rejected for the remainder of the day.
|
|
18
|
+
- `halt_all`: an emergency kill-switch tool that flattens all positions and stops all sessions in the server process.
|
|
19
19
|
|
|
20
20
|
Brackets (stop + target) are true OCO: when one leg fills, the sibling is canceled automatically.
|
|
21
21
|
|
package/docs/research.md
CHANGED
|
@@ -154,4 +154,19 @@ For a strategy you might run live, combine several checks:
|
|
|
154
154
|
5. Penalize multiple trials with deflated Sharpe or sweep haircut.
|
|
155
155
|
6. Re-run on a later untouched data period before using live credentials.
|
|
156
156
|
|
|
157
|
+
## Agent Research Loop
|
|
158
|
+
|
|
159
|
+
`createResearchStore({ dir })` persists a research session so an agent (or you) can iterate across many runs without losing the thread:
|
|
160
|
+
|
|
161
|
+
```js
|
|
162
|
+
import { createResearchStore } from "tradelab";
|
|
163
|
+
|
|
164
|
+
const store = createResearchStore({ dir: ".tradelab/research" });
|
|
165
|
+
await store.open("btc-trend", "find a robust BTC trend strategy");
|
|
166
|
+
await store.log("btc-trend", { hypothesis: "ema 20/50", params: { fast: 20, slow: 50 }, metrics, verdict });
|
|
167
|
+
const { entries, summary } = await store.recall("btc-trend");
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`recall` returns a synthesized summary naming the best Sharpe so far and how many runs were flagged as likely overfit. Over MCP, the same store backs the `research_open`, `research_log`, `research_recall`, and `research_close` tools, and `run_backtest` auto-logs an overfitting verdict when called with a `researchId`. See [the MCP guide](mcp.md).
|
|
171
|
+
|
|
157
172
|
<small>[Back to docs](README.md)</small>
|
package/package.json
CHANGED
package/src/live/session.js
CHANGED
|
@@ -161,11 +161,11 @@ export class TradingSession {
|
|
|
161
161
|
return order;
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
// Sync event handler
|
|
164
|
+
// Sync event handler; fire-and-forget async OCO work via a stored promise
|
|
165
165
|
_onBrokerFillSync(order) {
|
|
166
166
|
this._record("order:filled", this._withMeta(order));
|
|
167
167
|
|
|
168
|
-
// Resting entry order (e.g. a limit) just filled
|
|
168
|
+
// Resting entry order (e.g. a limit) just filled; attach its staged bracket.
|
|
169
169
|
// Scan _pendingBrackets for a match (works for both single- and multi-symbol sessions).
|
|
170
170
|
for (const [sym, staged] of this._pendingBrackets) {
|
|
171
171
|
if (matchesOrderRef(staged, order)) {
|
|
@@ -179,11 +179,11 @@ export class TradingSession {
|
|
|
179
179
|
}
|
|
180
180
|
}
|
|
181
181
|
|
|
182
|
-
// Track bracket leg fills for OCO
|
|
182
|
+
// Track bracket leg fills for OCO; find which symbol this fill belongs to
|
|
183
183
|
for (const [sym, bracket] of this.brackets) {
|
|
184
184
|
if (bracket && (order.orderId === bracket.stopId || order.orderId === bracket.targetId)) {
|
|
185
185
|
const siblingId = order.orderId === bracket.stopId ? bracket.targetId : bracket.stopId;
|
|
186
|
-
// Schedule the cancel
|
|
186
|
+
// Schedule the cancel; simulateBar is still iterating orders, so we must not await here.
|
|
187
187
|
// We keep a pending cancel promise that refresh() awaits.
|
|
188
188
|
this._pendingCancelPromise = (async () => {
|
|
189
189
|
if (siblingId) await this.broker.cancelOrder(siblingId).catch(() => {});
|
|
@@ -310,7 +310,7 @@ export class TradingSession {
|
|
|
310
310
|
clientOrderId: entryClientOrderId,
|
|
311
311
|
});
|
|
312
312
|
|
|
313
|
-
// Stage bracket if needed
|
|
313
|
+
// Stage bracket if needed; market orders fill synchronously in PaperEngine
|
|
314
314
|
if (Number.isFinite(stop) || Number.isFinite(target) || Number.isFinite(rr)) {
|
|
315
315
|
const parentEntryId = receipt?.clientOrderId ?? entryClientOrderId;
|
|
316
316
|
if (receipt.status === "filled") {
|
package/src/mcp/tools.js
CHANGED
|
@@ -193,7 +193,7 @@ export const researchPlusTools = {
|
|
|
193
193
|
metrics,
|
|
194
194
|
monteCarlo: null,
|
|
195
195
|
deflatedSharpe: null,
|
|
196
|
-
note: `Only ${tradePnls.length} trade(s)
|
|
196
|
+
note: `Only ${tradePnls.length} trade(s), need at least 2 for statistical analysis.`,
|
|
197
197
|
};
|
|
198
198
|
}
|
|
199
199
|
const mc = monteCarlo({
|