Big refactoring
This commit is contained in:
@@ -18,10 +18,17 @@ from app.dependencies import get_db, require_access
|
||||
from app.exceptions import ProviderError
|
||||
from app.models.user import User
|
||||
from app.providers.alpaca import AlpacaOHLCVProvider
|
||||
from app.providers.fmp import FMPFundamentalProvider
|
||||
from app.providers.fundamentals_chain import build_fundamental_provider_chain
|
||||
from app.providers.openai_sentiment import OpenAISentimentProvider
|
||||
from app.services.rr_scanner_service import scan_ticker
|
||||
from app.schemas.common import APIEnvelope
|
||||
from app.services import fundamental_service, ingestion_service, sentiment_service
|
||||
from app.services import (
|
||||
fundamental_service,
|
||||
ingestion_service,
|
||||
scoring_service,
|
||||
sentiment_service,
|
||||
sr_service,
|
||||
)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -99,10 +106,10 @@ async def fetch_symbol(
|
||||
}
|
||||
|
||||
# --- Fundamentals ---
|
||||
if settings.fmp_api_key:
|
||||
if settings.fmp_api_key or settings.finnhub_api_key or settings.alpha_vantage_api_key:
|
||||
try:
|
||||
fmp_provider = FMPFundamentalProvider(settings.fmp_api_key)
|
||||
fdata = await fmp_provider.fetch_fundamentals(symbol_upper)
|
||||
fundamentals_provider = build_fundamental_provider_chain()
|
||||
fdata = await fundamentals_provider.fetch_fundamentals(symbol_upper)
|
||||
await fundamental_service.store_fundamental(
|
||||
db,
|
||||
symbol=symbol_upper,
|
||||
@@ -119,9 +126,50 @@ async def fetch_symbol(
|
||||
else:
|
||||
sources["fundamentals"] = {
|
||||
"status": "skipped",
|
||||
"message": "FMP API key not configured",
|
||||
"message": "No fundamentals provider key configured",
|
||||
}
|
||||
|
||||
# --- Derived pipeline: S/R levels ---
|
||||
try:
|
||||
levels = await sr_service.recalculate_sr_levels(db, symbol_upper)
|
||||
sources["sr_levels"] = {
|
||||
"status": "ok",
|
||||
"count": len(levels),
|
||||
"message": None,
|
||||
}
|
||||
except Exception as exc:
|
||||
logger.error("S/R recalc failed for %s: %s", symbol_upper, exc)
|
||||
sources["sr_levels"] = {"status": "error", "message": str(exc)}
|
||||
|
||||
# --- Derived pipeline: scores ---
|
||||
try:
|
||||
score_payload = await scoring_service.get_score(db, symbol_upper)
|
||||
sources["scores"] = {
|
||||
"status": "ok",
|
||||
"composite_score": score_payload.get("composite_score"),
|
||||
"missing_dimensions": score_payload.get("missing_dimensions", []),
|
||||
"message": None,
|
||||
}
|
||||
except Exception as exc:
|
||||
logger.error("Score recompute failed for %s: %s", symbol_upper, exc)
|
||||
sources["scores"] = {"status": "error", "message": str(exc)}
|
||||
|
||||
# --- Derived pipeline: scanner ---
|
||||
try:
|
||||
setups = await scan_ticker(
|
||||
db,
|
||||
symbol_upper,
|
||||
rr_threshold=settings.default_rr_threshold,
|
||||
)
|
||||
sources["scanner"] = {
|
||||
"status": "ok",
|
||||
"setups_found": len(setups),
|
||||
"message": None,
|
||||
}
|
||||
except Exception as exc:
|
||||
logger.error("Scanner run failed for %s: %s", symbol_upper, exc)
|
||||
sources["scanner"] = {"status": "error", "message": str(exc)}
|
||||
|
||||
# Always return success — per-source breakdown tells the full story
|
||||
return APIEnvelope(
|
||||
status="success",
|
||||
|
||||
Reference in New Issue
Block a user