205 lines
8.0 KiB
Python
205 lines
8.0 KiB
Python
#!/usr/bin/env python3
|
|
"""Reusable historical event backtest entrypoint built on strict workflow."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
import sys
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
if str(ROOT) not in sys.path:
|
|
sys.path.insert(0, str(ROOT))
|
|
|
|
import mcp_server
|
|
|
|
|
|
SUPPORTED_DOMAINS = {
|
|
"career": {
|
|
"route": "career",
|
|
"question": "请严格回测这条事业事件是否成立,并判断是职业状态、角色变化、升迁窗口还是项目兑现。",
|
|
},
|
|
"wealth": {
|
|
"route": "finance",
|
|
"question": "请严格回测这条财富事件是否成立,并判断更接近收入增长、到账、套现还是公众财富状态。",
|
|
},
|
|
"finance": {
|
|
"route": "finance",
|
|
"question": "请严格回测这条财富事件是否成立,并判断更接近收入增长、到账、套现还是公众财富状态。",
|
|
},
|
|
"marriage": {
|
|
"route": "relationship",
|
|
"question": "请严格回测这条婚恋事件是否成立,并判断是否达到正式关系或婚姻层。",
|
|
},
|
|
"relationship": {
|
|
"route": "relationship",
|
|
"question": "请严格回测这条婚恋事件是否成立,并判断是否达到正式关系或婚姻层。",
|
|
},
|
|
}
|
|
|
|
|
|
def _route_for_domain(domain: str) -> dict[str, str] | None:
|
|
return SUPPORTED_DOMAINS.get(str(domain).strip().lower())
|
|
|
|
|
|
def _load_payload(path: str) -> dict[str, Any]:
|
|
with open(path, "r", encoding="utf-8") as handle:
|
|
return json.load(handle)
|
|
|
|
|
|
def _event_result_class(
|
|
verdict: str | None,
|
|
blocked: bool,
|
|
expected_label: str | None,
|
|
actual_label: str | None,
|
|
) -> tuple[str, dict[str, Any]]:
|
|
if blocked:
|
|
return "blocked", {"reason": "strict_workflow_blocked"}
|
|
if verdict == "high_probability_window" and actual_label and (
|
|
not expected_label or expected_label == actual_label
|
|
):
|
|
return "strong_hit", {"reason": "supported_route_and_label"}
|
|
if verdict in {"high_probability_window", "moderate_probability_window"}:
|
|
if expected_label and actual_label and expected_label != actual_label:
|
|
return "weak_hit", {"reason": "label_mismatch_under_supported_route"}
|
|
return "weak_hit", {"reason": "supported_route_without_exact_label"}
|
|
if verdict == "weak_window_needs_confirmation":
|
|
return "weak_hit", {"reason": "weak_window_needs_confirmation"}
|
|
return "miss", {"reason": verdict or "insufficient_evidence"}
|
|
|
|
|
|
def _official_snapshot_summary(strict: dict[str, Any]) -> dict[str, Any]:
|
|
present = strict.get("present_evidence") or {}
|
|
official = present.get("vedastro_official_snapshot")
|
|
if not isinstance(official, dict):
|
|
return {"level": "missing", "status": "missing", "source": None}
|
|
return {
|
|
"level": official.get("level") or "missing",
|
|
"status": official.get("status"),
|
|
"source": official.get("source"),
|
|
}
|
|
|
|
|
|
def _source_priority_mode(strict: dict[str, Any]) -> str | None:
|
|
present = strict.get("present_evidence") or {}
|
|
source_priority = present.get("source_priority")
|
|
if not isinstance(source_priority, dict):
|
|
return None
|
|
return source_priority.get("mode")
|
|
|
|
|
|
def _run_supported_event(subject: dict[str, Any], event: dict[str, Any]) -> dict[str, Any]:
|
|
route_info = _route_for_domain(event.get("domain", ""))
|
|
if route_info is None:
|
|
return {
|
|
"id": event.get("id"),
|
|
"date": event.get("date"),
|
|
"domain": event.get("domain"),
|
|
"route": None,
|
|
"expected_label": event.get("expected_label"),
|
|
"actual_label": None,
|
|
"matched_expected_label": False,
|
|
"result_class": "unsupported_domain",
|
|
"boundary": {"reason": "route_not_yet_implemented_for_event_backtest"},
|
|
"official_snapshot": {"level": "missing", "status": "missing", "source": None},
|
|
"evidence": {"source_priority_mode": None, "confidence_cap": "unsupported"},
|
|
}
|
|
|
|
result = mcp_server.strict_workflow(
|
|
question=route_info["question"],
|
|
year=int(subject["year"]),
|
|
month=int(subject["month"]),
|
|
day=int(subject["day"]),
|
|
hour=int(subject["hour"]),
|
|
minute=int(subject["minute"]),
|
|
lat=float(subject["lat"]),
|
|
lon=float(subject["lon"]),
|
|
tz=float(subject["tz"]),
|
|
age=int(subject.get("age", 0)),
|
|
transit_date=str(event["date"]),
|
|
node_mode=str(subject.get("node_mode", "mean")),
|
|
)
|
|
strict = result.get("strict_workflow") if isinstance(result, dict) else {}
|
|
if not isinstance(strict, dict):
|
|
strict = {}
|
|
|
|
judgement = strict.get("event_judgement") if isinstance(strict.get("event_judgement"), dict) else {}
|
|
actual_label = judgement.get("dominant_label")
|
|
expected_label = event.get("expected_label")
|
|
verdict = judgement.get("verdict")
|
|
blocked = bool(strict.get("blocked"))
|
|
result_class, boundary = _event_result_class(verdict, blocked, expected_label, actual_label)
|
|
|
|
return {
|
|
"id": event.get("id"),
|
|
"date": event.get("date"),
|
|
"domain": event.get("domain"),
|
|
"route": route_info["route"],
|
|
"expected_label": expected_label,
|
|
"actual_label": actual_label,
|
|
"matched_expected_label": bool(expected_label and expected_label == actual_label),
|
|
"result_class": result_class,
|
|
"boundary": boundary,
|
|
"official_snapshot": _official_snapshot_summary(strict),
|
|
"evidence": {
|
|
"verdict": verdict,
|
|
"score": judgement.get("score"),
|
|
"confidence_cap": strict.get("confidence_cap"),
|
|
"missing_evidence": strict.get("missing_evidence") or [],
|
|
"blocked_items": strict.get("blocked_items") or [],
|
|
"conflicts": strict.get("conflicts") or [],
|
|
"adjudication_stages": strict.get("adjudication_stages") or {},
|
|
"multi_reference_reading_summary": strict.get("multi_reference_reading_summary") or {},
|
|
"main_conflicts": strict.get("main_conflicts") or strict.get("conflicts") or [],
|
|
"source_priority_mode": _source_priority_mode(strict),
|
|
"primary_drivers": judgement.get("primary_drivers") or [],
|
|
"secondary_context": judgement.get("secondary_context") or [],
|
|
"technique_audit": strict.get("technique_audit") or [],
|
|
"life_event_graph": strict.get("life_event_graph") or {},
|
|
},
|
|
}
|
|
|
|
|
|
def build_report(payload: dict[str, Any]) -> dict[str, Any]:
|
|
subject = payload.get("subject") or {}
|
|
events = payload.get("events") or []
|
|
rows = [_run_supported_event(subject, event) for event in events]
|
|
|
|
summary = {
|
|
"total_events": len(rows),
|
|
"strong_hits": sum(1 for row in rows if row["result_class"] == "strong_hit"),
|
|
"weak_hits": sum(1 for row in rows if row["result_class"] == "weak_hit"),
|
|
"misses": sum(1 for row in rows if row["result_class"] == "miss"),
|
|
"blocked_events": sum(1 for row in rows if row["result_class"] == "blocked"),
|
|
"unsupported_domain_events": sum(1 for row in rows if row["result_class"] == "unsupported_domain"),
|
|
"official_primary_events": sum(
|
|
1 for row in rows if row["official_snapshot"].get("level") == "primary"
|
|
),
|
|
}
|
|
|
|
return {
|
|
"scope": "historical_event_backtest",
|
|
"summary": summary,
|
|
"boundary": (
|
|
"This report measures whether current strict routes can support supplied historical events. "
|
|
"Unsupported domains and blocked routes must not be overstated as validated predictive accuracy."
|
|
),
|
|
"events": rows,
|
|
}
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description="Run reusable historical-event backtest")
|
|
parser.add_argument("--input", required=True, help="Path to local backtest payload JSON")
|
|
args = parser.parse_args()
|
|
|
|
report = build_report(_load_payload(args.input))
|
|
print(json.dumps(report, ensure_ascii=False, indent=2))
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|