Quantis compares five forecasting approaches, LSTM, ARIMA, Random Forest, Logistic Regression, and a multi-horizon ensemble, across 100 US stocks and ETFs. Type a ticker on the left to load it; the sidebar shows price, technical indicators, and risk metrics computed from real OHLCV bars. The top panel derives buy/sell zones from Bollinger bands and ATR. The tabbed chart lets you compare each model's forecast against the actual price history and a 12-month backtest. Data is refreshed offline in Python and committed to the repo as JSON, no live API, no rate limits, no broken fetches. See the Methodology page for the math behind each model and why the architecture is what it is. Full source code, the Colab pipeline, and the list of covered tickers are on GitHub →
Stocks you're tracking. Live quotes update every time you load this tab. Your list is saved in your browser, so it persists across sessions, switch devices and you'll start fresh.
Quantis is the web port of a graduate research project (INFO 656 final, Pratt Institute) that compares classical ML, deep learning, and time-series approaches to stock forecasting. Below: the data pipeline, each model's design choices, how predictions are reconciled, and the honest limitations of the work.
View the source on GitHub → All code, Colab pipeline, ticker list, and generated JSONs are atgithub.com/amma-ctrl/quantis
The dashboard runs entirely client-side on GitHub Pages, no backend, no API keys,
no rate limits. OHLCV bars and ML forecasts are pre-generated in a single Colab
notebook (Quantis_Pipeline.ipynb) and committed to the repo as JSON
files under data/bars/ and data/forecasts/. The browser
reads those local files directly. The badge in the top corner of this page shows
when the data was last refreshed, currently
checking….
This is the third architecture I tried. The first prototype hit Yahoo Finance's
chart endpoint directly from the browser, that's how every static stock dashboard
worked for years, but Yahoo tightened CORS constraints in 2025 and started blocking
browser fetches. The second attempt used Finnhub's /stock/candle
endpoint, which has the right CORS headers, but Finnhub moved historical bars behind
a paywall in 2024-25. Alpha Vantage caps free use at 25 calls/day; Twelve Data and
Stooq via free CORS proxies break unpredictably from github.io origins.
For a portfolio site that must just work, every "live" option is broken.
The honest answer is to pre-generate. Yahoo data is still freely available, just
not from a browser. The Colab notebook pulls 5 years of daily OHLCV via
yfinance, trains all five models (LSTM benefits from a free Colab GPU),
and commits everything to GitHub in one batched API call. The dashboard then has
zero external dependencies. Re-running the notebook refreshes the live site in
~2 minutes (bars only) or ~45 minutes (bars + full model retrain on GPU).
Quantis_Pipeline.ipynb · GPU runtime for ~10× faster LSTMEach model approaches forecasting differently. Running them side-by-side surfaces where they agree (higher-confidence signals) and where they diverge (uncertainty). The point isn't to pick the "best" model, it's to make the disagreement legible.
| Lookback | 60 days |
| Architecture | 3× LSTM(50) |
| Optimizer | Adam |
| Loss | MSE |
| Forecast horizon | 30 days |
| Order | (5, 1, 0) |
| Window | 500 trading days |
| Stationarity | ADF, p<0.05 |
| Validation | Walk-forward |
| Trees | 100 |
| Max depth | 10 |
| Features | 19 engineered |
| Target | Up / Down (1 day) |
| Horizons | 1, 3, 5, 10, 20 |
| Per-horizon model | RF (80 trees, depth 8) |
| Output | P(UP) per horizon |
| Period | 252 days (rolling) |
| Capital | $10,000 |
| Benchmark | Buy & Hold |
| Friction | None (educational) |
The classifiers don't see raw price, they see 19 features derived from OHLCV. This is where domain knowledge enters the model. Features fall into five buckets:
RSI(14), MACD line / signal / histogram, Stochastic %K / %D. These capture short-term overbought / oversold conditions and trend acceleration.
Bollinger band width, Bollinger position (where current price sits inside the bands), ATR percent, daily high-low range. These describe how "wild" the recent price action is.
Volume ratio (current vs. 20-day average). Volume confirms or denies price moves.
Multi-period returns (1d, 5d, 10d, 20d), 20-day realized volatility, price/SMA ratios, trend strength. These give the model context: is the price stretched, mean-reverting, or trending?
Random Forest's feature importance ranking (visible on the RF tab) usually puts SMA-based
features near the top, which makes intuitive sense, short-term trend dominates next-day
direction. The full feature list is in the Colab notebook's FEATURE_COLS.
The "consensus" indicator on the dashboard isn't a weighted vote of the regression models (LSTM, ARIMA), those predict continuous prices, not directions. Instead it combines four directional signals:
| Random Forest next-day P(UP) | From the precomputed JSON |
| MACD line vs. signal line | Crossover direction |
| RSI(14) | <30 oversold, >70 overbought |
| Price vs. SMA-20 | Above = bullish |
A simple majority vote across these four produces BUY / SELL / HOLD. The LSTM and ARIMA forecasts inform the buy-zone target price but don't enter the directional vote, their job is magnitude, not direction.
Each model is evaluated on the last 252 trading days with $10,000 starting capital. The classifiers' equity curves assume a long-only strategy: enter on P(UP)>0.5, exit on P(UP)<0.5. The regressors (LSTM, ARIMA) translate their MAPE into an "edge" parameter, which then drives the equity curve.
This is a simplified backtest, no slippage, no spread, no commissions, no position sizing rules. Real trading reduces returns substantially. The point is comparison across models on a level playing field, not a forecast of live PnL.
Frontend: Vanilla ES modules, canvas-rendered charts, no framework, no build step.
Data: pre-generated JSON in data/bars/ (OHLCV) and
data/forecasts/ (model outputs), committed to the repo.
Pipeline: single Colab notebook (Quantis_Pipeline.ipynb)
handles fetch → feature engineering → train → commit, using yfinance,
TensorFlow, statsmodels, scikit-learn, and ta.
Deployment: GitHub Pages, no CI needed.
Source: reproducible end-to-end, open the notebook in Colab,
add a GITHUB_TOKEN secret, set repo coords, Runtime → Run all. ~2 minutes
for a bars-only refresh, ~45 minutes on a free GPU runtime for the full model retrain.