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

基于DataFrame中入场/离场信号列计算区间股价涨跌幅

高效计算股票信号区间内的PnL(涨跌幅)

需求说明

需要在包含Entry Signal(入场信号)、Exit Signal(离场信号)和股价的DataFrame中,计算每一组「入场-离场」区间内的涨跌幅(PnL),替代循环遍历每行维护持仓状态的低效方法。

示例数据

Date       Price    Entry Signal    Exit Signal   Price Change
2024-01-18  3595.0  NaN            NaN
2024-01-19  3280.0  Entry          NaN
2024-01-22  3505.0  NaN            NaN
2024-01-23  3945.0  NaN            Exit       (3945 / 3280 - 1)
2024-01-24  4075.0  NaN            NaN
2024-03-07  10270.0 Entry          NaN
2024-03-08  8120.0  NaN            NaN
2024-03-11  6620.0  NaN            Exit       (6620 / 10270 - 1)

高效实现方法(基于Pandas向量操作)

利用Pandas内置函数实现无循环计算,步骤如下:

1. 标记持仓状态

通过累加入场/离场信号生成持仓状态列,确保只有「空仓(0)」和「持仓(1)」两种状态:

# 入场信号记为+1,离场信号记为-1,累加后限制最小值为0
df['position'] = (df['Entry Signal'].notna() * 1) - (df['Exit Signal'].notna() * 1)
df['position'] = df['position'].cumsum().clip(lower=0)

2. 填充对应入场价格

在入场信号出现的行记录当日股价,并用向前填充(ffill)将入场价覆盖整个持仓区间:

# 仅在入场日记录价格,其余行用前一个入场价填充
df['entry_price'] = df.loc[df['Entry Signal'].notna(), 'Price']
df['entry_price'] = df['entry_price'].ffill()

3. 计算离场时的涨跌幅

仅在离场信号出现的行,用当日价格除以对应入场价计算涨跌幅:

# 仅在Exit Signal行计算涨跌幅,其余行留空
df['Price Change'] = df.apply(
    lambda x: (x['Price'] / x['entry_price'] - 1) if x['Exit Signal'] == 'Exit' else pd.NA,
    axis=1
)

完整代码示例

import pandas as pd

# 构造示例DataFrame
data = {
    'Date': ['2024-01-18', '2024-01-19', '2024-01-22', '2024-01-23', '2024-01-24', '2024-03-07', '2024-03-08', '2024-03-11'],
    'Price': [3595.0, 3280.0, 3505.0, 3945.0, 4075.0, 10270.0, 8120.0, 6620.0],
    'Entry Signal': [pd.NA, 'Entry', pd.NA, pd.NA, pd.NA, 'Entry', pd.NA, pd.NA],
    'Exit Signal': [pd.NA, pd.NA, pd.NA, 'Exit', pd.NA, pd.NA, pd.NA, 'Exit']
}
df = pd.DataFrame(data)
df['Date'] = pd.to_datetime(df['Date'])

# 计算持仓状态
df['position'] = (df['Entry Signal'].notna() * 1) - (df['Exit Signal'].notna() * 1)
df['position'] = df['position'].cumsum().clip(lower=0)

# 填充入场价格
df['entry_price'] = df.loc[df['Entry Signal'].notna(), 'Price']
df['entry_price'] = df['entry_price'].ffill()

# 计算涨跌幅
df['Price Change'] = df.apply(
    lambda x: (x['Price'] / x['entry_price'] - 1) if x['Exit Signal'] == 'Exit' else pd.NA,
    axis=1
)

# 查看结果
print(df[['Date', 'Price', 'Entry Signal', 'Exit Signal', 'Price Change']])

说明

这种方法全程使用Pandas的向量化操作,避免了循环遍历的性能瓶颈,在处理大规模行情数据时效率优势明显。

内容的提问来源于stack exchange,提问作者Anonymous

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 20:52:06