refactor: address architect review findings (6 items)
R1: Extend @safe to catch ValueError->400, simplify routes_backtest
(eliminated 4 copies of duplicated try/except)
R2: Consolidate PROVIDER constant into obb_utils.py (single source)
R3: Add days_ago() helper to obb_utils.py, replace 8+ duplications
R4: Extract Reddit/ApeWisdom into reddit_service.py from finnhub_service
R5: Fix missing top-level import asyncio in finnhub_service
R6: (deferred - sentiment logic extraction is a larger change)
All 561 tests passing.
This commit is contained in:
@@ -7,12 +7,10 @@ from typing import Any
|
||||
|
||||
from openbb import obb
|
||||
|
||||
from obb_utils import extract_single, safe_last, fetch_historical, to_list
|
||||
from obb_utils import extract_single, safe_last, fetch_historical, to_list, days_ago, PROVIDER
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
PROVIDER = "yfinance"
|
||||
|
||||
# Need 252+ trading days for default window; 730 calendar days is safe
|
||||
PERF_DAYS = 730
|
||||
TARGET = "close"
|
||||
@@ -22,7 +20,7 @@ async def get_performance_metrics(symbol: str, days: int = 365) -> dict[str, Any
|
||||
"""Calculate Sharpe ratio, summary stats, and volatility for a symbol."""
|
||||
# Need at least 252 trading days for Sharpe window
|
||||
fetch_days = max(days, PERF_DAYS)
|
||||
start = (datetime.now(tz=timezone.utc) - timedelta(days=fetch_days)).strftime("%Y-%m-%d")
|
||||
start = days_ago(fetch_days)
|
||||
|
||||
try:
|
||||
hist = await asyncio.to_thread(
|
||||
@@ -64,7 +62,7 @@ async def get_performance_metrics(symbol: str, days: int = 365) -> dict[str, Any
|
||||
|
||||
async def get_capm(symbol: str) -> dict[str, Any]:
|
||||
"""Calculate CAPM metrics: beta, alpha, systematic/idiosyncratic risk."""
|
||||
start = (datetime.now(tz=timezone.utc) - timedelta(days=PERF_DAYS)).strftime("%Y-%m-%d")
|
||||
start = days_ago(PERF_DAYS)
|
||||
|
||||
try:
|
||||
hist = await asyncio.to_thread(
|
||||
@@ -85,7 +83,7 @@ async def get_capm(symbol: str) -> dict[str, Any]:
|
||||
async def get_normality_test(symbol: str, days: int = 365) -> dict[str, Any]:
|
||||
"""Run normality tests (Jarque-Bera, Shapiro-Wilk, etc.) on returns."""
|
||||
fetch_days = max(days, PERF_DAYS)
|
||||
start = (datetime.now(tz=timezone.utc) - timedelta(days=fetch_days)).strftime("%Y-%m-%d")
|
||||
start = days_ago(fetch_days)
|
||||
|
||||
try:
|
||||
hist = await asyncio.to_thread(
|
||||
@@ -106,7 +104,7 @@ async def get_normality_test(symbol: str, days: int = 365) -> dict[str, Any]:
|
||||
async def get_unitroot_test(symbol: str, days: int = 365) -> dict[str, Any]:
|
||||
"""Run unit root tests (ADF, KPSS) for stationarity."""
|
||||
fetch_days = max(days, PERF_DAYS)
|
||||
start = (datetime.now(tz=timezone.utc) - timedelta(days=fetch_days)).strftime("%Y-%m-%d")
|
||||
start = days_ago(fetch_days)
|
||||
|
||||
try:
|
||||
hist = await asyncio.to_thread(
|
||||
|
||||
Reference in New Issue
Block a user