@livefolio/sdk 0.3.6 → 0.3.7
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 +102 -1
- package/dist/index.js +519 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -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","../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\n // For leveraged tickers the checkpoint state (`checkpoint.metadata`)\n // was built on the leveraged price series, so its `prev` is a\n // leveraged value. Scale the new raw bar up to the same leveraged\n // scale before stepping the recursive computation — otherwise the\n // one-step `change` mixes unleveraged with leveraged and produces\n // a runaway delta (e.g. QQQ 3x RSI(10) spiking from 80 → 97 on a\n // flat intraday day). Rate tickers (DTB3, DFF, …) skip this: their\n // stored series is raw by convention, with leverage applied at\n // accrual time by the simulator.\n const leverage = this.ticker?.leverage ?? 1;\n let nextValue = rawBar;\n if (leverage !== 1 && !isRateTickerSymbol(this.ticker?.symbol ?? null)) {\n // Overrides are scoped to `date`, not `checkpoint.date`; resolving\n // the prior close *with* overrides in scope returns the override\n // (same symbol, any date) and makes dailyReturn=0. Pass undefined\n // so the prior close comes from storage.\n const prevRaw = await this._resolveRawBarAt(info.symbol, checkpoint.date, undefined);\n const prevLev = (checkpoint.metadata as { prev?: number }).prev;\n if (prevRaw !== null && prevRaw !== 0 && typeof prevLev === 'number') {\n const dailyReturn = (rawBar - prevRaw) / prevRaw;\n nextValue = prevLev * (1 + leverage * dailyReturn);\n }\n }\n\n const step =\n this.type === 'Return' && info.rateSeries\n ? returnNext(checkpoint.metadata as { tail: number[] }, nextValue, this.lookback, 'abs')\n : nextFn(checkpoint.metadata, nextValue, 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 _ensureFresh(): Promise<void> {\n await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n // In-memory memoization: skip work if this handle already synced against\n // the current latestClosed. Still runs once per handle per trading day.\n if (this._cachedAsOf === latestClosed) return;\n\n // Always run _sync — even when the stored series already covers\n // latestClosed. _evaluate now re-derives [latestClosed, latestClosed] in\n // that case so a previously-written row is re-checked against the current\n // signals_series; if upstream signals have been recomputed since the\n // original write, writeSeries upserts the correction. Without this, once\n // a day is written the SDK never revisits it and drift accumulates.\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 // Latest-day refresh: when the stored series already covers limitDate,\n // re-derive that one day from current signals and allow the caller to\n // upsert if the rule-picked allocation has changed since the original\n // write. Covers both the preview path (overrides provided — today's bar\n // computed in-memory via signal.computeAt) and the post-close write path\n // (overrides undefined — today's bar read from current signals_series).\n // Guarded to `limitDate === lastDate` so we only re-evaluate the latest\n // written day — re-evaluating a strictly-past day would mis-seed `current`\n // from the latest stored allocation instead of the correct day-before\n // allocation.\n const isLatestRefresh = incrementalDays.length === 0 && limitDate === lastDate;\n const newDays = isLatestRefresh ? [limitDate] : incrementalDays;\n const startIdx = isLatestRefresh ? 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 // Thresholds are constants — lookback/delay are semantically unused,\n // but the DB's canonical form has (lookback=1, delay=0). Matching that\n // lets `indicators.findOrCreate` reuse existing rows instead of creating\n // duplicates at (lookback=0, delay=0) that the schema permits.\n lookback: 1,\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":["leverage","from","rawBars","id"]}
|
|
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/metrics/returns.ts","../src/metrics/summary.ts","../src/metrics/risk.ts","../src/metrics/drawdown.ts","../src/metrics/riskAdjusted.ts","../src/metrics/activity.ts","../src/metrics/tables.ts","../src/metrics/compute.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\n // For leveraged tickers the checkpoint state (`checkpoint.metadata`)\n // was built on the leveraged price series, so its `prev` is a\n // leveraged value. Scale the new raw bar up to the same leveraged\n // scale before stepping the recursive computation — otherwise the\n // one-step `change` mixes unleveraged with leveraged and produces\n // a runaway delta (e.g. QQQ 3x RSI(10) spiking from 80 → 97 on a\n // flat intraday day). Rate tickers (DTB3, DFF, …) skip this: their\n // stored series is raw by convention, with leverage applied at\n // accrual time by the simulator.\n const leverage = this.ticker?.leverage ?? 1;\n let nextValue = rawBar;\n if (leverage !== 1 && !isRateTickerSymbol(this.ticker?.symbol ?? null)) {\n // Overrides are scoped to `date`, not `checkpoint.date`; resolving\n // the prior close *with* overrides in scope returns the override\n // (same symbol, any date) and makes dailyReturn=0. Pass undefined\n // so the prior close comes from storage.\n const prevRaw = await this._resolveRawBarAt(info.symbol, checkpoint.date, undefined);\n const prevLev = (checkpoint.metadata as { prev?: number }).prev;\n if (prevRaw !== null && prevRaw !== 0 && typeof prevLev === 'number') {\n const dailyReturn = (rawBar - prevRaw) / prevRaw;\n nextValue = prevLev * (1 + leverage * dailyReturn);\n }\n }\n\n const step =\n this.type === 'Return' && info.rateSeries\n ? returnNext(checkpoint.metadata as { tail: number[] }, nextValue, this.lookback, 'abs')\n : nextFn(checkpoint.metadata, nextValue, 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 _ensureFresh(): Promise<void> {\n await this.resolve();\n const latestClosed = await this._getLatestClosedTradingDay();\n\n // In-memory memoization: skip work if this handle already synced against\n // the current latestClosed. Still runs once per handle per trading day.\n if (this._cachedAsOf === latestClosed) return;\n\n // Always run _sync — even when the stored series already covers\n // latestClosed. _evaluate now re-derives [latestClosed, latestClosed] in\n // that case so a previously-written row is re-checked against the current\n // signals_series; if upstream signals have been recomputed since the\n // original write, writeSeries upserts the correction. Without this, once\n // a day is written the SDK never revisits it and drift accumulates.\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 // Latest-day refresh: when the stored series already covers limitDate,\n // re-derive that one day from current signals and allow the caller to\n // upsert if the rule-picked allocation has changed since the original\n // write. Covers both the preview path (overrides provided — today's bar\n // computed in-memory via signal.computeAt) and the post-close write path\n // (overrides undefined — today's bar read from current signals_series).\n // Guarded to `limitDate === lastDate` so we only re-evaluate the latest\n // written day — re-evaluating a strictly-past day would mis-seed `current`\n // from the latest stored allocation instead of the correct day-before\n // allocation.\n const isLatestRefresh = incrementalDays.length === 0 && limitDate === lastDate;\n const newDays = isLatestRefresh ? [limitDate] : incrementalDays;\n const startIdx = isLatestRefresh ? 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';\n\nexport interface MonthlyReturn {\n year: number;\n month: number; // 0..11\n return: number;\n partial: boolean;\n}\n\nexport interface YearlyReturn {\n year: number;\n return: number;\n partial: boolean;\n}\n\nexport function dailyReturns(series: DailyBar[]): number[] {\n const out: number[] = [];\n for (let i = 1; i < series.length; i++) {\n const prev = series[i - 1]!.value;\n const curr = series[i]!.value;\n out.push(curr / prev - 1);\n }\n return out;\n}\n\nfunction ymd(date: string): { y: number; m: number; d: number } {\n return {\n y: Number(date.slice(0, 4)),\n m: Number(date.slice(5, 7)) - 1,\n d: Number(date.slice(8, 10)),\n };\n}\n\nfunction lastDayOfMonth(year: number, month: number): number {\n return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\nexport function monthlyReturns(series: DailyBar[]): MonthlyReturn[] {\n if (series.length < 2) return [];\n\n type Bucket = {\n year: number;\n month: number;\n firstDate: string;\n firstValue: number;\n lastDate: string;\n lastValue: number;\n };\n const buckets: Bucket[] = [];\n for (const bar of series) {\n const { y, m } = ymd(bar.date);\n const last = buckets[buckets.length - 1];\n if (!last || last.year !== y || last.month !== m) {\n buckets.push({\n year: y,\n month: m,\n firstDate: bar.date,\n firstValue: bar.value,\n lastDate: bar.date,\n lastValue: bar.value,\n });\n } else {\n last.lastDate = bar.date;\n last.lastValue = bar.value;\n }\n }\n\n const out: MonthlyReturn[] = [];\n for (let i = 0; i < buckets.length; i++) {\n const b = buckets[i]!;\n const prevLast = i === 0 ? b.firstValue : buckets[i - 1]!.lastValue;\n const ret = b.lastValue / prevLast - 1;\n const startsAtMonthStart = ymd(b.firstDate).d === 1;\n const endsAtMonthEnd = ymd(b.lastDate).d === lastDayOfMonth(b.year, b.month);\n const isFirst = i === 0;\n const isLast = i === buckets.length - 1;\n const partial = (isFirst && !startsAtMonthStart) || (isLast && !endsAtMonthEnd);\n out.push({ year: b.year, month: b.month, return: ret, partial });\n }\n return out;\n}\n\nexport function yearlyReturns(series: DailyBar[]): YearlyReturn[] {\n if (series.length < 2) return [];\n\n type Bucket = {\n year: number;\n firstDate: string;\n firstValue: number;\n lastDate: string;\n lastValue: number;\n };\n const buckets: Bucket[] = [];\n for (const bar of series) {\n const { y } = ymd(bar.date);\n const last = buckets[buckets.length - 1];\n if (!last || last.year !== y) {\n buckets.push({\n year: y,\n firstDate: bar.date,\n firstValue: bar.value,\n lastDate: bar.date,\n lastValue: bar.value,\n });\n } else {\n last.lastDate = bar.date;\n last.lastValue = bar.value;\n }\n }\n\n const out: YearlyReturn[] = [];\n for (let i = 0; i < buckets.length; i++) {\n const b = buckets[i]!;\n const prevLast = i === 0 ? b.firstValue : buckets[i - 1]!.lastValue;\n const ret = b.lastValue / prevLast - 1;\n const isFirst = i === 0;\n const isLast = i === buckets.length - 1;\n const startsAtYearStart = b.firstDate.endsWith('-01-01');\n const endsAtYearEnd = b.lastDate.endsWith('-12-31');\n const partial = (isFirst && !startsAtYearStart) || (isLast && !endsAtYearEnd);\n out.push({ year: b.year, return: ret, partial });\n }\n return out;\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { MonthlyReturn, YearlyReturn } from './returns';\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\n\nfunction dateUTC(iso: string): number {\n return Date.UTC(Number(iso.slice(0, 4)), Number(iso.slice(5, 7)) - 1, Number(iso.slice(8, 10)));\n}\n\nexport function totalReturn(series: DailyBar[]): number {\n return series[series.length - 1]!.value / series[0]!.value - 1;\n}\n\nexport function years(series: DailyBar[]): number {\n const first = dateUTC(series[0]!.date);\n const last = dateUTC(series[series.length - 1]!.date);\n return (last - first) / DAY_MS / 365.25;\n}\n\nexport function cagr(series: DailyBar[]): number {\n const y = years(series);\n if (y <= 0) return 0;\n const ratio = series[series.length - 1]!.value / series[0]!.value;\n return Math.pow(ratio, 1 / y) - 1;\n}\n\nexport function bestYear(yr: YearlyReturn[]): { year: number; return: number } | null {\n let best: YearlyReturn | null = null;\n for (const y of yr) {\n if (y.partial) continue;\n if (!best || y.return > best.return) best = y;\n }\n return best ? { year: best.year, return: best.return } : null;\n}\n\nexport function worstYear(yr: YearlyReturn[]): { year: number; return: number } | null {\n let worst: YearlyReturn | null = null;\n for (const y of yr) {\n if (y.partial) continue;\n if (!worst || y.return < worst.return) worst = y;\n }\n return worst ? { year: worst.year, return: worst.return } : null;\n}\n\nfunction monthKey(m: MonthlyReturn): string {\n return `${m.year}-${String(m.month + 1).padStart(2, '0')}`;\n}\n\nexport function bestMonth(mr: MonthlyReturn[]): { date: string; return: number } | null {\n let best: MonthlyReturn | null = null;\n for (const m of mr) {\n if (m.partial) continue;\n if (!best || m.return > best.return) best = m;\n }\n return best ? { date: monthKey(best), return: best.return } : null;\n}\n\nexport function worstMonth(mr: MonthlyReturn[]): { date: string; return: number } | null {\n let worst: MonthlyReturn | null = null;\n for (const m of mr) {\n if (m.partial) continue;\n if (!worst || m.return < worst.return) worst = m;\n }\n return worst ? { date: monthKey(worst), return: worst.return } : null;\n}\n\nexport function pctPositiveMonths(mr: MonthlyReturn[]): number {\n let total = 0;\n let pos = 0;\n for (const m of mr) {\n if (m.partial) continue;\n total++;\n if (m.return > 0) pos++;\n }\n return total === 0 ? 0 : pos / total;\n}\n","import type { DailyBar } from '../handles/indicator';\n\nconst TRADING_DAYS = 252;\n\nexport function mean(xs: number[]): number {\n if (xs.length === 0) return 0;\n let s = 0;\n for (const x of xs) s += x;\n return s / xs.length;\n}\n\nexport function stdev(xs: number[]): number {\n if (xs.length < 2) return 0;\n const m = mean(xs);\n let s = 0;\n for (const x of xs) {\n const d = x - m;\n s += d * d;\n }\n return Math.sqrt(s / (xs.length - 1));\n}\n\nexport function volatility(returns: number[]): number {\n return stdev(returns) * Math.sqrt(TRADING_DAYS);\n}\n\nexport function downsideDeviation(returns: number[], marDaily: number): number {\n if (returns.length === 0) return 0;\n let s = 0;\n for (const r of returns) {\n const d = Math.min(0, r - marDaily);\n s += d * d;\n }\n return Math.sqrt(s / returns.length) * Math.sqrt(TRADING_DAYS);\n}\n\nexport function skewness(xs: number[]): number {\n const n = xs.length;\n if (n < 3) return 0;\n const m = mean(xs);\n const s = stdev(xs);\n if (s === 0) return 0;\n let sum = 0;\n for (const x of xs) {\n const z = (x - m) / s;\n sum += z * z * z;\n }\n return (n / ((n - 1) * (n - 2))) * sum;\n}\n\nexport function excessKurtosis(xs: number[]): number {\n const n = xs.length;\n if (n < 4) return 0;\n const m = mean(xs);\n const s = stdev(xs);\n if (s === 0) return 0;\n let sum = 0;\n for (const x of xs) {\n const z = (x - m) / s;\n sum += z * z * z * z;\n }\n const term1 = (n * (n + 1)) / ((n - 1) * (n - 2) * (n - 3));\n const term2 = (3 * (n - 1) * (n - 1)) / ((n - 2) * (n - 3));\n return term1 * sum - term2;\n}\n\nfunction quantile(sortedAsc: number[], p: number): number {\n if (sortedAsc.length === 0) return NaN;\n if (sortedAsc.length === 1) return sortedAsc[0]!;\n const idx = p * (sortedAsc.length - 1);\n const lo = Math.floor(idx);\n const hi = Math.ceil(idx);\n if (lo === hi) return sortedAsc[lo]!;\n const frac = idx - lo;\n return sortedAsc[lo]! * (1 - frac) + sortedAsc[hi]! * frac;\n}\n\nexport function historicalVar(returns: number[], confidence: number): number {\n if (returns.length === 0) return 0;\n const sorted = [...returns].sort((a, b) => a - b);\n const q = quantile(sorted, 1 - confidence);\n return Math.max(0, -q);\n}\n\nexport function historicalCvar(returns: number[], confidence: number): number {\n if (returns.length === 0) return 0;\n const sorted = [...returns].sort((a, b) => a - b);\n const q = quantile(sorted, 1 - confidence);\n const tail = sorted.filter((r) => r <= q);\n if (tail.length === 0) return 0;\n return Math.max(0, -mean(tail));\n}\n\nexport function ulcerIndex(series: DailyBar[]): number {\n if (series.length === 0) return 0;\n let runningMax = -Infinity;\n let sumSq = 0;\n for (const bar of series) {\n if (bar.value > runningMax) runningMax = bar.value;\n const ddPct = ((bar.value - runningMax) / runningMax) * 100;\n sumSq += ddPct * ddPct;\n }\n return Math.sqrt(sumSq / series.length);\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { DrawdownEntry } from './types';\n\nconst DAY_MS = 24 * 60 * 60 * 1000;\nconst NOISE = 1e-4;\n\nfunction dateUTC(iso: string): number {\n return Date.UTC(Number(iso.slice(0, 4)), Number(iso.slice(5, 7)) - 1, Number(iso.slice(8, 10)));\n}\n\nfunction daysBetween(a: string, b: string): number {\n return Math.round((dateUTC(b) - dateUTC(a)) / DAY_MS);\n}\n\nexport function computeDrawdownTable(series: DailyBar[], topN: number): DrawdownEntry[] {\n if (series.length === 0) return [];\n\n type Open = { peakDate: string; peakValue: number; troughDate: string; troughValue: number };\n const segments: DrawdownEntry[] = [];\n let peakDate = series[0]!.date;\n let peakValue = series[0]!.value;\n let open: Open | null = null;\n\n for (let i = 0; i < series.length; i++) {\n const bar = series[i]!;\n if (bar.value >= peakValue) {\n if (open) {\n const recoveryDate = bar.date;\n const depth = open.troughValue / open.peakValue - 1;\n if (Math.abs(depth) >= NOISE) {\n segments.push({\n peakDate: open.peakDate,\n troughDate: open.troughDate,\n recoveryDate,\n depth,\n durationDays: daysBetween(open.peakDate, recoveryDate),\n underwaterDays: daysBetween(open.peakDate, open.troughDate),\n });\n }\n open = null;\n }\n peakDate = bar.date;\n peakValue = bar.value;\n } else {\n if (!open) {\n open = { peakDate, peakValue, troughDate: bar.date, troughValue: bar.value };\n } else if (bar.value < open.troughValue) {\n open.troughDate = bar.date;\n open.troughValue = bar.value;\n }\n }\n }\n\n if (open) {\n const lastDate = series[series.length - 1]!.date;\n const depth = open.troughValue / open.peakValue - 1;\n if (Math.abs(depth) >= NOISE) {\n segments.push({\n peakDate: open.peakDate,\n troughDate: open.troughDate,\n recoveryDate: null,\n depth,\n durationDays: daysBetween(open.peakDate, lastDate),\n underwaterDays: daysBetween(open.peakDate, open.troughDate),\n });\n }\n }\n\n segments.sort((a, b) => Math.abs(b.depth) - Math.abs(a.depth));\n return segments.slice(0, topN);\n}\n\nexport function currentDrawdown(series: DailyBar[]): number {\n if (series.length === 0) return 0;\n let runningMax = -Infinity;\n for (const bar of series) {\n if (bar.value > runningMax) runningMax = bar.value;\n }\n const last = series[series.length - 1]!.value;\n return last / runningMax - 1;\n}\n","import { mean, stdev, downsideDeviation } from './risk';\n\nconst TRADING_DAYS = 252;\n\nexport function dailyRiskFree(annual: number): number {\n return Math.pow(1 + annual, 1 / TRADING_DAYS) - 1;\n}\n\nexport function sharpe(returns: number[], rfAnnual: number): number {\n const rfDaily = dailyRiskFree(rfAnnual);\n const s = stdev(returns);\n if (s === 0) return NaN;\n return ((mean(returns) - rfDaily) / s) * Math.sqrt(TRADING_DAYS);\n}\n\nexport function sortino(returns: number[], rfAnnual: number): number {\n const rfDaily = dailyRiskFree(rfAnnual);\n const dd = downsideDeviation(returns, rfDaily);\n if (dd === 0) return NaN;\n return ((mean(returns) - rfDaily) * TRADING_DAYS) / dd;\n}\n\nexport function calmar(cagrValue: number, maxDdDepth: number): number {\n if (maxDdDepth === 0) return Infinity;\n return cagrValue / Math.abs(maxDdDepth);\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { Trade } from '../backtest/types';\n\nexport function rebalanceCount(trades: Trade[]): number {\n const dates = new Set<string>();\n for (const t of trades) dates.add(t.date);\n return dates.size;\n}\n\nexport function tradeCount(trades: Trade[]): number {\n return trades.length;\n}\n\nexport function turnover(trades: Trade[], series: DailyBar[], years: number): number {\n if (years <= 0 || series.length === 0) return 0;\n let gross = 0;\n for (const t of trades) {\n if (t.symbol === 'CASHX') continue;\n gross += Math.abs(t.quantity * t.price);\n }\n let navSum = 0;\n for (const bar of series) navSum += bar.value;\n const avgNav = navSum / series.length;\n if (avgNav === 0) return 0;\n return gross / avgNav / years;\n}\n\nfunction navAtOrBefore(series: DailyBar[], date: string): number | null {\n let result: number | null = null;\n for (const bar of series) {\n if (bar.date <= date) result = bar.value;\n else break;\n }\n return result;\n}\n\nexport function winRatePerRebalance(series: DailyBar[], trades: Trade[]): number {\n if (series.length < 2) return 0;\n const firstDate = series[0]!.date;\n const lastDate = series[series.length - 1]!.date;\n\n const distinctTradeDates = Array.from(new Set(trades.map((t) => t.date))).sort();\n const inRange = distinctTradeDates.filter((d) => d > firstDate && d < lastDate);\n\n if (inRange.length === 0) {\n const total = series[series.length - 1]!.value / series[0]!.value - 1;\n return total > 0 ? 1 : 0;\n }\n\n const boundaries = [firstDate, ...inRange, lastDate];\n let wins = 0;\n let total = 0;\n for (let i = 0; i < boundaries.length - 1; i++) {\n const a = navAtOrBefore(series, boundaries[i]!);\n const b = navAtOrBefore(series, boundaries[i + 1]!);\n if (a == null || b == null || a === 0) continue;\n total++;\n if (b / a - 1 > 0) wins++;\n }\n return total === 0 ? 0 : wins / total;\n}\n","import type { MonthlyReturnsTable } from './types';\nimport type { MonthlyReturn } from './returns';\n\nexport function buildMonthlyTable(monthly: MonthlyReturn[]): MonthlyReturnsTable {\n if (monthly.length === 0) return { rows: [] };\n\n const byYear = new Map<number, (number | null)[]>();\n for (const m of monthly) {\n let row = byYear.get(m.year);\n if (!row) {\n row = new Array(12).fill(null) as (number | null)[];\n byYear.set(m.year, row);\n }\n row[m.month] = m.return;\n }\n\n const years = Array.from(byYear.keys()).sort((a, b) => a - b);\n const rows = years.map((year) => {\n const months = byYear.get(year)!;\n let ytd: number | null = null;\n for (const v of months) {\n if (v == null) continue;\n ytd = (ytd == null ? 1 : 1 + ytd) * (1 + v) - 1;\n }\n return { year, months, ytd };\n });\n return { rows };\n}\n\nexport function buildYearlyList(monthly: MonthlyReturn[]): Array<{ year: number; return: number }> {\n const byYear = new Map<number, number[]>();\n for (const m of monthly) {\n if (m.partial) continue;\n let arr = byYear.get(m.year);\n if (!arr) {\n arr = [];\n byYear.set(m.year, arr);\n }\n arr.push(m.return);\n }\n const years = Array.from(byYear.keys()).sort((a, b) => a - b);\n return years.map((year) => {\n const months = byYear.get(year)!;\n let compounded = 1;\n for (const v of months) compounded *= 1 + v;\n return { year, return: compounded - 1 };\n });\n}\n","import type { DailyBar } from '../handles/indicator';\nimport type { Trade } from '../backtest/types';\nimport type { DrawdownEntry, MetricsOptions, MetricsResult } from './types';\nimport { dailyReturns, monthlyReturns, yearlyReturns } from './returns';\nimport { totalReturn, cagr, years, bestYear, worstYear, bestMonth, worstMonth, pctPositiveMonths } from './summary';\nimport {\n volatility,\n downsideDeviation,\n skewness,\n excessKurtosis,\n historicalVar,\n historicalCvar,\n ulcerIndex,\n} from './risk';\nimport { computeDrawdownTable, currentDrawdown } from './drawdown';\nimport { sharpe, sortino, calmar, dailyRiskFree } from './riskAdjusted';\nimport { rebalanceCount, tradeCount, turnover, winRatePerRebalance } from './activity';\nimport { buildMonthlyTable, buildYearlyList } from './tables';\n\nexport function computeMetrics(series: DailyBar[], trades: Trade[], options: MetricsOptions = {}): MetricsResult {\n if (series.length < 2) {\n throw new Error('metrics requires at least 2 daily bars');\n }\n const rfAnnual = options.riskFreeRate ?? 0;\n const topN = options.topDrawdowns ?? 5;\n const conf = options.varConfidence ?? 0.95;\n\n const ret = dailyReturns(series);\n const monthly = monthlyReturns(series);\n const yearly = yearlyReturns(series);\n const yrs = years(series);\n\n const dds = computeDrawdownTable(series, Math.max(topN, 1));\n const maxDd: DrawdownEntry = dds[0] ?? {\n peakDate: series[0]!.date,\n troughDate: series[0]!.date,\n recoveryDate: series[series.length - 1]!.date,\n depth: 0,\n durationDays: 0,\n underwaterDays: 0,\n };\n const cagrVal = cagr(series);\n\n return {\n range: { from: series[0]!.date, to: series[series.length - 1]!.date, years: yrs },\n returns: {\n totalReturn: totalReturn(series),\n cagr: cagrVal,\n bestYear: bestYear(yearly),\n worstYear: worstYear(yearly),\n bestMonth: bestMonth(monthly),\n worstMonth: worstMonth(monthly),\n pctPositiveMonths: pctPositiveMonths(monthly),\n },\n risk: {\n volatility: volatility(ret),\n downsideDeviation: downsideDeviation(ret, dailyRiskFree(rfAnnual)),\n maxDrawdown: maxDd,\n currentDrawdown: currentDrawdown(series),\n ulcerIndex: ulcerIndex(series),\n skew: skewness(ret),\n kurtosis: excessKurtosis(ret),\n var95: historicalVar(ret, conf),\n cvar95: historicalCvar(ret, conf),\n },\n riskAdjusted: {\n sharpe: sharpe(ret, rfAnnual),\n sortino: sortino(ret, rfAnnual),\n calmar: calmar(cagrVal, maxDd.depth),\n },\n activity: {\n rebalances: rebalanceCount(trades),\n trades: tradeCount(trades),\n turnover: turnover(trades, series, yrs),\n winRate: winRatePerRebalance(series, trades),\n },\n tables: {\n drawdowns: dds.slice(0, topN),\n monthly: buildMonthlyTable(monthly),\n yearly: buildYearlyList(monthly),\n },\n };\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';\nimport { computeMetrics } from '../metrics/compute';\nimport type { MetricsOptions, MetricsResult } from '../metrics/types';\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 metrics(options: MetricsOptions = {}): MetricsResult {\n return computeMetrics(this.series, this.trades, options);\n }\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 // Thresholds are constants — lookback/delay are semantically unused,\n // but the DB's canonical form has (lookback=1, delay=0). Matching that\n // lets `indicators.findOrCreate` reuse existing rows instead of creating\n // duplicates at (lookback=0, delay=0) that the schema permits.\n lookback: 1,\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":["dailyReturns","mean","leverage","from","rawBars","DAY_MS","dateUTC","daysBetween","TRADING_DAYS","years","total","years","id"]}
|