tradelab 0.5.0 → 1.0.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.
Files changed (54) hide show
  1. package/README.md +89 -41
  2. package/bin/tradelab.js +276 -30
  3. package/dist/cjs/data.cjs +134 -104
  4. package/dist/cjs/index.cjs +378 -177
  5. package/dist/cjs/live.cjs +3350 -0
  6. package/docs/README.md +21 -9
  7. package/docs/api-reference.md +87 -29
  8. package/docs/backtest-engine.md +37 -53
  9. package/docs/data-reporting-cli.md +60 -34
  10. package/docs/examples.md +6 -12
  11. package/docs/live-trading.md +186 -0
  12. package/examples/yahooEmaCross.js +1 -6
  13. package/package.json +18 -3
  14. package/src/data/csv.js +24 -14
  15. package/src/data/index.js +1 -5
  16. package/src/data/yahoo.js +6 -19
  17. package/src/engine/backtest.js +137 -144
  18. package/src/engine/backtestTicks.js +89 -37
  19. package/src/engine/barSystemRunner.js +182 -118
  20. package/src/engine/execution.js +11 -39
  21. package/src/engine/portfolio.js +54 -6
  22. package/src/engine/walkForward.js +37 -14
  23. package/src/index.js +2 -11
  24. package/src/live/broker/alpaca.js +254 -0
  25. package/src/live/broker/binance.js +351 -0
  26. package/src/live/broker/coinbase.js +339 -0
  27. package/src/live/broker/interactiveBrokers.js +123 -0
  28. package/src/live/broker/interface.js +74 -0
  29. package/src/live/clock.js +56 -0
  30. package/src/live/engine/candleAggregator.js +154 -0
  31. package/src/live/engine/liveEngine.js +694 -0
  32. package/src/live/engine/paperEngine.js +453 -0
  33. package/src/live/engine/riskManager.js +185 -0
  34. package/src/live/engine/stateManager.js +112 -0
  35. package/src/live/events.js +48 -0
  36. package/src/live/feed/brokerFeed.js +35 -0
  37. package/src/live/feed/interface.js +28 -0
  38. package/src/live/feed/pollingFeed.js +105 -0
  39. package/src/live/index.js +27 -0
  40. package/src/live/logger.js +82 -0
  41. package/src/live/orchestrator.js +133 -0
  42. package/src/live/storage/interface.js +36 -0
  43. package/src/live/storage/jsonFileStorage.js +112 -0
  44. package/src/metrics/buildMetrics.js +18 -41
  45. package/src/reporting/exportBacktestArtifacts.js +1 -4
  46. package/src/reporting/exportTradesCsv.js +2 -7
  47. package/src/reporting/renderHtmlReport.js +8 -13
  48. package/src/utils/indicators.js +1 -2
  49. package/src/utils/positionSizing.js +16 -2
  50. package/src/utils/time.js +4 -12
  51. package/templates/report.html +23 -9
  52. package/templates/report.js +83 -69
  53. package/types/index.d.ts +21 -3
  54. package/types/live.d.ts +382 -0
package/docs/README.md CHANGED
@@ -4,20 +4,23 @@
4
4
 
5
5
  - [Backtest engine](backtest-engine.md)
6
6
  - [Data, reporting, and CLI](data-reporting-cli.md)
7
+ - [Live trading](live-trading.md)
7
8
  - [Strategy examples](examples.md)
8
9
  - [API reference](api-reference.md)
9
10
 
10
11
  ## Choose a path
11
12
 
12
- | Goal | Start here |
13
- | --- | --- |
14
- | Run one strategy on one dataset | [Backtest engine](backtest-engine.md) |
15
- | Load Yahoo or CSV data | [Data, reporting, and CLI](data-reporting-cli.md) |
13
+ | Goal | Start here |
14
+ | ------------------------------------------ | ------------------------------------------------- |
15
+ | Run one strategy on one dataset | [Backtest engine](backtest-engine.md) |
16
+ | Load Yahoo or CSV data | [Data, reporting, and CLI](data-reporting-cli.md) |
16
17
  | Export reports or machine-readable results | [Data, reporting, and CLI](data-reporting-cli.md) |
17
- | Run multiple symbols together | [Backtest engine](backtest-engine.md) |
18
- | Run walk-forward validation | [Backtest engine](backtest-engine.md) |
19
- | See complete strategy patterns | [Strategy examples](examples.md) |
20
- | Check the exact public exports | [API reference](api-reference.md) |
18
+ | Run multiple symbols together | [Backtest engine](backtest-engine.md) |
19
+ | Run walk-forward validation | [Backtest engine](backtest-engine.md) |
20
+ | Run one strategy live or in paper mode | [Live trading](live-trading.md) |
21
+ | Run multiple live systems together | [Live trading](live-trading.md) |
22
+ | See complete strategy patterns | [Strategy examples](examples.md) |
23
+ | Check the exact public exports | [API reference](api-reference.md) |
21
24
 
22
25
  ## Package scope
23
26
 
@@ -26,12 +29,12 @@ tradelab is built for:
26
29
  - candle-based strategy research
27
30
  - optional tick or quote replay with event-driven fills
28
31
  - historical backtests with configurable fills and costs
32
+ - live and paper execution using broker adapters
29
33
  - CSV and Yahoo-based data workflows
30
34
  - exportable outputs for review or automation
31
35
 
32
36
  tradelab is not built for:
33
37
 
34
- - live broker execution
35
38
  - exchange microstructure modeling
36
39
 
37
40
  ## Common workflows
@@ -56,10 +59,19 @@ tradelab is not built for:
56
59
  3. Run `walkForwardOptimize()`
57
60
  4. Review per-window winners before trusting the aggregate result
58
61
 
62
+ ### Live execution workflow
63
+
64
+ 1. Build a `signal()` used in backtest first
65
+ 2. Wire it into `LiveEngine` with a broker or `PaperEngine`
66
+ 3. Persist state with `JsonFileStorage`
67
+ 4. Start with `tradelab paper` or `tradelab live --paper`
68
+ 5. Inspect persisted state with `tradelab status`
69
+
59
70
  ## Documentation map
60
71
 
61
72
  - [Backtest engine](backtest-engine.md): strategy inputs, engine options, result shape, portfolio mode, walk-forward mode
62
73
  - [Data, reporting, and CLI](data-reporting-cli.md): data loading, cache behavior, exports, terminal usage
74
+ - [Live trading](live-trading.md): live engine, broker adapters, paper mode, orchestration, lifecycle, and state
63
75
  - [Strategy examples](examples.md): mean reversion, breakout, sentiment, LLM, and portfolio research patterns
64
76
  - [API reference](api-reference.md): compact export index
65
77
 
@@ -1,5 +1,5 @@
1
-
2
1
  # API reference
2
+
3
3
  <small>[Back to main page](README.md)</small>
4
4
 
5
5
  This page is the compact index of public exports.
@@ -8,40 +8,95 @@ If you are learning the package, start with [backtest-engine.md](backtest-engine
8
8
 
9
9
  ## Backtesting
10
10
 
11
- | Export | Summary |
12
- | --- | --- |
13
- | `backtest(options)` | Run one strategy on one candle series |
14
- | `backtestTicks(options)` | Run one strategy on tick or quote data |
15
- | `backtestPortfolio(options)` | Run multiple systems through a shared-capital portfolio engine |
16
- | `walkForwardOptimize(options)` | Run rolling or anchored train/test validation |
17
- | `buildMetrics(input)` | Compute metrics from realized trades and equity data |
11
+ | Export | Summary |
12
+ | ------------------------------ | -------------------------------------------------------------- |
13
+ | `backtest(options)` | Run one strategy on one candle series |
14
+ | `backtestTicks(options)` | Run one strategy on tick or quote data |
15
+ | `backtestPortfolio(options)` | Run multiple systems through a shared-capital portfolio engine |
16
+ | `walkForwardOptimize(options)` | Run rolling or anchored train/test validation |
17
+ | `buildMetrics(input)` | Compute metrics from realized trades and equity data |
18
18
 
19
19
  ## Data
20
20
 
21
- | Export | Summary |
22
- | --- | --- |
23
- | `getHistoricalCandles(options)` | Load candles from Yahoo or CSV |
24
- | `backtestHistorical({ data, backtestOptions })` | Load candles and immediately run `backtest()` |
25
- | `fetchHistorical(symbol, interval, period, options)` | Call the Yahoo layer directly |
26
- | `fetchLatestCandle(symbol, interval, options)` | Fetch the latest Yahoo candle |
27
- | `loadCandlesFromCSV(filePath, options)` | Parse and normalize a CSV file |
28
- | `normalizeCandles(candles)` | Normalize candle field names and sort/dedupe |
29
- | `mergeCandles(...arrays)` | Merge multiple candle arrays |
30
- | `candleStats(candles)` | Return summary stats for a candle array |
31
- | `saveCandlesToCache(candles, meta)` | Write normalized candles to the local cache |
32
- | `loadCandlesFromCache(symbol, interval, period, outDir)` | Read normalized candles from the local cache |
33
- | `cachedCandlesPath(symbol, interval, period, outDir)` | Return the expected cache path |
21
+ | Export | Summary |
22
+ | -------------------------------------------------------- | --------------------------------------------- |
23
+ | `getHistoricalCandles(options)` | Load candles from Yahoo or CSV |
24
+ | `backtestHistorical({ data, backtestOptions })` | Load candles and immediately run `backtest()` |
25
+ | `fetchHistorical(symbol, interval, period, options)` | Call the Yahoo layer directly |
26
+ | `fetchLatestCandle(symbol, interval, options)` | Fetch the latest Yahoo candle |
27
+ | `loadCandlesFromCSV(filePath, options)` | Parse and normalize a CSV file |
28
+ | `normalizeCandles(candles)` | Normalize candle field names and sort/dedupe |
29
+ | `mergeCandles(...arrays)` | Merge multiple candle arrays |
30
+ | `candleStats(candles)` | Return summary stats for a candle array |
31
+ | `saveCandlesToCache(candles, meta)` | Write normalized candles to the local cache |
32
+ | `loadCandlesFromCache(symbol, interval, period, outDir)` | Read normalized candles from the local cache |
33
+ | `cachedCandlesPath(symbol, interval, period, outDir)` | Return the expected cache path |
34
34
 
35
35
  ## Reporting
36
36
 
37
- | Export | Summary |
38
- | --- | --- |
39
- | `renderHtmlReport(options)` | Return the HTML report as a string |
40
- | `exportHtmlReport(options)` | Write the HTML report to disk |
41
- | `exportTradesCsv(trades, options)` | Write a CSV ledger of trades or positions |
42
- | `exportMetricsJSON(options)` | Write machine-readable metrics JSON |
37
+ | Export | Summary |
38
+ | ---------------------------------- | ------------------------------------------ |
39
+ | `renderHtmlReport(options)` | Return the HTML report as a string |
40
+ | `exportHtmlReport(options)` | Write the HTML report to disk |
41
+ | `exportTradesCsv(trades, options)` | Write a CSV ledger of trades or positions |
42
+ | `exportMetricsJSON(options)` | Write machine-readable metrics JSON |
43
43
  | `exportBacktestArtifacts(options)` | Write HTML, CSV, and metrics JSON together |
44
44
 
45
+ ## Live module (`tradelab/live`)
46
+
47
+ Live exports are under a separate entrypoint:
48
+
49
+ ```js
50
+ import { LiveEngine, PaperEngine } from "tradelab/live";
51
+ ```
52
+
53
+ ### Engine and orchestration
54
+
55
+ - `LiveEngine`
56
+ - `LiveOrchestrator`
57
+ - `PaperEngine`
58
+ - `CandleAggregator`
59
+ - `RiskManager`
60
+ - `StateManager`
61
+
62
+ ### Broker and feed adapters
63
+
64
+ - `BrokerAdapter`
65
+ - `AlpacaBroker`
66
+ - `BinanceBroker`
67
+ - `CoinbaseBroker`
68
+ - `InteractiveBrokersBroker`
69
+ - `FeedProvider`
70
+ - `BrokerFeed`
71
+ - `PollingFeed`
72
+
73
+ ### Storage and runtime utilities
74
+
75
+ - `StorageProvider`
76
+ - `JsonFileStorage`
77
+ - `EventBus`
78
+ - `LiveLogger`
79
+ - `BrokerClock`
80
+
81
+ ### Factories
82
+
83
+ - `createLiveEngine(options)`
84
+ - `createLiveOrchestrator(options)`
85
+ - `createPaperEngine(options)`
86
+ - `createAlpacaBroker(options)`
87
+ - `createBinanceBroker(options)`
88
+ - `createCoinbaseBroker(options)`
89
+ - `createInteractiveBrokersBroker(options)`
90
+ - `createBrokerFeed(options)`
91
+ - `createPollingFeed(options)`
92
+ - `createJsonFileStorage(options)`
93
+ - `createCandleAggregator(options)`
94
+ - `createRiskManager(options)`
95
+ - `createStateManager(options)`
96
+ - `createEventBus()`
97
+ - `createLogger(options)`
98
+ - `createClock(options)`
99
+
45
100
  ## Indicators and utilities
46
101
 
47
102
  ### Indicators
@@ -70,6 +125,9 @@ If you are learning the package, start with [backtest-engine.md](backtest-engine
70
125
 
71
126
  ## Types
72
127
 
73
- The package ships declarations in [../types/index.d.ts](../types/index.d.ts). Use that file when you need the exact option and result contracts in TypeScript or editor IntelliSense.
128
+ The package ships declarations in:
74
129
 
75
- <small>[Back to main page](README.md)</small>
130
+ - [../types/index.d.ts](../types/index.d.ts) for the main module
131
+ - [../types/live.d.ts](../types/live.d.ts) for `tradelab/live`
132
+
133
+ <small>[Back to main page](README.md)</small>
@@ -2,7 +2,6 @@
2
2
 
3
3
  <small>[Back to main page](README.md)</small>
4
4
 
5
-
6
5
  This page covers the simulation layer:
7
6
 
8
7
  - `backtest(options)`
@@ -15,15 +14,17 @@ This page covers the simulation layer:
15
14
 
16
15
  Use the engine layer when you already have candles and want to simulate strategy behavior, inspect the result, and export or post-process it.
17
16
 
17
+ The same `signal()` contract is used by `LiveEngine` in `tradelab/live`, so strategy logic can move from research to execution without rewriting signal inputs.
18
+
18
19
  ## Choose the right function
19
20
 
20
- | Use case | Function |
21
- | --- | --- |
22
- | One strategy on one candle series | `backtest()` |
23
- | One strategy on tick or quote data | `backtestTicks()` |
24
- | Multiple symbols with one combined result | `backtestPortfolio()` |
21
+ | Use case | Function |
22
+ | ----------------------------------------- | ----------------------- |
23
+ | One strategy on one candle series | `backtest()` |
24
+ | One strategy on tick or quote data | `backtestTicks()` |
25
+ | Multiple symbols with one combined result | `backtestPortfolio()` |
25
26
  | Rolling or anchored train/test validation | `walkForwardOptimize()` |
26
- | Recompute metrics from realized trades | `buildMetrics()` |
27
+ | Recompute metrics from realized trades | `buildMetrics()` |
27
28
 
28
29
  ## Candle input
29
30
 
@@ -76,16 +77,16 @@ const result = backtest({
76
77
 
77
78
  ### Core options
78
79
 
79
- | Option | Purpose |
80
- | --- | --- |
81
- | `symbol`, `interval`, `range` | Labels carried into results and exports |
82
- | `equity` | Starting equity, default `10000` |
83
- | `riskPct` or `riskFraction` | Default risk per trade when `qty` is not provided |
84
- | `warmupBars` | Bars skipped before signal evaluation starts |
85
- | `flattenAtClose` | Forces end-of-day exit when enabled |
86
- | `collectEqSeries`, `collectReplay` | Builds extra output for charts and exports |
87
- | `strict` | Throws on direct lookahead access such as `candles[index + 1]` |
88
- | `costs` | Slippage, spread, and commission model |
80
+ | Option | Purpose |
81
+ | ---------------------------------- | -------------------------------------------------------------- |
82
+ | `symbol`, `interval`, `range` | Labels carried into results and exports |
83
+ | `equity` | Starting equity, default `10000` |
84
+ | `riskPct` or `riskFraction` | Default risk per trade when `qty` is not provided |
85
+ | `warmupBars` | Bars skipped before signal evaluation starts |
86
+ | `flattenAtClose` | Forces end-of-day exit when enabled |
87
+ | `collectEqSeries`, `collectReplay` | Builds extra output for charts and exports |
88
+ | `strict` | Throws on direct lookahead access such as `candles[index + 1]` |
89
+ | `costs` | Slippage, spread, and commission model |
89
90
 
90
91
  If you are starting from scratch, the most useful options to set explicitly are:
91
92
 
@@ -97,38 +98,31 @@ If you are starting from scratch, the most useful options to set explicitly are:
97
98
 
98
99
  ### Signal contract
99
100
 
100
- The signal function receives:
101
+ The signal function receives a context object with these fields:
101
102
 
103
+ <!-- prettier-ignore -->
102
104
  ```js
103
- {
104
- candles,
105
- index,
106
- bar,
107
- equity,
108
- openPosition,
109
- pendingOrder
110
- }
105
+ { candles, index, bar, equity, openPosition, pendingOrder }
111
106
  ```
112
107
 
113
108
  Return `null` for no trade, or a signal object:
114
109
 
115
110
  ```js
116
- {
117
- side: "long" | "short",
118
- entry: 101.25,
119
- stop: 99.75,
120
- takeProfit: 104.25
121
- }
111
+ // minimal
112
+ { side: "long", stop: 99.75, rr: 2 }
113
+
114
+ // explicit targets
115
+ { side: "long", entry: 101.25, stop: 99.75, takeProfit: 104.25 }
122
116
  ```
123
117
 
124
118
  ### Signal conveniences
125
119
 
126
- | Field | Behavior |
127
- | --- | --- |
128
- | `side` | Accepts `long`, `short`, `buy`, or `sell` |
129
- | `entry` | Defaults to the current close if omitted |
130
- | `takeProfit` | Can be derived from `rr` or `_rr` |
131
- | `qty` or `size` | Overrides risk-based sizing |
120
+ | Field | Behavior |
121
+ | --------------------------- | ------------------------------------------------ |
122
+ | `side` | Accepts `long`, `short`, `buy`, or `sell` |
123
+ | `entry` | Defaults to the current close if omitted |
124
+ | `takeProfit` | Can be derived from `rr` or `_rr` |
125
+ | `qty` or `size` | Overrides risk-based sizing |
132
126
  | `riskPct` or `riskFraction` | Overrides the global risk setting for that trade |
133
127
 
134
128
  Practical rule: return the smallest signal object that expresses the trade clearly. In many strategies that is just `side`, `stop`, and `rr`.
@@ -207,19 +201,11 @@ Recommended order of adoption:
207
201
 
208
202
  ## Result shape
209
203
 
210
- `backtest()` returns:
204
+ `backtest()` returns an object with these fields:
211
205
 
206
+ <!-- prettier-ignore -->
212
207
  ```js
213
- {
214
- symbol,
215
- interval,
216
- range,
217
- trades,
218
- positions,
219
- metrics,
220
- eqSeries,
221
- replay
222
- }
208
+ { symbol, interval, range, trades, positions, openPositions, metrics, eqSeries, replay }
223
209
  ```
224
210
 
225
211
  ### `trades`
@@ -267,9 +253,7 @@ Useful first checks after any run:
267
253
  Realized equity points:
268
254
 
269
255
  ```js
270
- [
271
- { time, timestamp, equity }
272
- ]
256
+ [{ time, timestamp, equity }];
273
257
  ```
274
258
 
275
259
  `time` and `timestamp` contain the same Unix-millisecond value.
@@ -390,4 +374,4 @@ Most users do not need this directly. Use it when:
390
374
  - trusting one backtest without out-of-sample validation
391
375
  - debugging a strategy with `strict: false` when lookahead is possible
392
376
 
393
- <small>[Back to main page](README.md)</small>
377
+ <small>[Back to main page](README.md)</small>
@@ -1,4 +1,5 @@
1
1
  # Data, reporting, and CLI
2
+
2
3
  <small>[Back to main page](README.md)</small>
3
4
 
4
5
  This page covers the parts of the package around the core engine:
@@ -6,7 +7,7 @@ This page covers the parts of the package around the core engine:
6
7
  - historical data loading
7
8
  - local cache helpers
8
9
  - export helpers
9
- - command-line usage
10
+ - command-line usage for backtest and live workflows
10
11
 
11
12
  ## Overview
12
13
 
@@ -14,13 +15,13 @@ If you are not bringing your own candles yet, start here.
14
15
 
15
16
  ## Choose the right entry point
16
17
 
17
- | Use case | Function |
18
- | --- | --- |
18
+ | Use case | Function |
19
+ | --------------------------------------------------------- | ------------------------ |
19
20
  | Load data without caring about the source-specific helper | `getHistoricalCandles()` |
20
- | Fetch directly from Yahoo | `fetchHistorical()` |
21
- | Load a local CSV file | `loadCandlesFromCSV()` |
22
- | Reuse saved normalized data | `loadCandlesFromCache()` |
23
- | Try the package from a terminal first | `tradelab` CLI |
21
+ | Fetch directly from Yahoo | `fetchHistorical()` |
22
+ | Load a local CSV file | `loadCandlesFromCSV()` |
23
+ | Reuse saved normalized data | `loadCandlesFromCache()` |
24
+ | Try the package from a terminal first | `tradelab` CLI |
24
25
 
25
26
  ## Historical data
26
27
 
@@ -50,15 +51,15 @@ If you are writing application code, prefer `getHistoricalCandles()` over callin
50
51
 
51
52
  ### Yahoo options
52
53
 
53
- | Option | Purpose |
54
- | --- | --- |
55
- | `symbol` | Ticker or Yahoo symbol |
56
- | `interval` | Candle interval such as `1d` or `5m` |
57
- | `period` | Lookback period such as `6mo` or `1y` |
54
+ | Option | Purpose |
55
+ | ---------------- | ----------------------------------------------------- |
56
+ | `symbol` | Ticker or Yahoo symbol |
57
+ | `interval` | Candle interval such as `1d` or `5m` |
58
+ | `period` | Lookback period such as `6mo` or `1y` |
58
59
  | `includePrePost` | Includes premarket and postmarket data when supported |
59
- | `cache` | Reuses saved normalized data |
60
- | `refresh` | Forces a fresh download even if cache exists |
61
- | `cacheDir` | Overrides the default cache directory |
60
+ | `cache` | Reuses saved normalized data |
61
+ | `refresh` | Forces a fresh download even if cache exists |
62
+ | `cacheDir` | Overrides the default cache directory |
62
63
 
63
64
  The Yahoo layer retries transient failures with exponential backoff. If the endpoint still fails, the error message points users toward CSV or cached data.
64
65
 
@@ -149,12 +150,9 @@ The main bundle export. By default it writes:
149
150
 
150
151
  Return value:
151
152
 
153
+ <!-- prettier-ignore -->
152
154
  ```js
153
- {
154
- csv,
155
- html,
156
- metrics
157
- }
155
+ { csv, html, metrics }
158
156
  ```
159
157
 
160
158
  If you only need one output type, call the narrower helper directly.
@@ -184,13 +182,16 @@ The CLI is best for quick iteration, smoke tests, and trying the package before
184
182
 
185
183
  ## Commands
186
184
 
187
- | Command | Purpose |
188
- | --- | --- |
189
- | `tradelab backtest` | Run a single backtest from Yahoo or CSV |
190
- | `tradelab portfolio` | Run a simple multi-file portfolio backtest |
185
+ | Command | Purpose |
186
+ | ----------------------- | ------------------------------------------------------------------------- |
187
+ | `tradelab backtest` | Run a single backtest from Yahoo or CSV |
188
+ | `tradelab portfolio` | Run a simple multi-file portfolio backtest |
191
189
  | `tradelab walk-forward` | Run rolling or anchored validation with built-in or local strategy search |
192
- | `tradelab prefetch` | Download and cache Yahoo data |
193
- | `tradelab import-csv` | Normalize and cache a CSV file |
190
+ | `tradelab live` | Run live engine or orchestrator mode |
191
+ | `tradelab paper` | Run live engine in paper broker mode |
192
+ | `tradelab status` | Inspect persisted live namespace state |
193
+ | `tradelab prefetch` | Download and cache Yahoo data |
194
+ | `tradelab import-csv` | Normalize and cache a CSV file |
194
195
 
195
196
  ### Backtest
196
197
 
@@ -238,6 +239,31 @@ tradelab walk-forward \
238
239
 
239
240
  The CLI walk-forward command defaults to the built-in `ema-cross` search, but `--strategy ./path/to/module.mjs` can now load a local module that exports `signalFactory(params, args)` and either `parameterSets` or `createParameterSets(args)`. Inline JSON grids are also accepted through `--parameterSets`.
240
241
 
242
+ ### Live and paper
243
+
244
+ ```bash
245
+ tradelab paper --symbol AAPL --interval 1m --mode polling --once true
246
+
247
+ tradelab live \
248
+ --strategy ./mySignal.js \
249
+ --symbol AAPL \
250
+ --interval 1m \
251
+ --broker alpaca \
252
+ --apiKey $APCA_KEY \
253
+ --apiSecret $APCA_SECRET
254
+
255
+ tradelab live --config ./live-portfolio.json --paper --mode polling --once true
256
+ ```
257
+
258
+ For full runtime details, see [live-trading.md](live-trading.md).
259
+
260
+ ### Status
261
+
262
+ ```bash
263
+ tradelab status --dir ./output/live-state
264
+ tradelab status --dir ./output/live-state --namespace my-system
265
+ ```
266
+
241
267
  ### Cache utilities
242
268
 
243
269
  ```bash
@@ -247,12 +273,12 @@ tradelab import-csv --csvPath ./data/spy.csv --symbol SPY --interval 1d
247
273
 
248
274
  ## Troubleshooting
249
275
 
250
- | Problem | Check first |
251
- | --- | --- |
252
- | Yahoo request errors | enable cache, retry later, or fall back to CSV |
253
- | Unexpected trade count | `warmupBars`, `flattenAtClose`, and signal frequency |
254
- | Empty result | candle order, signal logic, and stop/target validity |
255
- | Confusing CSV import | inspect normalized bars from `loadCandlesFromCSV()` before backtesting |
256
- | Export confusion | use metrics JSON first if you need programmatic output |
276
+ | Problem | Check first |
277
+ | ---------------------- | ---------------------------------------------------------------------- |
278
+ | Yahoo request errors | enable cache, retry later, or fall back to CSV |
279
+ | Unexpected trade count | `warmupBars`, `flattenAtClose`, and signal frequency |
280
+ | Empty result | candle order, signal logic, and stop/target validity |
281
+ | Confusing CSV import | inspect normalized bars from `loadCandlesFromCSV()` before backtesting |
282
+ | Export confusion | use metrics JSON first if you need programmatic output |
257
283
 
258
- <small>[Back to main page](README.md)</small>
284
+ <small>[Back to main page](README.md)</small>
package/docs/examples.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Strategy examples
2
+
2
3
  <small>[Back to main page](README.md)</small>
3
4
 
4
5
  These are research templates. They show how to wire different kinds of data and execution assumptions into the engine without changing the output pipeline.
@@ -117,14 +118,13 @@ const candles = await getHistoricalCandles({
117
118
 
118
119
  const sentimentByDay = new Map([
119
120
  ["2025-01-02", 0.75],
120
- ["2025-01-03", -0.10],
121
+ ["2025-01-03", -0.1],
121
122
  // ...
122
123
  ]);
123
124
 
124
125
  const enriched = candles.map((bar) => ({
125
126
  ...bar,
126
- sentiment:
127
- sentimentByDay.get(new Date(bar.time).toISOString().slice(0, 10)) ?? 0,
127
+ sentiment: sentimentByDay.get(new Date(bar.time).toISOString().slice(0, 10)) ?? 0,
128
128
  }));
129
129
 
130
130
  const result = backtest({
@@ -137,11 +137,7 @@ const result = backtest({
137
137
  const slow = ema(closes, 30);
138
138
  const last = closes.length - 1;
139
139
 
140
- if (
141
- fast[last - 1] <= slow[last - 1] &&
142
- fast[last] > slow[last] &&
143
- bar.sentiment > 0.5
144
- ) {
140
+ if (fast[last - 1] <= slow[last - 1] && fast[last] > slow[last] && bar.sentiment > 0.5) {
145
141
  return {
146
142
  side: "long",
147
143
  entry: bar.close,
@@ -180,9 +176,7 @@ const labeled = await Promise.all(
180
176
  regime:
181
177
  index < 20
182
178
  ? "neutral"
183
- : await classifyRegime(
184
- candles.slice(index - 20, index).map((c) => c.close)
185
- ),
179
+ : await classifyRegime(candles.slice(index - 20, index).map((c) => c.close)),
186
180
  }))
187
181
  );
188
182
 
@@ -278,4 +272,4 @@ const result = backtestPortfolio({
278
272
 
279
273
  `result.eqSeries` includes `lockedCapital` and `availableCapital` at each realized equity point. Use those to see how often the portfolio was fully deployed versus sitting partially idle.
280
274
 
281
- <small>[Back to main page](README.md)</small>
275
+ <small>[Back to main page](README.md)</small>