feat: 新增 ChanMacro 宏观 regime 检测模块

This commit is contained in:
jackyu66git
2026-08-20 16:03:25 +08:00
parent 340676bfbd
commit 29cff47f98
48 changed files with 5846 additions and 0 deletions
+113
View File
@@ -0,0 +1,113 @@
"""
config.py — Global configuration for ChanMacro.
All weights, thresholds, and paths are configurable.
V1 weights are deliberately simple; they will be tuned via Phase 0 validation.
"""
from dataclasses import dataclass, field
from pathlib import Path
from typing import Optional
@dataclass
class Config:
"""Global configuration. Override via config.json or env vars."""
# ── Paths ──────────────────────────────────────────────
db_path: str = "data/macro.db"
data_dir: str = "data"
# ── Data Provider ──────────────────────────────────────
provider_url: str = "https://provider.jackyu66.com"
btc_symbol: str = "BTC/USDT:USDT"
top50_symbols: list[str] = field(default_factory=lambda: [
"BTC/USDT:USDT", "ETH/USDT:USDT", "SOL/USDT:USDT",
"BNB/USDT:USDT", "XRP/USDT:USDT", "DOGE/USDT:USDT",
"SUI/USDT:USDT", "TON/USDT:USDT", "ZEC/USDT:USDT",
"1000PEPE/USDT:USDT", "SAGA/USDT:USDT",
"XAU/USDT:USDT", "XAG/USDT:USDT",
"CL/USDT:USDT", "BILL/USDT:USDT", "BZ/USDT:USDT",
"LAB/USDT:USDT", "CRCL/USDT:USDT", "SNDK/USDT:USDT",
"CHIP/USDT:USDT",
])
# ── Breadth ────────────────────────────────────────────
breadth_top_n: list[int] = field(default_factory=lambda: [20, 30, 50])
breadth_ema_period: int = 20
breadth_new_high_window: int = 20
# ── Regime (factor-locked: Price + Breadth + Vol) ─────
regime_version: str = "v1_price_breadth_vol"
# Weights for trend_score within regime detection
regime_w_price: float = 0.35
regime_w_breadth: float = 0.50
regime_w_vol: float = 0.15
# Weights for panic_score
regime_panic_w_anti_trend: float = 0.60
regime_panic_w_vol_extreme: float = 0.40
# ── Price Structure ────────────────────────────────────
ps_ema_fast: int = 20
ps_ema_mid: int = 60
ps_ema_slow: int = 120
ps_adx_period: int = 14
ps_adx_threshold: int = 25
ps_atr_period: int = 14
ps_bb_period: int = 20
ps_roc_periods: list[int] = field(default_factory=lambda: [5, 10, 20])
# ── OI Matrix ──────────────────────────────────────────
oi_price_threshold_pct: float = 0.5 # min price change% to classify
oi_oi_threshold_pct: float = 0.5 # min OI change% to classify
# ── Volatility Regime ──────────────────────────────────
vol_atr_period: int = 14
vol_hv_short: int = 20
vol_hv_long: int = 60
# Thresholds (ATR/Close %)
vol_low_threshold: float = 2.0
vol_high_threshold: float = 5.0
vol_explosive_threshold: float = 10.0
# ── Trend (L2 aggregation) ─────────────────────────────
trend_w_price: float = 0.30
trend_w_breadth: float = 0.70
# ── Maturity Score ─────────────────────────────────────
maturity_w_trend: float = 0.50
maturity_w_breadth: float = 0.30
maturity_w_vol: float = 0.20
# ── Expectancy ─────────────────────────────────────────
half_life_days: int = 180
sufficiency_min_effective: int = 30
sufficiency_low: int = 50
sufficiency_medium: int = 100
level_min_samples: int = 50
knn_max_distance: float = 0.35
knn_k: int = 200
# ── Validation ─────────────────────────────────────────
min_history_days: int = 365
regime_min_avg_duration: int = 5
regime_max_flip_rate: float = 0.15
@classmethod
def from_json(cls, path: str = "config.json") -> "Config":
"""Load config from JSON file, overriding defaults."""
import json
config = cls()
try:
with open(path) as f:
data = json.load(f)
for key, value in data.items():
if hasattr(config, key):
setattr(config, key, value)
except FileNotFoundError:
pass
return config
# Global singleton
config = Config()