Python交易策略回测for循环实现异常:求助排查问题原因
交易策略回测代码错误排查与修正
问题描述
尝试编写基于ETH价格数据的交易回测算法,规则为:
- 初始资金1000美元
- 当
Pct_Change <= -1.6819时,用全部资金买入资产 - 当
Pct_Change >= 1.4379时,卖出全部持仓 - 要求严格按买入-卖出-买入-卖出交替执行
但执行代码后,dollars和units均变为全0的Series,不符合预期。
原代码
dollars = 1000 units = 0 def buy(dollars,unit_price): global units units=dollars/unit_price dollars = 0 def sell(units,unit_price): global dollars dollars=units*unit_price units=0 for pct_change in df['ETH-Pct-Change']: if pct_change <=-1.6819: buy(dollars,df['ETH-Close']) elif pct_change >= 1.4379: sell(units,df['ETH-Close']) else: pass
错误原因分析
1. 全局变量与函数参数命名冲突
函数buy和sell的参数名与全局变量dollars、units同名,导致函数内的赋值操作只修改了局部参数,而非全局变量。例如buy函数里的dollars = 0只是修改了函数内部的局部变量,全局的dollars并未被重置为0;反之sell函数里的units=0也只修改了局部参数,全局units未变化。
2. 传入整个Series而非单日期价格
循环中遍历的是pct_change单个值,但调用buy/sell时传入的是df['ETH-Close']整个Series,而非当前日期对应的价格。这会导致units和dollars被赋值为Series对象,而非单个数值,后续计算会出现向量运算错误,最终变成全0的Series。
3. 未控制交易交替逻辑
代码没有记录当前的持仓状态(持有现金/持有资产),可能出现连续买入(当dollars已经为0时)或连续卖出(当units已经为0时)的情况,最终导致数值被错误重置为0的Series。
修正后的代码
import pandas as pd # 读取数据(请替换为你的数据加载方式) df = pd.read_csv('eth.csv', parse_dates=['Date'], index_col='Date') dollars = 1000.0 units = 0.0 is_holding = False # 记录当前是否持仓,确保交替交易 for idx, row in df.iterrows(): pct_change = row['ETH-Pct-Change'] current_price = row['ETH-Close'] # 满足买入条件且当前未持仓 if pct_change <= -1.6819 and not is_holding: units = dollars / current_price dollars = 0.0 is_holding = True print(f"{idx}: 买入 {units:.2f} 份,价格 {current_price:.2f}") # 满足卖出条件且当前持仓 elif pct_change >= 1.4379 and is_holding: dollars = units * current_price units = 0.0 is_holding = False print(f"{idx}: 卖出,价格 {current_price:.2f},当前资金 {dollars:.2f}") # 输出最终结果 if is_holding: final_value = units * df.iloc[-1]['ETH-Close'] print(f"最终持仓:{units:.2f} 份,对应市值 {final_value:.2f} 美元") else: print(f"最终资金:{dollars:.2f} 美元")
修正要点
- 去掉冗余函数,直接在循环内处理交易逻辑,避免全局变量与参数的冲突
- 使用
iterrows()遍历每一行数据,获取当前日期的价格而非整个Series - 新增
is_holding状态变量,严格控制买入和卖出的交替执行 - 保留打印日志,方便跟踪每一步交易操作
内容的提问来源于stack exchange,提问作者Shan Govind
相关产品推荐
相关产品推荐

