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

Python实现债券市场有效价差计算:时序数据合并与计算咨询

如何匹配交易前的报价并计算债券有效价差?

我来一步步帮你解决这个问题——核心就是给每笔交易匹配到它发生前最近的报价中点,然后套用公式计算有效价差。用Pandas的merge_asof函数就能完美解决时序匹配的问题,比自己写循环高效太多。

步骤1:准备并清洗数据

首先我们先把示例数据加载进来,然后统一时间格式(把日期和时间字段合并成完整的datetime类型,这样才能做时序比较),同时计算报价中点。

import pandas as pd

# 加载示例报价数据
quote_data = pd.DataFrame({
    'Id': [1, 1, 2],
    'BuyTime': ['09:00:20', '09:10:21', '09:11:22'],
    'BuyPrice': [1005, 1020, 1032],
    'Date': ['2010-01-01', '2010-01-01', '2010-01-02'],
    'SellTime': ['09:00:10', '09:10:25', '09:11:19'],
    'SellPrice': [1001, 1012, 1020]
})

# 加载示例交易数据
trade_data = pd.DataFrame({
    'Id': [1, 1, 2],
    'Time': ['09:00:21', '09:10:26', '09:11:23'],
    'Date': ['2010-01-01', '2010-01-01', '2010-01-02'],
    'Price': [1004, 1017, 1028]  # 修正示例笔误:2028→1028
})

# 处理报价数据:合并日期和最新的报价时间(取买卖报价时间中较晚的),计算中点
quote_data['BuyDatetime'] = pd.to_datetime(quote_data['Date'] + ' ' + quote_data['BuyTime'])
quote_data['SellDatetime'] = pd.to_datetime(quote_data['Date'] + ' ' + quote_data['SellTime'])
quote_data['QuoteDatetime'] = quote_data[['BuyDatetime', 'SellDatetime']].max(axis=1)
quote_data['MidQuote'] = (quote_data['BuyPrice'] + quote_data['SellPrice']) / 2.0
quote_clean = quote_data[['Id', 'Date', 'QuoteDatetime', 'MidQuote']]

# 处理交易数据:合并日期和时间成完整datetime
trade_data['TradeDatetime'] = pd.to_datetime(trade_data['Date'] + ' ' + trade_data['Time'])
trade_clean = trade_data[['Id', 'Date', 'TradeDatetime', 'Price']]

步骤2:时序匹配交易与报价

这里用pd.merge_asof是关键——它专门用于按时间顺序匹配两个数据集,能高效找到每笔交易发生前最近的报价:

  • by=['Id', 'Date']:确保只匹配同一个债券(Id)、同一天的报价,避免跨品种/跨日期错误匹配
  • direction='backward':指定只找交易时间之前的最近报价(t-ε时刻的报价)
  • 注意:必须先对两个数据集的时间列排序,merge_asof要求输入是有序的
# 执行时序匹配
merged_data = pd.merge_asof(
    trade_clean.sort_values('TradeDatetime'),
    quote_clean.sort_values('QuoteDatetime'),
    by=['Id', 'Date'],
    left_on='TradeDatetime',
    right_on='QuoteDatetime',
    direction='backward'
)

步骤3:计算有效价差

根据你给出的公式:

  • 买入市价单(成交价格>报价中点):2*(pt - mt)
  • 卖出市价单(成交价格<报价中点):2*(mt - pt)
  • 若成交价格等于中点,有效价差为0

用apply函数就能轻松实现这个逻辑:

# 计算有效价差
merged_data['EffectiveSpread'] = merged_data.apply(
    lambda row: 2 * (row['Price'] - row['MidQuote']) if row['Price'] > row['MidQuote']
    else 2 * (row['MidQuote'] - row['Price']) if row['Price'] < row['MidQuote']
    else 0,
    axis=1
)

# 查看最终结果
print(merged_data[['Id', 'TradeDatetime', 'Price', 'MidQuote', 'EffectiveSpread']])

输出结果和你的示例完全一致:

Id       TradeDatetime  Price  MidQuote  EffectiveSpread
0   1 2010-01-01 09:00:21   1004    1003.0              2.0
1   1 2010-01-01 09:10:26   1017    1016.0              2.0
2   2 2010-01-02 09:11:23   1028    1026.0              4.0

注意事项

  1. 边界情况处理:如果某笔交易之前没有任何报价(比如当天第一笔交易),merge_asof会让MidQuote为NaN,你可以根据需求用dropna()删除这些记录,或者用当天第一笔报价填充。
  2. 时间精度:如果你的数据有毫秒级精度,确保datetime列保留足够的精度,避免匹配错误。
  3. 大数据量适配:merge_asof是向量化操作,比循环处理快得多,即使是百万级别的数据也能高效运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:51:33