"""合成依赖式研究链;无真实行情、研报、AI调用。""" import json from decimal import Decimal as D def run(forecasts): request = {"symbol": "AAA", "as_of": "2026-10-26", "year": 2027, "currency": "CNY"} price = {"value": D("24"), "date": request["as_of"], "currency": "CNY", "source": "price-1"} steps = {"price": "success"} match = [r for r in forecasts if r["year"] == request["year"] and r["date"] <= request["as_of"]] if not match: steps.update(eps="blocked_missing_year", pe="blocked_dependency", peers="blocked_dependency") return {"status": "partial", "steps": steps, "pe": None} report = max(match, key=lambda r: r["date"]) assert report["currency"] == price["currency"] if report["eps"] <= 0: steps.update(eps="success", pe="blocked_nonpositive_eps", peers="blocked_dependency") return {"status": "partial", "steps": steps, "pe": None} steps.update(eps="success", pe="success", peers="success") pe = price["value"] / report["eps"] peers = [D("16"), D("20"), D("24")] median = sorted(peers)[1] return {"status": "complete", "steps": steps, "pe": str(pe), "peer_median": str(median), "relative": str(pe/median-1), "sources": [price["source"], report["source"]]} reports = [{"year": 2027, "date": "2026-10-20", "currency": "CNY", "eps": D("1.2"), "source": "report-1"}] complete = run(reports) missing = run([{**reports[0], "year": 2028}]) negative = run([{**reports[0], "eps": D("-1")}]) assert complete["pe"] == "2E+1" and complete["relative"] == "0" assert missing["pe"] is None and missing["status"] == "partial" assert missing["steps"]["pe"] == "blocked_dependency" assert negative["steps"]["pe"] == "blocked_nonpositive_eps" assert run(reports) == complete print(json.dumps({"complete": complete, "missing_year": missing, "negative_eps": negative}, sort_keys=True))