Add python_analysis_script/src/python_analysis_script/core.py

This commit is contained in:
Mika 2026-01-28 16:22:42 +00:00
commit 8defa11f88

View file

@ -0,0 +1,64 @@
from __future__ import annotations
import pandas as pd
from dataclasses import dataclass
from datetime import datetime
from typing import List
@dataclass
class DecisionResult:
"""Repräsentiert ein einzelnes CI-Entscheidungsresultat."""
timestamp: datetime
decision: str
margin: float
flaky_flag: bool
subset_flip_count: int
mischfenster_p95: float
def _validate_input_columns(df: pd.DataFrame) -> None:
required_cols = {"margin", "flaky_flag", "subset_flip_count", "mischfenster_p95"}
missing = required_cols - set(df.columns)
assert not missing, f"Missing required columns: {missing}"
def _apply_policy(row: pd.Series) -> str:
margin = row.get("margin", 0.0)
flaky = row.get("flaky_flag", False)
# CI-Policy v0.1: einfache Entscheidungslogik
if pd.isna(margin):
return "FAIL"
if flaky:
return "WARN"
if margin >= 0.0:
return "PASS"
elif -0.05 <= margin < 0.0:
return "WARN"
else:
return "FAIL"
def analyze_backtest(csv_file: str) -> List[DecisionResult]:
"""Analysiert Backtest-Ergebnisse und erstellt eine Liste DecisionResult."""
assert isinstance(csv_file, str) and csv_file.endswith('.csv'), "csv_file must be a CSV filepath string"
df = pd.read_csv(csv_file)
_validate_input_columns(df)
results: List[DecisionResult] = []
now = datetime.utcnow()
for _, row in df.iterrows():
decision = _apply_policy(row)
result = DecisionResult(
timestamp=now,
decision=decision,
margin=float(row.get("margin", 0.0)),
flaky_flag=bool(row.get("flaky_flag", False)),
subset_flip_count=int(row.get("subset_flip_count", 0)),
mischfenster_p95=float(row.get("mischfenster_p95", 0.0)),
)
results.append(result)
return results