feat: add portfolio optimization and congress tracking (TDD)
Portfolio optimization (3 endpoints): - POST /portfolio/optimize - HRP optimal weights via scipy clustering - POST /portfolio/correlation - pairwise correlation matrix - POST /portfolio/risk-parity - inverse-volatility risk parity weights Congress tracking (2 endpoints): - GET /regulators/congress/trades - congress member stock trades - GET /regulators/congress/bills?query= - search congress bills Implementation: - portfolio_service.py: HRP with scipy fallback to inverse-vol - congress_service.py: multi-provider fallback pattern - 51 new tests (14 portfolio unit, 20 portfolio route, 12 congress unit, 7 congress route) - All 312 tests passing
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
"""Routes for regulatory data (CFTC, SEC)."""
|
||||
"""Routes for regulatory data (CFTC, SEC, Congress)."""
|
||||
|
||||
from fastapi import APIRouter, Path, Query
|
||||
|
||||
from models import ApiResponse
|
||||
from route_utils import safe, validate_symbol
|
||||
import regulators_service
|
||||
import congress_service
|
||||
|
||||
router = APIRouter(prefix="/api/v1/regulators")
|
||||
|
||||
@@ -49,3 +50,22 @@ async def sec_cik_map(symbol: str = Path(..., min_length=1, max_length=20)):
|
||||
symbol = validate_symbol(symbol)
|
||||
data = await regulators_service.get_cik_map(symbol)
|
||||
return ApiResponse(data=data)
|
||||
|
||||
|
||||
# --- Congress Trading ---
|
||||
|
||||
|
||||
@router.get("/congress/trades", response_model=ApiResponse)
|
||||
@safe
|
||||
async def congress_trades():
|
||||
"""Recent US congress member stock trades."""
|
||||
data = await congress_service.get_congress_trades()
|
||||
return ApiResponse(data=data)
|
||||
|
||||
|
||||
@router.get("/congress/bills", response_model=ApiResponse)
|
||||
@safe
|
||||
async def congress_bills(query: str = Query(..., min_length=1, max_length=200)):
|
||||
"""Search US congress bills by keyword."""
|
||||
data = await congress_service.search_congress_bills(query)
|
||||
return ApiResponse(data=data)
|
||||
|
||||
Reference in New Issue
Block a user