2025-09-12 18:33:32 +01:00

119 lines
4.5 KiB
Python

from fastapi import APIRouter, Depends, HTTPException, Query
from pathlib import Path
import pandas as pd
import logging
from typing import List, Dict, Any
import json
from quote_db import QuoteDatabase
from quote_service import QuoteService
from quote_contracts import (
FetchQuoteRequest, FetchQuoteResponse,
ListSymbolsRequest, ListSymbolsResponse,
ListDatesRequest, ListDatesResponse,
ListSessionRequest, ListSessionResponse,
IngestRequest, IngestResponse,
FetchBrokersResponse, FetchDataResponse,
BrokersSymbolsResponse, IngestAllRequest, IngestAllResponse,
# QuoteDataRecord
)
router = APIRouter()
def get_db():
db = QuoteDatabase("quotes.db")
try:
yield db
finally:
db.conn.close()
def get_service(db: QuoteDatabase = Depends(get_db)):
return QuoteService(db=db)
@router.post("/ingestall", response_model = IngestAllResponse)
def ingest_archives(request: IngestAllRequest, service: QuoteService = Depends(get_service)):
return service.ingest_archives_from_folder(request)
@router.post("/ingest", response_model=IngestResponse)
def ingest_quotes(request: IngestRequest, service: QuoteService = Depends(get_service)):
return service.ingest_archive(request)
@router.get("/data")
async def get_data(
broker_a: str = Query(...),
symbol_a: str = Query(...),
broker_b: str = Query(...),
symbol_b: str = Query(...),
service: QuoteService = Depends(get_service)
):
df_a, df_b, last_data_points, markable_records = service.get_data(broker_a, symbol_a, broker_b, symbol_b)
combined_data = pd.concat([df_a, df_b], ignore_index=True) if not df_a.empty or not df_b.empty else pd.DataFrame()
dataset_source = combined_data.to_dict(orient='records') if not combined_data.empty else []
records: List[Dict[str, Any]] = []
timestamps = set()
for record in dataset_source:
timestamp = record["timestamp"]
if timestamp not in timestamps:
records.append({
"askA": record["ask"] if record["broker"] == broker_a else None,
"bidA": record["bid"] if record["broker"] == broker_a else None,
"midlineA": record["midline"] if record["broker"] == broker_a else None,
"spreadA": record["spread"] if record["broker"] == broker_a else None,
"directionA": record["direction"] if record["broker"] == broker_a else None,
"askB": record["ask"] if record["broker"] == broker_b else None,
"bidB": record["bid"] if record["broker"] == broker_b else None,
"midlineB": record["midline"] if record["broker"] == broker_b else None,
"spreadB": record["spread"] if record["broker"] == broker_b else None,
"directionB": record["direction"] if record["broker"] == broker_b else None,
"timestamp": timestamp
})
timestamps.add(timestamp)
response_data = {
"records": records,
"brokerA": broker_a,
"symbolA": symbol_a,
"brokerB": broker_b,
"symbolB": symbol_b,
"lastDataPoints": last_data_points,
"markableRecords": markable_records
}
print(f"Response data size: {len(response_data['records'])} records, lastDataPoints: {len(last_data_points)}, markableRecords: {len(markable_records)}")
print(f"Response data sample: {json.dumps(response_data, default=str)[:500]}...")
return response_data
@router.get("/brokers", response_model=FetchBrokersResponse)
def get_all_brokers(service: QuoteService = Depends(get_service)):
return service.get_all_brokers()
@router.post("/symbols", response_model=ListSymbolsResponse)
def get_symbols(request: ListSymbolsRequest, service: QuoteService = Depends(get_service)):
return service.get_symbols(request)
@router.post("/dates", response_model=ListDatesResponse)
def get_dates(request: ListDatesRequest, service: QuoteService = Depends(get_service)):
return service.get_dates(request)
@router.post("/sessions", response_model=ListSessionResponse)
def get_sessions(request: ListSessionRequest, service: QuoteService = Depends(get_service)):
return service.get_sessions(request)
@router.post("/quotes", response_model=FetchQuoteResponse)
def get_quotes(request: FetchQuoteRequest, service: QuoteService = Depends(get_service)):
return service.get_quotes(request)
@router.get("/brokers&symbols", response_model=BrokersSymbolsResponse)
def get_brokers_and_symbols(service: QuoteService = Depends(get_service)):
return service.get_brokers_and_symbols()