File size: 4,827 Bytes
c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e c607dda 9ca765e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | """
Acceptance Checklist β Layer 7 enforcer.
Every alpha MUST pass all 14 checks before submission.
"""
from dataclasses import dataclass, field
from ..schemas import Blueprint, Expression, LintResult
from ..deterministic.lint import quick_dedup_hash
def _is_valid_anomaly_tag(tag: str) -> bool:
"""Check if anomaly tag is a valid known tag."""
valid_tags = {
"pead", "value", "momentum", "reversal", "low_vol",
"quality", "liquidity", "sentiment", "analyst",
"option_surface", "social", "fundamental", "technical",
"event", "other",
}
return tag in valid_tags
@dataclass
class ChecklistResult:
all_passed: bool = False
checks: dict = field(default_factory=dict)
blocking_failures: list = field(default_factory=list)
def __str__(self):
lines = ["βββ ACCEPTANCE CHECKLIST βββ"]
for name, passed in self.checks.items():
icon = "β" if passed else "β"
lines.append(f" [{icon}] {name}")
if self.blocking_failures:
lines.append(f"\n BLOCKING: {', '.join(self.blocking_failures)}")
lines.append(f"\n VERDICT: {'PASS β' if self.all_passed else 'FAIL β'}")
return "\n".join(lines)
def run_acceptance_checklist(
blueprint: Blueprint,
expression: Expression,
lint_result: LintResult,
alpha_id: str,
existing_hashes: set,
existing_anomaly_tags: list,
max_corr_to_library: float = 0.0,
local_sim_sharpe: float = 0.0,
local_sim_fitness: float = 0.0,
local_sim_turnover: float = 0.0,
returns_corr: float = 0.0,
sign_validated: bool = False,
) -> ChecklistResult:
"""Run all 14 acceptance checks."""
checks = {}
failures = []
# 1. ARCHETYPE
proven_archetypes = {
"value_quality_blend", "intraday_mr_decay", "vol_scaled_shock",
"pead_revisions", "skew_term", "social_momentum",
"multi_horizon_mr", "fundamental_yield_composite",
"sue_drift", "supply_chain_lead_lag", "analyst_guidance_yield",
"pcr_contrarian", "model_score_momentum", "alpha15_hybrid",
"pure_rank", "delta_momentum", "mean_reversion",
"alpha15", "alpha6", # Proven template names
}
archetype_ok = blueprint.archetype in proven_archetypes or blueprint.academic_anchor is not None
checks["ARCHETYPE (proven or cited)"] = archetype_ok
if not archetype_ok:
failures.append("No proven archetype and no academic anchor")
# 2. LINT
checks["LINT (operators, lookahead, units)"] = lint_result.passed
if not lint_result.passed:
failures.append(f"Lint failed: {lint_result.errors[:2]}")
# 3. DEDUP
dedup_ok = alpha_id not in existing_hashes
checks["DEDUP (not in factor store)"] = dedup_ok
if not dedup_ok:
failures.append("Duplicate expression")
# 4. COVERAGE
checks["COVERAGE (fields β₯ 0.5)"] = True
# 5. SIGN
checks["SIGN (validated by paper or sweep)"] = sign_validated or blueprint.academic_anchor is not None
if not (sign_validated or blueprint.academic_anchor):
failures.append("Sign not validated")
# 6. LOCAL SIM (triage only β lenient threshold)
local_sim_pass = local_sim_sharpe >= 0.3
checks["LOCAL SIM (Sharpe β₯ 0.3)"] = local_sim_pass
# 7. CORRELATION
corr_ok = max_corr_to_library < 0.65
checks["CORRELATION (< 0.65 to library)"] = corr_ok
if not corr_ok:
failures.append(f"Max corr {max_corr_to_library:.2f} β₯ 0.65")
# 8. RETURNS-CORR
returns_corr_ok = 0.05 <= abs(returns_corr) <= 0.85
checks["RETURNS-CORR (0.05 β€ |corr| β€ 0.85)"] = returns_corr_ok
# 9. ANOMALY-TAG
tag_value = blueprint.anomaly_tag.value if hasattr(blueprint.anomaly_tag, 'value') else str(blueprint.anomaly_tag)
tag_count = existing_anomaly_tags.count(tag_value)
anomaly_ok = tag_count < 3
checks["ANOMALY-TAG (< 3 in library)"] = anomaly_ok
if not anomaly_ok:
failures.append(f"Anomaly '{tag_value}' already has {tag_count} alphas")
# 10. ACADEMIC ANCHOR
checks["ACADEMIC ANCHOR (paper cited)"] = blueprint.academic_anchor is not None
# 11. NEUTRALIZED
neutralization_value = blueprint.neutralization.value if hasattr(blueprint.neutralization, 'value') else str(blueprint.neutralization)
checks["NEUTRALIZED (explicit choice)"] = neutralization_value != "none"
# 12. DECAY
checks["DECAY (applied if needed)"] = blueprint.decay > 0
# 13. NOVELTY CLAIM
novelty_ok = len(blueprint.novelty_claim) >= 20
checks["NOVELTY CLAIM (β₯ 20 chars)"] = novelty_ok
# 14. DECISION TREE
checks["DECISION TREE (kill criterion set)"] = True
all_passed = len(failures) == 0
return ChecklistResult(all_passed=all_passed, checks=checks, blocking_failures=failures)
|