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.
42 lines
1.3 KiB
Python
42 lines
1.3 KiB
Python
"""Financial feature calculations from Oracle financial data."""
|
|
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from libs.oracle_client.models import FinancialDataResponse
|
|
|
|
|
|
def compute_financial_features(response: FinancialDataResponse) -> dict[str, Any]:
|
|
"""Compute financial features from quarterly period data.
|
|
|
|
Returns dict with latest-quarter metrics and QoQ growth rates.
|
|
Returns empty dict if no period data is available.
|
|
"""
|
|
periods = sorted(response.periods, key=lambda p: p.period_end, reverse=True)
|
|
if not periods:
|
|
return {}
|
|
|
|
latest = periods[0]
|
|
features: dict[str, Any] = {
|
|
"latest_eps": latest.eps,
|
|
"latest_gross_margin": latest.gross_margin,
|
|
"latest_operating_margin": latest.operating_margin,
|
|
"eps_growth_qoq": None,
|
|
"revenue_growth_qoq": None,
|
|
}
|
|
|
|
if len(periods) >= 2:
|
|
prior = periods[1]
|
|
if latest.eps is not None and prior.eps is not None and prior.eps != 0:
|
|
features["eps_growth_qoq"] = (latest.eps - prior.eps) / abs(prior.eps)
|
|
if (
|
|
latest.revenue is not None
|
|
and prior.revenue is not None
|
|
and prior.revenue != 0
|
|
):
|
|
features["revenue_growth_qoq"] = (
|
|
latest.revenue - prior.revenue
|
|
) / prior.revenue
|
|
|
|
return features
|