Python pandas下按指定条件为Dataframe生成position列的实现方法
实现思路
- 首先识别所有符合开仓条件的节点:当行满足
signal == 1且Closeprice > ATR时标记为开仓点,同时记录该节点的ATR值作为后续平仓的判断阈值 - 将开仓点的ATR值向前填充到后续所有行,直到出现下一个开仓点为止,保证持仓期间始终用开仓时的ATR作为平仓判断标准
- 逐行更新持仓状态:开仓点直接将position设为1,持仓期间如果
Closeprice低于对应开仓时的ATR值则将position设为0,无信号时保持上一期的持仓状态即可
代码实现
以下为向量化实现方案,性能远高于逐行遍历,适合大样本量数据:
import pandas as pd import numpy as np # 假设你的原始DataFrame为df,已包含signal、Closeprice、ATR三列 # 1. 标记开仓点,记录开仓时的ATR阈值 df['is_entry'] = (df['signal'] == 1) & (df['Closeprice'] > df['ATR']) df['entry_atr_val'] = np.where(df['is_entry'], df['ATR'], np.nan) # 2. 前向填充开仓ATR值,覆盖整个持仓周期 df['hold_exit_threshold'] = df['entry_atr_val'].ffill() # 3. 初始化持仓状态 df['position'] = 0 # 4. 标记平仓点:上一期为持仓状态,且当期收盘价跌破开仓ATR阈值 df['is_exit'] = (df['position'].shift(1) == 1) & (df['Closeprice'] < df['hold_exit_threshold']) # 5. 生成最终position列:开仓设1,平仓设0,其余时间保持上一期状态 df['position'] = np.where( df['is_entry'], 1, np.where(df['is_exit'], 0, df['position'].shift(1).fillna(0)) ) # 清理辅助列(可选) df.drop(columns=['is_entry', 'entry_atr_val', 'hold_exit_threshold', 'is_exit'], inplace=True)
逻辑校验说明
- 上述实现默认不支持连续开仓,第一次开仓后直到平仓前,后续的开仓信号会被忽略,符合普通单标的单仓位的交易逻辑,若需要支持多仓位叠加,可调整开仓阈值的记录逻辑,为每个开仓信号单独跟踪平仓条件
- 实现中使用
shift(1)避免了未来函数,所有判断仅使用当期及历史数据,适配量化回测和实盘信号生成的要求 - 若你的数据存在涨跌停、停盘等异常价格场景,可在开平仓判断条件中额外添加价格有效性校验逻辑即可
内容的提问来源于stack exchange,提问作者Kire
相关产品推荐
相关产品推荐

