@livefolio/sdk 0.3.3 → 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 +35 -2
- package/dist/index.js +392 -43
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/handles/ticker.ts","../src/providers/mappings.ts","../src/computations/sma.ts","../src/computations/ema.ts","../src/computations/rsi.ts","../src/computations/returns.ts","../src/computations/volatility.ts","../src/computations/drawdown.ts","../src/computations/calendar.ts","../src/computations/index.ts","../src/handles/indicator.ts","../src/computations/signal.ts","../src/handles/signal.ts","../src/handles/allocation.ts","../src/handles/strategy.ts","../src/computations/strategy.ts","../src/handles/portfolio.ts","../src/backtest/simulate.ts","../src/backtest/types.ts","../src/client.ts"],"sourcesContent":["import type { StorageProvider } from '../providers/storage';\n\nexport class TickerHandle {\n readonly symbol: string;\n readonly leverage: number;\n\n private _storage: StorageProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n constructor(storage: StorageProvider, symbol: string, leverage: number = 1) {\n this._storage = storage;\n this.symbol = symbol.toUpperCase();\n this.leverage = leverage;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('TickerHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(storage: StorageProvider, id: number, symbol: string, leverage: number): TickerHandle {\n const handle = new TickerHandle(storage, symbol, leverage);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n const result = await this._storage.tickers.findOrCreate(this.symbol, this.leverage);\n this._resolvedId = result.id;\n return result;\n }\n}\n","import type { IndicatorType } from './types';\n\nexport type ProviderInfo =\n | { provider: 'yahoo'; symbol: string; rateSeries?: true }\n | { provider: 'fred'; seriesId: string; rateSeries?: true }\n | { provider: 'computed'; dependsOn: 'Price'; symbol: string; rateSeries?: true }\n | { provider: 'calendar' }\n | { provider: 'none' };\n\nconst FRED_SERIES: Record<string, string> = {\n T3M: 'DGS3MO',\n T6M: 'DGS6MO',\n T1Y: 'DGS1',\n T2Y: 'DGS2',\n T3Y: 'DGS3',\n T5Y: 'DGS5',\n T7Y: 'DGS7',\n T10Y: 'DGS10',\n T20Y: 'DGS20',\n T30Y: 'DGS30',\n};\n\n// Ticker symbols whose \"price\" values are rates/yields (expressed in percent),\n// not prices. For these, percent-change returns are both broken (divide by\n// zero / sign flips) and semantically wrong — callers should use absolute\n// differences instead.\nconst RATE_TICKER_SYMBOLS = new Set<string>([\n 'DTB3',\n 'DTB6',\n 'DFF',\n 'DGS3MO',\n 'DGS6MO',\n 'DGS1',\n 'DGS2',\n 'DGS3',\n 'DGS5',\n 'DGS7',\n 'DGS10',\n 'DGS20',\n 'DGS30',\n]);\n\nconst COMPUTED_TYPES = new Set<string>(['SMA', 'EMA', 'RSI', 'Return', 'Volatility', 'Drawdown']);\nconst CALENDAR_TYPES = new Set<string>(['Month', 'Day of Week', 'Day of Month', 'Day of Year']);\n\nexport function isRateTickerSymbol(symbol: string | null): boolean {\n return symbol != null && RATE_TICKER_SYMBOLS.has(symbol);\n}\n\nexport function getProviderInfo(type: IndicatorType, tickerSymbol: string | null): ProviderInfo {\n if (type === 'Price') {\n const info: ProviderInfo = { provider: 'yahoo', symbol: tickerSymbol! };\n if (isRateTickerSymbol(tickerSymbol)) info.rateSeries = true;\n return info;\n }\n if (type === 'VIX') return { provider: 'yahoo', symbol: '^VIX' };\n if (type === 'VIX3M') return { provider: 'yahoo', symbol: '^VIX3M' };\n\n if (type in FRED_SERIES) return { provider: 'fred', seriesId: FRED_SERIES[type]!, rateSeries: true };\n\n if (COMPUTED_TYPES.has(type)) {\n const info: ProviderInfo = { provider: 'computed', dependsOn: 'Price', symbol: tickerSymbol! };\n if (isRateTickerSymbol(tickerSymbol)) info.rateSeries = true;\n return info;\n }\n\n if (CALENDAR_TYPES.has(type)) return { provider: 'calendar' };\n\n return { provider: 'none' };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeSma(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback) return [];\n const result: DailyBar[] = [];\n let sum = 0;\n for (let i = 0; i < lookback; i++) sum += bars[i].value;\n result.push({ date: bars[lookback - 1].date, value: sum / lookback });\n for (let i = lookback; i < bars.length; i++) {\n sum += bars[i].value - bars[i - lookback].value;\n result.push({ date: bars[i].date, value: sum / lookback });\n }\n return result;\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeEma(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback) return [];\n const multiplier = 2 / (lookback + 1);\n const result: DailyBar[] = [];\n let sum = 0;\n for (let i = 0; i < lookback; i++) sum += bars[i].value;\n let ema = sum / lookback;\n result.push({ date: bars[lookback - 1].date, value: ema });\n for (let i = lookback; i < bars.length; i++) {\n ema = bars[i].value * multiplier + ema * (1 - multiplier);\n result.push({ date: bars[i].date, value: ema });\n }\n return result;\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeRsi(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback + 1) return [];\n const changes: number[] = [];\n for (let i = 1; i < bars.length; i++) {\n changes.push(bars[i].value - bars[i - 1].value);\n }\n let avgGain = 0;\n let avgLoss = 0;\n for (let i = 0; i < lookback; i++) {\n if (changes[i] > 0) avgGain += changes[i];\n else avgLoss += Math.abs(changes[i]);\n }\n avgGain /= lookback;\n avgLoss /= lookback;\n const result: DailyBar[] = [];\n const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;\n result.push({\n date: bars[lookback].date,\n value: avgLoss === 0 ? 100 : 100 - 100 / (1 + rs),\n });\n for (let i = lookback; i < changes.length; i++) {\n const gain = changes[i] > 0 ? changes[i] : 0;\n const loss = changes[i] < 0 ? Math.abs(changes[i]) : 0;\n avgGain = (avgGain * (lookback - 1) + gain) / lookback;\n avgLoss = (avgLoss * (lookback - 1) + loss) / lookback;\n const smoothRs = avgLoss === 0 ? 100 : avgGain / avgLoss;\n result.push({\n date: bars[i + 1].date,\n value: avgLoss === 0 ? 100 : 100 - 100 / (1 + smoothRs),\n });\n }\n return result;\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport type ReturnMode = 'pct' | 'abs';\n\nexport function computeReturns(bars: DailyBar[], lookback: number, mode: ReturnMode = 'pct'): DailyBar[] {\n if (bars.length <= lookback) return [];\n const result: DailyBar[] = [];\n for (let i = lookback; i < bars.length; i++) {\n const curr = bars[i]!.value;\n const prev = bars[i - lookback]!.value;\n const value = mode === 'abs' ? curr - prev : (curr - prev) / prev;\n result.push({ date: bars[i]!.date, value });\n }\n return result;\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeVolatility(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback + 1) return [];\n const dailyReturns: { date: string; value: number }[] = [];\n for (let i = 1; i < bars.length; i++) {\n dailyReturns.push({\n date: bars[i].date,\n value: bars[i].value / bars[i - 1].value - 1,\n });\n }\n if (dailyReturns.length < lookback) return [];\n const result: DailyBar[] = [];\n for (let i = lookback - 1; i < dailyReturns.length; i++) {\n const window = dailyReturns.slice(i - lookback + 1, i + 1);\n const mean = window.reduce((s, r) => s + r.value, 0) / lookback;\n const variance = window.reduce((s, r) => s + (r.value - mean) ** 2, 0) / lookback;\n result.push({ date: dailyReturns[i].date, value: Math.sqrt(variance) });\n }\n return result;\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeDrawdown(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback) return [];\n const result: DailyBar[] = [];\n for (let i = lookback - 1; i < bars.length; i++) {\n let max = -Infinity;\n for (let j = i - lookback + 1; j <= i; j++) {\n if (bars[j].value > max) max = bars[j].value;\n }\n result.push({ date: bars[i].date, value: (bars[i].value - max) / max });\n }\n return result;\n}\n","import type { DailyBar } from '../handles/indicator';\n\ntype CalendarPeriod = 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year';\n\nfunction dayOfYear(d: Date): number {\n const start = new Date(d.getFullYear(), 0, 0);\n const diff = d.getTime() - start.getTime();\n return Math.floor(diff / (1000 * 60 * 60 * 24));\n}\n\nexport function computeCalendar(bars: DailyBar[], period: CalendarPeriod): DailyBar[] {\n return bars.map((bar) => {\n const [y, m, d] = bar.date.split('-').map(Number);\n const date = new Date(y, m - 1, d);\n let value: number;\n switch (period) {\n case 'Month':\n value = date.getMonth() + 1;\n break;\n case 'Day of Week':\n value = date.getDay();\n break;\n case 'Day of Month':\n value = date.getDate();\n break;\n case 'Day of Year':\n value = dayOfYear(date);\n break;\n }\n return { date: bar.date, value };\n });\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { IndicatorType } from '../providers/types';\nimport { computeSma } from './sma';\nimport { computeEma } from './ema';\nimport { computeRsi } from './rsi';\nimport { computeReturns } from './returns';\nimport { computeVolatility } from './volatility';\nimport { computeDrawdown } from './drawdown';\n\nexport { computeSma } from './sma';\nexport { computeEma } from './ema';\nexport { computeRsi } from './rsi';\nexport { computeReturns } from './returns';\nexport { computeVolatility } from './volatility';\nexport { computeDrawdown } from './drawdown';\nexport { computeCalendar } from './calendar';\ntype ComputeFn = (bars: DailyBar[], lookback: number) => DailyBar[];\n\nconst COMPUTATIONS: Partial<Record<IndicatorType, ComputeFn>> = {\n SMA: computeSma,\n EMA: computeEma,\n RSI: computeRsi,\n Return: computeReturns,\n Volatility: computeVolatility,\n Drawdown: computeDrawdown,\n};\n\nexport function getComputation(type: IndicatorType): ComputeFn | null {\n return COMPUTATIONS[type] ?? null;\n}\n","import type { StorageProvider } from '../providers/storage';\nimport type { MarketProvider } from '../providers/market';\nimport type { IndicatorType, Unit } from '../providers/types';\nimport { TickerHandle } from './ticker';\nimport { getProviderInfo, isRateTickerSymbol } from '../providers/mappings';\nimport { getComputation } from '../computations/index';\nimport { computeReturns } from '../computations/returns';\nimport { computeCalendar } from '../computations/calendar';\n\n/**\n * Inverse of `FRED_SERIES` in `providers/mappings.ts`. Lets `_readStoredBars`\n * map a FRED series ID (`DGS3MO`, `DGS10`, etc.) back to the indicator type\n * whose stored series holds that series' history.\n */\nconst FRED_SYMBOL_TO_TYPE: Record<string, string> = {\n DGS3MO: 'T3M',\n DGS6MO: 'T6M',\n DGS1: 'T1Y',\n DGS2: 'T2Y',\n DGS3: 'T3Y',\n DGS5: 'T5Y',\n DGS7: 'T7Y',\n DGS10: 'T10Y',\n DGS20: 'T20Y',\n DGS30: 'T30Y',\n};\n\n/**\n * Subtract `days` calendar days from an ISO date string (YYYY-MM-DD).\n * Used to compute a `from` cutoff for bounded bar fetches in `computeAt`.\n */\nfunction _subtractCalendarDays(date: string, days: number): string {\n const d = new Date(date);\n d.setUTCDate(d.getUTCDate() - days);\n return d.toISOString().slice(0, 10);\n}\n\nexport interface DailyBar {\n date: string;\n value: number;\n}\n\nexport interface IndicatorIdentity {\n type: IndicatorType;\n ticker: TickerHandle | null;\n lookback: number;\n delay: number;\n unit: Unit | null;\n threshold: number | null;\n}\n\nexport interface DateRange {\n from?: string;\n to?: string;\n}\n\nexport class IndicatorHandle {\n readonly type: IndicatorType;\n readonly ticker: TickerHandle | null;\n readonly lookback: number;\n readonly delay: number;\n readonly unit: Unit | null;\n readonly threshold: number | null;\n\n private _storage: StorageProvider;\n private _market: MarketProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n private _cachedSeries: DailyBar[] | null = null;\n private _cachedAsOf: string | null = null;\n private _syncing: Promise<void> | null = null;\n\n constructor(storage: StorageProvider, market: MarketProvider, identity: IndicatorIdentity) {\n this._storage = storage;\n this._market = market;\n this.type = identity.type;\n this.ticker = identity.ticker;\n this.lookback = identity.lookback;\n this.delay = identity.delay;\n this.unit = identity.unit;\n this.threshold = identity.threshold;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('IndicatorHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(\n storage: StorageProvider,\n market: MarketProvider,\n id: number,\n identity: IndicatorIdentity,\n ): IndicatorHandle {\n const handle = new IndicatorHandle(storage, market, identity);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n const tickerId = this.ticker ? (await this.ticker.resolve()).id : null;\n const result = await this._storage.indicators.findOrCreate({\n type: this.type,\n tickerId,\n lookback: this.lookback,\n delay: this.delay,\n unit: this.unit,\n threshold: this.threshold,\n });\n this._resolvedId = result.id;\n return result;\n }\n\n // ── Freshness & Sync ───────────────────────────────────────────────\n\n private async _getLatestClosedTradingDay(): Promise<string> {\n const date = await this._storage.tradingDays.getLatestClosed();\n if (!date) throw new Error('No closed trading days found');\n return date;\n }\n\n private async _getLatestSeriesDate(indicatorId: number): Promise<string | null> {\n return this._storage.indicators.getLatestSeriesDate(indicatorId);\n }\n\n private async _ensureFresh(): Promise<void> {\n const { id } = await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n // In-memory cache still valid\n if (this._cachedAsOf === latestClosed) return;\n\n // `horizon` = the latest date this indicator's series can be written at.\n // delay = 0 → latestClosed; delay > 0 → latestClosed − delay trading days.\n // \"Fresh\" means the stored series already reaches that horizon.\n let horizon = latestClosed;\n if (this.delay > 0) {\n const tradingDays = await this._storage.tradingDays.getRange();\n const idx = tradingDays.indexOf(latestClosed);\n if (idx >= this.delay) {\n horizon = tradingDays[idx - this.delay]!;\n }\n }\n\n const latestSeries = await this._getLatestSeriesDate(id);\n\n if (latestSeries === horizon) {\n // DB is fresh — invalidate in-memory cache so next read picks up DB data\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n return;\n }\n\n // Need to sync — deduplicate concurrent calls. On sync failure (e.g.,\n // browser has no market provider, or upstream feed hasn't published the\n // new date yet), fall back to whatever storage already has and treat the\n // cache as fresh so downstream callers don't retry the failing sync on\n // every read.\n if (!this._syncing) {\n this._syncing = this._sync(latestSeries ?? undefined, latestClosed)\n .catch((err) => {\n console.warn('[sdk] indicator sync failed, using stored data:', err);\n })\n .finally(() => {\n this._syncing = null;\n });\n }\n await this._syncing;\n\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n }\n\n private async _sync(fromDate: string | undefined, latestClosed: string): Promise<void> {\n const tickerSymbol = this.ticker?.symbol ?? null;\n const info = getProviderInfo(this.type, tickerSymbol);\n\n let bars: DailyBar[];\n\n switch (info.provider) {\n case 'yahoo':\n bars = await this._market.fetchBars(info.symbol, fromDate);\n break;\n\n case 'fred':\n bars = await this._market.fetchBars(info.seriesId, fromDate);\n break;\n\n case 'computed': {\n // Create an internal Price handle for the same ticker\n const priceHandle = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker: this.ticker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n\n // Recursively ensure Price data is fresh\n await priceHandle._ensureFresh();\n\n // Read Price series from DB\n const priceBars = await priceHandle._querySeriesFromDb();\n\n if (this.type === 'Return') {\n // For rate/yield series (e.g. DTB3, DFF), percentage change is broken\n // near zero and semantically wrong; use absolute differences instead.\n bars = computeReturns(priceBars, this.lookback, info.rateSeries ? 'abs' : 'pct');\n } else {\n const computeFn = getComputation(this.type);\n if (!computeFn) throw new Error(`No computation found for type \"${this.type}\"`);\n bars = computeFn(priceBars, this.lookback);\n }\n\n // If incremental, filter to only new bars\n if (fromDate) {\n bars = bars.filter((b) => b.date > fromDate);\n }\n break;\n }\n\n case 'calendar': {\n // Fetch all trading days to compute calendar values\n const allDays = await this._storage.tradingDays.getRange();\n const dayBars: DailyBar[] = allDays.map((date) => ({ date, value: 0 }));\n bars = computeCalendar(dayBars, this.type as 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year');\n\n if (fromDate) {\n bars = bars.filter((b) => b.date > fromDate);\n }\n break;\n }\n\n case 'none':\n // Threshold indicators have no series to sync\n return;\n }\n\n // Apply leverage to daily returns only for fetched (non-computed) indicators.\n // Computed indicators (RSI, SMA, etc.) already read from the leveraged price series.\n if (info.provider !== 'computed') {\n bars = await this._applyLeverage(bars, fromDate);\n }\n\n // Filter bars up to the indicator's publishable horizon: `latestClosed`\n // normally, or `latestClosed − delay` trading days when `delay > 0`. Each\n // (type, ticker, lookback, delay) tuple is its own `indicators` row with\n // its own `indicators_series`, so the stored series itself lags.\n let horizon = latestClosed;\n if (this.delay > 0) {\n const tradingDays = await this._storage.tradingDays.getRange();\n const idx = tradingDays.indexOf(latestClosed);\n if (idx < this.delay) {\n return; // not enough history yet for this delay\n }\n horizon = tradingDays[idx - this.delay]!;\n }\n bars = bars.filter((b) => b.date <= horizon);\n\n if (bars.length > 0) {\n await this._upsertSeries(bars);\n }\n }\n\n private async _upsertSeries(bars: DailyBar[]): Promise<void> {\n const { id } = await this.resolve();\n await this._storage.indicators.writeSeries(id, bars);\n }\n\n private async _querySeriesFromDb(range?: DateRange): Promise<DailyBar[]> {\n const { id } = await this.resolve();\n return this._storage.indicators.getSeries(id, range);\n }\n\n /**\n * Apply leverage compounding to a raw bar series, anchored to a stored\n * leveraged value. Used by both `_sync` and `computeAt` so they stay\n * consistent.\n *\n * `anchorDate` is the date of the last *already-stored* leveraged bar\n * (i.e., the bar just before `rawBars[0]`). The stored leveraged value\n * at that date becomes `leveraged[0]`; raw returns are then compounded\n * forward for each subsequent bar.\n *\n * If no stored anchor exists (first-ever sync), falls back to rawBars[0]\n * as the starting raw value — identical to `_sync`'s behaviour.\n */\n private async _applyLeverage(rawBars: DailyBar[], anchorDate: string | undefined): Promise<DailyBar[]> {\n const leverage = this.ticker?.leverage ?? 1;\n if (leverage === 1 || rawBars.length === 0) return rawBars;\n // Rate tickers (DTB3, DFF, etc.) skip leverage compounding: the stored series\n // stays raw; the simulator applies the leverage multiplier at accrual time.\n if (isRateTickerSymbol(this.ticker?.symbol ?? null)) return rawBars;\n\n let anchor: number;\n if (anchorDate) {\n const lastStored = await this._storage.indicators.getValue(this._resolvedId!, anchorDate);\n anchor = lastStored ?? rawBars[0]!.value;\n } else {\n anchor = rawBars[0]!.value;\n }\n\n const leveraged: DailyBar[] = [{ date: rawBars[0]!.date, value: anchor }];\n for (let i = 1; i < rawBars.length; i++) {\n const dailyReturn = (rawBars[i]!.value - rawBars[i - 1]!.value) / rawBars[i - 1]!.value;\n const prev = leveraged[i - 1]!.value;\n leveraged.push({ date: rawBars[i]!.date, value: prev * (1 + leverage * dailyReturn) });\n }\n return leveraged;\n }\n\n /**\n * Compute the indicator's value at `date` without persisting anything, with\n * optional live-quote `overrides` keyed by raw market symbol (the same symbol\n * space `MarketProvider.fetchBars` uses — ticker symbols for Price/SMA/etc.,\n * `^VIX` / `^VIX3M` for macro, FRED series IDs like `DGS3MO` for Treasury).\n *\n * Bars for the underlying symbol are resolved storage-first when the market\n * hasn't yet produced bars for `date` (trading day still open), and storage\n * is the fallback whenever the remote fetch fails — see `_resolveRawBars`.\n *\n * For Threshold: returns the threshold constant. For calendar types: computed\n * from `tradingDays.getRange()`. For all others: `_resolveRawBars` → leverage\n * compounding (if any) → lookback-specific computation. Returns null if the\n * value cannot be computed.\n */\n async computeAt(date: string, overrides?: Record<string, number>): Promise<number | null> {\n // Threshold is a special case: it has no market data, just a constant value.\n if (this.type === 'Threshold') return this.threshold;\n\n const tickerSymbol = this.ticker?.symbol ?? null;\n const info = getProviderInfo(this.type, tickerSymbol);\n\n if (info.provider === 'none') return null;\n\n if (info.provider === 'calendar') {\n const allDays = await this._storage.tradingDays.getRange();\n const dayBars: DailyBar[] = allDays.map((d) => ({ date: d, value: 0 }));\n const computed = computeCalendar(dayBars, this.type as 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year');\n return computed.find((b) => b.date === date)?.value ?? null;\n }\n\n if (info.provider === 'computed') {\n // Size the bar window by the computation's actual needs, expressed in\n // calendar days. Three buckets:\n //\n // Exact reads (SMA / Return / Volatility / Drawdown) want `lookback`\n // *trading* days in the result; with ~5 trading days per 7 calendar\n // days plus holidays that's ~`lookback * 1.5` calendar days, plus a\n // small fixed buffer for long weekends.\n //\n // EMA is recursive: seed = first N-bar SMA, then `(1-α)^k` decay with\n // α = 2 / (N+1). For small N the decay is fast; for N=200 decay is\n // ~0.99/bar, so we want several multiples of `lookback` to get close\n // to the fully-synced EMA value.\n //\n // Wilder's RSI decays at ~10%/bar regardless of lookback and starts\n // from a simple-average seed that can pin at 100 (or 0) for a window\n // full of only-up (or only-down) days; it needs the widest window.\n let calendarDays: number;\n if (this.type === 'RSI') {\n calendarDays = Math.max(this.lookback * 10, 90);\n } else if (this.type === 'EMA') {\n calendarDays = Math.max(this.lookback * 5, 60);\n } else {\n // SMA, Return, Volatility, Drawdown — exact-read, only need coverage.\n calendarDays = Math.ceil(this.lookback * 1.5) + 15;\n }\n const from = _subtractCalendarDays(date, this.lookback + calendarDays);\n const rawBars = await this._resolveRawBars(info.symbol, from, date, overrides);\n\n // Apply leverage anchored to the stored leveraged value at the date just\n // before the first resolved raw bar. Mirrors `_sync`'s anchor logic.\n const anchorDate = rawBars.length > 0 ? rawBars[0]!.date : undefined;\n const priceBars = await this._applyLeverage(rawBars, anchorDate);\n\n const computeFn = getComputation(this.type);\n if (!computeFn) throw new Error(`No computation found for type \"${this.type}\"`);\n const computed = computeFn(priceBars, this.lookback);\n return computed.find((b) => b.date === date)?.value ?? null;\n }\n\n // yahoo or fred: resolve a small window — just enough to get `date` and\n // one prior bar (needed for leverage return calculation). 15 calendar days\n // comfortably bridges a long weekend + holiday gap; FRED series in\n // particular publish on T+1 / T+2 cadences and can miss a market day.\n const symbol = info.provider === 'yahoo' ? info.symbol : info.seriesId;\n const from = _subtractCalendarDays(date, 15);\n const rawBars = await this._resolveRawBars(symbol, from, date, overrides);\n\n const leverage = this.ticker?.leverage ?? 1;\n if (leverage === 1) {\n return rawBars.find((b) => b.date === date)?.value ?? null;\n }\n\n // Apply leverage compounding.\n const dateIdx = rawBars.findIndex((b) => b.date === date);\n if (dateIdx < 0) return null; // date not in bars at all\n\n const prevBar = rawBars[dateIdx - 1];\n if (!prevBar) {\n // No previous bar in the window — can't compound. Return raw value as fallback.\n return rawBars[dateIdx]!.value;\n }\n\n const storedPrev = await this._storage.indicators.getValue(this._resolvedId!, prevBar.date);\n const leveragedPrev = storedPrev ?? prevBar.value;\n const rawReturn = (rawBars[dateIdx]!.value - prevBar.value) / prevBar.value;\n return leveragedPrev * (1 + leverage * rawReturn);\n }\n\n /**\n * Raw (unleveraged) bars for `symbol` up through `date`, with the live quote\n * from `overrides[symbol]` (if any) spliced in at `date`.\n *\n * Decision policy:\n * - `date` > `tradingDays.getLatestClosed()`: market has nothing for that\n * day yet — skip the remote fetch entirely and read from storage.\n * - otherwise: try `this._market.fetchBars(symbol, from)`. On failure, fall\n * back to storage — upstream HTTP providers (Yahoo / FRED) are flaky.\n *\n * After the base is resolved, `overrides[symbol]` is spliced at `date`\n * (replaces the existing bar, or is appended in-order). When no override is\n * present but `date` isn't in the base bars, the last known value is carried\n * forward to `date` — this preserves the fallbackMissingQuotes behaviour the\n * old overlay exposed so leverage compounding / computations always have a\n * point at `date` to land on.\n */\n private async _resolveRawBars(\n symbol: string,\n from: string,\n date: string,\n overrides?: Record<string, number>,\n ): Promise<DailyBar[]> {\n const latestClosed = await this._storage.tradingDays.getLatestClosed();\n const closedForDate = latestClosed !== null && date <= latestClosed;\n\n let bars: DailyBar[];\n if (closedForDate) {\n try {\n bars = await this._market.fetchBars(symbol, from);\n } catch {\n bars = await this._readStoredBars(symbol, from);\n }\n } else {\n bars = await this._readStoredBars(symbol, from);\n }\n\n const override = overrides?.[symbol];\n const existingIdx = bars.findIndex((b) => b.date === date);\n\n if (override !== undefined) {\n if (existingIdx >= 0) {\n bars[existingIdx] = { date, value: override };\n } else {\n bars = [...bars, { date, value: override }].sort((a, b) => a.date.localeCompare(b.date));\n }\n } else if (existingIdx < 0 && bars.length > 0) {\n // Carry last known value forward to `date` (matches the overlay's\n // `fallbackMissingQuotes` behaviour for every consumer that used it).\n bars = [...bars, { date, value: bars[bars.length - 1]!.value }];\n }\n\n return bars;\n }\n\n /**\n * Resolve raw (unleveraged) bars for a market symbol from storage. Maps:\n * - `^VIX` → the VIX indicator's stored series\n * - `^VIX3M` → the VIX3M indicator's stored series\n * - `DGS*` → the matching Treasury-tenor indicator's stored series\n * - anything else → the `Price` indicator for that ticker symbol with\n * `leverage = 1` (the raw contract that `MarketProvider.fetchBars` has).\n *\n * Returns `[]` when the resolved indicator has no stored bars yet.\n */\n private async _readStoredBars(symbol: string, from: string): Promise<DailyBar[]> {\n let identity: {\n type: string;\n tickerId: number | null;\n lookback: number;\n delay: number;\n unit: string | null;\n threshold: number | null;\n };\n if (symbol === '^VIX') {\n identity = { type: 'VIX', tickerId: null, lookback: 0, delay: 0, unit: null, threshold: null };\n } else if (symbol === '^VIX3M') {\n identity = { type: 'VIX3M', tickerId: null, lookback: 0, delay: 0, unit: null, threshold: null };\n } else if (FRED_SYMBOL_TO_TYPE[symbol]) {\n identity = {\n type: FRED_SYMBOL_TO_TYPE[symbol]!,\n tickerId: null,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n };\n } else {\n const { id: tickerId } = await this._storage.tickers.findOrCreate(symbol, 1);\n identity = { type: 'Price', tickerId, lookback: 0, delay: 0, unit: null, threshold: null };\n }\n const { id } = await this._storage.indicators.findOrCreate(identity);\n return this._storage.indicators.getSeries(id, { from });\n }\n\n // ── Public data access ─────────────────────────────────────────────\n\n async series(range?: DateRange): Promise<DailyBar[]> {\n if (this.type === 'Threshold') {\n return this._syntheticThresholdSeries(range);\n }\n await this._ensureFresh();\n if (this._cachedSeries && !range) return this._cachedSeries;\n const bars = await this._querySeriesFromDb(range);\n if (!range) this._cachedSeries = bars;\n return bars;\n }\n\n private async _syntheticThresholdSeries(range?: DateRange): Promise<DailyBar[]> {\n const v = this.threshold!;\n const dates = await this._storage.tradingDays.getRange(range);\n return dates.map((date) => ({ date, value: v }));\n }\n\n async value(date?: string): Promise<number | null> {\n await this._ensureFresh();\n const { id } = await this.resolve();\n return this._storage.indicators.getValue(id, date);\n }\n\n /**\n * Read-only preview of the indicator series with an in-memory bar at `date`\n * computed via `computeAt` with the supplied live-quote `overrides`. Does\n * NOT write to `indicators_series`. Safe to call before market close.\n *\n * @param date - Target trading day whose value is computed in-memory.\n * Must be in `tradingDays.getRange()`.\n * @param overrides - Raw (unleveraged) quotes keyed by market symbol.\n * Symbols omitted fall back to the last known value (see `_resolveRawBars`).\n * @param range - Optional filter applied to the returned bars.\n * @returns Stored historical bars plus (or with) today's in-memory value.\n */\n async previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<DailyBar[]> {\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewSeries: ${date} is not a trading day`);\n }\n\n let bars: DailyBar[];\n if (this.type === 'Threshold') {\n bars = await this._syntheticThresholdSeries();\n } else {\n bars = await this._querySeriesFromDb();\n }\n\n // Only splice a \"today\" bar when the indicator is publishable at `date`\n // — i.e. `delay === 0`. For delay > 0 the latest usable point is already\n // `latestClosed − delay`, which lives in `bars` as-is from storage.\n if (this.delay === 0) {\n const todayValue = await this.computeAt(date, overrides);\n if (todayValue !== null) {\n const idx = bars.findIndex((b) => b.date === date);\n if (idx >= 0) {\n bars[idx] = { date, value: todayValue };\n } else {\n bars = [...bars, { date, value: todayValue }].sort((a, b) => a.date.localeCompare(b.date));\n }\n }\n }\n\n if (range) {\n bars = bars.filter(\n (b) => (range.from === undefined || b.date >= range.from) && (range.to === undefined || b.date <= range.to),\n );\n }\n\n return bars;\n }\n}\n","import type { DailyBar } from '../handles/indicator';\n\ntype Comparison = '>' | '<' | '=';\n\nfunction computeBuffers(v2: number, tolerance: number, absolute: boolean): { upper: number; lower: number } {\n if (tolerance === 0) return { upper: v2, lower: v2 };\n if (absolute) return { upper: v2 + tolerance, lower: v2 - tolerance };\n return { upper: v2 * (1 + tolerance / 100), lower: v2 * (1 - tolerance / 100) };\n}\n\nfunction rawCompare(v1: number, v2: number, comparison: Comparison): number {\n switch (comparison) {\n case '>':\n return v1 > v2 ? 1 : 0;\n case '<':\n return v1 < v2 ? 1 : 0;\n case '=':\n return v1 === v2 ? 1 : 0;\n }\n}\n\nexport function evaluateSignal(\n series1: DailyBar[],\n series2: DailyBar[],\n comparison: Comparison,\n tolerance: number,\n absolute: boolean,\n previousValue?: number,\n): DailyBar[] {\n const s2Map = new Map<string, number>();\n for (const bar of series2) {\n s2Map.set(bar.date, bar.value);\n }\n\n const result: DailyBar[] = [];\n let prev = previousValue;\n\n for (const bar1 of series1) {\n const v2 = s2Map.get(bar1.date);\n if (v2 === undefined) continue;\n\n const v1 = bar1.value;\n const { upper, lower } = computeBuffers(v2, tolerance, absolute);\n\n let value: number;\n\n if (tolerance === 0) {\n value = rawCompare(v1, v2, comparison);\n } else if (comparison === '=') {\n value = v1 >= lower && v1 <= upper ? 1 : 0;\n } else if (prev === undefined) {\n value = rawCompare(v1, v2, comparison);\n } else if (comparison === '>') {\n if (prev === 1) {\n value = v1 < lower ? 0 : 1;\n } else {\n value = v1 > upper ? 1 : 0;\n }\n } else {\n // comparison === '<'\n if (prev === 1) {\n value = v1 > upper ? 0 : 1;\n } else {\n value = v1 < lower ? 1 : 0;\n }\n }\n\n result.push({ date: bar1.date, value });\n prev = value;\n }\n\n return result;\n}\n","// src/handles/signal.ts\nimport type { StorageProvider } from '../providers/storage';\nimport type { MarketProvider } from '../providers/market';\nimport type { Comparison } from '../providers/types';\nimport type { IndicatorHandle, DailyBar, DateRange } from './indicator';\nimport { evaluateSignal } from '../computations/signal';\n\nconst ABSOLUTE_TOLERANCE_TYPES = new Set([\n 'Return',\n 'Volatility',\n 'Drawdown',\n 'VIX',\n 'VIX3M',\n 'T3M',\n 'T6M',\n 'T1Y',\n 'T2Y',\n 'T3Y',\n 'T5Y',\n 'T7Y',\n 'T10Y',\n 'T20Y',\n 'T30Y',\n]);\n\nexport interface SignalIdentity {\n indicator1: IndicatorHandle;\n indicator2: IndicatorHandle;\n comparison: Comparison;\n tolerance: number;\n}\n\nexport class SignalHandle {\n readonly indicator1: IndicatorHandle;\n readonly indicator2: IndicatorHandle;\n readonly comparison: Comparison;\n readonly tolerance: number;\n\n private _storage: StorageProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n private _cachedSeries: DailyBar[] | null = null;\n private _cachedAsOf: string | null = null;\n private _syncing: Promise<void> | null = null;\n\n // The `market` parameter is kept in the signature for API compatibility with\n // `new SignalHandle(storage, market, identity)` — signals no longer carry\n // their own market reference since `computeAt` delegates to the indicator\n // handles, which already hold one.\n constructor(storage: StorageProvider, _market: MarketProvider, identity: SignalIdentity) {\n this._storage = storage;\n this.indicator1 = identity.indicator1;\n this.indicator2 = identity.indicator2;\n this.comparison = identity.comparison;\n this.tolerance = identity.tolerance;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('SignalHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(\n storage: StorageProvider,\n market: MarketProvider,\n id: number,\n identity: SignalIdentity,\n ): SignalHandle {\n const handle = new SignalHandle(storage, market, identity);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n const [ind1, ind2] = await Promise.all([this.indicator1.resolve(), this.indicator2.resolve()]);\n const result = await this._storage.signals.findOrCreate({\n indicatorId1: ind1.id,\n indicatorId2: ind2.id,\n comparison: this.comparison,\n tolerance: this.tolerance,\n });\n this._resolvedId = result.id;\n return result;\n }\n\n // ── Freshness & Sync ───────────────────────────────────────────────\n\n private async _getLatestClosedTradingDay(): Promise<string> {\n const date = await this._storage.tradingDays.getLatestClosed();\n if (!date) throw new Error('No closed trading days found');\n return date;\n }\n\n private async _getLatestSignalSeriesDate(signalId: number): Promise<string | null> {\n return this._storage.signals.getLatestSeriesDate(signalId);\n }\n\n private async _getLastSignalValue(signalId: number): Promise<number | null> {\n return this._storage.signals.getLastValue(signalId);\n }\n\n private async _ensureFresh(): Promise<void> {\n const { id } = await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n if (this._cachedAsOf === latestClosed) return;\n\n // Ensure both indicators are fresh first\n await Promise.all([this.indicator1.series(), this.indicator2.series()]);\n\n const latestSeries = await this._getLatestSignalSeriesDate(id);\n\n if (latestSeries === latestClosed) {\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n return;\n }\n\n if (!this._syncing) {\n this._syncing = this._sync(latestSeries ?? undefined, latestClosed)\n .catch((err) => {\n console.warn('[sdk] signal sync failed, using stored data:', err);\n })\n .finally(() => {\n this._syncing = null;\n });\n }\n await this._syncing;\n\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n }\n\n private async _sync(fromDate: string | undefined, latestClosed: string): Promise<void> {\n const { id } = await this.resolve();\n\n const range = fromDate ? { from: fromDate } : undefined;\n const [series1, series2] = await Promise.all([this.indicator1.series(range), this.indicator2.series(range)]);\n\n const previousValue = fromDate ? ((await this._getLastSignalValue(id)) ?? undefined) : undefined;\n\n const absolute = ABSOLUTE_TOLERANCE_TYPES.has(this.indicator1.type);\n const signalBars = evaluateSignal(series1, series2, this.comparison, this.tolerance, absolute, previousValue);\n\n const bars = signalBars.filter((b) => b.date <= latestClosed);\n\n if (bars.length > 0) {\n await this._upsertSeries(bars);\n }\n }\n\n private async _upsertSeries(bars: DailyBar[]): Promise<void> {\n const { id } = await this.resolve();\n await this._storage.signals.writeSeries(id, bars);\n }\n\n private async _querySeriesFromDb(range?: DateRange): Promise<DailyBar[]> {\n const { id } = await this.resolve();\n return this._storage.signals.getSeries(id, range);\n }\n\n /**\n * Compute the signal's boolean value at `date` without persisting anything,\n * with optional live-quote `overrides` that are routed through each\n * indicator's `computeAt`. Returns null if either indicator cannot produce\n * a value at `date`.\n *\n * @param prevBool - The signal's boolean value at the bar immediately\n * preceding `date`, used for hysteresis when `tolerance > 0`. If not\n * provided, falls back to `storage.signals.getLastValue` (suitable for\n * standalone callers). On the preview path `_evaluate` passes this from\n * the in-memory `dateMap` so we never read stale storage.\n */\n async computeAt(\n date: string,\n overrides?: Record<string, number>,\n prevBool?: boolean | null,\n ): Promise<boolean | null> {\n const [v1, v2] = await Promise.all([\n this.indicator1.computeAt(date, overrides),\n this.indicator2.computeAt(date, overrides),\n ]);\n if (v1 === null || v2 === null) return null;\n\n const absolute = ABSOLUTE_TOLERANCE_TYPES.has(this.indicator1.type);\n\n // Replicate the evaluateSignal single-bar logic inline (no hysteresis needed\n // for a single-point preview; we use the last historical value as \"prev\").\n if (this.tolerance === 0) {\n switch (this.comparison) {\n case '>':\n return v1 > v2;\n case '<':\n return v1 < v2;\n case '=':\n return v1 === v2;\n }\n }\n\n const tolerance = this.tolerance;\n const upper = absolute ? v2 + tolerance : v2 * (1 + tolerance / 100);\n const lower = absolute ? v2 - tolerance : v2 * (1 - tolerance / 100);\n\n if (this.comparison === '=') {\n return v1 >= lower && v1 <= upper;\n }\n // For '>' and '<' with tolerance, we need hysteresis (prev state).\n // Use the in-memory prevBool if provided (preview path); otherwise fall\n // back to storage (standalone callers / write path).\n let resolvedPrevBool: boolean;\n if (prevBool !== undefined && prevBool !== null) {\n resolvedPrevBool = prevBool;\n } else {\n const prev = await this._storage.signals.getLastValue(this.id);\n resolvedPrevBool = prev === 1;\n }\n if (this.comparison === '>') {\n return resolvedPrevBool ? v1 >= lower : v1 > upper;\n }\n // '<'\n return resolvedPrevBool ? v1 <= upper : v1 < lower;\n }\n\n // ── Public data access ─────────────────────────────────────────────\n\n async series(range?: DateRange): Promise<DailyBar[]> {\n await this._ensureFresh();\n if (this._cachedSeries && !range) return this._cachedSeries;\n const bars = await this._querySeriesFromDb(range);\n if (!range) this._cachedSeries = bars;\n return bars;\n }\n\n async value(date?: string): Promise<number | null> {\n await this._ensureFresh();\n if (date) {\n const series = await this._querySeriesFromDb({ from: date, to: date });\n return series.length > 0 ? series[0]!.value : null;\n }\n const { id } = await this.resolve();\n return this._storage.signals.getLastValue(id);\n }\n\n /**\n * Read-only preview of the signal series with an in-memory bar at `date`\n * computed via `computeAt` with the supplied live-quote `overrides`. Does\n * NOT write to `signals_series`.\n *\n * @param date - Target trading day whose boolean is computed in-memory.\n * @param overrides - Raw (unleveraged) quotes keyed by market symbol.\n * @param range - Optional filter applied to the returned bars.\n */\n async previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<DailyBar[]> {\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewSeries: ${date} is not a trading day`);\n }\n\n let bars = await this._querySeriesFromDb();\n\n // Derive yesterday's boolean from the in-memory dateMap for hysteresis,\n // mirroring StrategyHandle._evaluate's preview path.\n const dateMap = new Map<string, boolean>();\n for (const bar of bars) dateMap.set(bar.date, bar.value === 1);\n\n const limitIdx = tradingDays.indexOf(date);\n const prevDate = limitIdx > 0 ? tradingDays[limitIdx - 1] : undefined;\n const prevBool = prevDate !== undefined ? (dateMap.get(prevDate) ?? null) : null;\n\n const todayBool = await this.computeAt(date, overrides, prevBool);\n if (todayBool !== null) {\n const numeric = todayBool ? 1 : 0;\n const idx = bars.findIndex((b) => b.date === date);\n if (idx >= 0) {\n bars[idx] = { date, value: numeric };\n } else {\n bars = [...bars, { date, value: numeric }].sort((a, b) => a.date.localeCompare(b.date));\n }\n }\n\n if (range) {\n bars = bars.filter(\n (b) => (range.from === undefined || b.date >= range.from) && (range.to === undefined || b.date <= range.to),\n );\n }\n\n return bars;\n }\n}\n","import type { StorageProvider } from '../providers/storage';\nimport { TickerHandle } from './ticker';\n\nexport class AllocationHandle {\n readonly holdings: [TickerHandle, number][];\n\n private _storage: StorageProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n constructor(storage: StorageProvider, holdings: [TickerHandle, number][]) {\n const total = holdings.reduce((sum, [, weight]) => sum + weight, 0);\n if (Math.abs(total - 1) > 1e-9) {\n throw new Error(`Allocation weights must sum to 1, got ${total}`);\n }\n this._storage = storage;\n this.holdings = holdings;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('AllocationHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(storage: StorageProvider, id: number, holdings: [TickerHandle, number][]): AllocationHandle {\n const handle = new AllocationHandle(storage, holdings);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n await Promise.all(this.holdings.map(([ticker]) => ticker.resolve()));\n\n const holdingsJson: Record<string, number> = {};\n for (const [ticker, weight] of this.holdings) {\n const key = ticker.leverage !== 1 ? `${ticker.symbol}?L=${ticker.leverage}` : ticker.symbol;\n holdingsJson[key] = weight;\n }\n\n const result = await this._storage.allocations.findOrCreate(holdingsJson);\n this._resolvedId = result.id;\n return result;\n }\n}\n","import { customAlphabet } from 'nanoid';\nimport type { StorageProvider } from '../providers/storage';\nimport type { MarketProvider } from '../providers/market';\nimport type { TradingFreq, StrategySeriesEntry } from '../providers/types';\nimport { SignalHandle } from './signal';\nimport { AllocationHandle } from './allocation';\nimport { TickerHandle } from './ticker';\nimport { IndicatorHandle } from './indicator';\nimport type { DateRange } from './indicator';\nimport { evaluateStrategy, computeRebalanceDates } from '../computations/strategy';\nimport { runSimulation } from '../backtest/simulate';\nimport { SimulationHandle } from '../backtest/types';\nimport type {\n SimulateOptions,\n FinalState,\n LiveEvaluator,\n StrategyLiveState,\n LiveRuleState,\n LiveSignalState,\n} from '../backtest/types';\n\nconst nanoid = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 21);\n\nexport interface StrategyRule {\n when?: SignalHandle[];\n hold: AllocationHandle;\n}\n\nexport interface StrategyBar {\n date: string;\n allocation: AllocationHandle;\n}\n\nexport interface StrategyOptions {\n name: string;\n freq?: TradingFreq;\n offset?: number;\n rules: StrategyRule[];\n}\n\nexport class StrategyHandle {\n private _linkId: string | null;\n private _name: string | null;\n private _freq: TradingFreq;\n private _offset: number;\n private _rules: StrategyRule[];\n\n private _storage: StorageProvider;\n private _market: MarketProvider;\n private _resolvedId: number | null = null;\n private _resolvedLinkId: string | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n private _allocationMap: Map<number, AllocationHandle> = new Map();\n\n private _cache: StrategyBar[] | null = null;\n private _cachedAsOf: string | null = null;\n private _syncing: Promise<void> | null = null;\n\n constructor(storage: StorageProvider, market: MarketProvider, optionsOrLinkId: StrategyOptions | string) {\n this._storage = storage;\n this._market = market;\n\n if (typeof optionsOrLinkId === 'string') {\n this._linkId = optionsOrLinkId;\n this._name = null;\n this._freq = 'Daily';\n this._offset = 0;\n this._rules = [];\n } else {\n const opts = optionsOrLinkId;\n if (opts.rules.length === 0) {\n throw new Error('Strategy must have at least one rule');\n }\n const lastRule = opts.rules[opts.rules.length - 1]!;\n if (lastRule.when && lastRule.when.length > 0) {\n throw new Error('Last rule must be a fallback (no when clause)');\n }\n for (let i = 0; i < opts.rules.length - 1; i++) {\n const rule = opts.rules[i]!;\n if (rule.when !== undefined && rule.when.length === 0) {\n throw new Error(\n `Rule ${i} has an empty when clause and will match unconditionally, making subsequent rules unreachable`,\n );\n }\n }\n this._linkId = null;\n this._name = opts.name;\n this._freq = opts.freq ?? 'Daily';\n this._offset = opts.offset ?? 0;\n this._rules = opts.rules;\n }\n }\n\n get id(): number {\n if (this._resolvedId == null) throw new Error('StrategyHandle not yet resolved. Call resolve() first.');\n return this._resolvedId;\n }\n\n get link(): string {\n if (this._resolvedLinkId == null) throw new Error('StrategyHandle not yet resolved. Call resolve() first.');\n return this._resolvedLinkId;\n }\n\n get name(): string | null {\n return this._name;\n }\n\n get freq(): TradingFreq {\n return this._freq;\n }\n\n get offset(): number {\n return this._offset;\n }\n\n get rules(): StrategyRule[] {\n return this._rules;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) {\n this._resolving =\n this._linkId !== null && this._name === null ? this._doResolveReference() : this._doResolveCreate();\n }\n return this._resolving;\n }\n\n private async _doResolveCreate(): Promise<{ id: number }> {\n const allSignals = new Set<SignalHandle>();\n const allAllocations = new Set<AllocationHandle>();\n for (const rule of this._rules) {\n if (rule.when) rule.when.forEach((s) => allSignals.add(s));\n allAllocations.add(rule.hold);\n }\n\n await Promise.all([\n ...Array.from(allSignals).map((s) => s.resolve()),\n ...Array.from(allAllocations).map((a) => a.resolve()),\n ]);\n\n const linkId = nanoid();\n const result = await this._storage.strategies.create({\n linkId,\n name: this._name!,\n freq: this._freq,\n offset: this._offset,\n rules: this._rules.map((rule) => ({\n signalIds: (rule.when ?? []).map((s) => s.id),\n allocationId: rule.hold.id,\n })),\n });\n\n this._resolvedId = result.id;\n this._resolvedLinkId = linkId;\n\n for (const rule of this._rules) {\n this._allocationMap.set(rule.hold.id, rule.hold);\n }\n\n return result;\n }\n\n private async _doResolveReference(): Promise<{ id: number }> {\n const ref = await this._storage.strategies.resolveReference(this._linkId!);\n this._resolvedId = ref.id;\n this._resolvedLinkId = this._linkId!;\n this._name = ref.name;\n this._freq = ref.freq;\n this._offset = ref.offset;\n\n // Build handles bottom-up from reference data\n const tickerMap = new Map<number, TickerHandle>();\n for (const t of ref.rules.tickers) {\n tickerMap.set(t.id, TickerHandle.fromResolved(this._storage, t.id, t.symbol, t.leverage));\n }\n\n const indicatorMap = new Map<number, IndicatorHandle>();\n for (const ind of ref.rules.indicators) {\n const ticker = ind.tickerId ? (tickerMap.get(ind.tickerId) ?? null) : null;\n indicatorMap.set(\n ind.id,\n IndicatorHandle.fromResolved(this._storage, this._market, ind.id, {\n type: ind.type,\n ticker,\n lookback: ind.lookback,\n delay: ind.delay,\n unit: ind.unit,\n threshold: ind.threshold,\n }),\n );\n }\n\n const signalMap = new Map<number, SignalHandle>();\n for (const sig of ref.rules.signals) {\n signalMap.set(\n sig.id,\n SignalHandle.fromResolved(this._storage, this._market, sig.id, {\n indicator1: indicatorMap.get(sig.indicatorId1)!,\n indicator2: indicatorMap.get(sig.indicatorId2)!,\n comparison: sig.comparison,\n tolerance: sig.tolerance,\n }),\n );\n }\n\n const allocationHandleMap = new Map<number, AllocationHandle>();\n for (const alloc of ref.rules.allocations) {\n const holdings: [TickerHandle, number][] = Object.entries(alloc.holdings).map(([key, weight]) => {\n const match = key.match(/^(.+)\\?L=(.+)$/);\n const symbol = match ? match[1]! : key;\n const leverage = match ? Number(match[2]) : 1;\n return [new TickerHandle(this._storage, symbol, leverage), weight];\n });\n const handle = AllocationHandle.fromResolved(this._storage, alloc.id, holdings);\n allocationHandleMap.set(alloc.id, handle);\n this._allocationMap.set(alloc.id, handle);\n }\n\n // Reconstruct rules\n this._rules = ref.rules.definition.map((rule) => ({\n when: rule.signalIds && rule.signalIds.length > 0 ? rule.signalIds.map((id) => signalMap.get(id)!) : undefined,\n hold: allocationHandleMap.get(rule.allocationId)!,\n }));\n\n return { id: ref.id };\n }\n\n private async _getLatestClosedTradingDay(): Promise<string> {\n const date = await this._storage.tradingDays.getLatestClosed();\n if (!date) throw new Error('No closed trading days found');\n return date;\n }\n\n private async _getLatestStrategySeriesDate(): Promise<string | null> {\n const { id } = await this.resolve();\n return this._storage.strategies.getLatestSeriesDate(id);\n }\n\n private async _ensureFresh(): Promise<void> {\n await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n if (this._cachedAsOf === latestClosed) return;\n\n const latestSeries = await this._getLatestStrategySeriesDate();\n\n if (latestSeries === latestClosed) {\n this._cache = null;\n this._cachedAsOf = latestClosed;\n return;\n }\n\n if (!this._syncing) {\n this._syncing = this._sync(latestClosed)\n .catch((err) => {\n console.warn('[sdk] strategy sync failed, using stored data:', err);\n })\n .finally(() => {\n this._syncing = null;\n });\n }\n await this._syncing;\n\n this._cache = null;\n this._cachedAsOf = latestClosed;\n }\n\n private async _sync(latestClosed: string): Promise<void> {\n const { id } = await this.resolve();\n const { entries } = await this._evaluate(latestClosed);\n if (entries.length > 0) {\n await this._storage.strategies.writeSeries(id, entries);\n }\n }\n\n /**\n * Pure evaluate — runs the same pipeline as _sync but returns the computed\n * evaluation instead of persisting. Used by both _sync (post-close write\n * path) and the public preview methods (pre-close read-only path).\n *\n * When `overrides` is `undefined` we take the write path — syncing signals\n * through storage as normal. When `overrides` is provided (even an empty\n * map) we take the read-only preview path: historical signal bars come\n * straight from storage, today's bar is computed in-memory via\n * `signal.computeAt(date, overrides, prevBool)`, and nothing is written.\n */\n private async _evaluate(\n limitDate: string,\n overrides?: Record<string, number>,\n ): Promise<{ allocations: AllocationHandle[]; entries: StrategySeriesEntry[] }> {\n const allSignals = new Set<SignalHandle>();\n for (const rule of this._rules) {\n if (rule.when) rule.when.forEach((s) => allSignals.add(s));\n }\n\n const signalSeries = new Map<number, Map<string, boolean>>();\n\n // Collect the ordered list of trading days once so the preview path can\n // look up the day immediately before limitDate without a second storage call.\n const tradingDays = await this._storage.tradingDays.getRange();\n\n if (overrides === undefined) {\n // Normal (post-close) path: sync signals through storage, may write.\n await Promise.all(\n Array.from(allSignals).map(async (signal) => {\n const bars = await signal.series();\n const dateMap = new Map<string, boolean>();\n for (const bar of bars) dateMap.set(bar.date, bar.value === 1);\n signalSeries.set(signal.id, dateMap);\n }),\n );\n } else {\n // Preview (pre-close, no-write) path: read historical from storage, then\n // compute today's signal value in-memory via computeAt. No writes anywhere.\n //\n // Find the trading day immediately before limitDate so we can pass its\n // in-memory boolean as prevBool to computeAt (hysteresis).\n const limitIdx = tradingDays.indexOf(limitDate);\n const prevDate = limitIdx > 0 ? tradingDays[limitIdx - 1] : undefined;\n\n await Promise.all(\n Array.from(allSignals).map(async (signal) => {\n // Read all historical signal bars from storage (pure read).\n const historicalBars = await this._storage.signals.getSeries(signal.id);\n const dateMap = new Map<string, boolean>();\n for (const bar of historicalBars) dateMap.set(bar.date, bar.value === 1);\n\n // Look up yesterday's boolean from the in-memory map (avoids stale\n // storage read for hysteresis on the preview path).\n const prevBool = prevDate !== undefined ? (dateMap.get(prevDate) ?? null) : null;\n\n const todayValue = await signal.computeAt(limitDate, overrides, prevBool);\n if (todayValue !== null) {\n dateMap.set(limitDate, todayValue);\n }\n\n signalSeries.set(signal.id, dateMap);\n }),\n );\n }\n\n const rebalanceDates = computeRebalanceDates(tradingDays, this._freq, this._offset);\n\n const allocations: AllocationHandle[] = [];\n const allocIndexMap = new Map<number, number>();\n const rulesInput = this._rules.map((rule) => {\n let allocIdx = allocIndexMap.get(rule.hold.id);\n if (allocIdx === undefined) {\n allocIdx = allocations.length;\n allocations.push(rule.hold);\n allocIndexMap.set(rule.hold.id, allocIdx);\n }\n return {\n signalIds: (rule.when ?? []).map((s) => s.id),\n allocationIndex: allocIdx,\n };\n });\n\n const evalResult = evaluateStrategy(signalSeries, rulesInput, rebalanceDates, tradingDays);\n const entries: StrategySeriesEntry[] = Array.from(evalResult.entries())\n .filter(([date]) => date <= limitDate)\n .map(([date, allocIdx]) => ({ date, allocationId: allocations[allocIdx]!.id }));\n\n return { allocations, entries };\n }\n\n private async _querySeriesFromDb(range?: DateRange): Promise<StrategyBar[]> {\n const { id } = await this.resolve();\n const entries = await this._storage.strategies.getSeries(id, range);\n return entries.map((e) => ({\n date: e.date,\n allocation: this._allocationMap.get(e.allocationId)!,\n }));\n }\n\n async series(range?: DateRange): Promise<StrategyBar[]> {\n await this._ensureFresh();\n if (this._cache && !range) return this._cache;\n const bars = await this._querySeriesFromDb(range);\n if (!range) this._cache = bars;\n return bars;\n }\n\n async value(date?: string): Promise<AllocationHandle | null> {\n await this._ensureFresh();\n const bars = date ? await this._querySeriesFromDb({ from: date, to: date }) : await this._querySeriesFromDb();\n if (bars.length === 0) return null;\n return date ? bars[0]!.allocation : bars[bars.length - 1]!.allocation;\n }\n\n async simulate(options: SimulateOptions): Promise<SimulationHandle> {\n const bars = await this.series({ from: options.from, to: options.to });\n if (bars.length === 0) {\n return new SimulationHandle([], [], options.portfolio);\n }\n\n const prices = await this._fetchPricesForTickers(bars, options.from, options.to);\n const tradingDays = bars.map((b) => b.date);\n const rebalanceDates = computeRebalanceDates(tradingDays, this._freq, this._offset);\n\n // Force day 1 rebalance so existing positions align to strategy\n rebalanceDates.add(bars[0]!.date);\n\n const result = runSimulation(bars, prices, rebalanceDates, options.portfolio);\n\n // Build finalState for live push support\n const lastBar = bars[bars.length - 1]!;\n const lastDate = lastBar.date;\n const lastAllocation = lastBar.allocation;\n\n // leveragedPrices: keyed as \"symbol:leverage\", values are the leveraged prices from _fetchPricesForTickers\n const leveragedPrices: Record<string, number> = {};\n for (const [ticker, _weight] of lastAllocation.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n const key = `${ticker.symbol}:${ticker.leverage}`;\n const price = prices[key]?.[lastDate];\n if (price != null) leveragedPrices[key] = price;\n }\n\n // closePrices: raw (unleveraged) close prices for computing real returns\n const closePrices: Record<string, number> = {};\n await this._fetchRawClosePrices(bars, lastDate, closePrices);\n\n const finalState: FinalState = {\n portfolio: result.finalPortfolio,\n allocation: lastAllocation,\n closePrices,\n leveragedPrices,\n };\n\n const liveEvaluator: LiveEvaluator = {\n previewLiveState: (date, overrides) => this.previewLiveState(date, overrides),\n };\n return new SimulationHandle(result.series, result.trades, options.portfolio, finalState, liveEvaluator);\n }\n\n /**\n * Preview the allocation this strategy would produce for `date` if today\n * closed at the provided raw quote prices. Does NOT write to strategies_series,\n * signals_series, or indicators_series. Safe to call before market close.\n *\n * @param date - The trading day to preview (must be in tradingDays.getRange()).\n * @param overrides - Raw (unleveraged) live prices keyed by market symbol.\n * Symbols absent from this map fall back to the last stored value\n * (see `IndicatorHandle._resolveRawBars`).\n * @returns The AllocationHandle for `date`, or null if the strategy has no\n * evaluable entry for that date.\n */\n async previewAllocation(date: string, overrides: Record<string, number>): Promise<AllocationHandle | null> {\n await this.resolve();\n\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewAllocation: ${date} is not a trading day`);\n }\n\n const { allocations, entries } = await this._evaluate(date, overrides);\n\n const target = entries.find((e) => e.date === date);\n if (!target) return null;\n\n const alloc = allocations.find((a) => a.id === target.allocationId);\n return alloc ?? this._allocationMap.get(target.allocationId) ?? null;\n }\n\n /**\n * Read-only preview of the strategy's allocation series including `date`.\n * Returns stored historical allocations plus an in-memory bar at `date`\n * computed via the same overrides-based preview path as `previewAllocation`.\n *\n * @param date - Target trading day to splice in-memory.\n * @param overrides - Raw (unleveraged) quotes keyed by market symbol.\n * @param range - Optional filter applied to the returned bars.\n */\n async previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<StrategyBar[]> {\n await this.resolve();\n\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewSeries: ${date} is not a trading day`);\n }\n\n const { allocations, entries } = await this._evaluate(date, overrides);\n\n const allocById = new Map<number, AllocationHandle>();\n for (const a of allocations) allocById.set(a.id, a);\n for (const [id, a] of this._allocationMap) if (!allocById.has(id)) allocById.set(id, a);\n\n let bars: StrategyBar[] = entries.map((e) => ({\n date: e.date,\n allocation: allocById.get(e.allocationId)!,\n }));\n\n if (range) {\n bars = bars.filter(\n (b) => (range.from === undefined || b.date >= range.from) && (range.to === undefined || b.date <= range.to),\n );\n }\n\n return bars;\n }\n\n /**\n * Full live strategy view at `date` under live-quote `overrides`: the active\n * allocation, the index of the rule that fired (or fallback), and per-rule\n * per-signal indicator values + truth. Computed entirely through the\n * overrides preview path — no writes to any `*_series` tables.\n *\n * Threshold indicators have their date suppressed (`null`) since their\n * synthetic series runs over every trading day in storage including future\n * dates and would report a far-future date for the last bar.\n */\n async previewLiveState(date: string, overrides: Record<string, number>): Promise<StrategyLiveState> {\n await this.resolve();\n\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewLiveState: ${date} is not a trading day`);\n }\n\n const [{ allocations, entries }, rules] = await Promise.all([\n this._evaluate(date, overrides),\n Promise.all(\n this._rules.map(async (rule): Promise<LiveRuleState> => {\n const signalHandles = rule.when ?? [];\n const signals: LiveSignalState[] = await Promise.all(\n signalHandles.map(async (sig) => {\n const [i1Series, i2Series, sigSeries] = await Promise.all([\n sig.indicator1.previewSeries(date, overrides),\n sig.indicator2.previewSeries(date, overrides),\n sig.previewSeries(date, overrides),\n ]);\n const last1 = i1Series.at(-1);\n const last2 = i2Series.at(-1);\n const lastSig = sigSeries.at(-1);\n const i1IsThreshold = sig.indicator1.type === 'Threshold';\n const i2IsThreshold = sig.indicator2.type === 'Threshold';\n return {\n indicator1: {\n value: last1?.value ?? null,\n date: i1IsThreshold ? null : (last1?.date ?? null),\n },\n indicator2: {\n value: last2?.value ?? null,\n date: i2IsThreshold ? null : (last2?.date ?? null),\n },\n isTrue: lastSig?.value === 1,\n };\n }),\n );\n return { signals };\n }),\n ),\n ]);\n\n const target = entries.find((e) => e.date === date);\n const allocation = target\n ? (allocations.find((a) => a.id === target.allocationId) ?? this._allocationMap.get(target.allocationId) ?? null)\n : null;\n\n const fallbackIndex = this._rules.length - 1;\n let activeRuleIndex = fallbackIndex;\n if (target) {\n for (let r = 0; r < this._rules.length; r++) {\n if (this._rules[r]!.hold.id === target.allocationId) {\n activeRuleIndex = r;\n break;\n }\n }\n }\n\n return { allocation, activeRuleIndex, rules };\n }\n\n private async _fetchPricesForTickers(\n bars: StrategyBar[],\n from: string,\n to: string,\n ): Promise<Record<string, Record<string, number>>> {\n const tickerMap = new Map<string, TickerHandle>();\n for (const bar of bars) {\n for (const [ticker] of bar.allocation.holdings) {\n const key = `${ticker.symbol}:${ticker.leverage}`;\n if (!tickerMap.has(key)) {\n tickerMap.set(key, ticker);\n }\n }\n }\n\n const entries = await Promise.all(\n Array.from(tickerMap.entries()).map(async ([key, ticker]) => {\n const priceIndicator = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n const priceBars = await priceIndicator.series({ from, to });\n const dateMap: Record<string, number> = {};\n for (const bar of priceBars) {\n dateMap[bar.date] = bar.value;\n }\n return [key, dateMap] as const;\n }),\n );\n\n return Object.fromEntries(entries);\n }\n\n private async _fetchRawClosePrices(\n bars: StrategyBar[],\n lastDate: string,\n closePrices: Record<string, number>,\n ): Promise<void> {\n const symbols = new Set<string>();\n for (const bar of bars) {\n for (const [ticker] of bar.allocation.holdings) {\n if (ticker.symbol !== 'CASHX') symbols.add(ticker.symbol);\n }\n }\n\n await Promise.all(\n Array.from(symbols).map(async (symbol) => {\n const rawTicker = new TickerHandle(this._storage, symbol, 1);\n const priceIndicator = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker: rawTicker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n const priceBars = await priceIndicator.series({ from: lastDate, to: lastDate });\n if (priceBars.length > 0) {\n closePrices[symbol] = priceBars[0]!.value;\n }\n }),\n );\n }\n}\n","import type { TradingFreq } from '../providers/types';\n\nfunction getPeriodKey(dateStr: string, freq: TradingFreq): string {\n const d = new Date(dateStr + 'T00:00:00Z');\n const y = d.getUTCFullYear();\n const m = d.getUTCMonth();\n\n switch (freq) {\n case 'Weekly': {\n const thu = new Date(d);\n thu.setUTCDate(thu.getUTCDate() + 3 - ((thu.getUTCDay() + 6) % 7));\n const yearStart = new Date(Date.UTC(thu.getUTCFullYear(), 0, 1));\n const weekNo = Math.ceil(((thu.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n return `${thu.getUTCFullYear()}-W${weekNo}`;\n }\n case 'Monthly':\n return `${y}-${m}`;\n case 'Bi-monthly':\n return `${y}-${Math.floor(m / 2)}`;\n case 'Quarterly':\n return `${y}-Q${Math.floor(m / 3)}`;\n case 'Every 4 Months':\n return `${y}-${Math.floor(m / 4)}`;\n case 'Semiannually':\n return `${y}-H${Math.floor(m / 6)}`;\n case 'Yearly':\n return `${y}`;\n default:\n return `${y}-${m}`;\n }\n}\n\nexport function computeRebalanceDates(tradingDays: string[], freq: TradingFreq, offset: number): Set<string> {\n if (freq === 'Daily') return new Set(tradingDays);\n\n const groups = new Map<string, number[]>();\n for (let i = 0; i < tradingDays.length; i++) {\n const key = getPeriodKey(tradingDays[i], freq);\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(i);\n }\n\n const result = new Set<string>();\n for (const indices of groups.values()) {\n const lastIdx = indices[indices.length - 1];\n const targetIdx = lastIdx - offset;\n if (targetIdx >= 0 && targetIdx < tradingDays.length) {\n result.add(tradingDays[targetIdx]);\n }\n }\n\n return result;\n}\n\nexport interface StrategyRuleInput {\n signalIds: number[];\n allocationIndex: number;\n}\n\nexport function evaluateStrategy(\n signalSeries: Map<number, Map<string, boolean>>,\n rules: StrategyRuleInput[],\n rebalanceDates: Set<string>,\n tradingDays: string[],\n): Map<string, number> {\n const result = new Map<string, number>();\n let current: number | undefined;\n\n for (const date of tradingDays) {\n if (rebalanceDates.has(date)) {\n for (const rule of rules) {\n if (rule.signalIds.length === 0) {\n current = rule.allocationIndex;\n break;\n }\n const allTrue = rule.signalIds.every((id) => signalSeries.get(id)?.get(date) ?? false);\n if (allTrue) {\n current = rule.allocationIndex;\n break;\n }\n }\n }\n if (current !== undefined) {\n result.set(date, current);\n }\n }\n\n return result;\n}\n","import { TickerHandle } from './ticker';\nimport type { Trade } from '../backtest/types';\nimport { AllocationHandle } from './allocation';\nimport { isRateTickerSymbol } from '../providers/mappings';\n\nexport class PortfolioHandle {\n readonly holdings: [TickerHandle, number][];\n\n constructor(holdings: [TickerHandle, number][]) {\n // Check for duplicates\n const seen = new Set<string>();\n for (const [ticker] of holdings) {\n const key = `${ticker.symbol}:${ticker.leverage}`;\n if (seen.has(key)) {\n throw new Error(`Duplicate ticker: ${ticker.symbol}`);\n }\n seen.add(key);\n }\n\n this.holdings = holdings;\n }\n\n private _priceMap(prices: [TickerHandle, number][]): Map<string, number> {\n const map = new Map<string, number>();\n for (const [ticker, price] of prices) {\n map.set(`${ticker.symbol}:${ticker.leverage}`, price);\n }\n return map;\n }\n\n private _priceFor(ticker: TickerHandle, priceMap: Map<string, number>): number {\n if (ticker.symbol === 'CASHX') return 1;\n if (isRateTickerSymbol(ticker.symbol)) return 1;\n const key = `${ticker.symbol}:${ticker.leverage}`;\n const price = priceMap.get(key);\n if (price == null) {\n throw new Error(`Missing price for ${ticker.symbol}`);\n }\n return price;\n }\n\n value(prices: [TickerHandle, number][]): number {\n const priceMap = this._priceMap(prices);\n let total = 0;\n for (const [ticker, quantity] of this.holdings) {\n total += quantity * this._priceFor(ticker, priceMap);\n }\n return total;\n }\n\n weights(prices: [TickerHandle, number][]): [TickerHandle, number][] {\n const total = this.value(prices);\n if (total === 0) return [];\n\n const priceMap = this._priceMap(prices);\n const result: [TickerHandle, number][] = [];\n for (const [ticker, quantity] of this.holdings) {\n const dollarValue = quantity * this._priceFor(ticker, priceMap);\n if (dollarValue === 0) continue;\n result.push([ticker, dollarValue / total]);\n }\n return result;\n }\n\n trades(target: AllocationHandle, prices: [TickerHandle, number][], date: string): Trade[] {\n const priceMap = this._priceMap(prices);\n const totalValue = this.value(prices);\n\n // Build current dollar amounts by symbol\n const currentDollars = new Map<string, number>();\n for (const [ticker, quantity] of this.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n const price = this._priceFor(ticker, priceMap);\n currentDollars.set(ticker.symbol, quantity * price);\n }\n\n // Build target dollar amounts by symbol\n const targetDollars = new Map<string, number>();\n for (const [ticker, weight] of target.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n targetDollars.set(ticker.symbol, totalValue * weight);\n }\n\n // Build a symbol → TickerHandle lookup for price resolution\n const tickerBySymbol = new Map<string, TickerHandle>();\n for (const [ticker] of this.holdings) {\n if (ticker.symbol !== 'CASHX') tickerBySymbol.set(ticker.symbol, ticker);\n }\n for (const [ticker] of target.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n const existing = tickerBySymbol.get(ticker.symbol);\n if (existing && existing.leverage !== ticker.leverage) {\n throw new Error(`Conflicting leverage for ${ticker.symbol}`);\n }\n tickerBySymbol.set(ticker.symbol, ticker);\n }\n\n // Collect all non-CASHX symbols from both sides\n const allSymbols = new Set([...currentDollars.keys(), ...targetDollars.keys()]);\n\n const sells: Trade[] = [];\n const buys: Trade[] = [];\n\n for (const symbol of allSymbols) {\n const current = currentDollars.get(symbol) ?? 0;\n const target$ = targetDollars.get(symbol) ?? 0;\n const delta = target$ - current;\n\n const ticker = tickerBySymbol.get(symbol)!;\n const price = this._priceFor(ticker, priceMap);\n\n const quantity = Math.abs(delta) / price;\n if (quantity < 1e-10) continue;\n\n const trade: Trade = { date, symbol, quantity, price, action: delta > 0 ? 'buy' : 'sell' };\n\n if (trade.action === 'sell') {\n sells.push(trade);\n } else {\n buys.push(trade);\n }\n }\n\n return [...sells, ...buys];\n }\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { StrategyBar } from '../handles/strategy';\nimport type { TickerHandle } from '../handles/ticker';\nimport type { Trade } from './types';\nimport { PortfolioHandle } from '../handles/portfolio';\nimport { isRateTickerSymbol } from '../providers/mappings';\n\nconst EPSILON = 1e-8;\n\nfunction tkey(symbol: string, leverage: number): string {\n return `${symbol}:${leverage}`;\n}\n\nfunction symbolFromKey(key: string): string {\n const idx = key.lastIndexOf(':');\n return idx === -1 ? key : key.slice(0, idx);\n}\n\nfunction isRateKey(key: string): boolean {\n return isRateTickerSymbol(symbolFromKey(key));\n}\n\nfunction navPriceForKey(\n key: string,\n date: string,\n prices: Record<string, Record<string, number>>,\n lastPrice: Record<string, number>,\n): number | undefined {\n if (isRateKey(key)) return 1;\n const live = prices[key]?.[date];\n if (live != null) {\n lastPrice[key] = live;\n return live;\n }\n return lastPrice[key];\n}\n\nfunction daysBetween(prevIsoDate: string, currIsoDate: string): number {\n // Both inputs are 'YYYY-MM-DD'. UTC midnight → diff in ms → days.\n const ms =\n Date.UTC(Number(currIsoDate.slice(0, 4)), Number(currIsoDate.slice(5, 7)) - 1, Number(currIsoDate.slice(8, 10))) -\n Date.UTC(Number(prevIsoDate.slice(0, 4)), Number(prevIsoDate.slice(5, 7)) - 1, Number(prevIsoDate.slice(8, 10)));\n return Math.round(ms / (1000 * 60 * 60 * 24));\n}\n\nexport function runSimulation(\n bars: StrategyBar[],\n prices: Record<string, Record<string, number>>,\n rebalanceDates: Set<string>,\n portfolio: PortfolioHandle,\n): { series: DailyBar[]; trades: Trade[]; finalPortfolio: PortfolioHandle } {\n const positions: Record<string, number> = {};\n const lastPrice: Record<string, number> = {};\n let cash = 0;\n for (const [ticker, quantity] of portfolio.holdings) {\n if (ticker.symbol === 'CASHX') {\n cash = quantity;\n } else {\n positions[tkey(ticker.symbol, ticker.leverage)] = quantity;\n }\n }\n const series: DailyBar[] = [];\n const trades: Trade[] = [];\n\n // Carry forward the last known close when today's price is missing so\n // a held position isn't silently valued at $0 (e.g. mutual fund NAV that\n // posts after the trading-day cutoff).\n function valuationPrice(key: string, date: string): number | undefined {\n return navPriceForKey(key, date, prices, lastPrice);\n }\n\n let prevDate: string | null = null;\n\n for (const bar of bars) {\n const date = bar.date;\n\n // Accrue interest on rate-ticker positions between the previous bar and today.\n if (prevDate != null) {\n const days = daysBetween(prevDate, date);\n if (days > 0) {\n for (const [key, shares] of Object.entries(positions)) {\n if (!isRateKey(key)) continue;\n const ratePct = prices[key]?.[prevDate];\n if (ratePct == null) continue;\n const leverage = Number(key.slice(key.lastIndexOf(':') + 1)) || 1;\n const factor = 1 + leverage * (ratePct / 100) * (days / 360);\n positions[key] = shares * factor;\n }\n }\n }\n\n if (rebalanceDates.has(date)) {\n // Compute current portfolio value before rebalancing\n let portfolioValue = cash;\n for (const [key, shares] of Object.entries(positions)) {\n const price = valuationPrice(key, date);\n if (price != null) portfolioValue += shares * price;\n }\n\n // Determine target holdings\n const targetWeights: Record<string, number> = {};\n for (const [ticker, weight] of bar.allocation.holdings) {\n targetWeights[tkey(ticker.symbol, ticker.leverage)] = weight;\n }\n\n // Compute target shares and execute trades\n const allKeys = new Set([...Object.keys(positions), ...Object.keys(targetWeights)]);\n for (const key of allKeys) {\n let price: number;\n if (isRateKey(key)) {\n price = 1;\n } else {\n const live = prices[key]?.[date];\n if (live == null || live <= 0) continue;\n price = live;\n }\n\n const currentShares = positions[key] ?? 0;\n const targetValue = portfolioValue * (targetWeights[key] ?? 0);\n const targetShares = targetValue / price;\n const delta = targetShares - currentShares;\n\n if (Math.abs(delta) <= EPSILON) continue;\n\n if (Math.abs(targetShares) <= EPSILON) {\n delete positions[key];\n } else {\n positions[key] = targetShares;\n }\n cash -= delta * price;\n\n trades.push({\n date,\n symbol: key.split(':')[0]!,\n quantity: Math.abs(delta),\n price,\n action: delta > 0 ? 'buy' : 'sell',\n });\n }\n\n if (Math.abs(cash) <= EPSILON) cash = 0;\n }\n\n // Compute end-of-day portfolio value\n let value = cash;\n for (const [key, shares] of Object.entries(positions)) {\n const price = valuationPrice(key, date);\n if (price != null) value += shares * price;\n }\n series.push({ date, value });\n prevDate = date;\n }\n\n // Build finalPortfolio from ending positions + cash\n const finalHoldings: [TickerHandle, number][] = [];\n\n // Map ticker keys back to TickerHandles from allocations and starting portfolio\n const tickerByKey = new Map<string, TickerHandle>();\n for (const bar of bars) {\n for (const [ticker] of bar.allocation.holdings) {\n const key = tkey(ticker.symbol, ticker.leverage);\n if (!tickerByKey.has(key)) {\n tickerByKey.set(key, ticker);\n }\n }\n }\n for (const [ticker] of portfolio.holdings) {\n const key = tkey(ticker.symbol, ticker.leverage);\n if (!tickerByKey.has(key)) {\n tickerByKey.set(key, ticker);\n }\n }\n\n for (const [key, shares] of Object.entries(positions)) {\n const ticker = tickerByKey.get(key);\n if (ticker && Math.abs(shares) > EPSILON) {\n finalHoldings.push([ticker, shares]);\n }\n }\n\n // Add CASHX\n const cashKey = tkey('CASHX', 1);\n const cashTicker = tickerByKey.get(cashKey) ?? portfolio.holdings.find(([t]) => t.symbol === 'CASHX')?.[0];\n if (cashTicker && Math.abs(cash) > EPSILON) {\n finalHoldings.push([cashTicker, cash]);\n }\n\n const finalPortfolio = new PortfolioHandle(finalHoldings);\n\n return { series, trades, finalPortfolio };\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { AllocationHandle } from '../handles/allocation';\nimport { PortfolioHandle } from '../handles/portfolio';\nimport type { TickerHandle } from '../handles/ticker';\n\nexport interface SimulateOptions {\n from: string;\n to: string;\n portfolio: PortfolioHandle;\n}\n\nexport interface Trade {\n date: string;\n symbol: string;\n quantity: number;\n price: number;\n action: 'buy' | 'sell';\n}\n\nexport interface PortfolioSnapshot {\n value: number;\n holdings: [TickerHandle, number][];\n weights: [TickerHandle, number][];\n pendingTrades: Trade[];\n}\n\nexport interface FinalState {\n portfolio: PortfolioHandle;\n allocation: AllocationHandle;\n closePrices: Record<string, number>;\n leveragedPrices: Record<string, number>;\n}\n\n/** Per-signal slice of a live strategy snapshot. */\nexport interface LiveSignalState {\n indicator1: { value: number | null; date: string | null };\n indicator2: { value: number | null; date: string | null };\n isTrue: boolean;\n}\n\n/** Per-rule collection of live signal states, in the same order as the rule's `when` list. */\nexport interface LiveRuleState {\n signals: LiveSignalState[];\n}\n\n/** Full live strategy view for a single evaluation date — no portfolio info. */\nexport interface StrategyLiveState {\n allocation: AllocationHandle | null;\n activeRuleIndex: number;\n rules: LiveRuleState[];\n}\n\n/**\n * Combined live state returned by `SimulationHandle.pushAndPreview`: both the\n * portfolio snapshot from a `push` and the strategy evaluation at the target\n * date under the accumulated live-quote overrides.\n */\nexport interface LivePreviewState extends StrategyLiveState {\n snapshot: PortfolioSnapshot;\n}\n\n/**\n * Callback shape that `SimulationHandle.pushAndPreview` delegates to. Exists\n * purely to break the circular import between `SimulationHandle` (in this\n * file) and `StrategyHandle` (which creates simulations) — a strategy passes\n * a bound `(date, overrides) => previewLiveState(...)` into the handle.\n */\nexport interface LiveEvaluator {\n previewLiveState(date: string, overrides: Record<string, number>): Promise<StrategyLiveState>;\n}\n\nexport class SimulationHandle {\n readonly series: DailyBar[];\n readonly trades: Trade[];\n readonly startingPortfolio: PortfolioHandle;\n\n private _portfolio: PortfolioHandle | null;\n private _currentAllocation: AllocationHandle | null;\n private _lastClosePrices: Record<string, number>;\n private _lastLeveragedPrices: Map<string, number>;\n private _currentLeveragedPrices: Map<string, number>;\n private _lastDate: string;\n private _pushedQuotes: Record<string, number>;\n private _liveEvaluator: LiveEvaluator | null;\n\n constructor(\n series: DailyBar[],\n trades: Trade[],\n startingPortfolio: PortfolioHandle,\n finalState?: FinalState,\n liveEvaluator?: LiveEvaluator,\n ) {\n this.series = series;\n this.trades = trades;\n this.startingPortfolio = startingPortfolio;\n\n if (finalState) {\n this._portfolio = finalState.portfolio;\n this._currentAllocation = finalState.allocation;\n this._lastClosePrices = finalState.closePrices;\n this._lastLeveragedPrices = new Map(Object.entries(finalState.leveragedPrices));\n this._currentLeveragedPrices = new Map(Object.entries(finalState.leveragedPrices));\n this._lastDate = series.at(-1)?.date ?? '';\n } else {\n this._portfolio = null;\n this._currentAllocation = null;\n this._lastClosePrices = {};\n this._lastLeveragedPrices = new Map();\n this._currentLeveragedPrices = new Map();\n this._lastDate = '';\n }\n\n this._pushedQuotes = {};\n this._liveEvaluator = liveEvaluator ?? null;\n }\n\n push(...prices: [TickerHandle, number][]): PortfolioSnapshot {\n if (!this._portfolio || !this._currentAllocation) {\n return { value: 0, holdings: [], weights: [], pendingTrades: [] };\n }\n\n // Update leveraged prices from raw market prices\n for (const [ticker, realPrice] of prices) {\n if (ticker.symbol === 'CASHX') continue;\n const lastClose = this._lastClosePrices[ticker.symbol];\n if (lastClose == null) continue;\n\n const realReturn = (realPrice - lastClose) / lastClose;\n\n // Apply leverage to all portfolio tickers sharing this symbol\n for (const [held] of this._portfolio.holdings) {\n if (held.symbol !== ticker.symbol) continue;\n if (held.symbol === 'CASHX') continue;\n const key = `${held.symbol}:${held.leverage}`;\n const baseLeveragedPrice = this._lastLeveragedPrices.get(key);\n if (baseLeveragedPrice == null) continue;\n const leveragedReturn = held.leverage * realReturn;\n this._currentLeveragedPrices.set(key, baseLeveragedPrice * (1 + leveragedReturn));\n }\n }\n\n // Build price array for PortfolioHandle methods\n const priceArray: [TickerHandle, number][] = [];\n for (const [held] of this._portfolio.holdings) {\n if (held.symbol === 'CASHX') continue;\n const key = `${held.symbol}:${held.leverage}`;\n const price = this._currentLeveragedPrices.get(key);\n if (price != null) priceArray.push([held, price]);\n }\n\n return {\n value: this._portfolio.value(priceArray),\n holdings: this._portfolio.holdings,\n weights: this._portfolio.weights(priceArray),\n pendingTrades: this._portfolio.trades(this._currentAllocation, priceArray, this._lastDate),\n };\n }\n\n /**\n * One-call live update. Feeds portfolio-relevant ticker prices into `push`\n * (derived from `quotes` via the running portfolio's holdings), accumulates\n * every symbol in `quotes` into an internal override map so macro symbols\n * (e.g. `^VIX`) persist across ticks, then delegates to the simulation's\n * strategy for rule / signal / indicator evaluation at `date`.\n *\n * Without a live evaluator attached, returns just the portfolio snapshot\n * with allocation/rules/signals empty.\n *\n * @param quotes Symbol → raw live price. Portfolio tickers flow through\n * `push` for leveraged-equity math; non-portfolio symbols are still\n * layered into the overlay so indicators can see them.\n * @param options.date Target trading day to evaluate against. Defaults to\n * the current UTC ISO date; callers with non-UTC semantics or after-hours\n * rollover should supply their own.\n */\n async pushAndPreview(quotes: Record<string, number>, options: { date?: string } = {}): Promise<LivePreviewState> {\n const priceArgs: [TickerHandle, number][] = [];\n if (this._portfolio) {\n const seen = new Set<string>();\n for (const [ticker] of this._portfolio.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n if (seen.has(ticker.symbol)) continue;\n const price = quotes[ticker.symbol];\n if (price !== undefined) {\n priceArgs.push([ticker, price]);\n seen.add(ticker.symbol);\n }\n }\n }\n const snapshot = this.push(...priceArgs);\n\n // Merge into the running overlay map (macro symbols etc. persist across ticks).\n for (const [symbol, price] of Object.entries(quotes)) {\n this._pushedQuotes[symbol] = price;\n }\n\n if (!this._liveEvaluator) {\n return { snapshot, allocation: null, activeRuleIndex: -1, rules: [] };\n }\n\n const date = options.date ?? new Date().toISOString().slice(0, 10);\n // Pass a snapshot copy so downstream callers can retain the object without\n // seeing it mutate on later ticks.\n const strategyState = await this._liveEvaluator.previewLiveState(date, { ...this._pushedQuotes });\n return { snapshot, ...strategyState };\n }\n}\n","import type { StorageProvider } from './providers/storage';\nimport type { MarketProvider } from './providers/market';\nimport type { IndicatorType, Unit } from './providers/types';\nimport { TickerHandle } from './handles/ticker';\nimport { IndicatorHandle } from './handles/indicator';\nimport { SignalHandle } from './handles/signal';\nimport { AllocationHandle } from './handles/allocation';\nimport { StrategyHandle } from './handles/strategy';\nimport { PortfolioHandle } from './handles/portfolio';\nimport type { StrategyOptions } from './handles/strategy';\n\ntype TreasuryTenor = Extract<\n IndicatorType,\n 'T3M' | 'T6M' | 'T1Y' | 'T2Y' | 'T3Y' | 'T5Y' | 'T7Y' | 'T10Y' | 'T20Y' | 'T30Y'\n>;\ntype CalendarPeriod = Extract<IndicatorType, 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year'>;\n\ninterface IndicatorOpts {\n delay?: number;\n}\n\nexport interface LivefolioClient {\n ticker(symbol: string, leverage?: number): TickerHandle;\n\n // Ticker-bound\n sma(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n ema(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n price(ticker: TickerHandle, opts?: IndicatorOpts): IndicatorHandle;\n returns(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n volatility(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n drawdown(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n rsi(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n\n // Standalone\n vix(opts?: IndicatorOpts): IndicatorHandle;\n vix3m(opts?: IndicatorOpts): IndicatorHandle;\n treasury(tenor: TreasuryTenor, opts?: IndicatorOpts): IndicatorHandle;\n calendar(period: CalendarPeriod, opts?: IndicatorOpts): IndicatorHandle;\n\n // Threshold\n threshold(value: number, unit?: Unit): IndicatorHandle;\n\n // Signals\n gt(ind1: IndicatorHandle, ind2: IndicatorHandle, tolerance?: number): SignalHandle;\n lt(ind1: IndicatorHandle, ind2: IndicatorHandle, tolerance?: number): SignalHandle;\n eq(ind1: IndicatorHandle, ind2: IndicatorHandle, tolerance?: number): SignalHandle;\n\n // Allocations\n allocation(...holdings: [TickerHandle, number][]): AllocationHandle;\n\n // Portfolios\n portfolio(...holdings: [TickerHandle, number][]): PortfolioHandle;\n\n // Strategies\n strategy(linkId: string): StrategyHandle;\n strategy(options: StrategyOptions): StrategyHandle;\n strategy(optionsOrLinkId: string | StrategyOptions): StrategyHandle;\n}\n\nexport interface LivefolioClientOptions {\n storage: StorageProvider;\n market: MarketProvider;\n}\n\nfunction tickerBound(\n storage: StorageProvider,\n market: MarketProvider,\n type: IndicatorType,\n ticker: TickerHandle,\n lookback: number,\n opts?: IndicatorOpts,\n): IndicatorHandle {\n return new IndicatorHandle(storage, market, {\n type,\n ticker,\n lookback,\n delay: opts?.delay ?? 0,\n unit: null,\n threshold: null,\n });\n}\n\nfunction standalone(\n storage: StorageProvider,\n market: MarketProvider,\n type: IndicatorType,\n opts?: IndicatorOpts,\n): IndicatorHandle {\n return new IndicatorHandle(storage, market, {\n type,\n ticker: null,\n lookback: 0,\n delay: opts?.delay ?? 0,\n unit: null,\n threshold: null,\n });\n}\n\nexport function createClient(options: LivefolioClientOptions): LivefolioClient {\n const { storage, market } = options;\n\n return {\n ticker: (symbol, leverage) => new TickerHandle(storage, symbol, leverage),\n\n sma: (ticker, lookback, opts?) => tickerBound(storage, market, 'SMA', ticker, lookback, opts),\n ema: (ticker, lookback, opts?) => tickerBound(storage, market, 'EMA', ticker, lookback, opts),\n price: (ticker, opts?) => tickerBound(storage, market, 'Price', ticker, 0, opts),\n returns: (ticker, lookback, opts?) => tickerBound(storage, market, 'Return', ticker, lookback, opts),\n volatility: (ticker, lookback, opts?) => tickerBound(storage, market, 'Volatility', ticker, lookback, opts),\n drawdown: (ticker, lookback, opts?) => tickerBound(storage, market, 'Drawdown', ticker, lookback, opts),\n rsi: (ticker, lookback, opts?) => tickerBound(storage, market, 'RSI', ticker, lookback, opts),\n\n vix: (opts?) => standalone(storage, market, 'VIX', opts),\n vix3m: (opts?) => standalone(storage, market, 'VIX3M', opts),\n treasury: (tenor, opts?) => standalone(storage, market, tenor, opts),\n calendar: (period, opts?) => standalone(storage, market, period, opts),\n\n threshold: (value, unit?) =>\n new IndicatorHandle(storage, market, {\n type: 'Threshold',\n ticker: null,\n lookback: 0,\n delay: 0,\n unit: unit ?? null,\n threshold: value,\n }),\n\n gt: (ind1, ind2, tolerance?) =>\n new SignalHandle(storage, market, {\n indicator1: ind1,\n indicator2: ind2,\n comparison: '>',\n tolerance: tolerance ?? 0,\n }),\n lt: (ind1, ind2, tolerance?) =>\n new SignalHandle(storage, market, {\n indicator1: ind1,\n indicator2: ind2,\n comparison: '<',\n tolerance: tolerance ?? 0,\n }),\n eq: (ind1, ind2, tolerance?) =>\n new SignalHandle(storage, market, {\n indicator1: ind1,\n indicator2: ind2,\n comparison: '=',\n tolerance: tolerance ?? 0,\n }),\n\n allocation: (...holdings) => new AllocationHandle(storage, holdings),\n\n portfolio: (...holdings) => new PortfolioHandle(holdings),\n\n strategy: (optionsOrLinkId: StrategyOptions | string) => new StrategyHandle(storage, market, optionsOrLinkId),\n };\n}\n"],"mappings":"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","names":["from","rawBars"]}
|
|
1
|
+
{"version":3,"sources":["../src/handles/ticker.ts","../src/providers/mappings.ts","../src/computations/sma.ts","../src/computations/ema.ts","../src/computations/rsi.ts","../src/computations/returns.ts","../src/computations/volatility.ts","../src/computations/drawdown.ts","../src/computations/calendar.ts","../src/computations/index.ts","../src/handles/indicator.ts","../src/computations/signal.ts","../src/handles/signal.ts","../src/handles/allocation.ts","../src/handles/strategy.ts","../src/computations/strategy.ts","../src/handles/portfolio.ts","../src/backtest/simulate.ts","../src/backtest/types.ts","../src/client.ts","../src/handles/allocation-equality.ts"],"sourcesContent":["import type { StorageProvider } from '../providers/storage';\n\nexport class TickerHandle {\n readonly symbol: string;\n readonly leverage: number;\n\n private _storage: StorageProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n constructor(storage: StorageProvider, symbol: string, leverage: number = 1) {\n this._storage = storage;\n this.symbol = symbol.toUpperCase();\n this.leverage = leverage;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('TickerHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(storage: StorageProvider, id: number, symbol: string, leverage: number): TickerHandle {\n const handle = new TickerHandle(storage, symbol, leverage);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n const result = await this._storage.tickers.findOrCreate(this.symbol, this.leverage);\n this._resolvedId = result.id;\n return result;\n }\n}\n","import type { IndicatorType } from './types';\n\nexport type ProviderInfo =\n | { provider: 'yahoo'; symbol: string; rateSeries?: true }\n | { provider: 'fred'; seriesId: string; rateSeries?: true }\n | { provider: 'computed'; dependsOn: 'Price'; symbol: string; rateSeries?: true }\n | { provider: 'calendar' }\n | { provider: 'none' };\n\nconst FRED_SERIES: Record<string, string> = {\n T3M: 'DGS3MO',\n T6M: 'DGS6MO',\n T1Y: 'DGS1',\n T2Y: 'DGS2',\n T3Y: 'DGS3',\n T5Y: 'DGS5',\n T7Y: 'DGS7',\n T10Y: 'DGS10',\n T20Y: 'DGS20',\n T30Y: 'DGS30',\n};\n\n// Ticker symbols whose \"price\" values are rates/yields (expressed in percent),\n// not prices. For these, percent-change returns are both broken (divide by\n// zero / sign flips) and semantically wrong — callers should use absolute\n// differences instead.\nconst RATE_TICKER_SYMBOLS = new Set<string>([\n 'DTB3',\n 'DTB6',\n 'DFF',\n 'DGS3MO',\n 'DGS6MO',\n 'DGS1',\n 'DGS2',\n 'DGS3',\n 'DGS5',\n 'DGS7',\n 'DGS10',\n 'DGS20',\n 'DGS30',\n]);\n\nconst COMPUTED_TYPES = new Set<string>(['SMA', 'EMA', 'RSI', 'Return', 'Volatility', 'Drawdown']);\nconst CALENDAR_TYPES = new Set<string>(['Month', 'Day of Week', 'Day of Month', 'Day of Year']);\n\nexport function isRateTickerSymbol(symbol: string | null): boolean {\n return symbol != null && RATE_TICKER_SYMBOLS.has(symbol);\n}\n\nexport function getProviderInfo(type: IndicatorType, tickerSymbol: string | null): ProviderInfo {\n if (type === 'Price') {\n const info: ProviderInfo = { provider: 'yahoo', symbol: tickerSymbol! };\n if (isRateTickerSymbol(tickerSymbol)) info.rateSeries = true;\n return info;\n }\n if (type === 'VIX') return { provider: 'yahoo', symbol: '^VIX' };\n if (type === 'VIX3M') return { provider: 'yahoo', symbol: '^VIX3M' };\n\n if (type in FRED_SERIES) return { provider: 'fred', seriesId: FRED_SERIES[type]!, rateSeries: true };\n\n if (COMPUTED_TYPES.has(type)) {\n const info: ProviderInfo = { provider: 'computed', dependsOn: 'Price', symbol: tickerSymbol! };\n if (isRateTickerSymbol(tickerSymbol)) info.rateSeries = true;\n return info;\n }\n\n if (CALENDAR_TYPES.has(type)) return { provider: 'calendar' };\n\n return { provider: 'none' };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeSma(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback) return [];\n const result: DailyBar[] = [];\n let sum = 0;\n for (let i = 0; i < lookback; i++) sum += bars[i].value;\n result.push({ date: bars[lookback - 1].date, value: sum / lookback });\n for (let i = lookback; i < bars.length; i++) {\n sum += bars[i].value - bars[i - lookback].value;\n result.push({ date: bars[i].date, value: sum / lookback });\n }\n return result;\n}\n\nexport interface SmaState {\n tail: number[];\n}\n\nexport function smaInitialState(bars: DailyBar[], lookback: number): SmaState | null {\n if (bars.length < lookback) return null;\n return { tail: bars.slice(-lookback).map((b) => b.value) };\n}\n\nexport function smaNext(prev: SmaState, newRaw: number, lookback: number): { value: number; state: SmaState } {\n const tail = [...prev.tail.slice(1), newRaw];\n const sum = tail.reduce((a, b) => a + b, 0);\n return { value: sum / lookback, state: { tail } };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeEma(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback) return [];\n const multiplier = 2 / (lookback + 1);\n const result: DailyBar[] = [];\n let sum = 0;\n for (let i = 0; i < lookback; i++) sum += bars[i].value;\n let ema = sum / lookback;\n result.push({ date: bars[lookback - 1].date, value: ema });\n for (let i = lookback; i < bars.length; i++) {\n ema = bars[i].value * multiplier + ema * (1 - multiplier);\n result.push({ date: bars[i].date, value: ema });\n }\n return result;\n}\n\nexport interface EmaState {\n ema: number;\n}\n\nexport function emaInitialState(bars: DailyBar[], lookback: number): EmaState | null {\n if (bars.length < lookback) return null;\n const series = computeEma(bars, lookback);\n if (series.length === 0) return null;\n return { ema: series[series.length - 1]!.value };\n}\n\nexport function emaNext(prev: EmaState, newRaw: number, lookback: number): { value: number; state: EmaState } {\n const multiplier = 2 / (lookback + 1);\n const ema = newRaw * multiplier + prev.ema * (1 - multiplier);\n return { value: ema, state: { ema } };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeRsi(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback + 1) return [];\n const changes: number[] = [];\n for (let i = 1; i < bars.length; i++) {\n changes.push(bars[i].value - bars[i - 1].value);\n }\n let avgGain = 0;\n let avgLoss = 0;\n for (let i = 0; i < lookback; i++) {\n if (changes[i] > 0) avgGain += changes[i];\n else avgLoss += Math.abs(changes[i]);\n }\n avgGain /= lookback;\n avgLoss /= lookback;\n const result: DailyBar[] = [];\n const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;\n result.push({\n date: bars[lookback].date,\n value: avgLoss === 0 ? 100 : 100 - 100 / (1 + rs),\n });\n for (let i = lookback; i < changes.length; i++) {\n const gain = changes[i] > 0 ? changes[i] : 0;\n const loss = changes[i] < 0 ? Math.abs(changes[i]) : 0;\n avgGain = (avgGain * (lookback - 1) + gain) / lookback;\n avgLoss = (avgLoss * (lookback - 1) + loss) / lookback;\n const smoothRs = avgLoss === 0 ? 100 : avgGain / avgLoss;\n result.push({\n date: bars[i + 1].date,\n value: avgLoss === 0 ? 100 : 100 - 100 / (1 + smoothRs),\n });\n }\n return result;\n}\n\nexport interface RsiState {\n avgGain: number;\n avgLoss: number;\n prev: number;\n}\n\nexport function rsiInitialState(bars: DailyBar[], lookback: number): RsiState | null {\n if (bars.length < lookback + 1) return null;\n let avgGain = 0;\n let avgLoss = 0;\n for (let i = 1; i <= lookback; i++) {\n const change = bars[i]!.value - bars[i - 1]!.value;\n if (change > 0) avgGain += change;\n else avgLoss += -change;\n }\n avgGain /= lookback;\n avgLoss /= lookback;\n let state: RsiState = { avgGain, avgLoss, prev: bars[lookback]!.value };\n for (let i = lookback + 1; i < bars.length; i++) {\n const { state: next } = rsiNext(state, bars[i]!.value, lookback);\n state = next;\n }\n return state;\n}\n\nexport function rsiNext(prev: RsiState, newRaw: number, lookback: number): { value: number; state: RsiState } {\n const change = newRaw - prev.prev;\n const gain = change > 0 ? change : 0;\n const loss = change < 0 ? -change : 0;\n const avgGain = (prev.avgGain * (lookback - 1) + gain) / lookback;\n const avgLoss = (prev.avgLoss * (lookback - 1) + loss) / lookback;\n const rs = avgLoss === 0 ? 100 : avgGain / avgLoss;\n const value = avgLoss === 0 ? 100 : 100 - 100 / (1 + rs);\n return { value, state: { avgGain, avgLoss, prev: newRaw } };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport type ReturnMode = 'pct' | 'abs';\n\nexport function computeReturns(bars: DailyBar[], lookback: number, mode: ReturnMode = 'pct'): DailyBar[] {\n if (bars.length <= lookback) return [];\n const result: DailyBar[] = [];\n for (let i = lookback; i < bars.length; i++) {\n const curr = bars[i]!.value;\n const prev = bars[i - lookback]!.value;\n const value = mode === 'abs' ? curr - prev : (curr - prev) / prev;\n result.push({ date: bars[i]!.date, value });\n }\n return result;\n}\n\nexport interface ReturnState {\n tail: number[];\n}\n\nexport function returnInitialState(bars: DailyBar[], lookback: number): ReturnState | null {\n if (bars.length < lookback + 1) return null;\n return { tail: bars.slice(-(lookback + 1)).map((b) => b.value) };\n}\n\nexport function returnNext(\n prev: ReturnState,\n newRaw: number,\n lookback: number,\n mode: ReturnMode = 'pct',\n): { value: number; state: ReturnState } {\n const tail = [...prev.tail.slice(1), newRaw];\n const old = tail[0]!;\n const value = mode === 'abs' ? newRaw - old : (newRaw - old) / old;\n return { value, state: { tail } };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeVolatility(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback + 1) return [];\n const dailyReturns: { date: string; value: number }[] = [];\n for (let i = 1; i < bars.length; i++) {\n dailyReturns.push({\n date: bars[i].date,\n value: bars[i].value / bars[i - 1].value - 1,\n });\n }\n if (dailyReturns.length < lookback) return [];\n const result: DailyBar[] = [];\n for (let i = lookback - 1; i < dailyReturns.length; i++) {\n const window = dailyReturns.slice(i - lookback + 1, i + 1);\n const mean = window.reduce((s, r) => s + r.value, 0) / lookback;\n const variance = window.reduce((s, r) => s + (r.value - mean) ** 2, 0) / lookback;\n result.push({ date: dailyReturns[i].date, value: Math.sqrt(variance) });\n }\n return result;\n}\n\nexport interface VolatilityState {\n tail: number[];\n}\n\nexport function volatilityInitialState(bars: DailyBar[], lookback: number): VolatilityState | null {\n if (bars.length < lookback + 1) return null;\n return { tail: bars.slice(-(lookback + 1)).map((b) => b.value) };\n}\n\nexport function volatilityNext(\n prev: VolatilityState,\n newRaw: number,\n lookback: number,\n): { value: number; state: VolatilityState } {\n const tail = [...prev.tail.slice(1), newRaw];\n const returns: number[] = [];\n for (let i = 1; i < tail.length; i++) returns.push(tail[i]! / tail[i - 1]! - 1);\n const mean = returns.reduce((s, r) => s + r, 0) / lookback;\n const variance = returns.reduce((s, r) => s + (r - mean) ** 2, 0) / lookback;\n return { value: Math.sqrt(variance), state: { tail } };\n}\n","import type { DailyBar } from '../handles/indicator';\n\nexport function computeDrawdown(bars: DailyBar[], lookback: number): DailyBar[] {\n if (bars.length < lookback) return [];\n const result: DailyBar[] = [];\n for (let i = lookback - 1; i < bars.length; i++) {\n let max = -Infinity;\n for (let j = i - lookback + 1; j <= i; j++) {\n if (bars[j].value > max) max = bars[j].value;\n }\n result.push({ date: bars[i].date, value: (bars[i].value - max) / max });\n }\n return result;\n}\n\nexport interface DrawdownState {\n tail: number[];\n}\n\nexport function drawdownInitialState(bars: DailyBar[], lookback: number): DrawdownState | null {\n if (bars.length < lookback) return null;\n return { tail: bars.slice(-lookback).map((b) => b.value) };\n}\n\nexport function drawdownNext(\n prev: DrawdownState,\n newRaw: number,\n _lookback: number,\n): { value: number; state: DrawdownState } {\n const tail = [...prev.tail.slice(1), newRaw];\n let max = -Infinity;\n for (const v of tail) if (v > max) max = v;\n return { value: (newRaw - max) / max, state: { tail } };\n}\n","import type { DailyBar } from '../handles/indicator';\n\ntype CalendarPeriod = 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year';\n\nfunction dayOfYear(d: Date): number {\n const start = new Date(d.getFullYear(), 0, 0);\n const diff = d.getTime() - start.getTime();\n return Math.floor(diff / (1000 * 60 * 60 * 24));\n}\n\nexport function computeCalendar(bars: DailyBar[], period: CalendarPeriod): DailyBar[] {\n return bars.map((bar) => {\n const [y, m, d] = bar.date.split('-').map(Number);\n const date = new Date(y, m - 1, d);\n let value: number;\n switch (period) {\n case 'Month':\n value = date.getMonth() + 1;\n break;\n case 'Day of Week':\n value = date.getDay();\n break;\n case 'Day of Month':\n value = date.getDate();\n break;\n case 'Day of Year':\n value = dayOfYear(date);\n break;\n }\n return { date: bar.date, value };\n });\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { IndicatorType } from '../providers/types';\nimport { computeSma } from './sma';\nimport { computeEma } from './ema';\nimport { computeRsi } from './rsi';\nimport { computeReturns } from './returns';\nimport { computeVolatility } from './volatility';\nimport { computeDrawdown } from './drawdown';\nimport { smaNext, smaInitialState } from './sma';\nimport { emaNext, emaInitialState } from './ema';\nimport { rsiNext, rsiInitialState } from './rsi';\nimport { returnNext, returnInitialState } from './returns';\nimport { volatilityNext, volatilityInitialState } from './volatility';\nimport { drawdownNext, drawdownInitialState } from './drawdown';\n\nexport { computeSma } from './sma';\nexport { computeEma } from './ema';\nexport { computeRsi } from './rsi';\nexport { computeReturns } from './returns';\nexport { computeVolatility } from './volatility';\nexport { computeDrawdown } from './drawdown';\nexport { computeCalendar } from './calendar';\ntype ComputeFn = (bars: DailyBar[], lookback: number) => DailyBar[];\n\nconst COMPUTATIONS: Partial<Record<IndicatorType, ComputeFn>> = {\n SMA: computeSma,\n EMA: computeEma,\n RSI: computeRsi,\n Return: computeReturns,\n Volatility: computeVolatility,\n Drawdown: computeDrawdown,\n};\n\nexport function getComputation(type: IndicatorType): ComputeFn | null {\n return COMPUTATIONS[type] ?? null;\n}\n\nexport type NextStepFn = (prev: unknown, newRaw: number, lookback: number) => { value: number; state: unknown };\n\nexport type InitialStateFn = (bars: DailyBar[], lookback: number) => unknown | null;\n\nconst NEXT: Record<string, NextStepFn> = {\n SMA: smaNext as NextStepFn,\n EMA: emaNext as NextStepFn,\n RSI: rsiNext as NextStepFn,\n Return: ((prev, newRaw, lookback) => returnNext(prev as { tail: number[] }, newRaw, lookback, 'pct')) as NextStepFn,\n Volatility: volatilityNext as NextStepFn,\n Drawdown: drawdownNext as NextStepFn,\n};\n\nconst SEED: Record<string, InitialStateFn> = {\n SMA: smaInitialState as InitialStateFn,\n EMA: emaInitialState as InitialStateFn,\n RSI: rsiInitialState as InitialStateFn,\n Return: returnInitialState as InitialStateFn,\n Volatility: volatilityInitialState as InitialStateFn,\n Drawdown: drawdownInitialState as InitialStateFn,\n};\n\nexport function getNextComputation(type: string): NextStepFn | undefined {\n return NEXT[type];\n}\n\nexport function getInitialStateFn(type: string): InitialStateFn | undefined {\n return SEED[type];\n}\n","import type { StorageProvider } from '../providers/storage';\nimport type { MarketProvider } from '../providers/market';\nimport type { IndicatorType, Unit } from '../providers/types';\nimport { TickerHandle } from './ticker';\nimport { getProviderInfo, isRateTickerSymbol } from '../providers/mappings';\nimport { getComputation, getNextComputation, getInitialStateFn } from '../computations/index';\nimport { computeReturns, returnNext } from '../computations/returns';\nimport { computeCalendar } from '../computations/calendar';\n\n/**\n * Inverse of `FRED_SERIES` in `providers/mappings.ts`. Lets `_readStoredBars`\n * map a FRED series ID (`DGS3MO`, `DGS10`, etc.) back to the indicator type\n * whose stored series holds that series' history.\n */\nconst FRED_SYMBOL_TO_TYPE: Record<string, string> = {\n DGS3MO: 'T3M',\n DGS6MO: 'T6M',\n DGS1: 'T1Y',\n DGS2: 'T2Y',\n DGS3: 'T3Y',\n DGS5: 'T5Y',\n DGS7: 'T7Y',\n DGS10: 'T10Y',\n DGS20: 'T20Y',\n DGS30: 'T30Y',\n};\n\n/**\n * Subtract `days` calendar days from an ISO date string (YYYY-MM-DD).\n * Used to compute a `from` cutoff for bounded bar fetches in `computeAt`.\n */\nfunction _subtractCalendarDays(date: string, days: number): string {\n const d = new Date(date);\n d.setUTCDate(d.getUTCDate() - days);\n return d.toISOString().slice(0, 10);\n}\n\nexport interface DailyBar {\n date: string;\n value: number;\n}\n\nexport interface IndicatorIdentity {\n type: IndicatorType;\n ticker: TickerHandle | null;\n lookback: number;\n delay: number;\n unit: Unit | null;\n threshold: number | null;\n}\n\nexport interface DateRange {\n from?: string;\n to?: string;\n}\n\nexport class IndicatorHandle {\n readonly type: IndicatorType;\n readonly ticker: TickerHandle | null;\n readonly lookback: number;\n readonly delay: number;\n readonly unit: Unit | null;\n readonly threshold: number | null;\n\n private _storage: StorageProvider;\n private _market: MarketProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n private _cachedSeries: DailyBar[] | null = null;\n private _cachedAsOf: string | null = null;\n private _syncing: Promise<void> | null = null;\n\n constructor(storage: StorageProvider, market: MarketProvider, identity: IndicatorIdentity) {\n this._storage = storage;\n this._market = market;\n this.type = identity.type;\n this.ticker = identity.ticker;\n this.lookback = identity.lookback;\n this.delay = identity.delay;\n this.unit = identity.unit;\n this.threshold = identity.threshold;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('IndicatorHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(\n storage: StorageProvider,\n market: MarketProvider,\n id: number,\n identity: IndicatorIdentity,\n ): IndicatorHandle {\n const handle = new IndicatorHandle(storage, market, identity);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n const tickerId = this.ticker ? (await this.ticker.resolve()).id : null;\n const result = await this._storage.indicators.findOrCreate({\n type: this.type,\n tickerId,\n lookback: this.lookback,\n delay: this.delay,\n unit: this.unit,\n threshold: this.threshold,\n });\n this._resolvedId = result.id;\n return result;\n }\n\n // ── Freshness & Sync ───────────────────────────────────────────────\n\n private async _getLatestClosedTradingDay(): Promise<string> {\n const date = await this._storage.tradingDays.getLatestClosed();\n if (!date) throw new Error('No closed trading days found');\n return date;\n }\n\n private async _getLatestSeriesDate(indicatorId: number): Promise<string | null> {\n return this._storage.indicators.getLatestSeriesDate(indicatorId);\n }\n\n private async _ensureFresh(): Promise<void> {\n const { id } = await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n // In-memory cache still valid\n if (this._cachedAsOf === latestClosed) return;\n\n // `horizon` = the latest date this indicator's series can be written at.\n // delay = 0 → latestClosed; delay > 0 → latestClosed − delay trading days.\n // \"Fresh\" means the stored series already reaches that horizon.\n let horizon = latestClosed;\n if (this.delay > 0) {\n const tradingDays = await this._storage.tradingDays.getRange();\n const idx = tradingDays.indexOf(latestClosed);\n if (idx >= this.delay) {\n horizon = tradingDays[idx - this.delay]!;\n }\n }\n\n const latestSeries = await this._getLatestSeriesDate(id);\n\n if (latestSeries === horizon) {\n // DB is fresh — invalidate in-memory cache so next read picks up DB data\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n return;\n }\n\n // Need to sync — deduplicate concurrent calls. On sync failure (e.g.,\n // browser has no market provider, or upstream feed hasn't published the\n // new date yet), fall back to whatever storage already has and treat the\n // cache as fresh so downstream callers don't retry the failing sync on\n // every read.\n if (!this._syncing) {\n this._syncing = this._sync(latestSeries ?? undefined, latestClosed)\n .catch((err) => {\n console.warn('[sdk] indicator sync failed, using stored data:', err);\n })\n .finally(() => {\n this._syncing = null;\n });\n }\n await this._syncing;\n\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n }\n\n private async _sync(fromDate: string | undefined, latestClosed: string): Promise<void> {\n const tickerSymbol = this.ticker?.symbol ?? null;\n const info = getProviderInfo(this.type, tickerSymbol);\n if (info.provider === 'none') return;\n\n // Compute the horizon this indicator may publish up to.\n let horizon = latestClosed;\n if (this.delay > 0) {\n const tradingDays = await this._storage.tradingDays.getRange();\n const idx = tradingDays.indexOf(latestClosed);\n if (idx < this.delay) return;\n horizon = tradingDays[idx - this.delay]!;\n }\n\n // Fast path only applies when (a) we have a checkpoint, (b) the type is stateful\n // (has a *Next in the dispatch table), and (c) the checkpoint's date is strictly\n // less than horizon (i.e., there's at least one new bar to append).\n const nextFn = getNextComputation(this.type);\n const seedFn = getInitialStateFn(this.type);\n const { id } = await this.resolve();\n const checkpoint = nextFn ? await this._storage.indicators.getLatestBar(id) : null;\n\n if (fromDate && nextFn && seedFn && checkpoint && checkpoint.metadata != null && checkpoint.date < horizon) {\n // Fetch only the raw bars we need to step forward over.\n const rawBars = await this._fetchRawBarsForIncremental(info, checkpoint.date, horizon);\n if (rawBars.length === 0) return;\n const newBars: { date: string; value: number }[] = [];\n let state = checkpoint.metadata as unknown;\n for (const raw of rawBars) {\n if (raw.date <= checkpoint.date) continue;\n if (raw.date > horizon) break;\n const step =\n this.type === 'Return' && info.provider === 'computed' && info.rateSeries\n ? returnNext(state as { tail: number[] }, raw.value, this.lookback, 'abs')\n : nextFn(state, raw.value, this.lookback);\n newBars.push({ date: raw.date, value: step.value });\n state = step.state;\n }\n if (newBars.length === 0) return;\n await this._storage.indicators.writeSeries(id, newBars, { metadata: state });\n return;\n }\n\n // Cold path (existing logic, now augmented to park initial-state metadata).\n let bars: DailyBar[];\n switch (info.provider) {\n case 'yahoo':\n bars = await this._market.fetchBars(info.symbol, fromDate);\n break;\n\n case 'fred':\n bars = await this._market.fetchBars(info.seriesId, fromDate);\n break;\n\n case 'computed': {\n const priceHandle = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker: this.ticker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n await priceHandle._ensureFresh();\n const priceBars = await priceHandle._querySeriesFromDb();\n if (this.type === 'Return') {\n // For rate/yield series (e.g. DTB3, DFF), percentage change is broken\n // near zero and semantically wrong; use absolute differences instead.\n bars = computeReturns(priceBars, this.lookback, info.rateSeries ? 'abs' : 'pct');\n } else {\n const computeFn = getComputation(this.type);\n if (!computeFn) throw new Error(`No computation found for type \"${this.type}\"`);\n bars = computeFn(priceBars, this.lookback);\n }\n if (fromDate) bars = bars.filter((b) => b.date > fromDate);\n break;\n }\n\n case 'calendar': {\n // Fetch all trading days to compute calendar values\n const allDays = await this._storage.tradingDays.getRange();\n const dayBars: DailyBar[] = allDays.map((date) => ({ date, value: 0 }));\n bars = computeCalendar(dayBars, this.type as 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year');\n if (fromDate) bars = bars.filter((b) => b.date > fromDate);\n break;\n }\n }\n\n // Apply leverage to daily returns only for fetched (non-computed) indicators.\n // Computed indicators (RSI, SMA, etc.) already read from the leveraged price series.\n if (info.provider !== 'computed') {\n bars = await this._applyLeverage(bars, fromDate);\n }\n\n bars = bars.filter((b) => b.date <= horizon);\n if (bars.length === 0) return;\n\n // For stateful types, derive and park the terminal metadata so subsequent\n // syncs take the fast path.\n let metadata: unknown = undefined;\n if (seedFn) {\n // For stateful COMPUTED types, seed from the full price bars up to horizon;\n // for stateful FETCHED types (none in current code, but future-safe) seed\n // from the bars we're about to write.\n if (info.provider === 'computed') {\n const priceHandle = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker: this.ticker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n const priceBars = (await priceHandle._querySeriesFromDb()).filter((b) => b.date <= horizon);\n metadata = seedFn(priceBars, this.lookback) ?? undefined;\n } else {\n metadata = seedFn(bars, this.lookback) ?? undefined;\n }\n }\n\n await this._upsertSeries(bars, metadata);\n }\n\n private async _fetchRawBarsForIncremental(\n info: ReturnType<typeof getProviderInfo>,\n sinceDate: string,\n horizon: string,\n ): Promise<DailyBar[]> {\n if (info.provider === 'computed') {\n const priceHandle = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker: this.ticker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n await priceHandle._ensureFresh();\n return (await priceHandle._querySeriesFromDb({ from: sinceDate })).filter(\n (b) => b.date > sinceDate && b.date <= horizon,\n );\n }\n if (info.provider === 'yahoo' || info.provider === 'fred') {\n const symbol = info.provider === 'yahoo' ? info.symbol : info.seriesId;\n const bars = await this._market.fetchBars(symbol, sinceDate);\n return bars.filter((b) => b.date > sinceDate && b.date <= horizon);\n }\n if (info.provider === 'calendar') {\n const allDays = await this._storage.tradingDays.getRange();\n const dayBars: DailyBar[] = allDays.map((date) => ({ date, value: 0 }));\n return computeCalendar(dayBars, this.type as 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year').filter(\n (b) => b.date > sinceDate && b.date <= horizon,\n );\n }\n return [];\n }\n\n private async _upsertSeries(bars: DailyBar[], metadata?: unknown): Promise<void> {\n const { id } = await this.resolve();\n await this._storage.indicators.writeSeries(id, bars, metadata !== undefined ? { metadata } : undefined);\n }\n\n private async _querySeriesFromDb(range?: DateRange): Promise<DailyBar[]> {\n const { id } = await this.resolve();\n return this._storage.indicators.getSeries(id, range);\n }\n\n /**\n * Apply leverage compounding to a raw bar series, anchored to a stored\n * leveraged value. Used by both `_sync` and `computeAt` so they stay\n * consistent.\n *\n * `anchorDate` is the date of the last *already-stored* leveraged bar\n * (i.e., the bar just before `rawBars[0]`). The stored leveraged value\n * at that date becomes `leveraged[0]`; raw returns are then compounded\n * forward for each subsequent bar.\n *\n * If no stored anchor exists (first-ever sync), falls back to rawBars[0]\n * as the starting raw value — identical to `_sync`'s behaviour.\n */\n private async _applyLeverage(rawBars: DailyBar[], anchorDate: string | undefined): Promise<DailyBar[]> {\n const leverage = this.ticker?.leverage ?? 1;\n if (leverage === 1 || rawBars.length === 0) return rawBars;\n // Rate tickers (DTB3, DFF, etc.) skip leverage compounding: the stored series\n // stays raw; the simulator applies the leverage multiplier at accrual time.\n if (isRateTickerSymbol(this.ticker?.symbol ?? null)) return rawBars;\n\n let anchor: number;\n if (anchorDate) {\n const lastStored = await this._storage.indicators.getValue(this._resolvedId!, anchorDate);\n anchor = lastStored ?? rawBars[0]!.value;\n } else {\n anchor = rawBars[0]!.value;\n }\n\n const leveraged: DailyBar[] = [{ date: rawBars[0]!.date, value: anchor }];\n for (let i = 1; i < rawBars.length; i++) {\n const dailyReturn = (rawBars[i]!.value - rawBars[i - 1]!.value) / rawBars[i - 1]!.value;\n const prev = leveraged[i - 1]!.value;\n leveraged.push({ date: rawBars[i]!.date, value: prev * (1 + leverage * dailyReturn) });\n }\n return leveraged;\n }\n\n /**\n * Compute the indicator's value at `date` without persisting anything, with\n * optional live-quote `overrides` keyed by raw market symbol (the same symbol\n * space `MarketProvider.fetchBars` uses — ticker symbols for Price/SMA/etc.,\n * `^VIX` / `^VIX3M` for macro, FRED series IDs like `DGS3MO` for Treasury).\n *\n * Bars for the underlying symbol are resolved storage-first when the market\n * hasn't yet produced bars for `date` (trading day still open), and storage\n * is the fallback whenever the remote fetch fails — see `_resolveRawBars`.\n *\n * For Threshold: returns the threshold constant. For calendar types: computed\n * from `tradingDays.getRange()`. For all others: `_resolveRawBars` → leverage\n * compounding (if any) → lookback-specific computation. Returns null if the\n * value cannot be computed.\n */\n async computeAt(date: string, overrides?: Record<string, number>): Promise<number | null> {\n // Threshold is a special case: it has no market data, just a constant value.\n if (this.type === 'Threshold') return this.threshold;\n\n const tickerSymbol = this.ticker?.symbol ?? null;\n const info = getProviderInfo(this.type, tickerSymbol);\n\n if (info.provider === 'none') return null;\n\n if (info.provider === 'calendar') {\n const allDays = await this._storage.tradingDays.getRange();\n const dayBars: DailyBar[] = allDays.map((d) => ({ date: d, value: 0 }));\n const computed = computeCalendar(dayBars, this.type as 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year');\n return computed.find((b) => b.date === date)?.value ?? null;\n }\n\n if (info.provider === 'computed') {\n // Fast path: checkpoint is the trading day immediately before `date`.\n const nextFn = getNextComputation(this.type);\n if (nextFn) {\n const { id } = await this.resolve();\n const checkpoint = await this._storage.indicators.getLatestBar(id);\n if (checkpoint && checkpoint.metadata != null) {\n const tradingDays = await this._storage.tradingDays.getRange();\n const ckIdx = tradingDays.indexOf(checkpoint.date);\n const tgtIdx = tradingDays.indexOf(date);\n if (ckIdx >= 0 && tgtIdx === ckIdx + 1) {\n const rawBar = await this._resolveRawBarAt(info.symbol, date, overrides);\n if (rawBar === null) return null;\n const step =\n this.type === 'Return' && info.rateSeries\n ? returnNext(checkpoint.metadata as { tail: number[] }, rawBar, this.lookback, 'abs')\n : nextFn(checkpoint.metadata, rawBar, this.lookback);\n return step.value;\n }\n }\n }\n\n // Size the bar window by the computation's actual needs, expressed in\n // calendar days. Three buckets:\n //\n // Exact reads (SMA / Return / Volatility / Drawdown) want `lookback`\n // *trading* days in the result; with ~5 trading days per 7 calendar\n // days plus holidays that's ~`lookback * 1.5` calendar days, plus a\n // small fixed buffer for long weekends.\n //\n // EMA is recursive: seed = first N-bar SMA, then `(1-α)^k` decay with\n // α = 2 / (N+1). For small N the decay is fast; for N=200 decay is\n // ~0.99/bar, so we want several multiples of `lookback` to get close\n // to the fully-synced EMA value.\n //\n // Wilder's RSI decays at ~10%/bar regardless of lookback and starts\n // from a simple-average seed that can pin at 100 (or 0) for a window\n // full of only-up (or only-down) days; it needs the widest window.\n let calendarDays: number;\n if (this.type === 'RSI') {\n calendarDays = Math.max(this.lookback * 10, 90);\n } else if (this.type === 'EMA') {\n calendarDays = Math.max(this.lookback * 5, 60);\n } else {\n // SMA, Return, Volatility, Drawdown — exact-read, only need coverage.\n calendarDays = Math.ceil(this.lookback * 1.5) + 15;\n }\n const from = _subtractCalendarDays(date, this.lookback + calendarDays);\n const rawBars = await this._resolveRawBars(info.symbol, from, date, overrides);\n\n // Apply leverage anchored to the stored leveraged value at the date just\n // before the first resolved raw bar. Mirrors `_sync`'s anchor logic.\n const anchorDate = rawBars.length > 0 ? rawBars[0]!.date : undefined;\n const priceBars = await this._applyLeverage(rawBars, anchorDate);\n\n const computeFn = getComputation(this.type);\n if (!computeFn) throw new Error(`No computation found for type \"${this.type}\"`);\n const computed = computeFn(priceBars, this.lookback);\n return computed.find((b) => b.date === date)?.value ?? null;\n }\n\n // yahoo or fred: resolve a small window — just enough to get `date` and\n // one prior bar (needed for leverage return calculation). 15 calendar days\n // comfortably bridges a long weekend + holiday gap; FRED series in\n // particular publish on T+1 / T+2 cadences and can miss a market day.\n const symbol = info.provider === 'yahoo' ? info.symbol : info.seriesId;\n const from = _subtractCalendarDays(date, 15);\n const rawBars = await this._resolveRawBars(symbol, from, date, overrides);\n\n const leverage = this.ticker?.leverage ?? 1;\n if (leverage === 1) {\n return rawBars.find((b) => b.date === date)?.value ?? null;\n }\n\n // Apply leverage compounding.\n const dateIdx = rawBars.findIndex((b) => b.date === date);\n if (dateIdx < 0) return null; // date not in bars at all\n\n const prevBar = rawBars[dateIdx - 1];\n if (!prevBar) {\n // No previous bar in the window — can't compound. Return raw value as fallback.\n return rawBars[dateIdx]!.value;\n }\n\n const storedPrev = await this._storage.indicators.getValue(this._resolvedId!, prevBar.date);\n const leveragedPrev = storedPrev ?? prevBar.value;\n const rawReturn = (rawBars[dateIdx]!.value - prevBar.value) / prevBar.value;\n return leveragedPrev * (1 + leverage * rawReturn);\n }\n\n /**\n * Raw (unleveraged) bars for `symbol` up through `date`, with the live quote\n * from `overrides[symbol]` (if any) spliced in at `date`.\n *\n * Decision policy:\n * - `date` > `tradingDays.getLatestClosed()`: market has nothing for that\n * day yet — skip the remote fetch entirely and read from storage.\n * - otherwise: try `this._market.fetchBars(symbol, from)`. On failure, fall\n * back to storage — upstream HTTP providers (Yahoo / FRED) are flaky.\n *\n * After the base is resolved, `overrides[symbol]` is spliced at `date`\n * (replaces the existing bar, or is appended in-order). When no override is\n * present but `date` isn't in the base bars, the last known value is carried\n * forward to `date` — this preserves the fallbackMissingQuotes behaviour the\n * old overlay exposed so leverage compounding / computations always have a\n * point at `date` to land on.\n */\n private async _resolveRawBars(\n symbol: string,\n from: string,\n date: string,\n overrides?: Record<string, number>,\n ): Promise<DailyBar[]> {\n const latestClosed = await this._storage.tradingDays.getLatestClosed();\n const closedForDate = latestClosed !== null && date <= latestClosed;\n\n let bars: DailyBar[];\n if (closedForDate) {\n try {\n bars = await this._market.fetchBars(symbol, from);\n } catch {\n bars = await this._readStoredBars(symbol, from);\n }\n } else {\n bars = await this._readStoredBars(symbol, from);\n }\n\n const override = overrides?.[symbol];\n const existingIdx = bars.findIndex((b) => b.date === date);\n\n if (override !== undefined) {\n if (existingIdx >= 0) {\n bars[existingIdx] = { date, value: override };\n } else {\n bars = [...bars, { date, value: override }].sort((a, b) => a.date.localeCompare(b.date));\n }\n } else if (existingIdx < 0 && bars.length > 0) {\n // Carry last known value forward to `date` (matches the overlay's\n // `fallbackMissingQuotes` behaviour for every consumer that used it).\n bars = [...bars, { date, value: bars[bars.length - 1]!.value }];\n }\n\n return bars;\n }\n\n /**\n * Resolve the single raw (unleveraged) value for `symbol` at `date`.\n * Returns the override directly when present; otherwise delegates to\n * `_resolveRawBars` with a one-day window and picks the matching bar.\n */\n private async _resolveRawBarAt(\n symbol: string,\n date: string,\n overrides?: Record<string, number>,\n ): Promise<number | null> {\n const override = overrides?.[symbol];\n if (override !== undefined) return override;\n const bars = await this._resolveRawBars(symbol, date, date, overrides);\n const hit = bars.find((b) => b.date === date);\n return hit?.value ?? null;\n }\n\n /**\n * Resolve raw (unleveraged) bars for a market symbol from storage. Maps:\n * - `^VIX` → the VIX indicator's stored series\n * - `^VIX3M` → the VIX3M indicator's stored series\n * - `DGS*` → the matching Treasury-tenor indicator's stored series\n * - anything else → the `Price` indicator for that ticker symbol with\n * `leverage = 1` (the raw contract that `MarketProvider.fetchBars` has).\n *\n * Returns `[]` when the resolved indicator has no stored bars yet.\n */\n private async _readStoredBars(symbol: string, from: string): Promise<DailyBar[]> {\n let identity: {\n type: string;\n tickerId: number | null;\n lookback: number;\n delay: number;\n unit: string | null;\n threshold: number | null;\n };\n if (symbol === '^VIX') {\n identity = { type: 'VIX', tickerId: null, lookback: 0, delay: 0, unit: null, threshold: null };\n } else if (symbol === '^VIX3M') {\n identity = { type: 'VIX3M', tickerId: null, lookback: 0, delay: 0, unit: null, threshold: null };\n } else if (FRED_SYMBOL_TO_TYPE[symbol]) {\n identity = {\n type: FRED_SYMBOL_TO_TYPE[symbol]!,\n tickerId: null,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n };\n } else {\n const { id: tickerId } = await this._storage.tickers.findOrCreate(symbol, 1);\n identity = { type: 'Price', tickerId, lookback: 0, delay: 0, unit: null, threshold: null };\n }\n const { id } = await this._storage.indicators.findOrCreate(identity);\n return this._storage.indicators.getSeries(id, { from });\n }\n\n // ── Public data access ─────────────────────────────────────────────\n\n async series(range?: DateRange): Promise<DailyBar[]> {\n if (this.type === 'Threshold') {\n return this._syntheticThresholdSeries(range);\n }\n await this._ensureFresh();\n if (this._cachedSeries && !range) return this._cachedSeries;\n const bars = await this._querySeriesFromDb(range);\n if (!range) this._cachedSeries = bars;\n return bars;\n }\n\n private async _syntheticThresholdSeries(range?: DateRange): Promise<DailyBar[]> {\n const v = this.threshold!;\n const dates = await this._storage.tradingDays.getRange(range);\n return dates.map((date) => ({ date, value: v }));\n }\n\n async value(date?: string): Promise<number | null> {\n await this._ensureFresh();\n const { id } = await this.resolve();\n return this._storage.indicators.getValue(id, date);\n }\n\n /**\n * Read-only preview of the indicator series with an in-memory bar at `date`\n * computed via `computeAt` with the supplied live-quote `overrides`. Does\n * NOT write to `indicators_series`. Safe to call before market close.\n *\n * @param date - Target trading day whose value is computed in-memory.\n * Must be in `tradingDays.getRange()`.\n * @param overrides - Raw (unleveraged) quotes keyed by market symbol.\n * Symbols omitted fall back to the last known value (see `_resolveRawBars`).\n * @param range - Optional filter applied to the returned bars.\n * @returns Stored historical bars plus (or with) today's in-memory value.\n */\n async previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<DailyBar[]> {\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewSeries: ${date} is not a trading day`);\n }\n\n let bars: DailyBar[];\n if (this.type === 'Threshold') {\n bars = await this._syntheticThresholdSeries();\n } else {\n bars = await this._querySeriesFromDb();\n }\n\n // Only splice a \"today\" bar when the indicator is publishable at `date`\n // — i.e. `delay === 0`. For delay > 0 the latest usable point is already\n // `latestClosed − delay`, which lives in `bars` as-is from storage.\n if (this.delay === 0) {\n const todayValue = await this.computeAt(date, overrides);\n if (todayValue !== null) {\n const idx = bars.findIndex((b) => b.date === date);\n if (idx >= 0) {\n bars[idx] = { date, value: todayValue };\n } else {\n bars = [...bars, { date, value: todayValue }].sort((a, b) => a.date.localeCompare(b.date));\n }\n }\n }\n\n if (range) {\n bars = bars.filter(\n (b) => (range.from === undefined || b.date >= range.from) && (range.to === undefined || b.date <= range.to),\n );\n }\n\n return bars;\n }\n}\n","import type { DailyBar } from '../handles/indicator';\n\ntype Comparison = '>' | '<' | '=';\n\nfunction computeBuffers(v2: number, tolerance: number, absolute: boolean): { upper: number; lower: number } {\n if (tolerance === 0) return { upper: v2, lower: v2 };\n if (absolute) return { upper: v2 + tolerance, lower: v2 - tolerance };\n return { upper: v2 * (1 + tolerance / 100), lower: v2 * (1 - tolerance / 100) };\n}\n\nfunction rawCompare(v1: number, v2: number, comparison: Comparison): number {\n switch (comparison) {\n case '>':\n return v1 > v2 ? 1 : 0;\n case '<':\n return v1 < v2 ? 1 : 0;\n case '=':\n return v1 === v2 ? 1 : 0;\n }\n}\n\nexport function evaluateSignal(\n series1: DailyBar[],\n series2: DailyBar[],\n comparison: Comparison,\n tolerance: number,\n absolute: boolean,\n previousValue?: number,\n): DailyBar[] {\n const s2Map = new Map<string, number>();\n for (const bar of series2) {\n s2Map.set(bar.date, bar.value);\n }\n\n const result: DailyBar[] = [];\n let prev = previousValue;\n\n for (const bar1 of series1) {\n const v2 = s2Map.get(bar1.date);\n if (v2 === undefined) continue;\n\n const v1 = bar1.value;\n const { upper, lower } = computeBuffers(v2, tolerance, absolute);\n\n let value: number;\n\n if (tolerance === 0) {\n value = rawCompare(v1, v2, comparison);\n } else if (comparison === '=') {\n value = v1 >= lower && v1 <= upper ? 1 : 0;\n } else if (prev === undefined) {\n value = rawCompare(v1, v2, comparison);\n } else if (comparison === '>') {\n if (prev === 1) {\n value = v1 < lower ? 0 : 1;\n } else {\n value = v1 > upper ? 1 : 0;\n }\n } else {\n // comparison === '<'\n if (prev === 1) {\n value = v1 > upper ? 0 : 1;\n } else {\n value = v1 < lower ? 1 : 0;\n }\n }\n\n result.push({ date: bar1.date, value });\n prev = value;\n }\n\n return result;\n}\n","// src/handles/signal.ts\nimport type { StorageProvider } from '../providers/storage';\nimport type { MarketProvider } from '../providers/market';\nimport type { Comparison } from '../providers/types';\nimport type { IndicatorHandle, DailyBar, DateRange } from './indicator';\nimport { evaluateSignal } from '../computations/signal';\n\nconst ABSOLUTE_TOLERANCE_TYPES = new Set([\n 'Return',\n 'Volatility',\n 'Drawdown',\n 'VIX',\n 'VIX3M',\n 'T3M',\n 'T6M',\n 'T1Y',\n 'T2Y',\n 'T3Y',\n 'T5Y',\n 'T7Y',\n 'T10Y',\n 'T20Y',\n 'T30Y',\n]);\n\nexport interface SignalIdentity {\n indicator1: IndicatorHandle;\n indicator2: IndicatorHandle;\n comparison: Comparison;\n tolerance: number;\n}\n\nexport class SignalHandle {\n readonly indicator1: IndicatorHandle;\n readonly indicator2: IndicatorHandle;\n readonly comparison: Comparison;\n readonly tolerance: number;\n\n private _storage: StorageProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n private _cachedSeries: DailyBar[] | null = null;\n private _cachedAsOf: string | null = null;\n private _syncing: Promise<void> | null = null;\n\n // The `market` parameter is kept in the signature for API compatibility with\n // `new SignalHandle(storage, market, identity)` — signals no longer carry\n // their own market reference since `computeAt` delegates to the indicator\n // handles, which already hold one.\n constructor(storage: StorageProvider, _market: MarketProvider, identity: SignalIdentity) {\n this._storage = storage;\n this.indicator1 = identity.indicator1;\n this.indicator2 = identity.indicator2;\n this.comparison = identity.comparison;\n this.tolerance = identity.tolerance;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('SignalHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(\n storage: StorageProvider,\n market: MarketProvider,\n id: number,\n identity: SignalIdentity,\n ): SignalHandle {\n const handle = new SignalHandle(storage, market, identity);\n handle._resolvedId = id;\n return handle;\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n const [ind1, ind2] = await Promise.all([this.indicator1.resolve(), this.indicator2.resolve()]);\n const result = await this._storage.signals.findOrCreate({\n indicatorId1: ind1.id,\n indicatorId2: ind2.id,\n comparison: this.comparison,\n tolerance: this.tolerance,\n });\n this._resolvedId = result.id;\n return result;\n }\n\n // ── Freshness & Sync ───────────────────────────────────────────────\n\n private async _getLatestClosedTradingDay(): Promise<string> {\n const date = await this._storage.tradingDays.getLatestClosed();\n if (!date) throw new Error('No closed trading days found');\n return date;\n }\n\n private async _getLatestSignalSeriesDate(signalId: number): Promise<string | null> {\n return this._storage.signals.getLatestSeriesDate(signalId);\n }\n\n private async _getLastSignalValue(signalId: number): Promise<number | null> {\n return this._storage.signals.getLastValue(signalId);\n }\n\n private async _ensureFresh(): Promise<void> {\n const { id } = await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n if (this._cachedAsOf === latestClosed) return;\n\n const latestSeries = await this._getLatestSignalSeriesDate(id);\n\n if (latestSeries === latestClosed) {\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n return;\n }\n\n // Determine whether the single-bar fast path applies so we know whether to\n // pre-sync the indicator series. The fast path uses `computeAt` and handles\n // its own freshness; the cold/multi-bar path requires indicators to be\n // synced to storage first.\n const isFastPath = await this._isSingleBarFastPath(latestSeries ?? undefined, latestClosed);\n if (!isFastPath) {\n await Promise.all([this.indicator1.series(), this.indicator2.series()]);\n }\n\n if (!this._syncing) {\n this._syncing = this._sync(latestSeries ?? undefined, latestClosed)\n .catch((err) => {\n console.warn('[sdk] signal sync failed, using stored data:', err);\n })\n .finally(() => {\n this._syncing = null;\n });\n }\n await this._syncing;\n\n this._cachedSeries = null;\n this._cachedAsOf = latestClosed;\n }\n\n private async _isSingleBarFastPath(fromDate: string | undefined, latestClosed: string): Promise<boolean> {\n if (!fromDate) return false;\n const tradingDays = await this._storage.tradingDays.getRange();\n const fromIdx = tradingDays.indexOf(fromDate);\n const closedIdx = tradingDays.indexOf(latestClosed);\n return fromIdx >= 0 && closedIdx === fromIdx + 1;\n }\n\n private async _sync(fromDate: string | undefined, latestClosed: string): Promise<void> {\n const { id } = await this.resolve();\n\n const absolute = ABSOLUTE_TOLERANCE_TYPES.has(this.indicator1.type);\n\n // Single-bar fast path: we have a checkpoint (fromDate), and the next bar to\n // produce is the trading day immediately after fromDate.\n if (fromDate) {\n const tradingDays = await this._storage.tradingDays.getRange();\n const fromIdx = tradingDays.indexOf(fromDate);\n const closedIdx = tradingDays.indexOf(latestClosed);\n if (fromIdx >= 0 && closedIdx === fromIdx + 1) {\n const newDate = tradingDays[closedIdx]!;\n const [v1, v2] = await Promise.all([\n this.indicator1.computeAt(newDate, undefined),\n this.indicator2.computeAt(newDate, undefined),\n ]);\n if (v1 === null || v2 === null) return;\n const prev = (await this._getLastSignalValue(id)) ?? undefined;\n const value = this._evaluateOneBar(v1, v2, absolute, prev);\n await this._upsertSeries([{ date: newDate, value }]);\n return;\n }\n }\n\n // Existing multi-bar / cold path.\n const range = fromDate ? { from: fromDate } : undefined;\n const [series1, series2] = await Promise.all([this.indicator1.series(range), this.indicator2.series(range)]);\n const previousValue = fromDate ? ((await this._getLastSignalValue(id)) ?? undefined) : undefined;\n const signalBars = evaluateSignal(series1, series2, this.comparison, this.tolerance, absolute, previousValue);\n const bars = signalBars.filter((b) => b.date <= latestClosed);\n if (bars.length > 0) await this._upsertSeries(bars);\n }\n\n private _evaluateOneBar(v1: number, v2: number, absolute: boolean, prev: number | undefined): number {\n if (this.tolerance === 0) {\n switch (this.comparison) {\n case '>':\n return v1 > v2 ? 1 : 0;\n case '<':\n return v1 < v2 ? 1 : 0;\n case '=':\n return v1 === v2 ? 1 : 0;\n }\n }\n const upper = absolute ? v2 + this.tolerance : v2 * (1 + this.tolerance / 100);\n const lower = absolute ? v2 - this.tolerance : v2 * (1 - this.tolerance / 100);\n if (this.comparison === '=') return v1 >= lower && v1 <= upper ? 1 : 0;\n if (prev === undefined) {\n return this.comparison === '>' ? (v1 > v2 ? 1 : 0) : v1 < v2 ? 1 : 0;\n }\n if (this.comparison === '>') {\n return prev === 1 ? (v1 < lower ? 0 : 1) : v1 > upper ? 1 : 0;\n }\n return prev === 1 ? (v1 > upper ? 0 : 1) : v1 < lower ? 1 : 0;\n }\n\n private async _upsertSeries(bars: DailyBar[]): Promise<void> {\n const { id } = await this.resolve();\n await this._storage.signals.writeSeries(id, bars);\n }\n\n private async _querySeriesFromDb(range?: DateRange): Promise<DailyBar[]> {\n const { id } = await this.resolve();\n return this._storage.signals.getSeries(id, range);\n }\n\n /**\n * Compute the signal's boolean value at `date` without persisting anything,\n * with optional live-quote `overrides` that are routed through each\n * indicator's `computeAt`. Returns null if either indicator cannot produce\n * a value at `date`.\n *\n * @param prevBool - The signal's boolean value at the bar immediately\n * preceding `date`, used for hysteresis when `tolerance > 0`. If not\n * provided, falls back to `storage.signals.getLastValue` (suitable for\n * standalone callers). On the preview path `_evaluate` passes this from\n * the in-memory `dateMap` so we never read stale storage.\n */\n async computeAt(\n date: string,\n overrides?: Record<string, number>,\n prevBool?: boolean | null,\n ): Promise<boolean | null> {\n const [v1, v2] = await Promise.all([\n this.indicator1.computeAt(date, overrides),\n this.indicator2.computeAt(date, overrides),\n ]);\n if (v1 === null || v2 === null) return null;\n\n const absolute = ABSOLUTE_TOLERANCE_TYPES.has(this.indicator1.type);\n\n // Replicate the evaluateSignal single-bar logic inline (no hysteresis needed\n // for a single-point preview; we use the last historical value as \"prev\").\n if (this.tolerance === 0) {\n switch (this.comparison) {\n case '>':\n return v1 > v2;\n case '<':\n return v1 < v2;\n case '=':\n return v1 === v2;\n }\n }\n\n const tolerance = this.tolerance;\n const upper = absolute ? v2 + tolerance : v2 * (1 + tolerance / 100);\n const lower = absolute ? v2 - tolerance : v2 * (1 - tolerance / 100);\n\n if (this.comparison === '=') {\n return v1 >= lower && v1 <= upper;\n }\n // For '>' and '<' with tolerance, we need hysteresis (prev state).\n // Use the in-memory prevBool if provided (preview path); otherwise fall\n // back to storage (standalone callers / write path).\n let resolvedPrevBool: boolean;\n if (prevBool !== undefined && prevBool !== null) {\n resolvedPrevBool = prevBool;\n } else {\n const prev = await this._storage.signals.getLastValue(this.id);\n resolvedPrevBool = prev === 1;\n }\n if (this.comparison === '>') {\n return resolvedPrevBool ? v1 >= lower : v1 > upper;\n }\n // '<'\n return resolvedPrevBool ? v1 <= upper : v1 < lower;\n }\n\n // ── Public data access ─────────────────────────────────────────────\n\n async series(range?: DateRange): Promise<DailyBar[]> {\n await this._ensureFresh();\n if (this._cachedSeries && !range) return this._cachedSeries;\n const bars = await this._querySeriesFromDb(range);\n if (!range) this._cachedSeries = bars;\n return bars;\n }\n\n async value(date?: string): Promise<number | null> {\n await this._ensureFresh();\n if (date) {\n const series = await this._querySeriesFromDb({ from: date, to: date });\n return series.length > 0 ? series[0]!.value : null;\n }\n const { id } = await this.resolve();\n return this._storage.signals.getLastValue(id);\n }\n\n /**\n * Read-only preview of the signal series with an in-memory bar at `date`\n * computed via `computeAt` with the supplied live-quote `overrides`. Does\n * NOT write to `signals_series`.\n *\n * @param date - Target trading day whose boolean is computed in-memory.\n * @param overrides - Raw (unleveraged) quotes keyed by market symbol.\n * @param range - Optional filter applied to the returned bars.\n */\n async previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<DailyBar[]> {\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewSeries: ${date} is not a trading day`);\n }\n\n let bars = await this._querySeriesFromDb();\n\n // Derive yesterday's boolean from the in-memory dateMap for hysteresis,\n // mirroring StrategyHandle._evaluate's preview path.\n const dateMap = new Map<string, boolean>();\n for (const bar of bars) dateMap.set(bar.date, bar.value === 1);\n\n const limitIdx = tradingDays.indexOf(date);\n const prevDate = limitIdx > 0 ? tradingDays[limitIdx - 1] : undefined;\n const prevBool = prevDate !== undefined ? (dateMap.get(prevDate) ?? null) : null;\n\n const todayBool = await this.computeAt(date, overrides, prevBool);\n if (todayBool !== null) {\n const numeric = todayBool ? 1 : 0;\n const idx = bars.findIndex((b) => b.date === date);\n if (idx >= 0) {\n bars[idx] = { date, value: numeric };\n } else {\n bars = [...bars, { date, value: numeric }].sort((a, b) => a.date.localeCompare(b.date));\n }\n }\n\n if (range) {\n bars = bars.filter(\n (b) => (range.from === undefined || b.date >= range.from) && (range.to === undefined || b.date <= range.to),\n );\n }\n\n return bars;\n }\n}\n","import type { StorageProvider } from '../providers/storage';\nimport { TickerHandle } from './ticker';\n\nexport class AllocationHandle {\n readonly holdings: [TickerHandle, number][];\n\n private _storage: StorageProvider;\n private _resolvedId: number | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n\n constructor(storage: StorageProvider, holdings: [TickerHandle, number][]) {\n const total = holdings.reduce((sum, [, weight]) => sum + weight, 0);\n if (Math.abs(total - 1) > 1e-9) {\n throw new Error(`Allocation weights must sum to 1, got ${total}`);\n }\n this._storage = storage;\n this.holdings = holdings;\n }\n\n get id(): number {\n if (this._resolvedId == null)\n throw new Error('AllocationHandle not yet resolved. Call resolve(), or access via an async method.');\n return this._resolvedId;\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) this._resolving = this._doResolve();\n return this._resolving;\n }\n\n static fromResolved(storage: StorageProvider, id: number, holdings: [TickerHandle, number][]): AllocationHandle {\n const handle = new AllocationHandle(storage, holdings);\n handle._resolvedId = id;\n return handle;\n }\n\n toJSON(): Array<{ symbol: string; leverage: number; weight: number }> {\n return this.holdings\n .map(([ticker, weight]) => ({ symbol: ticker.symbol, leverage: ticker.leverage, weight }))\n .sort((a, b) => a.symbol.localeCompare(b.symbol) || a.leverage - b.leverage);\n }\n\n private async _doResolve(): Promise<{ id: number }> {\n await Promise.all(this.holdings.map(([ticker]) => ticker.resolve()));\n\n const holdingsJson: Record<string, number> = {};\n for (const [ticker, weight] of this.holdings) {\n const key = ticker.leverage !== 1 ? `${ticker.symbol}?L=${ticker.leverage}` : ticker.symbol;\n holdingsJson[key] = weight;\n }\n\n const result = await this._storage.allocations.findOrCreate(holdingsJson);\n this._resolvedId = result.id;\n return result;\n }\n}\n","import { customAlphabet } from 'nanoid';\nimport type { StorageProvider } from '../providers/storage';\nimport type { MarketProvider } from '../providers/market';\nimport type { TradingFreq, StrategySeriesEntry } from '../providers/types';\nimport { SignalHandle } from './signal';\nimport { AllocationHandle } from './allocation';\nimport { TickerHandle } from './ticker';\nimport { IndicatorHandle } from './indicator';\nimport type { DateRange } from './indicator';\nimport { evaluateStrategy, computeRebalanceDates } from '../computations/strategy';\nimport { runSimulation } from '../backtest/simulate';\nimport { SimulationHandle } from '../backtest/types';\nimport type {\n SimulateOptions,\n FinalState,\n LiveEvaluator,\n StrategyLiveState,\n LiveRuleState,\n LiveSignalState,\n} from '../backtest/types';\n\nconst nanoid = customAlphabet('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 21);\n\nexport interface StrategyRule {\n when?: SignalHandle[];\n hold: AllocationHandle;\n}\n\nexport interface StrategyBar {\n date: string;\n allocation: AllocationHandle;\n}\n\nexport interface StrategyOptions {\n name: string;\n freq?: TradingFreq;\n offset?: number;\n rules: StrategyRule[];\n}\n\nexport class StrategyHandle {\n private _linkId: string | null;\n private _name: string | null;\n private _freq: TradingFreq;\n private _offset: number;\n private _rules: StrategyRule[];\n\n private _storage: StorageProvider;\n private _market: MarketProvider;\n private _resolvedId: number | null = null;\n private _resolvedLinkId: string | null = null;\n private _resolving: Promise<{ id: number }> | null = null;\n private _allocationMap: Map<number, AllocationHandle> = new Map();\n\n private _cache: StrategyBar[] | null = null;\n private _cachedAsOf: string | null = null;\n private _syncing: Promise<void> | null = null;\n\n constructor(storage: StorageProvider, market: MarketProvider, optionsOrLinkId: StrategyOptions | string) {\n this._storage = storage;\n this._market = market;\n\n if (typeof optionsOrLinkId === 'string') {\n this._linkId = optionsOrLinkId;\n this._name = null;\n this._freq = 'Daily';\n this._offset = 0;\n this._rules = [];\n } else {\n const opts = optionsOrLinkId;\n if (opts.rules.length === 0) {\n throw new Error('Strategy must have at least one rule');\n }\n const lastRule = opts.rules[opts.rules.length - 1]!;\n if (lastRule.when && lastRule.when.length > 0) {\n throw new Error('Last rule must be a fallback (no when clause)');\n }\n for (let i = 0; i < opts.rules.length - 1; i++) {\n const rule = opts.rules[i]!;\n if (rule.when !== undefined && rule.when.length === 0) {\n throw new Error(\n `Rule ${i} has an empty when clause and will match unconditionally, making subsequent rules unreachable`,\n );\n }\n }\n this._linkId = null;\n this._name = opts.name;\n this._freq = opts.freq ?? 'Daily';\n this._offset = opts.offset ?? 0;\n this._rules = opts.rules;\n }\n }\n\n get id(): number {\n if (this._resolvedId == null) throw new Error('StrategyHandle not yet resolved. Call resolve() first.');\n return this._resolvedId;\n }\n\n get link(): string {\n if (this._resolvedLinkId == null) throw new Error('StrategyHandle not yet resolved. Call resolve() first.');\n return this._resolvedLinkId;\n }\n\n get name(): string | null {\n return this._name;\n }\n\n get freq(): TradingFreq {\n return this._freq;\n }\n\n get offset(): number {\n return this._offset;\n }\n\n get rules(): StrategyRule[] {\n return this._rules;\n }\n\n marketSymbols(): string[] {\n const set = new Set<string>();\n for (const rule of this._rules) {\n for (const [ticker] of rule.hold.holdings) {\n if (ticker.symbol !== 'CASHX') set.add(ticker.symbol);\n }\n for (const signal of rule.when ?? []) {\n for (const ind of [signal.indicator1, signal.indicator2]) {\n if (ind.ticker !== null && ind.ticker.symbol !== 'CASHX') set.add(ind.ticker.symbol);\n if (ind.type === 'VIX') set.add('^VIX');\n if (ind.type === 'VIX3M') set.add('^VIX3M');\n }\n }\n }\n return Array.from(set).sort();\n }\n\n async resolve(): Promise<{ id: number }> {\n if (this._resolvedId != null) return { id: this._resolvedId };\n if (!this._resolving) {\n this._resolving =\n this._linkId !== null && this._name === null ? this._doResolveReference() : this._doResolveCreate();\n }\n return this._resolving;\n }\n\n private async _doResolveCreate(): Promise<{ id: number }> {\n const allSignals = new Set<SignalHandle>();\n const allAllocations = new Set<AllocationHandle>();\n for (const rule of this._rules) {\n if (rule.when) rule.when.forEach((s) => allSignals.add(s));\n allAllocations.add(rule.hold);\n }\n\n await Promise.all([\n ...Array.from(allSignals).map((s) => s.resolve()),\n ...Array.from(allAllocations).map((a) => a.resolve()),\n ]);\n\n const linkId = nanoid();\n const result = await this._storage.strategies.create({\n linkId,\n name: this._name!,\n freq: this._freq,\n offset: this._offset,\n rules: this._rules.map((rule) => ({\n signalIds: (rule.when ?? []).map((s) => s.id),\n allocationId: rule.hold.id,\n })),\n });\n\n this._resolvedId = result.id;\n this._resolvedLinkId = linkId;\n\n for (const rule of this._rules) {\n this._allocationMap.set(rule.hold.id, rule.hold);\n }\n\n return result;\n }\n\n private async _doResolveReference(): Promise<{ id: number }> {\n const ref = await this._storage.strategies.resolveReference(this._linkId!);\n this._resolvedId = ref.id;\n this._resolvedLinkId = this._linkId!;\n this._name = ref.name;\n this._freq = ref.freq;\n this._offset = ref.offset;\n\n // Build handles bottom-up from reference data\n const tickerMap = new Map<number, TickerHandle>();\n for (const t of ref.rules.tickers) {\n tickerMap.set(t.id, TickerHandle.fromResolved(this._storage, t.id, t.symbol, t.leverage));\n }\n\n const indicatorMap = new Map<number, IndicatorHandle>();\n for (const ind of ref.rules.indicators) {\n const ticker = ind.tickerId ? (tickerMap.get(ind.tickerId) ?? null) : null;\n indicatorMap.set(\n ind.id,\n IndicatorHandle.fromResolved(this._storage, this._market, ind.id, {\n type: ind.type,\n ticker,\n lookback: ind.lookback,\n delay: ind.delay,\n unit: ind.unit,\n threshold: ind.threshold,\n }),\n );\n }\n\n const signalMap = new Map<number, SignalHandle>();\n for (const sig of ref.rules.signals) {\n signalMap.set(\n sig.id,\n SignalHandle.fromResolved(this._storage, this._market, sig.id, {\n indicator1: indicatorMap.get(sig.indicatorId1)!,\n indicator2: indicatorMap.get(sig.indicatorId2)!,\n comparison: sig.comparison,\n tolerance: sig.tolerance,\n }),\n );\n }\n\n const allocationHandleMap = new Map<number, AllocationHandle>();\n for (const alloc of ref.rules.allocations) {\n const holdings: [TickerHandle, number][] = Object.entries(alloc.holdings).map(([key, weight]) => {\n const match = key.match(/^(.+)\\?L=(.+)$/);\n const symbol = match ? match[1]! : key;\n const leverage = match ? Number(match[2]) : 1;\n return [new TickerHandle(this._storage, symbol, leverage), weight];\n });\n const handle = AllocationHandle.fromResolved(this._storage, alloc.id, holdings);\n allocationHandleMap.set(alloc.id, handle);\n this._allocationMap.set(alloc.id, handle);\n }\n\n // Reconstruct rules\n this._rules = ref.rules.definition.map((rule) => ({\n when: rule.signalIds && rule.signalIds.length > 0 ? rule.signalIds.map((id) => signalMap.get(id)!) : undefined,\n hold: allocationHandleMap.get(rule.allocationId)!,\n }));\n\n return { id: ref.id };\n }\n\n private async _getLatestClosedTradingDay(): Promise<string> {\n const date = await this._storage.tradingDays.getLatestClosed();\n if (!date) throw new Error('No closed trading days found');\n return date;\n }\n\n private async _getLatestStrategySeriesDate(): Promise<string | null> {\n const { id } = await this.resolve();\n return this._storage.strategies.getLatestSeriesDate(id);\n }\n\n private async _ensureFresh(): Promise<void> {\n await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n if (this._cachedAsOf === latestClosed) return;\n\n const latestSeries = await this._getLatestStrategySeriesDate();\n\n if (latestSeries === latestClosed) {\n this._cache = null;\n this._cachedAsOf = latestClosed;\n return;\n }\n\n if (!this._syncing) {\n this._syncing = this._sync(latestClosed)\n .catch((err) => {\n console.warn('[sdk] strategy sync failed, using stored data:', err);\n })\n .finally(() => {\n this._syncing = null;\n });\n }\n await this._syncing;\n\n this._cache = null;\n this._cachedAsOf = latestClosed;\n }\n\n private async _sync(latestClosed: string): Promise<void> {\n const { id } = await this.resolve();\n const { entries } = await this._evaluate(latestClosed);\n if (entries.length > 0) {\n await this._storage.strategies.writeSeries(id, entries);\n }\n }\n\n /**\n * Pure evaluate — runs the same pipeline as _sync but returns the computed\n * evaluation instead of persisting. Used by both _sync (post-close write\n * path) and the public preview methods (pre-close read-only path).\n *\n * When `overrides` is `undefined` we take the write path — syncing signals\n * through storage as normal. When `overrides` is provided (even an empty\n * map) we take the read-only preview path: historical signal bars come\n * straight from storage, today's bar is computed in-memory via\n * `signal.computeAt(date, overrides, prevBool)`, and nothing is written.\n *\n * Incremental path: when a strategy checkpoint exists (`getLatestSeriesDate`\n * returns non-null), only the window (lastDate, limitDate] is processed.\n * The current allocation is carried forward from `getLatestAllocationId`.\n * Bootstrap: when no checkpoint exists, falls back to `_evaluateCold` which\n * runs the full-history evaluation.\n */\n private async _evaluate(\n limitDate: string,\n overrides?: Record<string, number>,\n ): Promise<{ allocations: AllocationHandle[]; entries: StrategySeriesEntry[] }> {\n const { id } = await this.resolve();\n const lastDate = await this._storage.strategies.getLatestSeriesDate(id);\n\n const tradingDays = await this._storage.tradingDays.getRange();\n const limitIdx = tradingDays.indexOf(limitDate);\n\n // Build the allocation index map exactly once per call.\n const allocations: AllocationHandle[] = [];\n const allocIndexMap = new Map<number, number>();\n const rulesInput = this._rules.map((rule) => {\n let allocIdx = allocIndexMap.get(rule.hold.id);\n if (allocIdx === undefined) {\n allocIdx = allocations.length;\n allocations.push(rule.hold);\n allocIndexMap.set(rule.hold.id, allocIdx);\n }\n return {\n signalIds: (rule.when ?? []).map((s) => s.id),\n allocationIndex: allocIdx,\n };\n });\n\n // Bootstrap: no checkpoint yet → fall back to full history compute.\n if (lastDate === null) {\n return this._evaluateCold(limitDate, overrides, rulesInput, allocations, tradingDays);\n }\n\n const lastAllocId = await this._storage.strategies.getLatestAllocationId(id);\n\n // Incremental window: (lastDate, limitDate], bounded by tradingDays.\n const incrementalStartIdx = tradingDays.indexOf(lastDate) + 1;\n const incrementalDays = tradingDays.slice(incrementalStartIdx, limitIdx + 1);\n\n // Preview-only refresh: when overrides are provided but the stored series\n // already covers limitDate (common case: `previewAllocation` called with\n // `date = latestClosed` after post-close sync). Without this branch, the\n // incremental path returns no entries and previewAllocation returns null\n // for any day the strategy has already been evaluated. Guarded to\n // `limitDate === lastDate` so we only re-evaluate today — re-evaluating\n // a strictly-past day under overrides would mis-seed `current` from the\n // latest stored allocation instead of the correct day-before allocation.\n const isOverrideRefresh = incrementalDays.length === 0 && overrides !== undefined && limitDate === lastDate;\n const newDays = isOverrideRefresh ? [limitDate] : incrementalDays;\n const startIdx = isOverrideRefresh ? limitIdx : incrementalStartIdx;\n if (newDays.length === 0) return { allocations, entries: [] };\n\n // Build signal bar maps only for the new window.\n const allSignals = new Set<SignalHandle>();\n for (const rule of this._rules) if (rule.when) rule.when.forEach((s) => allSignals.add(s));\n const signalSeries = new Map<number, Map<string, boolean>>();\n await Promise.all(\n Array.from(allSignals).map(async (signal) => {\n const bars =\n overrides === undefined\n ? await signal.series({ from: newDays[0]!, to: limitDate })\n : await this._storage.signals.getSeries(signal.id, { from: newDays[0]!, to: limitDate });\n const dateMap = new Map<string, boolean>();\n for (const bar of bars) dateMap.set(bar.date, bar.value === 1);\n if (overrides !== undefined) {\n const prevDateIdx = startIdx - 1 >= 0 ? tradingDays[startIdx - 1] : undefined;\n const prevBool = prevDateIdx !== undefined ? (await signal.value(prevDateIdx)) === 1 : null;\n const todayValue = await signal.computeAt(limitDate, overrides, prevBool);\n if (todayValue !== null) dateMap.set(limitDate, todayValue);\n }\n signalSeries.set(signal.id, dateMap);\n }),\n );\n\n const rebalanceDates = computeRebalanceDates(tradingDays, this._freq, this._offset);\n\n // Walk new days, carrying forward `current` from the checkpoint allocation.\n const entries: StrategySeriesEntry[] = [];\n let current: number | undefined = lastAllocId !== null ? (allocIndexMap.get(lastAllocId) ?? undefined) : undefined;\n\n for (const date of newDays) {\n if (rebalanceDates.has(date)) {\n for (const rule of rulesInput) {\n if (rule.signalIds.length === 0) {\n current = rule.allocationIndex;\n break;\n }\n const allTrue = rule.signalIds.every((sid) => signalSeries.get(sid)?.get(date) ?? false);\n if (allTrue) {\n current = rule.allocationIndex;\n break;\n }\n }\n }\n if (current !== undefined) {\n entries.push({ date, allocationId: allocations[current]!.id });\n }\n }\n\n return { allocations, entries };\n }\n\n // Renamed body of the old _evaluate — used only for first-ever evaluate (bootstrap).\n private async _evaluateCold(\n limitDate: string,\n overrides: Record<string, number> | undefined,\n rulesInput: { signalIds: number[]; allocationIndex: number }[],\n allocations: AllocationHandle[],\n tradingDays: string[],\n ): Promise<{ allocations: AllocationHandle[]; entries: StrategySeriesEntry[] }> {\n const allSignals = new Set<SignalHandle>();\n for (const rule of this._rules) if (rule.when) rule.when.forEach((s) => allSignals.add(s));\n const signalSeries = new Map<number, Map<string, boolean>>();\n\n if (overrides === undefined) {\n // Normal (post-close) path: sync signals through storage, may write.\n await Promise.all(\n Array.from(allSignals).map(async (signal) => {\n const bars = await signal.series();\n const dateMap = new Map<string, boolean>();\n for (const bar of bars) dateMap.set(bar.date, bar.value === 1);\n signalSeries.set(signal.id, dateMap);\n }),\n );\n } else {\n // Preview (pre-close, no-write) path: read historical from storage, then\n // compute today's signal value in-memory via computeAt. No writes anywhere.\n //\n // Find the trading day immediately before limitDate so we can pass its\n // in-memory boolean as prevBool to computeAt (hysteresis).\n const limitIdx = tradingDays.indexOf(limitDate);\n const prevDate = limitIdx > 0 ? tradingDays[limitIdx - 1] : undefined;\n\n await Promise.all(\n Array.from(allSignals).map(async (signal) => {\n // Read all historical signal bars from storage (pure read).\n const historicalBars = await this._storage.signals.getSeries(signal.id);\n const dateMap = new Map<string, boolean>();\n for (const bar of historicalBars) dateMap.set(bar.date, bar.value === 1);\n\n // Look up yesterday's boolean from the in-memory map (avoids stale\n // storage read for hysteresis on the preview path).\n const prevBool = prevDate !== undefined ? (dateMap.get(prevDate) ?? null) : null;\n\n const todayValue = await signal.computeAt(limitDate, overrides, prevBool);\n if (todayValue !== null) {\n dateMap.set(limitDate, todayValue);\n }\n\n signalSeries.set(signal.id, dateMap);\n }),\n );\n }\n\n const rebalanceDates = computeRebalanceDates(tradingDays, this._freq, this._offset);\n const evalResult = evaluateStrategy(signalSeries, rulesInput, rebalanceDates, tradingDays);\n const entries: StrategySeriesEntry[] = Array.from(evalResult.entries())\n .filter(([date]) => date <= limitDate)\n .map(([date, allocIdx]) => ({ date, allocationId: allocations[allocIdx]!.id }));\n return { allocations, entries };\n }\n\n private async _querySeriesFromDb(range?: DateRange): Promise<StrategyBar[]> {\n const { id } = await this.resolve();\n const entries = await this._storage.strategies.getSeries(id, range);\n return entries.map((e) => ({\n date: e.date,\n allocation: this._allocationMap.get(e.allocationId)!,\n }));\n }\n\n async series(range?: DateRange): Promise<StrategyBar[]> {\n await this._ensureFresh();\n if (this._cache && !range) return this._cache;\n const bars = await this._querySeriesFromDb(range);\n if (!range) this._cache = bars;\n return bars;\n }\n\n async value(date?: string): Promise<AllocationHandle | null> {\n await this._ensureFresh();\n const bars = date ? await this._querySeriesFromDb({ from: date, to: date }) : await this._querySeriesFromDb();\n if (bars.length === 0) return null;\n return date ? bars[0]!.allocation : bars[bars.length - 1]!.allocation;\n }\n\n async simulate(options: SimulateOptions): Promise<SimulationHandle> {\n const bars = await this.series({ from: options.from, to: options.to });\n if (bars.length === 0) {\n return new SimulationHandle([], [], options.portfolio);\n }\n\n const prices = await this._fetchPricesForTickers(bars, options.from, options.to);\n const tradingDays = bars.map((b) => b.date);\n const rebalanceDates = computeRebalanceDates(tradingDays, this._freq, this._offset);\n\n // Force day 1 rebalance so existing positions align to strategy\n rebalanceDates.add(bars[0]!.date);\n\n const result = runSimulation(bars, prices, rebalanceDates, options.portfolio);\n\n // Build finalState for live push support\n const lastBar = bars[bars.length - 1]!;\n const lastDate = lastBar.date;\n const lastAllocation = lastBar.allocation;\n\n // leveragedPrices: keyed as \"symbol:leverage\", values are the leveraged prices from _fetchPricesForTickers\n const leveragedPrices: Record<string, number> = {};\n for (const [ticker, _weight] of lastAllocation.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n const key = `${ticker.symbol}:${ticker.leverage}`;\n const price = prices[key]?.[lastDate];\n if (price != null) leveragedPrices[key] = price;\n }\n\n // closePrices: raw (unleveraged) close prices for computing real returns\n const closePrices: Record<string, number> = {};\n await this._fetchRawClosePrices(bars, lastDate, closePrices);\n\n const finalState: FinalState = {\n portfolio: result.finalPortfolio,\n allocation: lastAllocation,\n closePrices,\n leveragedPrices,\n };\n\n const liveEvaluator: LiveEvaluator = {\n previewLiveState: (date, overrides) => this.previewLiveState(date, overrides),\n };\n return new SimulationHandle(result.series, result.trades, options.portfolio, finalState, liveEvaluator);\n }\n\n /**\n * Preview the allocation this strategy would produce for `date` if today\n * closed at the provided raw quote prices. Does NOT write to strategies_series,\n * signals_series, or indicators_series. Safe to call before market close.\n *\n * @param date - The trading day to preview (must be in tradingDays.getRange()).\n * @param overrides - Raw (unleveraged) live prices keyed by market symbol.\n * Symbols absent from this map fall back to the last stored value\n * (see `IndicatorHandle._resolveRawBars`).\n * @returns The AllocationHandle for `date`, or null if the strategy has no\n * evaluable entry for that date.\n */\n async previewAllocation(date: string, overrides: Record<string, number>): Promise<AllocationHandle | null> {\n await this.resolve();\n\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewAllocation: ${date} is not a trading day`);\n }\n\n const { allocations, entries } = await this._evaluate(date, overrides);\n\n const target = entries.find((e) => e.date === date);\n if (!target) return null;\n\n const alloc = allocations.find((a) => a.id === target.allocationId);\n return alloc ?? this._allocationMap.get(target.allocationId) ?? null;\n }\n\n /**\n * Read-only preview of the strategy's allocation series including `date`.\n * Returns stored historical allocations plus an in-memory bar at `date`\n * computed via the same overrides-based preview path as `previewAllocation`.\n *\n * @param date - Target trading day to splice in-memory.\n * @param overrides - Raw (unleveraged) quotes keyed by market symbol.\n * @param range - Optional filter applied to the returned bars.\n */\n async previewSeries(date: string, overrides: Record<string, number>, range?: DateRange): Promise<StrategyBar[]> {\n await this.resolve();\n\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewSeries: ${date} is not a trading day`);\n }\n\n const { allocations, entries } = await this._evaluate(date, overrides);\n\n const allocById = new Map<number, AllocationHandle>();\n for (const a of allocations) allocById.set(a.id, a);\n for (const [id, a] of this._allocationMap) if (!allocById.has(id)) allocById.set(id, a);\n\n // When _evaluate returned only incremental entries (checkpoint path), fetch\n // stored history from the DB and prepend it so the caller gets the full series.\n const { id } = await this.resolve();\n const lastDate = await this._storage.strategies.getLatestSeriesDate(id);\n let storedBars: StrategyBar[] = [];\n if (lastDate !== null && entries.length > 0 && entries[0]!.date > (tradingDays[0] ?? '')) {\n // There may be stored history before the first entry — fetch it.\n const storedEntries = await this._storage.strategies.getSeries(id, { to: lastDate });\n storedBars = storedEntries.map((e) => ({\n date: e.date,\n allocation: allocById.get(e.allocationId) ?? this._allocationMap.get(e.allocationId)!,\n }));\n } else if (lastDate !== null && entries.length === 0) {\n // No new entries (e.g. limitDate === lastDate): return all stored history.\n const storedEntries = await this._storage.strategies.getSeries(id);\n storedBars = storedEntries.map((e) => ({\n date: e.date,\n allocation: allocById.get(e.allocationId) ?? this._allocationMap.get(e.allocationId)!,\n }));\n }\n\n const newBars: StrategyBar[] = entries.map((e) => ({\n date: e.date,\n allocation: allocById.get(e.allocationId)!,\n }));\n\n // Merge: stored history (excluding any dates already in newBars) + newBars.\n const newDates = new Set(newBars.map((b) => b.date));\n let bars: StrategyBar[] = [...storedBars.filter((b) => !newDates.has(b.date)), ...newBars];\n bars.sort((a, b) => a.date.localeCompare(b.date));\n\n if (range) {\n bars = bars.filter(\n (b) => (range.from === undefined || b.date >= range.from) && (range.to === undefined || b.date <= range.to),\n );\n }\n\n return bars;\n }\n\n /**\n * Full live strategy view at `date` under live-quote `overrides`: the active\n * allocation, the index of the rule that fired (or fallback), and per-rule\n * per-signal indicator values + truth. Computed entirely through the\n * overrides preview path — no writes to any `*_series` tables.\n *\n * Threshold indicators have their date suppressed (`null`) since their\n * synthetic series runs over every trading day in storage including future\n * dates and would report a far-future date for the last bar.\n */\n async previewLiveState(date: string, overrides: Record<string, number>): Promise<StrategyLiveState> {\n await this.resolve();\n\n const tradingDays = await this._storage.tradingDays.getRange();\n if (!tradingDays.includes(date)) {\n throw new Error(`previewLiveState: ${date} is not a trading day`);\n }\n\n const [{ allocations, entries }, rules] = await Promise.all([\n this._evaluate(date, overrides),\n Promise.all(\n this._rules.map(async (rule): Promise<LiveRuleState> => {\n const signalHandles = rule.when ?? [];\n const signals: LiveSignalState[] = await Promise.all(\n signalHandles.map(async (sig) => {\n const [i1Series, i2Series, sigSeries] = await Promise.all([\n sig.indicator1.previewSeries(date, overrides),\n sig.indicator2.previewSeries(date, overrides),\n sig.previewSeries(date, overrides),\n ]);\n const last1 = i1Series.at(-1);\n const last2 = i2Series.at(-1);\n const lastSig = sigSeries.at(-1);\n const i1IsThreshold = sig.indicator1.type === 'Threshold';\n const i2IsThreshold = sig.indicator2.type === 'Threshold';\n return {\n indicator1: {\n value: last1?.value ?? null,\n date: i1IsThreshold ? null : (last1?.date ?? null),\n },\n indicator2: {\n value: last2?.value ?? null,\n date: i2IsThreshold ? null : (last2?.date ?? null),\n },\n isTrue: lastSig?.value === 1,\n };\n }),\n );\n return { signals };\n }),\n ),\n ]);\n\n const target = entries.find((e) => e.date === date);\n const allocation = target\n ? (allocations.find((a) => a.id === target.allocationId) ?? this._allocationMap.get(target.allocationId) ?? null)\n : null;\n\n const fallbackIndex = this._rules.length - 1;\n let activeRuleIndex = fallbackIndex;\n if (target) {\n for (let r = 0; r < this._rules.length; r++) {\n if (this._rules[r]!.hold.id === target.allocationId) {\n activeRuleIndex = r;\n break;\n }\n }\n }\n\n return { allocation, activeRuleIndex, rules };\n }\n\n private async _fetchPricesForTickers(\n bars: StrategyBar[],\n from: string,\n to: string,\n ): Promise<Record<string, Record<string, number>>> {\n const tickerMap = new Map<string, TickerHandle>();\n for (const bar of bars) {\n for (const [ticker] of bar.allocation.holdings) {\n const key = `${ticker.symbol}:${ticker.leverage}`;\n if (!tickerMap.has(key)) {\n tickerMap.set(key, ticker);\n }\n }\n }\n\n const entries = await Promise.all(\n Array.from(tickerMap.entries()).map(async ([key, ticker]) => {\n const priceIndicator = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n const priceBars = await priceIndicator.series({ from, to });\n const dateMap: Record<string, number> = {};\n for (const bar of priceBars) {\n dateMap[bar.date] = bar.value;\n }\n return [key, dateMap] as const;\n }),\n );\n\n return Object.fromEntries(entries);\n }\n\n private async _fetchRawClosePrices(\n bars: StrategyBar[],\n lastDate: string,\n closePrices: Record<string, number>,\n ): Promise<void> {\n const symbols = new Set<string>();\n for (const bar of bars) {\n for (const [ticker] of bar.allocation.holdings) {\n if (ticker.symbol !== 'CASHX') symbols.add(ticker.symbol);\n }\n }\n\n await Promise.all(\n Array.from(symbols).map(async (symbol) => {\n const rawTicker = new TickerHandle(this._storage, symbol, 1);\n const priceIndicator = new IndicatorHandle(this._storage, this._market, {\n type: 'Price',\n ticker: rawTicker,\n lookback: 0,\n delay: 0,\n unit: null,\n threshold: null,\n });\n const priceBars = await priceIndicator.series({ from: lastDate, to: lastDate });\n if (priceBars.length > 0) {\n closePrices[symbol] = priceBars[0]!.value;\n }\n }),\n );\n }\n}\n","import type { TradingFreq } from '../providers/types';\n\nfunction getPeriodKey(dateStr: string, freq: TradingFreq): string {\n const d = new Date(dateStr + 'T00:00:00Z');\n const y = d.getUTCFullYear();\n const m = d.getUTCMonth();\n\n switch (freq) {\n case 'Weekly': {\n const thu = new Date(d);\n thu.setUTCDate(thu.getUTCDate() + 3 - ((thu.getUTCDay() + 6) % 7));\n const yearStart = new Date(Date.UTC(thu.getUTCFullYear(), 0, 1));\n const weekNo = Math.ceil(((thu.getTime() - yearStart.getTime()) / 86400000 + 1) / 7);\n return `${thu.getUTCFullYear()}-W${weekNo}`;\n }\n case 'Monthly':\n return `${y}-${m}`;\n case 'Bi-monthly':\n return `${y}-${Math.floor(m / 2)}`;\n case 'Quarterly':\n return `${y}-Q${Math.floor(m / 3)}`;\n case 'Every 4 Months':\n return `${y}-${Math.floor(m / 4)}`;\n case 'Semiannually':\n return `${y}-H${Math.floor(m / 6)}`;\n case 'Yearly':\n return `${y}`;\n default:\n return `${y}-${m}`;\n }\n}\n\nexport function computeRebalanceDates(tradingDays: string[], freq: TradingFreq, offset: number): Set<string> {\n if (freq === 'Daily') return new Set(tradingDays);\n\n const groups = new Map<string, number[]>();\n for (let i = 0; i < tradingDays.length; i++) {\n const key = getPeriodKey(tradingDays[i]!, freq);\n if (!groups.has(key)) groups.set(key, []);\n groups.get(key)!.push(i);\n }\n\n const result = new Set<string>();\n for (const indices of groups.values()) {\n const lastIdx = indices[indices.length - 1]!;\n const targetIdx = lastIdx - offset;\n if (targetIdx >= 0 && targetIdx < tradingDays.length) {\n result.add(tradingDays[targetIdx]!);\n }\n }\n\n return result;\n}\n\nexport interface StrategyRuleInput {\n signalIds: number[];\n allocationIndex: number;\n}\n\nexport function evaluateStrategy(\n signalSeries: Map<number, Map<string, boolean>>,\n rules: StrategyRuleInput[],\n rebalanceDates: Set<string>,\n tradingDays: string[],\n): Map<string, number> {\n const result = new Map<string, number>();\n let current: number | undefined;\n\n for (const date of tradingDays) {\n if (rebalanceDates.has(date)) {\n for (const rule of rules) {\n if (rule.signalIds.length === 0) {\n current = rule.allocationIndex;\n break;\n }\n const allTrue = rule.signalIds.every((id) => signalSeries.get(id)?.get(date) ?? false);\n if (allTrue) {\n current = rule.allocationIndex;\n break;\n }\n }\n }\n if (current !== undefined) {\n result.set(date, current);\n }\n }\n\n return result;\n}\n","import { TickerHandle } from './ticker';\nimport type { Trade } from '../backtest/types';\nimport { AllocationHandle } from './allocation';\nimport { isRateTickerSymbol } from '../providers/mappings';\n\nexport class PortfolioHandle {\n readonly holdings: [TickerHandle, number][];\n\n constructor(holdings: [TickerHandle, number][]) {\n // Check for duplicates\n const seen = new Set<string>();\n for (const [ticker] of holdings) {\n const key = `${ticker.symbol}:${ticker.leverage}`;\n if (seen.has(key)) {\n throw new Error(`Duplicate ticker: ${ticker.symbol}`);\n }\n seen.add(key);\n }\n\n this.holdings = holdings;\n }\n\n private _priceMap(prices: [TickerHandle, number][]): Map<string, number> {\n const map = new Map<string, number>();\n for (const [ticker, price] of prices) {\n map.set(`${ticker.symbol}:${ticker.leverage}`, price);\n }\n return map;\n }\n\n private _priceFor(ticker: TickerHandle, priceMap: Map<string, number>): number {\n if (ticker.symbol === 'CASHX') return 1;\n if (isRateTickerSymbol(ticker.symbol)) return 1;\n const key = `${ticker.symbol}:${ticker.leverage}`;\n const price = priceMap.get(key);\n if (price == null) {\n throw new Error(`Missing price for ${ticker.symbol}`);\n }\n return price;\n }\n\n value(prices: [TickerHandle, number][]): number {\n const priceMap = this._priceMap(prices);\n let total = 0;\n for (const [ticker, quantity] of this.holdings) {\n total += quantity * this._priceFor(ticker, priceMap);\n }\n return total;\n }\n\n weights(prices: [TickerHandle, number][]): [TickerHandle, number][] {\n const total = this.value(prices);\n if (total === 0) return [];\n\n const priceMap = this._priceMap(prices);\n const result: [TickerHandle, number][] = [];\n for (const [ticker, quantity] of this.holdings) {\n const dollarValue = quantity * this._priceFor(ticker, priceMap);\n if (dollarValue === 0) continue;\n result.push([ticker, dollarValue / total]);\n }\n return result;\n }\n\n trades(target: AllocationHandle, prices: [TickerHandle, number][], date: string): Trade[] {\n const priceMap = this._priceMap(prices);\n const totalValue = this.value(prices);\n\n // Build current dollar amounts by symbol\n const currentDollars = new Map<string, number>();\n for (const [ticker, quantity] of this.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n const price = this._priceFor(ticker, priceMap);\n currentDollars.set(ticker.symbol, quantity * price);\n }\n\n // Build target dollar amounts by symbol\n const targetDollars = new Map<string, number>();\n for (const [ticker, weight] of target.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n targetDollars.set(ticker.symbol, totalValue * weight);\n }\n\n // Build a symbol → TickerHandle lookup for price resolution\n const tickerBySymbol = new Map<string, TickerHandle>();\n for (const [ticker] of this.holdings) {\n if (ticker.symbol !== 'CASHX') tickerBySymbol.set(ticker.symbol, ticker);\n }\n for (const [ticker] of target.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n const existing = tickerBySymbol.get(ticker.symbol);\n if (existing && existing.leverage !== ticker.leverage) {\n throw new Error(`Conflicting leverage for ${ticker.symbol}`);\n }\n tickerBySymbol.set(ticker.symbol, ticker);\n }\n\n // Collect all non-CASHX symbols from both sides\n const allSymbols = new Set([...currentDollars.keys(), ...targetDollars.keys()]);\n\n const sells: Trade[] = [];\n const buys: Trade[] = [];\n\n for (const symbol of allSymbols) {\n const current = currentDollars.get(symbol) ?? 0;\n const target$ = targetDollars.get(symbol) ?? 0;\n const delta = target$ - current;\n\n const ticker = tickerBySymbol.get(symbol)!;\n const price = this._priceFor(ticker, priceMap);\n\n const quantity = Math.abs(delta) / price;\n if (quantity < 1e-10) continue;\n\n const trade: Trade = { date, symbol, quantity, price, action: delta > 0 ? 'buy' : 'sell' };\n\n if (trade.action === 'sell') {\n sells.push(trade);\n } else {\n buys.push(trade);\n }\n }\n\n return [...sells, ...buys];\n }\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { StrategyBar } from '../handles/strategy';\nimport type { TickerHandle } from '../handles/ticker';\nimport type { Trade } from './types';\nimport { PortfolioHandle } from '../handles/portfolio';\nimport { isRateTickerSymbol } from '../providers/mappings';\n\nconst EPSILON = 1e-8;\n\nfunction tkey(symbol: string, leverage: number): string {\n return `${symbol}:${leverage}`;\n}\n\nfunction symbolFromKey(key: string): string {\n const idx = key.lastIndexOf(':');\n return idx === -1 ? key : key.slice(0, idx);\n}\n\nfunction isRateKey(key: string): boolean {\n return isRateTickerSymbol(symbolFromKey(key));\n}\n\nfunction navPriceForKey(\n key: string,\n date: string,\n prices: Record<string, Record<string, number>>,\n lastPrice: Record<string, number>,\n): number | undefined {\n if (isRateKey(key)) return 1;\n const live = prices[key]?.[date];\n if (live != null) {\n lastPrice[key] = live;\n return live;\n }\n return lastPrice[key];\n}\n\nfunction daysBetween(prevIsoDate: string, currIsoDate: string): number {\n // Both inputs are 'YYYY-MM-DD'. UTC midnight → diff in ms → days.\n const ms =\n Date.UTC(Number(currIsoDate.slice(0, 4)), Number(currIsoDate.slice(5, 7)) - 1, Number(currIsoDate.slice(8, 10))) -\n Date.UTC(Number(prevIsoDate.slice(0, 4)), Number(prevIsoDate.slice(5, 7)) - 1, Number(prevIsoDate.slice(8, 10)));\n return Math.round(ms / (1000 * 60 * 60 * 24));\n}\n\nexport function runSimulation(\n bars: StrategyBar[],\n prices: Record<string, Record<string, number>>,\n rebalanceDates: Set<string>,\n portfolio: PortfolioHandle,\n): { series: DailyBar[]; trades: Trade[]; finalPortfolio: PortfolioHandle } {\n const positions: Record<string, number> = {};\n const lastPrice: Record<string, number> = {};\n let cash = 0;\n for (const [ticker, quantity] of portfolio.holdings) {\n if (ticker.symbol === 'CASHX') {\n cash = quantity;\n } else {\n positions[tkey(ticker.symbol, ticker.leverage)] = quantity;\n }\n }\n const series: DailyBar[] = [];\n const trades: Trade[] = [];\n\n // Carry forward the last known close when today's price is missing so\n // a held position isn't silently valued at $0 (e.g. mutual fund NAV that\n // posts after the trading-day cutoff).\n function valuationPrice(key: string, date: string): number | undefined {\n return navPriceForKey(key, date, prices, lastPrice);\n }\n\n let prevDate: string | null = null;\n\n for (const bar of bars) {\n const date = bar.date;\n\n // Accrue interest on rate-ticker positions between the previous bar and today.\n if (prevDate != null) {\n const days = daysBetween(prevDate, date);\n if (days > 0) {\n for (const [key, shares] of Object.entries(positions)) {\n if (!isRateKey(key)) continue;\n const ratePct = prices[key]?.[prevDate];\n if (ratePct == null) continue;\n const leverage = Number(key.slice(key.lastIndexOf(':') + 1)) || 1;\n const factor = 1 + leverage * (ratePct / 100) * (days / 360);\n positions[key] = shares * factor;\n }\n }\n }\n\n if (rebalanceDates.has(date)) {\n // Compute current portfolio value before rebalancing\n let portfolioValue = cash;\n for (const [key, shares] of Object.entries(positions)) {\n const price = valuationPrice(key, date);\n if (price != null) portfolioValue += shares * price;\n }\n\n // Determine target holdings\n const targetWeights: Record<string, number> = {};\n for (const [ticker, weight] of bar.allocation.holdings) {\n targetWeights[tkey(ticker.symbol, ticker.leverage)] = weight;\n }\n\n // Compute target shares and execute trades\n const allKeys = new Set([...Object.keys(positions), ...Object.keys(targetWeights)]);\n for (const key of allKeys) {\n let price: number;\n if (isRateKey(key)) {\n price = 1;\n } else {\n const live = prices[key]?.[date];\n if (live == null || live <= 0) continue;\n price = live;\n }\n\n const currentShares = positions[key] ?? 0;\n const targetValue = portfolioValue * (targetWeights[key] ?? 0);\n const targetShares = targetValue / price;\n const delta = targetShares - currentShares;\n\n if (Math.abs(delta) <= EPSILON) continue;\n\n if (Math.abs(targetShares) <= EPSILON) {\n delete positions[key];\n } else {\n positions[key] = targetShares;\n }\n cash -= delta * price;\n\n trades.push({\n date,\n symbol: key.split(':')[0]!,\n quantity: Math.abs(delta),\n price,\n action: delta > 0 ? 'buy' : 'sell',\n });\n }\n\n if (Math.abs(cash) <= EPSILON) cash = 0;\n }\n\n // Compute end-of-day portfolio value\n let value = cash;\n for (const [key, shares] of Object.entries(positions)) {\n const price = valuationPrice(key, date);\n if (price != null) value += shares * price;\n }\n series.push({ date, value });\n prevDate = date;\n }\n\n // Build finalPortfolio from ending positions + cash\n const finalHoldings: [TickerHandle, number][] = [];\n\n // Map ticker keys back to TickerHandles from allocations and starting portfolio\n const tickerByKey = new Map<string, TickerHandle>();\n for (const bar of bars) {\n for (const [ticker] of bar.allocation.holdings) {\n const key = tkey(ticker.symbol, ticker.leverage);\n if (!tickerByKey.has(key)) {\n tickerByKey.set(key, ticker);\n }\n }\n }\n for (const [ticker] of portfolio.holdings) {\n const key = tkey(ticker.symbol, ticker.leverage);\n if (!tickerByKey.has(key)) {\n tickerByKey.set(key, ticker);\n }\n }\n\n for (const [key, shares] of Object.entries(positions)) {\n const ticker = tickerByKey.get(key);\n if (ticker && Math.abs(shares) > EPSILON) {\n finalHoldings.push([ticker, shares]);\n }\n }\n\n // Add CASHX\n const cashKey = tkey('CASHX', 1);\n const cashTicker = tickerByKey.get(cashKey) ?? portfolio.holdings.find(([t]) => t.symbol === 'CASHX')?.[0];\n if (cashTicker && Math.abs(cash) > EPSILON) {\n finalHoldings.push([cashTicker, cash]);\n }\n\n const finalPortfolio = new PortfolioHandle(finalHoldings);\n\n return { series, trades, finalPortfolio };\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { AllocationHandle } from '../handles/allocation';\nimport { PortfolioHandle } from '../handles/portfolio';\nimport type { TickerHandle } from '../handles/ticker';\n\nexport interface SimulateOptions {\n from: string;\n to: string;\n portfolio: PortfolioHandle;\n}\n\nexport interface Trade {\n date: string;\n symbol: string;\n quantity: number;\n price: number;\n action: 'buy' | 'sell';\n}\n\nexport interface PortfolioSnapshot {\n value: number;\n holdings: [TickerHandle, number][];\n weights: [TickerHandle, number][];\n pendingTrades: Trade[];\n}\n\nexport interface FinalState {\n portfolio: PortfolioHandle;\n allocation: AllocationHandle;\n closePrices: Record<string, number>;\n leveragedPrices: Record<string, number>;\n}\n\n/** Per-signal slice of a live strategy snapshot. */\nexport interface LiveSignalState {\n indicator1: { value: number | null; date: string | null };\n indicator2: { value: number | null; date: string | null };\n isTrue: boolean;\n}\n\n/** Per-rule collection of live signal states, in the same order as the rule's `when` list. */\nexport interface LiveRuleState {\n signals: LiveSignalState[];\n}\n\n/** Full live strategy view for a single evaluation date — no portfolio info. */\nexport interface StrategyLiveState {\n allocation: AllocationHandle | null;\n activeRuleIndex: number;\n rules: LiveRuleState[];\n}\n\n/**\n * Combined live state returned by `SimulationHandle.pushAndPreview`: both the\n * portfolio snapshot from a `push` and the strategy evaluation at the target\n * date under the accumulated live-quote overrides.\n */\nexport interface LivePreviewState extends StrategyLiveState {\n snapshot: PortfolioSnapshot;\n}\n\n/**\n * Callback shape that `SimulationHandle.pushAndPreview` delegates to. Exists\n * purely to break the circular import between `SimulationHandle` (in this\n * file) and `StrategyHandle` (which creates simulations) — a strategy passes\n * a bound `(date, overrides) => previewLiveState(...)` into the handle.\n */\nexport interface LiveEvaluator {\n previewLiveState(date: string, overrides: Record<string, number>): Promise<StrategyLiveState>;\n}\n\nexport class SimulationHandle {\n readonly series: DailyBar[];\n readonly trades: Trade[];\n readonly startingPortfolio: PortfolioHandle;\n\n private _portfolio: PortfolioHandle | null;\n private _currentAllocation: AllocationHandle | null;\n private _lastClosePrices: Record<string, number>;\n private _lastLeveragedPrices: Map<string, number>;\n private _currentLeveragedPrices: Map<string, number>;\n private _lastDate: string;\n private _pushedQuotes: Record<string, number>;\n private _liveEvaluator: LiveEvaluator | null;\n\n constructor(\n series: DailyBar[],\n trades: Trade[],\n startingPortfolio: PortfolioHandle,\n finalState?: FinalState,\n liveEvaluator?: LiveEvaluator,\n ) {\n this.series = series;\n this.trades = trades;\n this.startingPortfolio = startingPortfolio;\n\n if (finalState) {\n this._portfolio = finalState.portfolio;\n this._currentAllocation = finalState.allocation;\n this._lastClosePrices = finalState.closePrices;\n this._lastLeveragedPrices = new Map(Object.entries(finalState.leveragedPrices));\n this._currentLeveragedPrices = new Map(Object.entries(finalState.leveragedPrices));\n this._lastDate = series.at(-1)?.date ?? '';\n } else {\n this._portfolio = null;\n this._currentAllocation = null;\n this._lastClosePrices = {};\n this._lastLeveragedPrices = new Map();\n this._currentLeveragedPrices = new Map();\n this._lastDate = '';\n }\n\n this._pushedQuotes = {};\n this._liveEvaluator = liveEvaluator ?? null;\n }\n\n push(...prices: [TickerHandle, number][]): PortfolioSnapshot {\n if (!this._portfolio || !this._currentAllocation) {\n return { value: 0, holdings: [], weights: [], pendingTrades: [] };\n }\n\n // Update leveraged prices from raw market prices\n for (const [ticker, realPrice] of prices) {\n if (ticker.symbol === 'CASHX') continue;\n const lastClose = this._lastClosePrices[ticker.symbol];\n if (lastClose == null) continue;\n\n const realReturn = (realPrice - lastClose) / lastClose;\n\n // Apply leverage to all portfolio tickers sharing this symbol\n for (const [held] of this._portfolio.holdings) {\n if (held.symbol !== ticker.symbol) continue;\n if (held.symbol === 'CASHX') continue;\n const key = `${held.symbol}:${held.leverage}`;\n const baseLeveragedPrice = this._lastLeveragedPrices.get(key);\n if (baseLeveragedPrice == null) continue;\n const leveragedReturn = held.leverage * realReturn;\n this._currentLeveragedPrices.set(key, baseLeveragedPrice * (1 + leveragedReturn));\n }\n }\n\n // Build price array for PortfolioHandle methods\n const priceArray: [TickerHandle, number][] = [];\n for (const [held] of this._portfolio.holdings) {\n if (held.symbol === 'CASHX') continue;\n const key = `${held.symbol}:${held.leverage}`;\n const price = this._currentLeveragedPrices.get(key);\n if (price != null) priceArray.push([held, price]);\n }\n\n return {\n value: this._portfolio.value(priceArray),\n holdings: this._portfolio.holdings,\n weights: this._portfolio.weights(priceArray),\n pendingTrades: this._portfolio.trades(this._currentAllocation, priceArray, this._lastDate),\n };\n }\n\n /**\n * One-call live update. Feeds portfolio-relevant ticker prices into `push`\n * (derived from `quotes` via the running portfolio's holdings), accumulates\n * every symbol in `quotes` into an internal override map so macro symbols\n * (e.g. `^VIX`) persist across ticks, then delegates to the simulation's\n * strategy for rule / signal / indicator evaluation at `date`.\n *\n * Without a live evaluator attached, returns just the portfolio snapshot\n * with allocation/rules/signals empty.\n *\n * @param quotes Symbol → raw live price. Portfolio tickers flow through\n * `push` for leveraged-equity math; non-portfolio symbols are still\n * layered into the overlay so indicators can see them.\n * @param options.date Target trading day to evaluate against. Defaults to\n * the current UTC ISO date; callers with non-UTC semantics or after-hours\n * rollover should supply their own.\n */\n async pushAndPreview(quotes: Record<string, number>, options: { date?: string } = {}): Promise<LivePreviewState> {\n const priceArgs: [TickerHandle, number][] = [];\n if (this._portfolio) {\n const seen = new Set<string>();\n for (const [ticker] of this._portfolio.holdings) {\n if (ticker.symbol === 'CASHX') continue;\n if (seen.has(ticker.symbol)) continue;\n const price = quotes[ticker.symbol];\n if (price !== undefined) {\n priceArgs.push([ticker, price]);\n seen.add(ticker.symbol);\n }\n }\n }\n const snapshot = this.push(...priceArgs);\n\n // Merge into the running overlay map (macro symbols etc. persist across ticks).\n for (const [symbol, price] of Object.entries(quotes)) {\n this._pushedQuotes[symbol] = price;\n }\n\n if (!this._liveEvaluator) {\n return { snapshot, allocation: null, activeRuleIndex: -1, rules: [] };\n }\n\n const date = options.date ?? new Date().toISOString().slice(0, 10);\n // Pass a snapshot copy so downstream callers can retain the object without\n // seeing it mutate on later ticks.\n const strategyState = await this._liveEvaluator.previewLiveState(date, { ...this._pushedQuotes });\n return { snapshot, ...strategyState };\n }\n}\n","import type { StorageProvider } from './providers/storage';\nimport type { MarketProvider } from './providers/market';\nimport type { IndicatorType, Unit } from './providers/types';\nimport { TickerHandle } from './handles/ticker';\nimport { IndicatorHandle } from './handles/indicator';\nimport { SignalHandle } from './handles/signal';\nimport { AllocationHandle } from './handles/allocation';\nimport { StrategyHandle } from './handles/strategy';\nimport { PortfolioHandle } from './handles/portfolio';\nimport type { StrategyOptions } from './handles/strategy';\n\ntype TreasuryTenor = Extract<\n IndicatorType,\n 'T3M' | 'T6M' | 'T1Y' | 'T2Y' | 'T3Y' | 'T5Y' | 'T7Y' | 'T10Y' | 'T20Y' | 'T30Y'\n>;\ntype CalendarPeriod = Extract<IndicatorType, 'Month' | 'Day of Week' | 'Day of Month' | 'Day of Year'>;\n\ninterface IndicatorOpts {\n delay?: number;\n}\n\nexport interface LivefolioClient {\n ticker(symbol: string, leverage?: number): TickerHandle;\n\n // Ticker-bound\n sma(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n ema(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n price(ticker: TickerHandle, opts?: IndicatorOpts): IndicatorHandle;\n returns(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n volatility(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n drawdown(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n rsi(ticker: TickerHandle, lookback: number, opts?: IndicatorOpts): IndicatorHandle;\n\n // Standalone\n vix(opts?: IndicatorOpts): IndicatorHandle;\n vix3m(opts?: IndicatorOpts): IndicatorHandle;\n treasury(tenor: TreasuryTenor, opts?: IndicatorOpts): IndicatorHandle;\n calendar(period: CalendarPeriod, opts?: IndicatorOpts): IndicatorHandle;\n\n // Threshold\n threshold(value: number, unit?: Unit): IndicatorHandle;\n\n // Signals\n gt(ind1: IndicatorHandle, ind2: IndicatorHandle, tolerance?: number): SignalHandle;\n lt(ind1: IndicatorHandle, ind2: IndicatorHandle, tolerance?: number): SignalHandle;\n eq(ind1: IndicatorHandle, ind2: IndicatorHandle, tolerance?: number): SignalHandle;\n\n // Allocations\n allocation(...holdings: [TickerHandle, number][]): AllocationHandle;\n\n // Portfolios\n portfolio(...holdings: [TickerHandle, number][]): PortfolioHandle;\n\n // Strategies\n strategy(linkId: string): StrategyHandle;\n strategy(options: StrategyOptions): StrategyHandle;\n strategy(optionsOrLinkId: string | StrategyOptions): StrategyHandle;\n}\n\nexport interface LivefolioClientOptions {\n storage: StorageProvider;\n market: MarketProvider;\n}\n\nfunction tickerBound(\n storage: StorageProvider,\n market: MarketProvider,\n type: IndicatorType,\n ticker: TickerHandle,\n lookback: number,\n opts?: IndicatorOpts,\n): IndicatorHandle {\n return new IndicatorHandle(storage, market, {\n type,\n ticker,\n lookback,\n delay: opts?.delay ?? 0,\n unit: null,\n threshold: null,\n });\n}\n\nfunction standalone(\n storage: StorageProvider,\n market: MarketProvider,\n type: IndicatorType,\n opts?: IndicatorOpts,\n): IndicatorHandle {\n return new IndicatorHandle(storage, market, {\n type,\n ticker: null,\n lookback: 0,\n delay: opts?.delay ?? 0,\n unit: null,\n threshold: null,\n });\n}\n\nexport function createClient(options: LivefolioClientOptions): LivefolioClient {\n const { storage, market } = options;\n\n return {\n ticker: (symbol, leverage) => new TickerHandle(storage, symbol, leverage),\n\n sma: (ticker, lookback, opts?) => tickerBound(storage, market, 'SMA', ticker, lookback, opts),\n ema: (ticker, lookback, opts?) => tickerBound(storage, market, 'EMA', ticker, lookback, opts),\n price: (ticker, opts?) => tickerBound(storage, market, 'Price', ticker, 0, opts),\n returns: (ticker, lookback, opts?) => tickerBound(storage, market, 'Return', ticker, lookback, opts),\n volatility: (ticker, lookback, opts?) => tickerBound(storage, market, 'Volatility', ticker, lookback, opts),\n drawdown: (ticker, lookback, opts?) => tickerBound(storage, market, 'Drawdown', ticker, lookback, opts),\n rsi: (ticker, lookback, opts?) => tickerBound(storage, market, 'RSI', ticker, lookback, opts),\n\n vix: (opts?) => standalone(storage, market, 'VIX', opts),\n vix3m: (opts?) => standalone(storage, market, 'VIX3M', opts),\n treasury: (tenor, opts?) => standalone(storage, market, tenor, opts),\n calendar: (period, opts?) => standalone(storage, market, period, opts),\n\n threshold: (value, unit?) =>\n new IndicatorHandle(storage, market, {\n type: 'Threshold',\n ticker: null,\n lookback: 0,\n delay: 0,\n unit: unit ?? null,\n threshold: value,\n }),\n\n gt: (ind1, ind2, tolerance?) =>\n new SignalHandle(storage, market, {\n indicator1: ind1,\n indicator2: ind2,\n comparison: '>',\n tolerance: tolerance ?? 0,\n }),\n lt: (ind1, ind2, tolerance?) =>\n new SignalHandle(storage, market, {\n indicator1: ind1,\n indicator2: ind2,\n comparison: '<',\n tolerance: tolerance ?? 0,\n }),\n eq: (ind1, ind2, tolerance?) =>\n new SignalHandle(storage, market, {\n indicator1: ind1,\n indicator2: ind2,\n comparison: '=',\n tolerance: tolerance ?? 0,\n }),\n\n allocation: (...holdings) => new AllocationHandle(storage, holdings),\n\n portfolio: (...holdings) => new PortfolioHandle(holdings),\n\n strategy: (optionsOrLinkId: StrategyOptions | string) => new StrategyHandle(storage, market, optionsOrLinkId),\n };\n}\n","import { AllocationHandle } from './allocation';\n\nexport function allocationsEqual(a: AllocationHandle | null, b: AllocationHandle | null): boolean {\n if (a === null && b === null) return true;\n if (a === null || b === null) return false;\n const aj = a.toJSON();\n const bj = b.toJSON();\n if (aj.length !== bj.length) return false;\n for (let i = 0; i < aj.length; i++) {\n if (aj[i]!.symbol !== bj[i]!.symbol) return false;\n if (aj[i]!.leverage !== bj[i]!.leverage) return false;\n if (Math.abs(aj[i]!.weight - bj[i]!.weight) > 1e-9) return false;\n }\n return true;\n}\n"],"mappings":"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","names":["from","rawBars","id"]}
|