File size: 9,154 Bytes
95349f4
b5749b3
95349f4
 
 
 
 
 
c1d60a3
95349f4
 
 
 
a58d858
 
 
 
 
 
95349f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a58d858
 
 
 
 
 
 
 
 
 
 
95349f4
 
 
 
 
a58d858
95349f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a58d858
95349f4
a58d858
 
95349f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a58d858
95349f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a58d858
 
 
95349f4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a58d858
 
 
 
95349f4
 
 
 
 
 
 
b5749b3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
---
title: Forex Crypto Prediction
emoji: πŸ“ˆ
colorFrom: blue
colorTo: green
sdk: gradio
app_file: app.py
pinned: false
python_version: "3.11"
---

# πŸ“ˆ Forex & Crypto Prediction Dashboard

Multi-timeframe forex & crypto price prediction with **ARIMA**,
**Auto-ARIMA**, **ARIMA-GARCH**, **Moirai** (Salesforce) and **TimesFM**
(Google) β€” each model's accuracy is backtested and reported **separately**,
plus a candle-by-candle correct/incorrect verification log. Pure Python,
built for a free/low CPU-only Hugging Face Space (2 vCPU / 16GB RAM / ~50GB
storage).

**Educational / research project β€” not financial advice.** Forex and crypto
trading carries substantial risk of loss. Nothing this app outputs is a
recommendation to trade.

## What's inside

- **Live + historical data**, free, no API key β€” [yfinance](https://github.com/ranaroussi/yfinance)
  (Yahoo Finance). Live means polling the same free source on a timer, since
  Yahoo has no free websocket feed.
- **Any symbol** β€” a dropdown of popular forex pairs (`EURUSD=X`, `GBPUSD=X`, ...)
  and crypto pairs (`BTC-USD`, `ETH-USD`, ...) that also accepts any custom
  yfinance-valid ticker you type in.
- **Any timeframe** β€” 1m, 5m, 10m, 15m, 30m, 1h, 4h, 1d out of the box.
  Timeframes Yahoo doesn't serve natively (like 10m) are built by resampling
  a smaller native interval, so you're not limited to Yahoo's fixed list.
- **5 forecasting models**, one shared interface (`models/base_model.py`):
  - **ARIMA** (`statsmodels`) β€” fast, classical, always available. Order
    (p,d,q) is found with a brute-force AIC grid search.
  - **Auto-ARIMA** (`pmdarima`) β€” same idea as ARIMA, but the order is found
    with pmdarima's stepwise search (the Python port of R's
    `auto.arima()`) instead of a brute-force grid.
  - **ARIMA-GARCH** (`statsmodels` + `arch`) β€” ARIMA models the conditional
    mean of returns, GARCH(1,1) models the conditional variance (volatility
    clustering) on top of it. Forecasted volatility is kept on the model
    instance (`last_volatility_forecast`) for anyone who wants to build
    confidence bands later.
  - **Moirai** (`uni2ts`) β€” Salesforce's pretrained time-series foundation model.
  - **TimesFM 2.5** (`timesfm`) β€” Google's pretrained time-series foundation model.
- **Top 5 technical indicators** (hand-implemented on pandas, no extra
  dependency): RSI, MACD, Bollinger Bands, SMA/EMA, Stochastic Oscillator.
  These are shown for chart analysis β€” they're separate from, and not mixed
  into, the 5 models' backtested accuracy.
- **Walk-forward backtesting** with a **separate** accuracy card per model
  (correct / incorrect / accuracy % / MAE / RMSE) β€” numbers are never
  averaged together across models β€” plus a per-candle log of every
  prediction vs. what actually happened, so you can verify exactly how many
  candles each model got right or wrong.
- **Live tab**: polls for the newest candle, predicts the next one, and once
  that candle closes, checks whether the prediction was right β€” with a
  running accuracy tally. `live_runner.py` does the same thing unattended
  from the command line, logging to CSV.

## Project layout

```
config.py              symbols, timeframes, model checkpoints
app.py                 Gradio dashboard (entry point for the Space)
live_runner.py         standalone CLI for unattended live logging
data/
  historical.py        yfinance fetch + resampling + 7-day-chunked 1m fetch
  live.py               polling loop helper
indicators/
  indicators.py         RSI, MACD, Bollinger Bands, SMA/EMA, Stochastic
models/
  base_model.py          shared interface all 5 models implement
  arima_model.py          ARIMA (statsmodels), cached order search
  auto_arima_model.py     Auto-ARIMA (pmdarima), cached stepwise search
  arima_garch_model.py    ARIMA-GARCH (statsmodels + arch), mean + volatility
  moirai_model.py         Moirai (uni2ts + GluonTS)
  timesfm_model.py        TimesFM 2.5 (timesfm[torch])
  registry.py             lazy-loading model factory
backtest/
  backtester.py           walk-forward loop + per-model accuracy summary
utils/
  helpers.py               small shared utilities
requirements.txt
```

## Running locally

```bash
python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt
python app.py
```

Open the local URL Gradio prints (usually `http://127.0.0.1:7860`).

## Deploying to Hugging Face Spaces

1. Create a new Space β†’ SDK: **Gradio** β†’ hardware: **2 vCPU / 16GB RAM**
   (the free CPU tier) is enough for all 5 models at their default (small)
   checkpoints.
2. Upload every file in this project, keeping the folder structure
   (`data/`, `models/`, etc.) intact β€” Spaces builds from the repo root.
3. The YAML block at the top of this README is what Spaces reads to
   configure the app (`sdk: gradio`, `app_file: app.py`). No changes needed
   unless you want a different title/emoji/colors.
4. Push. The Space installs `requirements.txt` and launches `app.py`
   automatically. First launch is normal Python-only (ARIMA works
   immediately); Moirai/TimesFM download their pretrained weights
   on-demand the first time you actually use them from the UI.

## Models β€” what to expect on CPU-only hardware

| Model | Package | Approx. size | Notes |
|---|---|---|---|
| ARIMA | `statsmodels` | tiny | Fastest by far. Order (p,d,q) is searched once per backtest run (brute-force AIC grid) and reused, not re-searched every candle. |
| Auto-ARIMA | `pmdarima` | tiny | Same speed idea as ARIMA β€” stepwise order search runs once and is reused. Stepwise search is usually quicker than ARIMA's brute-force grid, but each individual fit is a bit heavier than plain ARIMA. |
| ARIMA-GARCH | `statsmodels` + `arch` | tiny | Two fits per prediction (ARIMA for the mean, GARCH for the volatility), so a little slower than plain ARIMA β€” still fast next to the foundation models. |
| Moirai (`moirai-1.1-R-small`) | `uni2ts` | small (~14M params) | Zero-shot foundation model, no training needed. |
| TimesFM 2.5 (`timesfm-2.5-200m`) | `timesfm[torch]` | ~800MB download, ~4GB RAM | Zero-shot foundation model, no training needed. |

Both foundation models are **zero-shot** β€” they were pretrained elsewhere and
just run inference here, no training step in this project. They're slower
per-prediction than ARIMA on CPU, which matters most in the **Backtest** tab
(one model call per candle). Use the **Step** slider there to skip candles
(e.g. step=5 or 10) and keep Moirai/TimesFM backtests fast on 2 vCPUs.
Checkpoints are configurable in `config.py` if you later move to GPU hardware
and want the bigger `base`/`large` variants.

## How accuracy is measured

For each candle in a backtest (or each live prediction), the model forecasts
the next close; we compare **predicted direction** (up/down vs. the current
close) to what **actually** happened once that candle closes. That's one
verified candle: correct or incorrect. A model's accuracy % is
`correct / (correct + incorrect)` over the whole run β€” and each model's
numbers live in their own card/tab, never averaged with another model's.
MAE/RMSE (predicted price vs. actual price) are reported alongside as a
secondary, continuous-error view.

## Known limitations (please read before relying on this for anything real)

- **Yahoo/yfinance history limits** (enforced by Yahoo, not this project):
  1-minute candles β‰ˆ last 7–30 days only; other intraday intervals β‰ˆ last 60
  days; hourly β‰ˆ last 730 days; daily+ is full history. The app tells you if
  a request falls outside what's available rather than failing silently.
- **"Live" is polling, not push.** Free forex/crypto data has no public
  websocket firehose, so "live" here means re-fetching on a timer β€” fine for
  candle-close-level decisions, not for tick-by-tick/HFT use.
- **"All symbols"** means any symbol yfinance/Yahoo covers β€” there's no
  finite master list to ship, so the app takes any ticker you type in rather
  than pretending to enumerate everything.
- **Small foundation-model checkpoints** were chosen to fit 2 vCPU/16GB
  comfortably. Bigger checkpoints (`base`/`large`) may forecast better but
  need more RAM/CPU time β€” swap them in `config.py` if your hardware allows.
- This was built and syntax-checked without live internet access in the
  build environment, so package APIs were verified against each project's
  current documentation but not executed end-to-end here. Test on your own
  machine or Space before trusting it, and check each library's docs/repo if
  an API has moved since (`uni2ts` and `timesfm` are active research
  projects that occasionally make breaking changes; `pmdarima` and `arch`
  are more stable but worth a version check too).

## Disclaimer

This project is for education and research. It does not constitute
financial advice, and past backtested accuracy is not a promise of future
performance. Forex and crypto markets are volatile and you can lose money
trading them β€” always do your own research and consider consulting a
licensed financial advisor before trading real capital.