You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 00:18:03