|
37 | 37 | _CCXT_FETCH_BUDGET_S = float(os.getenv("CCXT_FETCH_BUDGET_S", "60")) |
38 | 38 |
|
39 | 39 |
|
| 40 | +def _first_proxy_env(*names: str) -> str: |
| 41 | + for name in names: |
| 42 | + value = os.getenv(name, "").strip() |
| 43 | + if value: |
| 44 | + return value |
| 45 | + return "" |
| 46 | + |
| 47 | + |
| 48 | +def _ccxt_proxy_config() -> dict[str, str]: |
| 49 | + """Build CCXT proxy settings from conventional proxy environment variables.""" |
| 50 | + all_proxy = _first_proxy_env("ALL_PROXY", "all_proxy") |
| 51 | + http_proxy = _first_proxy_env("HTTP_PROXY", "http_proxy") or all_proxy |
| 52 | + https_proxy = _first_proxy_env("HTTPS_PROXY", "https_proxy") or all_proxy or http_proxy |
| 53 | + |
| 54 | + proxies: dict[str, str] = {} |
| 55 | + if http_proxy: |
| 56 | + proxies["http"] = http_proxy |
| 57 | + if https_proxy: |
| 58 | + proxies["https"] = https_proxy |
| 59 | + return proxies |
| 60 | + |
| 61 | + |
40 | 62 | @register |
41 | 63 | class DataLoader: |
42 | 64 | """CCXT-backed crypto OHLCV loader (100+ exchanges).""" |
@@ -64,7 +86,12 @@ def _get_exchange(self): |
64 | 86 | if exchange_cls is None: |
65 | 87 | logger.warning("Unknown CCXT exchange %s, falling back to binance", exchange_id) |
66 | 88 | exchange_cls = ccxt.binance |
67 | | - return exchange_cls({"enableRateLimit": True, "timeout": _CCXT_TIMEOUT_MS}) |
| 89 | + |
| 90 | + config = {"enableRateLimit": True, "timeout": _CCXT_TIMEOUT_MS} |
| 91 | + proxies = _ccxt_proxy_config() |
| 92 | + if proxies: |
| 93 | + config["proxies"] = proxies |
| 94 | + return exchange_cls(config) |
68 | 95 |
|
69 | 96 | def fetch( |
70 | 97 | self, |
|
0 commit comments