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

R语言循环计算各标的800/100手往返买卖加权价差

R语言盘口往返交易加权价差计算实现

原有代码核心问题

  • 硬编码按10行步长切分数据,没有按reference字段分组,也没有按type字段区分买卖盘,不同分组盘口行数不固定的情况下必然计算错误
  • 函数内引用了不存在的quote字段,实际数据集中价格字段为price,字段不匹配导致计算失败
  • 缺少成交量前置校验逻辑,没有过滤买卖盘单侧总成交量小于目标往返手数的分组
  • 相对价差计算逻辑错误,未按要求除以分组对应的中点价PM
  • 手动维护行号start/end的逻辑鲁棒性极差,数据顺序稍有变动就会出问题

修正后代码

首先实现核心的成交量加权平均价计算函数,逻辑完全匹配给出的累加规则:

# 传入单方向盘口数据(买盘/卖盘)、目标往返手数,返回加权平均价
# 若该方向总成交量不足目标手数,返回NA用于后续过滤
calc_vwap <- function(order_df, target_vol) {
  total_avail <- sum(order_df$total_volume)
  if (total_avail < target_vol) return(NA_real_)
  
  total_amount <- 0
  remain <- target_vol
  for (i in seq_len(nrow(order_df))) {
    if (remain <= 0) break
    take <- min(remain, order_df$total_volume[i])
    total_amount <- total_amount + take * order_df$price[i]
    remain <- remain - take
  }
  return(total_amount / target_vol)
}

然后实现分组计算主逻辑,自动按reference分组处理,不需要手动维护行号:

library(dplyr)

# 传入原始数据集,可自定义要计算的往返手数,默认计算100、800手
calc_spread <- function(raw_data, roundtrip_vols = c(100, 800)) {
  result <- raw_data %>%
    group_by(reference) %>%
    group_modify(~{
      # 拆分当前分组的买卖盘,按盘口优先级排序
      # 买盘按sign降序:sign=1为买一(最高买价)、sign=2为买二,和示例逻辑一致
      bid_df <- .x %>% filter(type == "bid") %>% arrange(desc(sign))
      # 卖盘按sign升序:sign=-1为卖一(最低卖价)、sign=-2为卖二,和800手计算逻辑一致
      ask_df <- .x %>% filter(type == "ask") %>% arrange(sign)
      pm <- first(.x$PM)
      
      # 初始化结果行,需要保留date、time字段的话在这里加,比如:
      # res <- tibble(date = first(.x$date), time = first(.x$time), PM = pm)
      res <- tibble(PM = pm)
      
      # 逐个计算每个目标手数的指标
      for (vol in roundtrip_vols) {
        s_b <- calc_vwap(bid_df, vol)
        s_a <- calc_vwap(ask_df, vol)
        # 任意一侧成交量不足则丢弃该分组
        if (is.na(s_b) | is.na(s_a)) return(tibble())
        res[[paste0("S_B_", vol)]] <- s_b
        res[[paste0("S_A_", vol)]] <- s_a
        res[[paste0("rel_spread_", vol)]] <- (s_a - s_b) / pm
      }
      return(res)
    }) %>%
    ungroup()
  return(result)
}

使用说明

  • 直接将原始数据集传入函数即可得到结果:final_result <- calc_spread(你的数据集名)
  • 返回结果中每个reference对应一行,包含PM中点价、各手数对应的买盘加权价S_B、卖盘加权价S_A、相对价差,自动过滤掉买卖盘任意一侧成交量不足的分组
  • 如果实际业务中盘口档位排序和代码默认规则不一致,只要修改bid_df/ask_df的arrange排序参数即可
  • 示例中100手S_A写为16.85和给出的800手计算逻辑存在冲突:按800手先取16.84档位200手的规则,100手S_A应为16.84,如果是笔误调整排序即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 18:09:26