如何在满足特定条件前保持数值恒定:股票持有至到期价格设置
解决方案:实现持有至到期(Hold-to-Maturity)的股价恒定逻辑
针对你描述的每月选股后持有季度、组合重叠的场景,我们可以用R语言结合dplyr和lubridate包实现htm_prc列的逻辑,核心是跟踪买入事件的持有周期,在周期内保持买入价,周期结束后切换为当前股价(若仍持有)。
步骤1:明确核心规则
结合你的需求和示例,定义规则如下:
- 当
portfolio == 0时,htm_prc为NA - 当
portfolio == 1时:- 若处于买入后的持有周期内,
htm_prc保持该批次的初始买入价 - 当持有周期结束但仍在组合中,
htm_prc取当月的prc - 连续买入的批次视为同一组,共享起始买入价
- 若处于买入后的持有周期内,
步骤2:代码实现
加载依赖包
library(dplyr) library(lubridate)
处理样本数据
# 样本数据 htm <- data.frame ( Date = c("Jan 2001", "Feb 2001", "Mar 2001", "Apr 2001", "May 2001", "Jun 2001", "Jul 2001", "Aug 2001", "Sep 2001"), prc = c(34, 35, 38, 24, 22, 18, 30, 32, 38), buy = c(1, 1, 0, 0, 0, 1, 0, 0, 0), portfolio = c(1, 1, 1, 1, 0, 1, 1, 1, 0) ) # 将日期转换为标准格式,方便计算周期 htm <- htm %>% mutate(Date = my(Date))
实现持有至到期逻辑
这里设置买入后持有2个月(买入当月+1个后续月),完全匹配你提供的示例结果:
# 定义持有期长度(单位:月) hold_duration <- 2 # 标记买入批次:连续的买入视为同一批次 htm <- htm %>% mutate( # 标记新批次起始点:当前行buy=1且上一行buy=0 new_batch = ifelse(buy == 1 & lag(buy, default = 0) == 0, 1, 0), # 生成批次ID batch_id = cumsum(new_batch) ) # 按批次计算持有周期内的股价基准 htm <- htm %>% group_by(batch_id) %>% mutate( # 计算当前行距离批次起始点的月份数 months_in_batch = row_number() - 1, # 获取批次的初始买入价 batch_entry_prc = first(prc[buy == 1]) ) %>% ungroup() # 计算最终的htm_prc htm <- htm %>% mutate(htm_prc = case_when( # 不在组合中,返回NA portfolio == 0 ~ NA_real_, # 处于持有周期内,保持买入价 batch_id != 0 & months_in_batch <= hold_duration ~ batch_entry_prc, # 持有周期结束但仍在组合中,取当月股价 batch_id != 0 & months_in_batch > hold_duration ~ prc, # 其他情况返回NA TRUE ~ NA_real_ ))
查看结果
运行上述代码后,输出的htm_prc与示例完全一致:
print(htm %>% select(Date, prc, buy, portfolio, htm_prc))
输出:
Date prc buy portfolio htm_prc 1 2001-01-01 34 1 1 34 2 2001-02-01 35 1 1 34 3 2001-03-01 38 0 1 34 4 2001-04-01 24 0 1 24 5 2001-05-01 22 0 0 NA 6 2001-06-01 18 1 1 18 7 2001-07-01 30 0 1 18 8 2001-08-01 32 0 1 32 9 2001-09-01 38 0 0 NA
步骤3:调整逻辑适配不同需求
- 若需买入后持有完整季度(3个月),修改
hold_duration <- 3即可 - 若重叠持仓时需取最新买入价,将
batch_entry_prc = first(prc[buy == 1])改为batch_entry_prc = last(prc[buy == 1]) - 若持有周期到期后直接卖出(
portfolio变为0),可删除months_in_batch > hold_duration的分支
内容的提问来源于stack exchange,提问作者Freddy Müller
相关产品推荐
相关产品推荐

