arbret/backend/price_fetcher.py

44 lines
1.3 KiB
Python
Raw Normal View History

"""Bitfinex price fetcher for BTC/EUR pair."""
from datetime import UTC, datetime
import httpx
BITFINEX_TICKER_URL = "https://api-pub.bitfinex.com/v2/ticker/tBTCEUR"
LAST_PRICE_INDEX = 6
REQUEST_TIMEOUT_SECONDS = 30.0
# Constants for price history records
SOURCE_BITFINEX = "bitfinex"
PAIR_BTC_EUR = "BTC/EUR"
async def fetch_btc_eur_price() -> tuple[float, datetime]:
"""
Fetch the current BTC/EUR price from Bitfinex.
Returns:
Tuple of (price, timestamp) where timestamp is the current UTC time.
Raises:
httpx.HTTPStatusError: If the API returns a non-2xx status code.
httpx.RequestError: If a network error occurs (including timeout).
ValueError: If the response format is unexpected.
"""
async with httpx.AsyncClient(timeout=REQUEST_TIMEOUT_SECONDS) as client:
response = await client.get(BITFINEX_TICKER_URL)
response.raise_for_status()
data = response.json()
# Bitfinex ticker response is an array:
# [BID, BID_SIZE, ASK, ASK_SIZE, DAILY_CHANGE, DAILY_CHANGE_RELATIVE,
# LAST_PRICE, VOLUME, HIGH, LOW]
if not isinstance(data, list) or len(data) <= LAST_PRICE_INDEX:
raise ValueError(f"Unexpected response format: {data}")
price = float(data[LAST_PRICE_INDEX])
timestamp = datetime.now(UTC)
return price, timestamp