Merge branch 'chan' of ssh://git.jackyu66.com:2222/jack/chan into chan

This commit is contained in:
jack
2026-08-28 16:07:28 +08:00
8 changed files with 905 additions and 78 deletions
+123
View File
@@ -0,0 +1,123 @@
"""把 `inner_ms` 拆成和本地一致的分档,用来定位两边测不一致的那部分。
起因:本地量到的构成是 TF_DF 占 ~80%、信号链 ~20%,服务器报的是 chan 构建
22ms、信号链 86ms。按机器差(×1.36)也解释不了四倍差距,说明两边测的不是
同一件事,或者有个环节只在服务器上贵。
用同一批窗口跑,比较分档而不是总数。两边都跑一遍再对表:
python research/live/probe_inner.py --syms BTC,ETH,SOL --repeat 5
分档口径(与 shadow_signal.compute 的调用顺序一致):
rebuild payload → DataFrame
ind_ltf/htf 两条腿各自的 add_indicatorsTF_DF 内部会做,这里单独计时)
chan_ltf/htf TF_DF 构建(lean
zones build_htf_zones
ladder add_zone_ladder
bsp find_fast_bsp3
timeline htf_fx_timeline5m 分型时间线)
attach attach_htf_agree + attach_zone_ladder
注意 `ind_*` 与 `chan_*` 在真实路径里是合一的(TF_DF 内部调 add_indicators),
这里拆开只为定位。总和会略大于实际 inner_ms。
"""
from __future__ import annotations
import argparse
import os
import sys
import time
import warnings
from pathlib import Path
import numpy as np
import pandas as pd
warnings.filterwarnings("ignore")
for _v in ("OMP_NUM_THREADS", "OPENBLAS_NUM_THREADS", "MKL_NUM_THREADS"):
os.environ.setdefault(_v, "1")
HERE = Path(__file__).resolve()
sys.path.insert(0, str(HERE.parents[1]))
sys.path.insert(0, str(HERE.parents[2]))
sys.path.insert(0, str(HERE.parent))
LTF_BARS, HTF_BARS = 2001, 801
def med(fn, n: int):
ts = []
out = None
for _ in range(n):
t = time.perf_counter()
out = fn()
ts.append((time.perf_counter() - t) * 1000)
return float(np.median(ts)), out
def probe(sym: str, repeat: int) -> dict:
from chanlun import TF_DF
from chanlun.analysis.fast_bsp import (
add_zone_ladder, attach_htf_agree, attach_zone_ladder,
build_htf_zones, find_fast_bsp3, htf_fx_timeline,
)
from lib.data import fetch_ohlcv
dl = fetch_ohlcv(f"{sym}/USDT:USDT", "1m", LTF_BARS * 3).tail(LTF_BARS).reset_index(drop=True)
dh = fetch_ohlcv(f"{sym}/USDT:USDT", "5m", HTF_BARS * 3).tail(HTF_BARS).reset_index(drop=True)
probe_tf = TF_DF(lean=True)
r = {"sym": sym}
r["ind_ltf"], _ = med(lambda: probe_tf.add_indicators(dl.copy()), repeat)
r["ind_htf"], _ = med(lambda: probe_tf.add_indicators(dh.copy()), repeat)
r["chan_ltf"], cl = med(lambda: TF_DF(dl, 1, "1m", lean=True), repeat)
r["chan_htf"], ch = med(lambda: TF_DF(dh, 1, "5m", lean=True), repeat)
cdf = cl.dataframe
r["zones"], z = med(lambda: build_htf_zones(cdf, "1m", chan=cl), repeat)
if z is None or z.empty:
r["n_zones"] = 0
return r
z0 = z.reset_index(drop=True)
r["ladder"], zl = med(lambda: add_zone_ladder(z0), repeat)
r["bsp"], sg = med(lambda: find_fast_bsp3(cdf, zl), repeat)
r["timeline"], tl = med(lambda: htf_fx_timeline(ch, ch.dataframe), repeat)
r["attach"], _ = med(
lambda: attach_zone_ladder(attach_htf_agree(sg, cdf, tl), zl), repeat)
r["n_zones"], r["n_sig"] = len(z0), len(sg)
# 增量口径:init 一次后追加,看稳态单根成本
c = TF_DF(lean=True)
c.init_stream(dl.iloc[:-60].reset_index(drop=True), 1, "1m")
ts = []
for k in range(len(dl) - 60, len(dl)):
t = time.perf_counter()
c.append_bar(dl.iloc[k])
ts.append((time.perf_counter() - t) * 1000)
r["append_bar"] = float(np.median(ts[20:]))
return r
def main() -> None:
ap = argparse.ArgumentParser()
ap.add_argument("--syms", default="BTC,ETH,SOL")
ap.add_argument("--repeat", type=int, default=5)
args = ap.parse_args()
rows = [probe(s.strip(), args.repeat) for s in args.syms.split(",") if s.strip()]
d = pd.DataFrame(rows).set_index("sym")
parts = [c for c in ("ind_ltf", "ind_htf", "chan_ltf", "chan_htf", "zones",
"ladder", "bsp", "timeline", "attach") if c in d]
d["合计"] = d[parts].sum(axis=1)
pd.set_option("display.width", 220)
print("\n分档耗时(ms,中位)")
print(d[parts + ["合计", "append_bar"]].round(2).to_string())
print("\n占比(%")
print((d[parts].div(d["合计"], axis=0) * 100).round(1).to_string())
print("\n规模")
print(d[[c for c in ("n_zones", "n_sig") if c in d]].to_string())
print("\n注:ind_* 与 chan_* 在真实路径里合一(TF_DF 内部调 add_indicators),"
"拆开只为定位,合计会略大于实际 inner_ms。")
if __name__ == "__main__":
main()