This contains everything you need to run your app locally.
View your app in AI Studio: https://ai.studio/apps/d6dd78f9-8412-4bd7-bf1b-76dad78f86de
Prerequisites: Node.js
- Install dependencies:
npm install - Set the
GEMINI_API_KEYin .env.local to your Gemini API key. - Refresh the cached market data:
npm run update:market-data - Run the S&P 500 statistical relevance gate:
npm run backtest:market - Run the app:
npm run dev
The app defaults to the BTC tab and preserves the Bitcoin power-law forecast workspace. The S&P 500 tab uses VOO as an investable S&P 500 proxy because it has daily OHLCV and volume data; VTI is deferred as a broader-market option.
VOO data lives in src/data/voo-history.json and is regenerated with npm run update:market-data. The updater uses Yahoo Finance's no-key chart endpoint and normalizes OHLC values with the adjusted-close ratio when the source provides adjusted close.
The S&P 500 forecast uses a statistical log-return model:
equity_premium = clamp(expanding mean daily log return, 0.00005, 0.00055)
drift = equity_premium - 0.25 * mean(r_90) + 0.25 * mean(r_252) + 0.10 * trend_252
volatility = 0.65 * stdev(r_90) + 0.35 * stdev(r_252)
median_h = close * exp(drift * h)
interval_h = median_h * exp(+/- z * volatility * sqrt(h))
The S&P 500 lower/top lines reuse the same chart fields as BTC floor/peak lines, but use a VOO-specific statistical channel instead of Bitcoin power-law curves:
trend = 126-session SMA
residual = log(close / trend)
lower = trend * exp(2.5th percentile residual over prior 1,260 sessions)
top = trend * exp(99th percentile residual over prior 1,260 sessions)
npm run backtest:market is the reproducible statistical gate for the S&P 500 model. On the current VOO cache through 2026-06-05, the walk-forward channel test covers 96.3% of sampled closes with 2.4% below-channel breaks and 1.4% above-channel breaks. The median forecast also passes at 30, 90, and 180 trading-day horizons with statistically significant median-error improvement versus a no-change baseline and directional relevance against a 50% null.
