feat: ECR-003 主站威科夫分析与图表叠层(已审)
独立 wyckoff 引擎 + 按需 include_wyckoff;主站 Lightweight 绘制区间/阶段/事件/VP。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -16,9 +16,19 @@ sys.path.insert(0, str(ROOT / "web"))
|
||||
from tests.generate_golden import make_ohlcv # noqa: E402
|
||||
|
||||
|
||||
CONTRACT_KEYS = json.loads(
|
||||
_CONTRACT_DOC = json.loads(
|
||||
(ROOT / "tests" / "fixtures" / "analyze_contract_keys.json").read_text(encoding="utf-8")
|
||||
)
|
||||
CONTRACT_KEYS = (
|
||||
_CONTRACT_DOC["required"]
|
||||
if isinstance(_CONTRACT_DOC, dict) and "required" in _CONTRACT_DOC
|
||||
else _CONTRACT_DOC
|
||||
)
|
||||
WYCKOFF_KEYS = (
|
||||
_CONTRACT_DOC.get("wyckoff_keys", [])
|
||||
if isinstance(_CONTRACT_DOC, dict)
|
||||
else []
|
||||
)
|
||||
|
||||
# analyze_chan 直接返回的对象字段(未序列化前)
|
||||
ANALYZE_CHAN_KEYS = {
|
||||
@@ -117,3 +127,33 @@ def test_analyze_http_contract_with_mocked_kl():
|
||||
assert payload is not None and "error" not in payload
|
||||
missing = [k for k in CONTRACT_KEYS if k not in payload]
|
||||
assert not missing, f"missing contract keys: {missing}"
|
||||
assert "wyckoff" not in payload
|
||||
|
||||
|
||||
def test_analyze_http_wyckoff_opt_in():
|
||||
"""include_wyckoff=1 时响应含 wyckoff 约定键;默认不返回。"""
|
||||
from app import app
|
||||
from services.runtime import add_indicators
|
||||
|
||||
df = add_indicators(make_ohlcv(300))
|
||||
df = df.copy()
|
||||
if "timestamp" not in df.columns:
|
||||
df["timestamp"] = (pd.to_datetime(df["date"]).astype("int64") // 10**6).astype("int64")
|
||||
|
||||
with patch("api.analyze.get_kl_data", return_value=df):
|
||||
client = app.test_client()
|
||||
resp = client.get(
|
||||
"/api/analyze",
|
||||
query_string={
|
||||
"symbol": "BTC/USDT:USDT",
|
||||
"timeframe": "5m",
|
||||
"timezone": "Asia/Shanghai",
|
||||
"include_wyckoff": 1,
|
||||
},
|
||||
)
|
||||
assert resp.status_code == 200, resp.data[:500]
|
||||
payload = resp.get_json()
|
||||
assert payload is not None and "wyckoff" in payload
|
||||
w = payload["wyckoff"]
|
||||
for k in WYCKOFF_KEYS:
|
||||
assert k in w, f"missing wyckoff key: {k}"
|
||||
|
||||
Reference in New Issue
Block a user