添加批量解析
This commit is contained in:
+10
-25
@@ -189,28 +189,9 @@ def extended_metrics(trades: pd.DataFrame) -> Dict[str, Any]:
|
||||
|
||||
|
||||
# =========================================================================== #
|
||||
# What-If 假设分析(通用场景)
|
||||
# 单段通用指标(从 mt5_report_parser 复用)
|
||||
# =========================================================================== #
|
||||
def _stats_from_net(net: pd.Series) -> Dict[str, float]:
|
||||
"""由净盈亏序列算关键统计。"""
|
||||
n = len(net)
|
||||
if n == 0:
|
||||
return {"n": 0, "net": 0, "pf": 0, "win": 0, "dd": 0, "exp": 0}
|
||||
wins = net[net > 0]
|
||||
losses = net[net <= 0]
|
||||
gp = wins.sum()
|
||||
gl = -losses.sum()
|
||||
pf = gp / gl if gl > 0 else np.inf
|
||||
equity = net.cumsum()
|
||||
dd = (equity - equity.cummax()).min()
|
||||
return {
|
||||
"n": int(n),
|
||||
"net": float(net.sum()),
|
||||
"pf": float(pf),
|
||||
"win": float(len(wins) / n * 100),
|
||||
"dd": float(dd),
|
||||
"exp": float(net.mean()),
|
||||
}
|
||||
from mt5_report_parser import compute_segment_metrics as _stats_from_net
|
||||
|
||||
|
||||
def whatif_scenarios(rep: mp.MT5Report) -> List[Dict[str, Any]]:
|
||||
@@ -324,12 +305,16 @@ def monte_carlo_dd(net: pd.Series, n_sim: int = 1000, seed: int = 42) -> Dict[st
|
||||
n = len(arr)
|
||||
if n == 0:
|
||||
return {"p5": 0, "p50": 0, "p95": 0, "actual": 0, "mean": 0}
|
||||
# 向量化:一次性生成 (n_sim, n) 置换矩阵,在 C 层完成
|
||||
# 每行是一个随机打乱的交易顺序
|
||||
perms = rng.integers(n, size=(n_sim, n))
|
||||
# 每行按该行的索引排序得到 (n_sim, n) 的排列索引
|
||||
idx = np.argsort(perms, axis=1)
|
||||
dds = np.empty(n_sim)
|
||||
for i in range(n_sim):
|
||||
perm = rng.permutation(n)
|
||||
eq = np.cumsum(arr[perm])
|
||||
dd = (eq - np.maximum.accumulate(eq)).min()
|
||||
dds[i] = dd
|
||||
perm = arr[idx[i]]
|
||||
eq = np.cumsum(perm)
|
||||
dds[i] = (eq - np.maximum.accumulate(eq)).min()
|
||||
return {
|
||||
"p5": float(np.percentile(dds, 5)),
|
||||
"p50": float(np.percentile(dds, 50)),
|
||||
|
||||
Reference in New Issue
Block a user