Artifex/control_plane/trading_studio/indicators/registry.py
2026-08-18 02:00:53 +07:00

193 lines
7.7 KiB
Python

"""Deterministic registry/universe construction and artifact serialization."""
from __future__ import annotations
import hashlib
import json
from collections import Counter
from dataclasses import dataclass
from pathlib import Path
from .definitions import (
HISTORICAL_DEFINITIONS,
HISTORICAL_VARIANTS,
ImplementationStatus,
IndicatorDefinition,
IndicatorVariant,
Role,
)
HISTORICAL_ARTIFACT_PATH = Path(__file__).with_name("hs22_historical_registry_v1.json")
@dataclass(frozen=True, slots=True)
class IndicatorUniverse:
name: str
variants: tuple[IndicatorVariant, ...]
namespace: str = "historical"
def by_role(self, role: Role | str) -> tuple[IndicatorVariant, ...]:
return tuple(variant for variant in self.variants if variant.role == Role(role))
def contains(self, variant: IndicatorVariant) -> bool:
return variant in self.variants
@dataclass(frozen=True, slots=True)
class IndicatorRegistry:
definitions: tuple[IndicatorDefinition, ...]
variants: tuple[IndicatorVariant, ...]
def definition(self, indicator_id: int) -> IndicatorDefinition | None:
return next((item for item in self.definitions if item.indicator_id == indicator_id), None)
def variant(self, indicator_id: int, period: int, p1: float = 0.0) -> IndicatorVariant | None:
return next(
(
item
for item in self.variants
if (item.indicator_id, item.period, item.p1) == (indicator_id, period, p1)
),
None,
)
def role_pool(self, role: Role | str) -> tuple[IndicatorVariant, ...]:
return HS22_HISTORICAL_COMPLETE_V1.by_role(role)
def _all_definitions() -> tuple[IndicatorDefinition, ...]:
# Historical aliases remain metadata only. Formula execution is unavailable.
existing = {item.indicator_id: item for item in HISTORICAL_DEFINITIONS}
aliases = {25: 1, 26: None, 27: None}
for indicator_id, target in aliases.items():
base = existing[indicator_id]
existing[indicator_id] = IndicatorDefinition(
indicator_id,
base.name,
base.role,
ImplementationStatus.ALIAS,
target,
"historical_alias; execution_refused",
)
definitions = tuple(sorted(existing.values(), key=lambda item: item.indicator_id))
assert len(definitions) == 145
return definitions
HISTORICAL_REGISTRY = IndicatorRegistry(_all_definitions(), HISTORICAL_VARIANTS)
HS22_HISTORICAL_COMPLETE_V1 = IndicatorUniverse("HS22_HISTORICAL_COMPLETE_V1", HISTORICAL_VARIANTS)
EXPERIMENTAL_UNIVERSE = IndicatorUniverse("HS22_EXPERIMENTAL_V1", (), "experimental")
UNREGISTERED_INDICATORS = {
"MOM_JERK": "unregistered; unknown_dispatch_returns_all_nan; no_fallback",
}
def cohort001_universe(manifest: object | None = None) -> IndicatorUniverse:
"""Build the derived universe only from canonical manifest variants.
A missing manifest intentionally produces an empty placeholder; it never
substitutes the broad historical pool.
"""
variants: list[IndicatorVariant] = []
if isinstance(manifest, dict):
rows = manifest.get("variants", ())
else:
rows = ()
for row in rows:
if not isinstance(row, dict):
continue
try:
candidate = IndicatorVariant(
int(row["indicator_id"]),
int(row["period"]),
float(row.get("p1", 0.0)),
Role(row["role"]),
)
except (KeyError, TypeError, ValueError):
continue
if candidate in HISTORICAL_VARIANTS:
variants.append(candidate)
return IndicatorUniverse("HS22_COHORT001_V1", tuple(variants), "derived")
HS22_COHORT001_V1 = cohort001_universe()
# This is the complete, role-sensitive Cohort001 execution surface recovered
# from the frozen oracle. It is product data, not an oracle dependency.
_HS22_REQUIRED_TRIPLES = (
(17, 16, 2.0, "signal"), (18, 16, 2.0, "signal"), (18, 22, 2.5, "signal"), (18, 24, 2.5, "signal"),
(19, 8, 4.0, "signal"), (19, 10, 2.0, "signal"), (19, 10, 4.0, "signal"), (19, 14, 3.0, "signal"),
(21, 10, 0.0, "trigger"), (21, 14, 0.0, "trigger"), (21, 18, 0.0, "signal"), (21, 22, 0.0, "trigger"),
(24, 14, 1.0, "signal"), (30, 14, 0.0, "confirm"), (31, 5, 0.0, "confirm"), (31, 7, 0.0, "confirm"),
(31, 21, 0.0, "confirm"), (33, 16, 0.0, "confirm"), (33, 20, 0.0, "confirm"), (33, 22, 0.0, "confirm"),
(33, 24, 0.0, "confirm"), (36, 10, 0.0, "confirm"), (36, 18, 0.0, "confirm"), (36, 20, 0.0, "confirm"),
(39, 20, 0.0, "vol"), (40, 12, 0.0, "vol"), (40, 14, 0.0, "vol"), (41, 12, 0.0, "vol"),
(41, 16, 0.0, "vol"), (41, 22, 0.0, "vol"), (42, 20, 0.0, "vol"), (42, 44, 0.0, "confirm"),
(50, 8, 0.0, "trend"), (53, 18, 0.0, "vol"), (53, 30, 0.0, "vol"), (54, 22, 0.0, "trend"),
(54, 30, 0.0, "trend"), (55, 10, 0.0, "vol"), (57, 10, 0.0, "trend"), (58, 30, 0.0, "trend"),
(61, 14, 0.0, "trend"), (63, 11, 0.0, "trend"), (70, 18, 0.0, "trend"), (70, 20, 0.0, "trend"),
(71, 14, 0.0, "trend"), (71, 18, 0.0, "trend"), (72, 18, 0.0, "trend"), (73, 20, 0.0, "trend"),
(75, 26, 0.0, "trend"), (76, 23, 0.0, "trend"), (77, 1, 0.0, "vol"), (79, 30, 2.0, "trigger"),
(79, 30, 8.0, "trend"), (79, 40, 8.0, "trigger"), (79, 50, 2.0, "trigger"), (79, 50, 8.0, "trigger"),
(79, 60, 2.0, "trend"), (79, 60, 2.0, "trigger"), (81, 25, 0.0, "trigger"), (82, 30, 3.0, "trigger"),
(82, 40, 1.0, "trigger"), (91, 8, 0.0, "signal"), (91, 11, 0.0, "signal"), (92, 5, 0.0, "signal"),
(92, 17, 0.0, "signal"), (101, 8, 0.0, "trend"), (106, 8, 0.0, "confirm"), (106, 14, 0.0, "confirm"),
(112, 30, 0.0, "vol"), (113, 30, 0.0, "vol"), (114, 20, 10.0, "vol"), (114, 30, 50.0, "vol"),
(122, 60, 0.0, "trigger"), (122, 90, 0.0, "trigger"), (122, 150, 0.0, "trigger"), (122, 180, 0.0, "trigger"),
(122, 210, 0.0, "trigger"), (124, 60, 0.0, "signal"), (129, 22, 2.0, "signal"), (129, 30, 2.0, "signal"),
(152, 15, 0.0, "vol"),
)
HS22_REQUIRED_V1 = IndicatorUniverse(
"HS22_COHORT001_REQUIRED_V1",
tuple(
IndicatorVariant(
indicator_id,
period,
p1,
{"trend": Role.TREND, "signal": Role.OSC, "trigger": Role.LEVEL,
"confirm": Role.OSC, "vol": Role.FILTER}[slot],
)
for indicator_id, period, p1, slot in _HS22_REQUIRED_TRIPLES
),
"derived",
)
def historical_artifact() -> dict[str, object]:
role_counts = Counter(item.role.value for item in HISTORICAL_VARIANTS)
return {
"schema_version": 1,
"registry": "HS22_HISTORICAL_COMPLETE_V1",
"definition_count": len(HISTORICAL_REGISTRY.definitions),
"variant_count": len(HISTORICAL_VARIANTS),
"role_counts": dict(sorted(role_counts.items())),
"definitions": [
{
"indicator_id": item.indicator_id,
"name": item.name,
"role": item.role.value if item.role else None,
"status": item.status.value,
"alias_of": item.alias_of,
"behavior": item.behavior,
}
for item in HISTORICAL_REGISTRY.definitions
],
"variants": [item.asdict() for item in HISTORICAL_VARIANTS],
"unknown_behavior": "all_nan; no_fallback",
"unregistered": UNREGISTERED_INDICATORS,
}
def historical_artifact_bytes() -> bytes:
return json.dumps(
historical_artifact(), sort_keys=True, separators=(",", ":"), allow_nan=False
).encode()
def historical_artifact_digest() -> str:
return hashlib.sha256(historical_artifact_bytes()).hexdigest()
def write_historical_artifact(path: Path = HISTORICAL_ARTIFACT_PATH) -> None:
path.write_bytes(historical_artifact_bytes() + b"\n")