如何用Pandas为股票周数据打涨跌标签并模拟买卖操作
解决股票DataFrame周度标签标记与自动买卖回测问题
一、给每周标记"green"/"red"标签
你的DataFrame已包含Week_Number字段,我们可以按周分组提取关键价格,生成周标签后映射回原数据,确保每周所有行都有对应标签。
步骤1:计算周度价格并生成标签
import pandas as pd # 确保Date为datetime类型 df['Date'] = pd.to_datetime(df['Date']) # 按周分组,提取每周首个开盘价和最后收盘价 weekly_summary = df.groupby('Week_Number').agg( week_open=('Open', 'first'), week_close=('Close', 'last') ).reset_index() # 生成周标签:周收盘>周开盘标记green,否则red weekly_summary['week_label'] = weekly_summary.apply( lambda x: 'green' if x['week_close'] > x['week_open'] else 'red', axis=1 ) # 将周标签合并回原DataFrame,确保所有行都匹配 df = df.merge(weekly_summary[['Week_Number', 'week_label']], on='Week_Number', how='left')
关键说明
- 用
groupby+agg精准定位每周的开盘/收盘价,避免单日内价格波动干扰 how='left'保证原数据无丢失,所有行都能获取对应周的标签- 可直接将生成的
week_label覆盖原labels字段,统一标签逻辑
二、基于下周标签实现自动买卖回测
假设策略逻辑:
- 每周首个交易日开盘时,根据下周标签操作:
- 下周标签为
green:全仓买入股票(资金买满整股) - 下周标签为
red:卖出所有持仓,持有现金
- 下周标签为
- 初始资金:100美元,暂不考虑交易成本
步骤1:生成下周标签数据
先将周标签向下移位,得到每个周对应的下周操作信号:
# 给周数据添加下周标签 weekly_summary['next_week_label'] = weekly_summary['week_label'].shift(-1) # 合并回原DataFrame,让每日数据都携带对应周的下周信号 df = df.merge(weekly_summary[['Week_Number', 'next_week_label']], on='Week_Number', how='left')
步骤2:模拟买卖操作
跟踪现金、持仓股数、总资产的变化:
# 初始化回测参数 initial_cash = 100 cash = initial_cash shares_held = 0 total_assets = [] # 遍历数据执行周初操作 for idx, row in df.iterrows(): # 判断是否为每周第一个交易日(按索引首次出现判断) is_first_day = (df['Week_Number'] == row['Week_Number']).idxmax() == idx if is_first_day: next_label = row['next_week_label'] open_price = row['Open'] if next_label == 'green' and cash > 0: # 全仓买整股 shares_held = cash // open_price cash -= shares_held * open_price elif next_label == 'red' and shares_held > 0: # 清仓卖出 cash += shares_held * open_price shares_held = 0 # 计算当日总资产 daily_total = cash + shares_held * row['Close'] total_assets.append(daily_total) # 将总资产添加到DataFrame df['total_assets'] = total_assets
结果验证
查看最终收益或绘制资产曲线:
# 打印最终总资产 print(f"最终总资产: ${df['total_assets'].iloc[-1]:.2f}") # 绘制资产变化曲线(需matplotlib) import matplotlib.pyplot as plt plt.plot(df['Date'], df['total_assets']) plt.title('Strategy Asset Growth') plt.xlabel('Date') plt.ylabel('USD') plt.show()
可优化点
- 若每周首个交易日不是周一,可改为判断
row['Weekday'] == 'Monday' - 如需加入交易成本,可在买入/卖出时扣除固定佣金或比例费用
内容的提问来源于stack exchange,提问作者Jean-Paul Azzopardi
相关产品推荐
相关产品推荐

