You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

87 lines
2.9 KiB
Python

"""Price-related Oracle service methods."""
from __future__ import annotations
from libs.oracle_client.client import OracleClient
from libs.oracle_client.models import (
IntradayBar,
IntradayResponse,
PriceBar,
PriceDataResponse,
PriceQuote,
)
class PriceService:
def __init__(self, client: OracleClient) -> None:
self._client = client
async def get_daily_bars(
self,
ticker: str,
start: str | None = None,
end: str | None = None,
) -> PriceDataResponse:
params: dict[str, str] = {}
if start:
params["start_date"] = start
if end:
params["end_date"] = end
data = await self._client.get(f"/api/v1/price/data/{ticker}", params=params)
# Real Oracle: {"ticker": ..., "interval": "1d", "data": [...bars...], "metadata": {...}}
bars = [
PriceBar(
date=b["date"],
open=b["open"],
high=b["high"],
low=b["low"],
close=b["close"],
volume=int(b["volume"]),
)
for b in data.get("data", [])
]
return PriceDataResponse(ticker=data.get("ticker", ticker), bars=bars)
async def get_quote(self, ticker: str) -> PriceQuote:
data = await self._client.get(f"/api/v1/price/quote/{ticker}")
return PriceQuote.model_validate(data)
async def get_intraday(self, ticker: str) -> IntradayResponse:
data = await self._client.get(f"/api/v1/price/intraday/{ticker}")
bars = [IntradayBar.model_validate(b) for b in data.get("data", [])]
return IntradayResponse(ticker=data.get("ticker", ticker), bars=bars)
async def get_historical_intraday(
self,
ticker: str,
date: str,
interval: str = "5min",
) -> IntradayResponse:
"""Fetch historical intraday bars for a specific date via Alpaca endpoint.
Uses: GET /api/v1/alpaca/intraday/{ticker}?interval=5min&start_date=DATE&end_date=DATE
"""
params: dict[str, str] = {
"interval": interval,
"start_date": date,
"end_date": date,
}
data = await self._client.get(f"/api/v1/alpaca/intraday/{ticker}", params=params)
bars = [IntradayBar.model_validate(b) for b in data.get("data", [])]
return IntradayResponse(ticker=data.get("ticker", ticker), bars=bars)
async def get_today(self, ticker: str) -> PriceDataResponse:
data = await self._client.get(f"/api/v1/price/today/{ticker}")
bars = [
PriceBar(
date=b["date"],
open=b["open"],
high=b["high"],
low=b["low"],
close=b["close"],
volume=int(b["volume"]),
)
for b in data.get("data", [])
]
return PriceDataResponse(ticker=data.get("ticker", ticker), bars=bars)