fix: validate scraper metric semantics

This commit is contained in:
Hermes Agent
2026-07-26 23:15:37 +00:00
parent b06cabf3aa
commit 6655bcfa5a
4 changed files with 67 additions and 12 deletions
+9 -2
View File
@@ -114,8 +114,15 @@ def collect_onchain_history(progress_cb=None):
for metric_key, trace_name in cfg["traces"].items():
if trace_name is None:
# Grab first trace with numeric data
for candidate in traces:
if metric_key == "lth_supply":
from scrapers.lookintobitcoin import _find_lth_supply_trace
candidates = [_find_lth_supply_trace(traces)]
else:
candidates = traces
# Grab the first validated trace with numeric data.
for candidate in candidates:
if not candidate:
continue
y = candidate.get("y", [])
if y and any(v is not None for v in y[-10:]):
dates, values = _extract_series(candidate)
+28 -9
View File
@@ -115,6 +115,30 @@ def _find_trace(traces, name):
return None
def _trace_signal_is_active(trace):
"""Return true only when the signal trace is active at its latest point."""
if not trace:
return False
values = trace.get("y", [])
if not values:
return False
latest = values[-1]
try:
return latest is not None and float(latest) != 0
except (TypeError, ValueError):
return bool(latest)
def _find_lth_supply_trace(traces):
"""Select an explicitly named LTH supply series and never a price fallback."""
for trace in traces or []:
name = str(trace.get("name", "")).lower()
is_lth = "long-term holder" in name or "long term holder" in name or "lth" in name
if is_lth and "supply" in name and "price" not in name:
return trace
return None
def _get_latest_value(trace):
"""Get the most recent non-null y value from a trace."""
if not trace:
@@ -210,21 +234,16 @@ def scrape_all():
],
"value": None,
}
# Try to detect buy signal from trace names/colors
# A named signal trace is not itself proof that the signal is active.
for t in traces:
name = t.get("name", "").lower()
if "buy" in name or "signal" in name:
if ("buy" in name or "signal" in name) and _trace_signal_is_active(t):
results[metric_key]["buy_signal"] = True
break
elif metric_key == "lth_supply":
# Get main supply trace
t = traces[0] if traces else None
for candidate in traces:
name = candidate.get("name", "").lower()
if "supply" in name or "lth" in name:
t = candidate
break
# Require an explicitly named LTH supply trace; price is not supply.
t = _find_lth_supply_trace(traces)
recent = _get_recent_values(t, 60)
# Determine trend: compare recent avg to older avg
trend = None