File size: 4,373 Bytes
a720b3d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Central configuration for the Forex & Crypto Prediction project.
Edit this file to add symbols, change default model checkpoints, etc.
Nothing here needs internet access to import.
"""
import os

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DATA_CACHE_DIR = os.path.join(BASE_DIR, "data_cache")
OUTPUT_DIR = os.path.join(BASE_DIR, "outputs")

os.makedirs(DATA_CACHE_DIR, exist_ok=True)
os.makedirs(OUTPUT_DIR, exist_ok=True)

# ---------------------------------------------------------------------------
# Symbols (yfinance ticker format)
# ---------------------------------------------------------------------------
# Forex pairs use the "=X" suffix, crypto pairs use "-USD".
# NOTE on "all symbols": yfinance/Yahoo Finance covers a huge number of forex
# and crypto tickers, so there is no fixed master list to hardcode. The app's
# Symbol dropdown ships with the popular ones below AND accepts any custom
# yfinance-valid ticker typed in directly (allow_custom_value=True) — so you
# are not limited to this list, this is just a convenient starting set.
DEFAULT_FOREX_SYMBOLS = [
    "EURUSD=X", "GBPUSD=X", "USDJPY=X", "USDCHF=X", "AUDUSD=X",
    "USDCAD=X", "NZDUSD=X", "EURJPY=X", "EURGBP=X", "GBPJPY=X",
]

DEFAULT_CRYPTO_SYMBOLS = [
    "BTC-USD", "ETH-USD", "BNB-USD", "XRP-USD", "SOL-USD",
    "ADA-USD", "DOGE-USD", "DOT-USD", "LTC-USD", "MATIC-USD",
]

ALL_DEFAULT_SYMBOLS = DEFAULT_FOREX_SYMBOLS + DEFAULT_CRYPTO_SYMBOLS

# ---------------------------------------------------------------------------
# Timeframes
# ---------------------------------------------------------------------------
# Yahoo Finance only serves a fixed set of native intraday intervals, each
# with its own history-depth limit (enforced by Yahoo, not by us):
#   1m            -> last 7 days only
#   2m/5m/15m/30m/90m -> last 60 days
#   60m (1h)      -> last 730 days
#   1d/1wk/1mo    -> full history
YF_NATIVE_INTERVALS = {
    "1m":  {"max_days": 7},
    "2m":  {"max_days": 60},
    "5m":  {"max_days": 60},
    "15m": {"max_days": 60},
    "30m": {"max_days": 60},
    "60m": {"max_days": 730},
    "90m": {"max_days": 60},
    "1d":  {"max_days": None},
    "1wk": {"max_days": None},
    "1mo": {"max_days": None},
}

# Timeframes offered in the app UI. Ones that aren't native Yahoo intervals
# (e.g. "10m") are built by resampling a smaller native interval, so you can
# ask for basically any custom candle size, not just what Yahoo natively has.
#
# `rule: None` means this timeframe IS a native Yahoo interval already (just
# under a friendlier display name) -- return it as-is, no resampling.
# `rule: "<pandas rule>"` means genuine upsampling from a smaller native
# interval is needed.
#
# "1h" -> source "60m" is the one case where the display name and yfinance's
# native interval name differ ("1h" vs "60m") even though they're the same
# candle size. That mismatch used to make get_historical()'s
# `source_interval != timeframe` check misfire and re-resample already-hourly
# candles through rule="1h" -- a harmless-looking no-op when Yahoo's 60m
# candles happen to fall on clean UTC hour boundaries, but not otherwise: it
# silently re-labels each candle's timestamp to the bucket start (observed
# shifting real candle times by up to 59 minutes in testing) and, for
# irregularly-spaced candles (weekend gaps, DST), can merge two distinct
# candles into one bucket or drop one to a dropna(how="any"). Native
# passthrough (`rule: None`) sidesteps all of that.
CUSTOM_TIMEFRAMES = {
    "1m":  {"source": "1m",  "rule": None},
    "5m":  {"source": "5m",  "rule": None},
    "10m": {"source": "5m",  "rule": "10min"},
    "15m": {"source": "15m", "rule": None},
    "30m": {"source": "30m", "rule": None},
    "1h":  {"source": "60m", "rule": None},
    "4h":  {"source": "60m", "rule": "4h"},
    "1d":  {"source": "1d",  "rule": None},
}

# ---------------------------------------------------------------------------
# Models
# ---------------------------------------------------------------------------
MODEL_NAMES = ["ARIMA", "Auto-ARIMA", "ARIMA-GARCH", "Moirai", "TimesFM"]

# Small/CPU-friendly checkpoints, picked to fit comfortably in 2 vCPU / 16GB
# RAM. Change these if you deploy on bigger (e.g. GPU) hardware.
MOIRAI_CHECKPOINT = "Salesforce/moirai-1.1-R-small"
TIMESFM_CHECKPOINT = "google/timesfm-2.5-200m-pytorch"

RANDOM_SEED = 42