Pandas中满足止损条件时如何终止原有持仓标记逻辑执行?
解决方案
原有代码逻辑为先完整生成全量的BUY/HOLD/SELL标记,再替换止损行的内容,没有阻断止损触发后的原有标记生成,所以会出现止损后仍然有HOLD/SELL的问题。需要调整逻辑为:先按BUY事件分组,每组内先判断止损触发位置,止损触发后的行直接中断正常交易标记逻辑,仅在未触发止损的区间生成对应标记。
修改后可直接运行的完整代码如下:
import pandas as pd import numpy as np # 构造测试数据集 data = { 'Close': [60.6, 57.8, 59.6, 54.1, 53.6, 54.5, 66.1, 66.0], 'X': [0, 100, 0, 0, 0, 0, 100, 0], 'SL': [np.nan, 55.4, 55.4, 55.4, 55.4, 55.4, 62.3, 62.3] } df = pd.DataFrame(data) # 给每次BUY事件分组,每次X=100时分组编号+1 df['buy_group'] = df['X'].eq(100).cumsum() # 保留原始行索引,处理完后恢复顺序 df = df.reset_index(drop=False) def process_group(g): # 跳过BUY出现前的无效分组 if (g['X'] == 100).sum() == 0: g['Remarks'] = '' return g # 定位当前分组第一次触发止损的位置 stop_trigger_idx = g[g['Close'] < g['SL']].first_valid_index() g['Remarks'] = '' valid_end = len(g) # 处理止损逻辑 if stop_trigger_idx is not None: stop_pos = g.index.get_indexer([stop_trigger_idx])[0] stop_end = min(stop_pos + 2, len(g)) g.iloc[stop_pos:stop_end, g.columns.get_loc('Remarks')] = 'Stopped Out' # 止损触发后中断后续正常标记逻辑 valid_end = stop_pos # 未止损区间生成正常交易标记 for i in range(min(valid_end, len(g))): if i == 0: g.iloc[i, g.columns.get_loc('Remarks')] = 'BUY' elif 1 <= i <= 3: g.iloc[i, g.columns.get_loc('Remarks')] = 'HOLD' elif 4 <= i <= 5: g.iloc[i, g.columns.get_loc('Remarks')] = 'SELL' return g # 按分组处理后恢复原始顺序 df = df.groupby('buy_group', group_keys=False).apply(process_group).sort_values('index').drop(columns=['index', 'buy_group']).reset_index(drop=True) print(df)
运行后输出结果和需求完全一致。
内容的提问来源于stack exchange,提问作者Johar Inam Unnar
相关产品推荐
相关产品推荐

