indicator validation looks for all NaN's and all zeroes
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
# Development Plan
|
||||
|
||||
* Wiki memory
|
||||
* Agent unification & spawn tool
|
||||
* Realtime data
|
||||
* Triggers
|
||||
* Strategy UI
|
||||
@@ -13,6 +11,5 @@
|
||||
* Chat channels
|
||||
* MCP channel (with or without images)
|
||||
* TradingView indicator import tool
|
||||
* Trader preferences tool
|
||||
* Results persistence: research analysis, backtests, strategy performance metrics, etc.
|
||||
*
|
||||
* Results persistence: ~~research analysis~~, backtests, strategy performance metrics, etc.
|
||||
* Free tier with token limits and sandbox shutdown
|
||||
|
||||
@@ -61,14 +61,33 @@ def make_synthetic_ohlcv(n: int = 200):
|
||||
def summarize(result, n: int) -> str:
|
||||
import pandas as pd
|
||||
|
||||
warnings = []
|
||||
|
||||
def _check_series_warnings(s: "pd.Series", label: str = "") -> None:
|
||||
valid = s.dropna()
|
||||
prefix = f"Column '{label}': " if label else ""
|
||||
if len(valid) == 0:
|
||||
warnings.append(
|
||||
f"⚠ WARNING: {prefix}All {n} output values are NaN. "
|
||||
"The indicator produced no usable data — check for NaN propagation bugs "
|
||||
"(e.g. uninitialized recursive filter, division by zero, insufficient warmup)."
|
||||
)
|
||||
elif (valid == 0).all():
|
||||
warnings.append(
|
||||
f"⚠ WARNING: {prefix}All non-NaN output values are zero. "
|
||||
"The indicator may have a computation bug "
|
||||
"(e.g. log(1) always being 0, constant input, or a formula that cancels out)."
|
||||
)
|
||||
|
||||
if isinstance(result, pd.Series):
|
||||
nan_count = int(result.isna().sum())
|
||||
valid = result.dropna()
|
||||
sample = [round(float(v), 4) for v in valid.tail(5).values] if len(valid) else []
|
||||
return (
|
||||
summary = (
|
||||
f"Series({n} bars), NaN: {nan_count}/{n}, "
|
||||
f"last 5 valid values: {sample}"
|
||||
)
|
||||
_check_series_warnings(result)
|
||||
elif isinstance(result, pd.DataFrame):
|
||||
cols = list(result.columns)
|
||||
nan_counts = {c: int(result[c].isna().sum()) for c in cols}
|
||||
@@ -77,13 +96,18 @@ def summarize(result, n: int) -> str:
|
||||
valid = result[col].dropna()
|
||||
if len(valid):
|
||||
sample[col] = [round(float(v), 4) for v in valid.tail(3).values]
|
||||
return (
|
||||
_check_series_warnings(result[col], label=col)
|
||||
summary = (
|
||||
f"DataFrame({n} bars × {len(cols)} cols {cols}), "
|
||||
f"NaN counts: {nan_counts}, last 3 valid per col: {sample}"
|
||||
)
|
||||
else:
|
||||
return f"Unexpected return type: {type(result).__name__}"
|
||||
|
||||
if warnings:
|
||||
return summary + "\n" + "\n".join(warnings)
|
||||
return summary
|
||||
|
||||
|
||||
def run(impl_path: Path, metadata_path: Path) -> dict:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user