@livefolio/sdk 0.3.2 → 0.3.4
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/dist/index.d.ts +181 -50
- package/dist/index.js +692 -160
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -112,9 +112,9 @@ declare class IndicatorHandle {
|
|
|
112
112
|
private _getLatestSeriesDate;
|
|
113
113
|
private _ensureFresh;
|
|
114
114
|
private _sync;
|
|
115
|
+
private _fetchRawBarsForIncremental;
|
|
115
116
|
private _upsertSeries;
|
|
116
117
|
private _querySeriesFromDb;
|
|
117
|
-
withMarket(market: MarketProvider): IndicatorHandle;
|
|
118
118
|
/**
|
|
119
119
|
* Apply leverage compounding to a raw bar series, anchored to a stored
|
|
120
120
|
* leveraged value. Used by both `_sync` and `computeAt` so they stay
|
|
@@ -130,37 +130,72 @@ declare class IndicatorHandle {
|
|
|
130
130
|
*/
|
|
131
131
|
private _applyLeverage;
|
|
132
132
|
/**
|
|
133
|
-
* Compute the indicator's value at `date`
|
|
134
|
-
*
|
|
133
|
+
* Compute the indicator's value at `date` without persisting anything, with
|
|
134
|
+
* optional live-quote `overrides` keyed by raw market symbol (the same symbol
|
|
135
|
+
* space `MarketProvider.fetchBars` uses — ticker symbols for Price/SMA/etc.,
|
|
136
|
+
* `^VIX` / `^VIX3M` for macro, FRED series IDs like `DGS3MO` for Treasury).
|
|
135
137
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
*
|
|
142
|
-
*
|
|
143
|
-
*
|
|
144
|
-
|
|
145
|
-
|
|
138
|
+
* Bars for the underlying symbol are resolved storage-first when the market
|
|
139
|
+
* hasn't yet produced bars for `date` (trading day still open), and storage
|
|
140
|
+
* is the fallback whenever the remote fetch fails — see `_resolveRawBars`.
|
|
141
|
+
*
|
|
142
|
+
* For Threshold: returns the threshold constant. For calendar types: computed
|
|
143
|
+
* from `tradingDays.getRange()`. For all others: `_resolveRawBars` → leverage
|
|
144
|
+
* compounding (if any) → lookback-specific computation. Returns null if the
|
|
145
|
+
* value cannot be computed.
|
|
146
|
+
*/
|
|
147
|
+
computeAt(date: string, overrides?: Record<string, number>): Promise<number | null>;
|
|
148
|
+
/**
|
|
149
|
+
* Raw (unleveraged) bars for `symbol` up through `date`, with the live quote
|
|
150
|
+
* from `overrides[symbol]` (if any) spliced in at `date`.
|
|
151
|
+
*
|
|
152
|
+
* Decision policy:
|
|
153
|
+
* - `date` > `tradingDays.getLatestClosed()`: market has nothing for that
|
|
154
|
+
* day yet — skip the remote fetch entirely and read from storage.
|
|
155
|
+
* - otherwise: try `this._market.fetchBars(symbol, from)`. On failure, fall
|
|
156
|
+
* back to storage — upstream HTTP providers (Yahoo / FRED) are flaky.
|
|
157
|
+
*
|
|
158
|
+
* After the base is resolved, `overrides[symbol]` is spliced at `date`
|
|
159
|
+
* (replaces the existing bar, or is appended in-order). When no override is
|
|
160
|
+
* present but `date` isn't in the base bars, the last known value is carried
|
|
161
|
+
* forward to `date` — this preserves the fallbackMissingQuotes behaviour the
|
|
162
|
+
* old overlay exposed so leverage compounding / computations always have a
|
|
163
|
+
* point at `date` to land on.
|
|
164
|
+
*/
|
|
165
|
+
private _resolveRawBars;
|
|
166
|
+
/**
|
|
167
|
+
* Resolve the single raw (unleveraged) value for `symbol` at `date`.
|
|
168
|
+
* Returns the override directly when present; otherwise delegates to
|
|
169
|
+
* `_resolveRawBars` with a one-day window and picks the matching bar.
|
|
146
170
|
*/
|
|
147
|
-
|
|
171
|
+
private _resolveRawBarAt;
|
|
172
|
+
/**
|
|
173
|
+
* Resolve raw (unleveraged) bars for a market symbol from storage. Maps:
|
|
174
|
+
* - `^VIX` → the VIX indicator's stored series
|
|
175
|
+
* - `^VIX3M` → the VIX3M indicator's stored series
|
|
176
|
+
* - `DGS*` → the matching Treasury-tenor indicator's stored series
|
|
177
|
+
* - anything else → the `Price` indicator for that ticker symbol with
|
|
178
|
+
* `leverage = 1` (the raw contract that `MarketProvider.fetchBars` has).
|
|
179
|
+
*
|
|
180
|
+
* Returns `[]` when the resolved indicator has no stored bars yet.
|
|
181
|
+
*/
|
|
182
|
+
private _readStoredBars;
|
|
148
183
|
series(range?: DateRange): Promise<DailyBar[]>;
|
|
149
184
|
private _syntheticThresholdSeries;
|
|
150
185
|
value(date?: string): Promise<number | null>;
|
|
151
186
|
/**
|
|
152
|
-
* Read-only preview of the indicator series
|
|
153
|
-
*
|
|
187
|
+
* Read-only preview of the indicator series with an in-memory bar at `date`
|
|
188
|
+
* computed via `computeAt` with the supplied live-quote `overrides`. Does
|
|
154
189
|
* NOT write to `indicators_series`. Safe to call before market close.
|
|
155
190
|
*
|
|
156
|
-
* @param date - Target trading day whose value is computed in-memory
|
|
157
|
-
*
|
|
158
|
-
* @param
|
|
159
|
-
* Symbols omitted
|
|
191
|
+
* @param date - Target trading day whose value is computed in-memory.
|
|
192
|
+
* Must be in `tradingDays.getRange()`.
|
|
193
|
+
* @param overrides - Raw (unleveraged) quotes keyed by market symbol.
|
|
194
|
+
* Symbols omitted fall back to the last known value (see `_resolveRawBars`).
|
|
160
195
|
* @param range - Optional filter applied to the returned bars.
|
|
161
196
|
* @returns Stored historical bars plus (or with) today's in-memory value.
|
|
162
197
|
*/
|
|
163
|
-
previewSeries(date: string,
|
|
198
|
+
previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<DailyBar[]>;
|
|
164
199
|
}
|
|
165
200
|
|
|
166
201
|
interface StorageProvider {
|
|
@@ -194,9 +229,16 @@ interface StorageProvider {
|
|
|
194
229
|
id: number;
|
|
195
230
|
}>;
|
|
196
231
|
getSeries(indicatorId: number, range?: DateRange): Promise<DailyBar[]>;
|
|
197
|
-
writeSeries(indicatorId: number, bars: DailyBar[]
|
|
232
|
+
writeSeries(indicatorId: number, bars: DailyBar[], opts?: {
|
|
233
|
+
metadata?: unknown;
|
|
234
|
+
}): Promise<void>;
|
|
198
235
|
getLatestSeriesDate(indicatorId: number): Promise<string | null>;
|
|
199
236
|
getValue(indicatorId: number, date?: string): Promise<number | null>;
|
|
237
|
+
getLatestBar(indicatorId: number): Promise<{
|
|
238
|
+
date: string;
|
|
239
|
+
value: number;
|
|
240
|
+
metadata: unknown;
|
|
241
|
+
} | null>;
|
|
200
242
|
};
|
|
201
243
|
signals: {
|
|
202
244
|
upsert(identity: {
|
|
@@ -253,13 +295,12 @@ declare class SignalHandle {
|
|
|
253
295
|
readonly comparison: Comparison;
|
|
254
296
|
readonly tolerance: number;
|
|
255
297
|
private _storage;
|
|
256
|
-
private _market;
|
|
257
298
|
private _resolvedId;
|
|
258
299
|
private _resolving;
|
|
259
300
|
private _cachedSeries;
|
|
260
301
|
private _cachedAsOf;
|
|
261
302
|
private _syncing;
|
|
262
|
-
constructor(storage: StorageProvider,
|
|
303
|
+
constructor(storage: StorageProvider, _market: MarketProvider, identity: SignalIdentity);
|
|
263
304
|
get id(): number;
|
|
264
305
|
resolve(): Promise<{
|
|
265
306
|
id: number;
|
|
@@ -270,14 +311,16 @@ declare class SignalHandle {
|
|
|
270
311
|
private _getLatestSignalSeriesDate;
|
|
271
312
|
private _getLastSignalValue;
|
|
272
313
|
private _ensureFresh;
|
|
314
|
+
private _isSingleBarFastPath;
|
|
273
315
|
private _sync;
|
|
316
|
+
private _evaluateOneBar;
|
|
274
317
|
private _upsertSeries;
|
|
275
318
|
private _querySeriesFromDb;
|
|
276
|
-
withMarket(market: MarketProvider): SignalHandle;
|
|
277
319
|
/**
|
|
278
|
-
* Compute the signal's boolean value at `date`
|
|
279
|
-
*
|
|
280
|
-
* Returns null if either indicator cannot produce
|
|
320
|
+
* Compute the signal's boolean value at `date` without persisting anything,
|
|
321
|
+
* with optional live-quote `overrides` that are routed through each
|
|
322
|
+
* indicator's `computeAt`. Returns null if either indicator cannot produce
|
|
323
|
+
* a value at `date`.
|
|
281
324
|
*
|
|
282
325
|
* @param prevBool - The signal's boolean value at the bar immediately
|
|
283
326
|
* preceding `date`, used for hysteresis when `tolerance > 0`. If not
|
|
@@ -285,19 +328,19 @@ declare class SignalHandle {
|
|
|
285
328
|
* standalone callers). On the preview path `_evaluate` passes this from
|
|
286
329
|
* the in-memory `dateMap` so we never read stale storage.
|
|
287
330
|
*/
|
|
288
|
-
computeAt(
|
|
331
|
+
computeAt(date: string, overrides?: Record<string, number>, prevBool?: boolean | null): Promise<boolean | null>;
|
|
289
332
|
series(range?: DateRange): Promise<DailyBar[]>;
|
|
290
333
|
value(date?: string): Promise<number | null>;
|
|
291
334
|
/**
|
|
292
335
|
* Read-only preview of the signal series with an in-memory bar at `date`
|
|
293
|
-
* computed via `computeAt`
|
|
294
|
-
* to `signals_series`.
|
|
336
|
+
* computed via `computeAt` with the supplied live-quote `overrides`. Does
|
|
337
|
+
* NOT write to `signals_series`.
|
|
295
338
|
*
|
|
296
339
|
* @param date - Target trading day whose boolean is computed in-memory.
|
|
297
|
-
* @param
|
|
340
|
+
* @param overrides - Raw (unleveraged) quotes keyed by market symbol.
|
|
298
341
|
* @param range - Optional filter applied to the returned bars.
|
|
299
342
|
*/
|
|
300
|
-
previewSeries(date: string,
|
|
343
|
+
previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<DailyBar[]>;
|
|
301
344
|
}
|
|
302
345
|
|
|
303
346
|
declare class AllocationHandle {
|
|
@@ -311,6 +354,11 @@ declare class AllocationHandle {
|
|
|
311
354
|
id: number;
|
|
312
355
|
}>;
|
|
313
356
|
static fromResolved(storage: StorageProvider, id: number, holdings: [TickerHandle, number][]): AllocationHandle;
|
|
357
|
+
toJSON(): Array<{
|
|
358
|
+
symbol: string;
|
|
359
|
+
leverage: number;
|
|
360
|
+
weight: number;
|
|
361
|
+
}>;
|
|
314
362
|
private _doResolve;
|
|
315
363
|
}
|
|
316
364
|
|
|
@@ -348,6 +396,45 @@ interface FinalState {
|
|
|
348
396
|
closePrices: Record<string, number>;
|
|
349
397
|
leveragedPrices: Record<string, number>;
|
|
350
398
|
}
|
|
399
|
+
/** Per-signal slice of a live strategy snapshot. */
|
|
400
|
+
interface LiveSignalState {
|
|
401
|
+
indicator1: {
|
|
402
|
+
value: number | null;
|
|
403
|
+
date: string | null;
|
|
404
|
+
};
|
|
405
|
+
indicator2: {
|
|
406
|
+
value: number | null;
|
|
407
|
+
date: string | null;
|
|
408
|
+
};
|
|
409
|
+
isTrue: boolean;
|
|
410
|
+
}
|
|
411
|
+
/** Per-rule collection of live signal states, in the same order as the rule's `when` list. */
|
|
412
|
+
interface LiveRuleState {
|
|
413
|
+
signals: LiveSignalState[];
|
|
414
|
+
}
|
|
415
|
+
/** Full live strategy view for a single evaluation date — no portfolio info. */
|
|
416
|
+
interface StrategyLiveState {
|
|
417
|
+
allocation: AllocationHandle | null;
|
|
418
|
+
activeRuleIndex: number;
|
|
419
|
+
rules: LiveRuleState[];
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* Combined live state returned by `SimulationHandle.pushAndPreview`: both the
|
|
423
|
+
* portfolio snapshot from a `push` and the strategy evaluation at the target
|
|
424
|
+
* date under the accumulated live-quote overrides.
|
|
425
|
+
*/
|
|
426
|
+
interface LivePreviewState extends StrategyLiveState {
|
|
427
|
+
snapshot: PortfolioSnapshot;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* Callback shape that `SimulationHandle.pushAndPreview` delegates to. Exists
|
|
431
|
+
* purely to break the circular import between `SimulationHandle` (in this
|
|
432
|
+
* file) and `StrategyHandle` (which creates simulations) — a strategy passes
|
|
433
|
+
* a bound `(date, overrides) => previewLiveState(...)` into the handle.
|
|
434
|
+
*/
|
|
435
|
+
interface LiveEvaluator {
|
|
436
|
+
previewLiveState(date: string, overrides: Record<string, number>): Promise<StrategyLiveState>;
|
|
437
|
+
}
|
|
351
438
|
declare class SimulationHandle {
|
|
352
439
|
readonly series: DailyBar[];
|
|
353
440
|
readonly trades: Trade[];
|
|
@@ -358,8 +445,30 @@ declare class SimulationHandle {
|
|
|
358
445
|
private _lastLeveragedPrices;
|
|
359
446
|
private _currentLeveragedPrices;
|
|
360
447
|
private _lastDate;
|
|
361
|
-
|
|
448
|
+
private _pushedQuotes;
|
|
449
|
+
private _liveEvaluator;
|
|
450
|
+
constructor(series: DailyBar[], trades: Trade[], startingPortfolio: PortfolioHandle, finalState?: FinalState, liveEvaluator?: LiveEvaluator);
|
|
362
451
|
push(...prices: [TickerHandle, number][]): PortfolioSnapshot;
|
|
452
|
+
/**
|
|
453
|
+
* One-call live update. Feeds portfolio-relevant ticker prices into `push`
|
|
454
|
+
* (derived from `quotes` via the running portfolio's holdings), accumulates
|
|
455
|
+
* every symbol in `quotes` into an internal override map so macro symbols
|
|
456
|
+
* (e.g. `^VIX`) persist across ticks, then delegates to the simulation's
|
|
457
|
+
* strategy for rule / signal / indicator evaluation at `date`.
|
|
458
|
+
*
|
|
459
|
+
* Without a live evaluator attached, returns just the portfolio snapshot
|
|
460
|
+
* with allocation/rules/signals empty.
|
|
461
|
+
*
|
|
462
|
+
* @param quotes Symbol → raw live price. Portfolio tickers flow through
|
|
463
|
+
* `push` for leveraged-equity math; non-portfolio symbols are still
|
|
464
|
+
* layered into the overlay so indicators can see them.
|
|
465
|
+
* @param options.date Target trading day to evaluate against. Defaults to
|
|
466
|
+
* the current UTC ISO date; callers with non-UTC semantics or after-hours
|
|
467
|
+
* rollover should supply their own.
|
|
468
|
+
*/
|
|
469
|
+
pushAndPreview(quotes: Record<string, number>, options?: {
|
|
470
|
+
date?: string;
|
|
471
|
+
}): Promise<LivePreviewState>;
|
|
363
472
|
}
|
|
364
473
|
|
|
365
474
|
interface StrategyRule {
|
|
@@ -398,6 +507,7 @@ declare class StrategyHandle {
|
|
|
398
507
|
get freq(): TradingFreq;
|
|
399
508
|
get offset(): number;
|
|
400
509
|
get rules(): StrategyRule[];
|
|
510
|
+
marketSymbols(): string[];
|
|
401
511
|
resolve(): Promise<{
|
|
402
512
|
id: number;
|
|
403
513
|
}>;
|
|
@@ -410,16 +520,22 @@ declare class StrategyHandle {
|
|
|
410
520
|
/**
|
|
411
521
|
* Pure evaluate — runs the same pipeline as _sync but returns the computed
|
|
412
522
|
* evaluation instead of persisting. Used by both _sync (post-close write
|
|
413
|
-
* path) and
|
|
523
|
+
* path) and the public preview methods (pre-close read-only path).
|
|
524
|
+
*
|
|
525
|
+
* When `overrides` is `undefined` we take the write path — syncing signals
|
|
526
|
+
* through storage as normal. When `overrides` is provided (even an empty
|
|
527
|
+
* map) we take the read-only preview path: historical signal bars come
|
|
528
|
+
* straight from storage, today's bar is computed in-memory via
|
|
529
|
+
* `signal.computeAt(date, overrides, prevBool)`, and nothing is written.
|
|
414
530
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
418
|
-
*
|
|
419
|
-
*
|
|
420
|
-
* *different* market object — for example one produced by `createQuoteOverlay`.
|
|
531
|
+
* Incremental path: when a strategy checkpoint exists (`getLatestSeriesDate`
|
|
532
|
+
* returns non-null), only the window (lastDate, limitDate] is processed.
|
|
533
|
+
* The current allocation is carried forward from `getLatestAllocationId`.
|
|
534
|
+
* Bootstrap: when no checkpoint exists, falls back to `_evaluateCold` which
|
|
535
|
+
* runs the full-history evaluation.
|
|
421
536
|
*/
|
|
422
537
|
private _evaluate;
|
|
538
|
+
private _evaluateCold;
|
|
423
539
|
private _querySeriesFromDb;
|
|
424
540
|
series(range?: DateRange): Promise<StrategyBar[]>;
|
|
425
541
|
value(date?: string): Promise<AllocationHandle | null>;
|
|
@@ -430,23 +546,34 @@ declare class StrategyHandle {
|
|
|
430
546
|
* signals_series, or indicators_series. Safe to call before market close.
|
|
431
547
|
*
|
|
432
548
|
* @param date - The trading day to preview (must be in tradingDays.getRange()).
|
|
433
|
-
* @param
|
|
434
|
-
* Symbols absent from this map
|
|
435
|
-
*
|
|
549
|
+
* @param overrides - Raw (unleveraged) live prices keyed by market symbol.
|
|
550
|
+
* Symbols absent from this map fall back to the last stored value
|
|
551
|
+
* (see `IndicatorHandle._resolveRawBars`).
|
|
436
552
|
* @returns The AllocationHandle for `date`, or null if the strategy has no
|
|
437
553
|
* evaluable entry for that date.
|
|
438
554
|
*/
|
|
439
|
-
previewAllocation(date: string,
|
|
555
|
+
previewAllocation(date: string, overrides: Record<string, number>): Promise<AllocationHandle | null>;
|
|
440
556
|
/**
|
|
441
557
|
* Read-only preview of the strategy's allocation series including `date`.
|
|
442
558
|
* Returns stored historical allocations plus an in-memory bar at `date`
|
|
443
|
-
* computed via the same
|
|
559
|
+
* computed via the same overrides-based preview path as `previewAllocation`.
|
|
444
560
|
*
|
|
445
|
-
* @param date - Target trading day to splice in-memory
|
|
446
|
-
* @param
|
|
561
|
+
* @param date - Target trading day to splice in-memory.
|
|
562
|
+
* @param overrides - Raw (unleveraged) quotes keyed by market symbol.
|
|
447
563
|
* @param range - Optional filter applied to the returned bars.
|
|
448
564
|
*/
|
|
449
|
-
previewSeries(date: string,
|
|
565
|
+
previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<StrategyBar[]>;
|
|
566
|
+
/**
|
|
567
|
+
* Full live strategy view at `date` under live-quote `overrides`: the active
|
|
568
|
+
* allocation, the index of the rule that fired (or fallback), and per-rule
|
|
569
|
+
* per-signal indicator values + truth. Computed entirely through the
|
|
570
|
+
* overrides preview path — no writes to any `*_series` tables.
|
|
571
|
+
*
|
|
572
|
+
* Threshold indicators have their date suppressed (`null`) since their
|
|
573
|
+
* synthetic series runs over every trading day in storage including future
|
|
574
|
+
* dates and would report a far-future date for the last bar.
|
|
575
|
+
*/
|
|
576
|
+
previewLiveState(date: string, overrides: Record<string, number>): Promise<StrategyLiveState>;
|
|
450
577
|
private _fetchPricesForTickers;
|
|
451
578
|
private _fetchRawClosePrices;
|
|
452
579
|
}
|
|
@@ -498,4 +625,8 @@ interface PriceStream {
|
|
|
498
625
|
close(): void;
|
|
499
626
|
}
|
|
500
627
|
|
|
501
|
-
|
|
628
|
+
declare function allocationsEqual(a: AllocationHandle | null, b: AllocationHandle | null): boolean;
|
|
629
|
+
|
|
630
|
+
declare function computeRebalanceDates(tradingDays: string[], freq: TradingFreq, offset: number): Set<string>;
|
|
631
|
+
|
|
632
|
+
export { AllocationHandle, type Comparison, type DailyBar, type DateRange, IndicatorHandle, type IndicatorIdentity, type IndicatorType, type LiveEvaluator, type LivePreviewState, type LiveRuleState, type LiveSignalState, type LivefolioClient, type LivefolioClientOptions, type MarketProvider, PortfolioHandle, type PortfolioSnapshot, type PriceStream, SignalHandle, type SignalIdentity, type SimulateOptions, SimulationHandle, type StorageProvider, type StrategyBar, type StrategyDefinition, StrategyHandle, type StrategyLiveState, type StrategyOptions, type StrategyReferenceData, type StrategyRule, type StrategyRuleDefinition, type StrategySeriesEntry, type StreamStatus, TickerHandle, type Trade, type TradingFreq, type Unit, allocationsEqual, computeRebalanceDates, createClient };
|