from typing import List, Dict, Iterable, Tuple
import math
def sharpe_from_history(
account_value_history: Iterable[Tuple[int, float]],
pnl_history: Iterable[Tuple[int, float]],
min_periods: int = 2
) -> float:
"""
按照上传 JS 的逻辑计算 Sharpe Ratio(简化版):
- account_value_history: list of (timestamp, total_value)
- pnl_history: list of (timestamp, cumulative_pnl) 或者每 period 的 pnl 也可(JS 用的是 pnlHistory 和 accountValueHistory 对应索引)
- 实现细节与 JS 对齐:
1. 构造一个列表 l,其元素包含 time, totalValue, pnl (period pnl)
2. 计算 avg_total = average of totalValue across the period (JS 用 sum/len)
3. 对每个 period(跳过第一个),计算 r_i = 100 * pnl / avg_total
4. 计算 mean_r = mean(r)
5. 计算样本标准差(分母 n-1):std = sqrt( sum((r - mean_r)^2) / (n-1) )
6. 若 std == 0 返回 0;否则返回 mean_r / std
"""
# 将输入转换为 list,确保索引访问
av = list(account_value_history)
ph = list(pnl_history)
# 边界:长度不一致或长度太小
if not av or len(av) != len(ph) or len(av) < min_periods:
return 0.0
# 构造每 period 的记录(与 JS 逻辑一致)
records = []
for i in range(len(av)):
t_av, total_value = av[i]
# JS 用 pnlHistory[t][1] - pnlHistory[t-1][1] 做 period pnl
if i == 0:
period_pnl = 0.0
else:
prev_pnl = ph[i-1][1] if i-1 < len(ph) else 0.0
cur_pnl = ph[i][1]
period_pnl = cur_pnl - prev_pnl
records.append({"time": t_av, "totalValue": float(total_value), "pnl": float(period_pnl)})
# avg totalValue (JS: s = l.reduce(...); i = ue(s, l.length))
total_sum = sum(r["totalValue"] for r in records)
avg_total = total_sum / len(records) if len(records) > 0 else 0.0
if avg_total == 0:
return 0.0
# 计算 r:从 records 的 index 1 开始(JS: if (0 === t) continue; they skip first in building r)
r_vals: List[float] = []
for idx, rec in enumerate(records):
if idx == 0:
continue
# JS 使用 te(100*e.pnl/i) 然后 Number(a) -> 100 * pnl / avg_total
r_vals.append(100.0 * rec["pnl"] / avg_total)
n = len(r_vals)
if n < 2:
return 0.0
mean_r = sum(r_vals) / n
# 样本方差(分母 n-1),与 JS 一致
sum_sq = sum((x - mean_r) ** 2 for x in r_vals)
variance = sum_sq / (n - 1)
stddev = math.sqrt(variance)
if stddev == 0:
return 0.0
return mean_r / stddev
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)