Python Pandas投资策略回测代码结果不符,求排查逻辑漏洞
问题排查与解决方案
1. 核心逻辑的常见错误点
你的回测逻辑核心是逐行检查历史同组(market_name/runner_name/odds)的累计盈亏,仅当历史累计>0时计入当前盈亏。代码结果不符通常是以下几个细节出错:
- 累计计算包含当前行:用
cumsum()时未做偏移,误把当前行的back算进历史总和 - 分组键处理不当:
odds作为浮点数存在精度差异(比如2.0和2.00被判定为不同值),或字符串列有大小写/空格差异(比如"Market A"和"market a") - 数据顺序错误:CSV导入后未按投资时间排序,导致"之前"的记录顺序混乱
- 总收益计算逻辑错误:误将符合条件的行直接求和,但未严格遵循逐行判断的累计规则
2. 可验证的正确实现代码
你可以对比这段标准实现,定位自己代码的差异:
import pandas as pd # 读取数据 df = pd.read_csv("your_investment_data.csv") # 关键:确保数据按投资发生顺序排序(有时间列用时间,无则用行号) df = df.sort_values(by="trade_time", ascending=True) # 替换为你的时间列名,无则删除此行用默认顺序 # 处理浮点数精度问题(针对odds列) df["odds"] = df["odds"].round(2) # 根据实际数据调整小数位数 # 计算每组的历史累计盈亏(排除当前行) df["prev_group_sum"] = df.groupby(["market_name", "runner_name", "odds"])["back"].cumsum().shift(1) # 首行无历史数据,填充0(历史总和为0,不满足>0条件) df["prev_group_sum"] = df["prev_group_sum"].fillna(0) # 判断是否计入总收益并计算最终结果 df["include_profit"] = df.apply(lambda x: x["back"] if x["prev_group_sum"] > 0 else 0, axis=1) total_profit = df["include_profit"].sum() print(f"最终总收益:{total_profit}")
3. 逐行排查步骤
- 验证分组键有效性:运行以下代码排查无效区分问题
# 检查odds的精度差异 print(df["odds"].unique()) # 统一字符串列格式,消除大小写/空格影响 df["market_name"] = df["market_name"].str.strip().str.lower() df["runner_name"] = df["runner_name"].str.strip().str.lower() - 手动验证历史累计:取前2-3行数据,手动计算
prev_group_sum,对比代码输出是否符合预期 - 确认数据顺序:检查排序后的DataFrame是否与实际投资发生顺序一致,这是逻辑成立的基础
内容的提问来源于stack exchange,提问作者Digital Farmer
相关产品推荐
相关产品推荐

