Download engine/bridge.py from s-ttp/crucible: direct link, hf CLI and curl.
- Browser
- Download file 7.29 kB
-
https://huggingface.co/spaces/s-ttp/crucible/resolve/main/engine/bridge.py
- Command line
-
hf download hf://spaces/s-ttp/crucible/engine/bridge.py
-
curl -L -o bridge.py https://huggingface.co/spaces/s-ttp/crucible/resolve/main/engine/bridge.py
7.29 kB
| """The adjusted↔GAAP earnings bridge, measured like for like. | |
| An adjusted EPS forecast becomes GAAP net income only through a bridge: how much larger the adjusted | |
| figure is than GAAP diluted EPS for the same period and the same share basis. The earlier bridge was | |
| one trailing point that divided adjusted EPS × *today's* share count by GAAP net income, mixing a | |
| per-share series computed on historical weighted shares with the current count, and it was carried | |
| forward as if it could never change. | |
| Here the bridge is a series of like-for-like observations: | |
| ratio(period) = Σ adjusted EPS over the period ÷ GAAP diluted EPS for the same period | |
| using fiscal years (four provider quarters summed against the filed annual diluted EPS) and the | |
| trailing twelve months. Both sides are per diluted share for the same period, so share-count | |
| changes cancel. The bridge records the median, range, latest value and trend, and flags a probable | |
| change in the adjustment methodology when the latest observation departs materially from its own | |
| history. In that case the older observations are not carried forward: only the latest is used, with | |
| a wider uncertainty band. | |
| """ | |
| from __future__ import annotations | |
| import datetime as _dt | |
| import statistics | |
| import definitions as D | |
| RATIO_BOUNDS = (0.5, 3.0) # outside this the two EPS series are not describing the same earnings | |
| CHANGE_THRESHOLD = 0.20 # latest vs its own history: a methodology change is likely beyond this | |
| MIN_UNCERTAINTY = 0.05 # never claim the bridge is known to better than ±5% | |
| def _d(x): | |
| try: | |
| return _dt.date.fromisoformat(str(x)[:10]) | |
| except (TypeError, ValueError): | |
| return None | |
| def _f(v): | |
| try: | |
| x = float(v) | |
| return None if x != x else x | |
| except (TypeError, ValueError): | |
| return None | |
| def observations(quarterly_adjusted, gaap_eps_rows, ttm_adjusted=None, ttm_gaap=None, ttm_end=None): | |
| """Like-for-like (adjusted, GAAP, ratio) observations, oldest first. | |
| ``quarterly_adjusted``: [{fiscalDateEnding, reportedEPS}] (provider quarters). | |
| ``gaap_eps_rows``: [{start, end, value, days}] SEC diluted EPS rows (annual rows are used). | |
| """ | |
| q = sorted(((_d(x.get("fiscalDateEnding")), _f(x.get("reportedEPS"))) for x in quarterly_adjusted or []), | |
| key=lambda t: (t[0] or _dt.date.min)) | |
| q = [(e, v) for e, v in q if e and v is not None] | |
| obs = [] | |
| for r in gaap_eps_rows or []: | |
| if not (350 <= int(r.get("days") or 0) <= 380): | |
| continue | |
| s, e, g = _d(r.get("start")), _d(r.get("end")), _f(r.get("value")) | |
| if not (s and e and g) or g <= 0: | |
| continue | |
| inside = [v for (qe, v) in q if s < qe <= e + _dt.timedelta(days=10)] | |
| if len(inside) != 4: | |
| continue | |
| adj = sum(inside) | |
| ratio = adj / g | |
| if RATIO_BOUNDS[0] <= ratio <= RATIO_BOUNDS[1]: | |
| obs.append({"period": f"FY ending {e.isoformat()}", "start": s.isoformat(), "end": e.isoformat(), | |
| "adjusted_eps": round(adj, 4), "gaap_eps": g, "ratio": ratio, "kind": "fiscal year"}) | |
| ta, tg = _f(ttm_adjusted), _f(ttm_gaap) | |
| if ta and tg and tg > 0 and RATIO_BOUNDS[0] <= ta / tg <= RATIO_BOUNDS[1]: | |
| te = str(ttm_end or "")[:10] | |
| if not any(o["end"] == te for o in obs): | |
| obs.append({"period": f"TTM ending {te}", "start": None, "end": te, "adjusted_eps": ta, "gaap_eps": tg, | |
| "ratio": ta / tg, "kind": "trailing twelve months"}) | |
| obs.sort(key=lambda o: o["end"]) | |
| return obs | |
| def build(quarterly_adjusted, gaap_eps_rows, ttm_adjusted=None, ttm_gaap=None, ttm_end=None, | |
| adjusted_definition=D.PROVIDER_REPORTED_EPS, adjusted_provider="Alpha Vantage"): | |
| """AdjustmentBridge dict, or an unavailable record with the reason.""" | |
| obs = observations(quarterly_adjusted, gaap_eps_rows, ttm_adjusted, ttm_gaap, ttm_end) | |
| base = {"definition_id": adjusted_definition, "adjusted_provider": adjusted_provider, | |
| "gaap_definition": "GAAP diluted EPS (SEC XBRL)", "numerator": "adjusted EPS (provider quarters summed)", | |
| "denominator": "GAAP diluted EPS, same period", "share_basis": "per diluted share, same period (like for like)", | |
| "historical_ratios": [{k: (round(v, 5) if isinstance(v, float) else v) for k, v in o.items()} for o in obs]} | |
| if not obs: | |
| return dict(base, available=False, selected_ratio=None, selected_method="unavailable", | |
| reason="no period with positive GAAP EPS and a matching adjusted EPS series", | |
| uncertainty=None, methodology_change=False) | |
| ratios = [o["ratio"] for o in obs] | |
| latest = ratios[-1] | |
| prior = ratios[:-1][-4:] | |
| change = False | |
| if len(prior) >= 2: | |
| med_prior = statistics.median(prior) | |
| change = abs(latest / med_prior - 1.0) > CHANGE_THRESHOLD | |
| if change: | |
| sel, method = latest, (f"latest observation only: it departs {abs(latest / statistics.median(prior) - 1):.0%} from the " | |
| "prior median: a structural break (the adjustment definition, or the size of the items it excludes, " | |
| "changed), so older ratios are not carried forward") | |
| lo, hi = latest * (1 - max(0.10, MIN_UNCERTAINTY)), latest * (1 + max(0.10, MIN_UNCERTAINTY)) | |
| valid_from = obs[-1]["start"] or obs[-1]["end"] | |
| elif len(ratios) >= 3: | |
| recent = ratios[-3:] | |
| sel, method = statistics.median(recent), "median of the last three like-for-like observations" | |
| lo, hi = min(recent), max(recent) | |
| valid_from = obs[-3]["start"] or obs[-3]["end"] | |
| else: | |
| sel = latest | |
| method = "latest observation (fewer than three like-for-like observations)" | |
| lo, hi = min(ratios), max(ratios) | |
| valid_from = obs[0]["start"] or obs[0]["end"] | |
| lo, hi = min(lo, sel * (1 - MIN_UNCERTAINTY)), max(hi, sel * (1 + MIN_UNCERTAINTY)) | |
| trend = "flat" | |
| if len(ratios) >= 3: | |
| d = ratios[-1] - ratios[-3] | |
| trend = "rising" if d > 0.03 else "falling" if d < -0.03 else "flat" | |
| return dict(base, available=True, selected_ratio=sel, selected_method=method, | |
| median=statistics.median(ratios), range=[min(ratios), max(ratios)], latest=latest, trend=trend, | |
| uncertainty={"low": lo, "high": hi}, methodology_change=change, | |
| valid_from=valid_from, valid_to=obs[-1]["end"], n_observations=len(obs), | |
| definition_version=(f"{adjusted_definition}@{valid_from}" if change else adjusted_definition)) | |
| def latest_diluted_shares(series): | |
| """(value, source) — the most recent quarterly weighted-average diluted share count from the filings, | |
| else the trailing annual one, else None.""" | |
| rows = sorted(series or [], key=lambda r: (r.get("end") or "", -(r.get("days") or 0))) | |
| q = [r for r in rows if 80 <= int(r.get("days") or 0) <= 100] | |
| if q: | |
| return q[-1]["value"], f"SEC weighted-average diluted shares, quarter ending {q[-1]['end']}" | |
| a = [r for r in rows if 350 <= int(r.get("days") or 0) <= 380] | |
| if a: | |
| return a[-1]["value"], f"SEC weighted-average diluted shares, year ending {a[-1]['end']}" | |
| return None, None | |