feat: B组挖掘存逐笔trades(entry_date+pnl)供温区预计算归因——融合后能进温区表

This commit is contained in:
xxm
2026-08-16 18:27:55 +08:00
parent c1b3830063
commit 5daca7fa6b
+13 -5
View File
@@ -100,6 +100,7 @@ def _simulate_verify(market, regime, panel, cond, tp=20, sl=10, maxh=40):
return None return None
sub = sub.sort_values(["code", "date"]) sub = sub.sort_values(["code", "date"])
trades = [] trades = []
trade_details = []
for code, g in sub.groupby("code"): for code, g in sub.groupby("code"):
g = g.sort_values("date") g = g.sort_values("date")
idxs = list(g.index) idxs = list(g.index)
@@ -121,10 +122,15 @@ def _simulate_verify(market, regime, panel, cond, tp=20, sl=10, maxh=40):
if res is None: if res is None:
res = (fut.iloc[-1]["close"] / ep - 1) * 100 res = (fut.iloc[-1]["close"] / ep - 1) * 100
trades.append(res) trades.append(res)
trade_details.append({"entry_date": str(g.loc[i, "date"]), "pnl_pct": round(res, 2),
"code": str(code)})
if not trades: if not trades:
return None return None
wins = [x for x in trades if x > 0] wins = [x for x in trades if x > 0]
return len(trades), len(wins) / len(trades) * 100, sum(trades) / len(trades) if not trades:
return None
return {"n": len(trades), "win_rate": len(wins) / len(trades) * 100,
"avg_pnl": sum(trades) / len(trades), "trades": trade_details}
def to_entry(cond_dict): def to_entry(cond_dict):
@@ -155,11 +161,12 @@ def mine(market="a", regimes=None):
passed_params = [] passed_params = []
for tp, sl, mh in [(20, 10, 40), (25, 10, 45), (30, 12, 50), (15, 8, 35)]: for tp, sl, mh in [(20, 10, 40), (25, 10, 45), (30, 12, 50), (15, 8, 35)]:
r = _simulate_verify(market, rg, panel, c, tp, sl, mh) r = _simulate_verify(market, rg, panel, c, tp, sl, mh)
if r and r[1] >= 50 and r[2] > 0: if r and r["win_rate"] >= 50 and r["avg_pnl"] > 0:
passed_params.append((tp, sl, mh, *r)) passed_params.append((tp, sl, mh, r))
if passed_params: if passed_params:
best = max(passed_params, key=lambda x: x[5]) # (tp,sl,mh,tn,twr,tavg) -> tavg=index5 best = max(passed_params, key=lambda x: x[3]["avg_pnl"])
tp, sl, mh, tn, twr, tavg = best tp, sl, mh, rd = best
tn, twr, tavg = rd["n"], rd["win_rate"], rd["avg_pnl"]
if twr >= 50 and tavg > 0: if twr >= 50 and tavg > 0:
cand = { cand = {
"regime": rg, "market": market, "group": "B", "status": "verified", "regime": rg, "market": market, "group": "B", "status": "verified",
@@ -167,6 +174,7 @@ def mine(market="a", regimes=None):
"avg60": avg, "excess_pp": extra, "avg60": avg, "excess_pp": extra,
"sim_trades": tn, "sim_win_rate": round(twr, 1), "sim_avg_pnl": round(tavg, 2), "sim_trades": tn, "sim_win_rate": round(twr, 1), "sim_avg_pnl": round(tavg, 2),
"sim_tp": tp, "sim_sl": sl, "sim_maxh": mh, "sim_tp": tp, "sim_sl": sl, "sim_maxh": mh,
"trades": rd.get("trades", []),
"hypothesis": f"[{rg}] 由果及因{nf}因子: {list(cond.keys())} → 大涨率{rate}%(基线+{extra}pp)", "hypothesis": f"[{rg}] 由果及因{nf}因子: {list(cond.keys())} → 大涨率{rate}%(基线+{extra}pp)",
} }
out["candidates"].append(cand) out["candidates"].append(cand)