feat(agents): market summary builder for hypothesis prompt
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pandas as pd # type: ignore[import-untyped]
|
||||||
|
from scipy import stats # type: ignore[import-untyped]
|
||||||
|
|
||||||
|
from .hypothesis import MarketSummary
|
||||||
|
|
||||||
|
|
||||||
|
def build_market_summary(
|
||||||
|
ohlcv: pd.DataFrame,
|
||||||
|
symbol: str,
|
||||||
|
timeframe: str,
|
||||||
|
) -> MarketSummary:
|
||||||
|
returns = ohlcv["close"].pct_change().dropna()
|
||||||
|
return_mean = float(returns.mean())
|
||||||
|
return_std = float(returns.std(ddof=1))
|
||||||
|
skew = float(stats.skew(returns, bias=False))
|
||||||
|
kurt = float(stats.kurtosis(returns, fisher=True, bias=False))
|
||||||
|
|
||||||
|
if return_std < 0.005:
|
||||||
|
regime = "low"
|
||||||
|
elif return_std < 0.02:
|
||||||
|
regime = "medium"
|
||||||
|
else:
|
||||||
|
regime = "high"
|
||||||
|
|
||||||
|
return MarketSummary(
|
||||||
|
symbol=symbol,
|
||||||
|
timeframe=timeframe,
|
||||||
|
n_bars=len(ohlcv),
|
||||||
|
return_mean=return_mean,
|
||||||
|
return_std=return_std,
|
||||||
|
skew=skew,
|
||||||
|
kurtosis=kurt,
|
||||||
|
volatility_regime=regime,
|
||||||
|
)
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import numpy as np
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
from multi_swarm.agents.market_summary import build_market_summary
|
||||||
|
|
||||||
|
|
||||||
|
def test_build_summary_basic() -> None:
|
||||||
|
idx = pd.date_range("2024-01-01", periods=200, freq="1h", tz="UTC")
|
||||||
|
np.random.seed(0)
|
||||||
|
close = 100 + np.cumsum(np.random.normal(0, 1, 200))
|
||||||
|
df = pd.DataFrame(
|
||||||
|
{"open": close, "high": close + 0.5, "low": close - 0.5, "close": close, "volume": 1.0},
|
||||||
|
index=idx,
|
||||||
|
)
|
||||||
|
s = build_market_summary(df, symbol="BTC/USDT", timeframe="1h")
|
||||||
|
assert s.symbol == "BTC/USDT"
|
||||||
|
assert s.timeframe == "1h"
|
||||||
|
assert s.n_bars == 200
|
||||||
|
assert isinstance(s.return_mean, float)
|
||||||
|
assert isinstance(s.return_std, float)
|
||||||
|
assert s.volatility_regime in {"low", "medium", "high"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_volatility_regime_high_for_volatile() -> None:
|
||||||
|
idx = pd.date_range("2024-01-01", periods=200, freq="1h", tz="UTC")
|
||||||
|
np.random.seed(0)
|
||||||
|
close = 100 + np.cumsum(np.random.normal(0, 5.0, 200)) # alta vol
|
||||||
|
df = pd.DataFrame(
|
||||||
|
{"open": close, "high": close + 0.5, "low": close - 0.5, "close": close, "volume": 1.0},
|
||||||
|
index=idx,
|
||||||
|
)
|
||||||
|
s = build_market_summary(df, symbol="BTC/USDT", timeframe="1h")
|
||||||
|
assert s.volatility_regime in {"medium", "high"}
|
||||||
Reference in New Issue
Block a user