A pure neural network stock direction predictor. No decision trees, no rule-based logic, no ensembles. A single FiLM-conditioned residual network that learns patterns across all market caps and sectors, making BUY/HOLD/SELL calls for 1-day, 5-day, 30-day, 60-day, and 90-day horizons.
Predict a single stock at all horizons:
python3 main.py AAPL --all-horizons
Predict a specific horizon:
python3 main.py AAPL --horizon 30d
Compare multiple stocks:
python3 main.py AAPL MSFT NVDA --compare --all-horizons
Detailed output (probabilities, confidence, thresholds):
python3 main.py AAPL --detailed --horizon 60d
Use a specific checkpoint:
python3 main.py AAPL --checkpoint checkpoints_v5/best_model_5y_1.38M.pt
1d — Next trading day 5d — Next 5 trading days (1 week) 30d — Next 30 trading days (~6 weeks) 60d — Next 60 trading days (~3 months) 90d — Next 90 trading days (~4.5 months)
Each horizon has its own classification head with adaptive thresholds:
1d: BUY > +1.5% SELL < -1.5% 5d: BUY > +2.5% SELL < -2.5% 30d: BUY > +3.5% SELL < -3.5% 60d: BUY > +6.0% SELL < -6.0% 90d: BUY > +8.0% SELL < -8.0%
Short horizons use wider thresholds to filter out noise. Only strong moves get BUY or SELL labels. Everything else is HOLD.
Input: 128-dim feature vector |-> LayerNorm |-> FiLM conditioning (horizon + sector embeddings) |-> Cross-group attention (4 groups x 32-dim, 2-head) |-> FiLM conditioning (second pass) |-> Input projection (128 -> 256) |-> 3 residual MLP blocks (256-dim, pre-norm, GELU) |-> 5 per-horizon classification heads (256 -> 64 -> 3) | Output: SELL / HOLD / BUY probabilities per horizon
Key design choices:
- FiLM conditioning: horizon and sector MODULATE features rather than just concatenating. This lets the same trunk learn different decision boundaries for different time horizons and stock types.
- Per-horizon heads: each horizon gets its own classifier. A 1-day prediction uses different patterns than a 90-day prediction.
- No regression head: removed because it added noise that distorted the shared trunk. Pure classification.
- Cross-group attention: lets the model learn interactions between feature groups (e.g. momentum signals vs volume patterns).
Model size: 534K parameters (~2.1 MB).
Group 0 — Momentum & Trend (32-dim): RSI, MACD, MACD signal, MACD histogram, Stochastic %K/%D, Williams %R, ADX, CCI, MFI, trend signals (5/10/20/60/120d)
Group 1 — Volatility & Risk (32-dim): Bollinger Bands (upper/mid/lower/pct/width), ATR, ATR ratio, return kurtosis/skew, max drawdown, beta, SPY correlation, volatility regime, return z-scores
Group 2 — Volume & Flow (32-dim): OBV, OBV z-score, volume ratios (5/10/20/60d vs 120d), Chaikin Money Flow, Accumulation/Distribution, money flow ratio, volume profile features, relative volume
Group 3 — Fundamentals & Context (32-dim): P/E, P/S, P/B, EPS, profit margins (gross/operating/net), revenue growth, sector relative performance (5/20/60d), insider buy/sell ratios, sentiment proxies, market cap tier
Source: Yahoo Finance via yfinance Period: 5 years of daily history Tickers: ~390 stocks across 11 GICS sectors Samples: 430,073 Split: 70% train / 15% val / 15% test (temporal)
Sector coverage: Technology (68K), Healthcare (50K), Financials (49K), Industrials (43K), Communication Services (32K), Real Estate (33K), Utilities (32K), Materials (30K), Consumer Staples (29K), Energy (29K), Consumer Discretionary (35K)
Label distribution (30d horizon example): SELL: 32.7% HOLD: 27.5% BUY: 39.8%
Horizon Directional Accuracy vs Random (33%)
1d 44.8% +11.8% 5d 46.8% +13.8% 30d 48.4% +15.4% 60d 50.3% +17.3% 90d 55.0% +22.0%
Longer horizons are more predictable (less noise, stronger trends). The model has near-maximum prediction entropy across all horizons, meaning it actually distinguishes between directions rather than defaulting to one class.
Note: An earlier 2-year model showed 65-68% on 60d/90d but that was inflated by single-regime overfitting. The 5-year model's 55% is a more honest number with balanced, diverse predictions.
-
Collect fresh data:
python3 prepare_data.py --period 5y --output data/training_data.ptOptions: --max-tickers N Only fetch first N tickers (for testing) --period 5y History length (2y, 5y, 10y, max) --delay 0.25 Seconds between API calls (avoid rate limits)
Takes ~15-20 minutes for 390 tickers at 5y.
-
Train the model:
python3 train_v5.py --epochs 300 --batch-size 256 --lr 5e-4 \ --hidden-dim 256 --n-blocks 3 --patience 40Key options: --hidden-dim 256 Trunk width (256 = 534K params, 384 = 1.38M) --n-blocks 3 Number of residual blocks --lr 5e-4 Learning rate (3e-4 for bigger models) --label-smoothing 0.1 Smooths labels to prevent overconfidence --diversity-weight 0.05 Penalizes collapsed prediction distributions --patience 40 Early stopping patience (epochs without improvement)
Training time: ~30-45 minutes on CPU (Pi 5).
IMPORTANT: hidden-dim=256 / n-blocks=3 is the sweet spot for 430K samples. Bigger models (384-dim, 4 blocks = 1.38M params) perform WORSE because the data-to-param ratio drops too low.
main.py CLI entry point (predict) model_v5.py Model architecture (DeepStockModel, FiLM, etc.) predict_v5.py Prediction engine (load model, fetch features, infer) feature_engineer.py Feature extraction from raw price/fundamental data data_fetcher.py Yahoo Finance data fetching prepare_data.py Training data collection and preprocessing train_v5.py Training loop with focal loss + diversity penalty
data/ training_data.pt Current 5y dataset (430K samples) training_data_v5_2y_backup.pt Old 2y dataset (88K samples)
checkpoints_v5/ best_model.pt Active model (534K params, 5y data) best_model_2y_88k.pt Old 2y model backup best_model_5y_1.38M.pt Larger model (worse, kept for reference) best_model_5y_small.pt Earlier 5y/534K run backup
- This is a directional predictor, not a price target estimator. It tells you BUY/HOLD/SELL, not "the price will be $X".
- 1-day and 5-day predictions are inherently noisy. The model averages ~45% directional accuracy on short horizons. Use longer horizons (30d+) for more reliable signals.
- The model works best on stocks it was trained on (US equities with sufficient trading history). Penny stocks, crypto, and recent IPOs may produce unreliable predictions.
- Past performance != future results. This is a research tool, not financial advice. Always do your own due diligence.