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

如何按Symbol生命周期补全时序表缺失数据?

补全时序表中的缺失数据

问题背景

需要补全时序表中每个symbol在其生命周期内的缺失工作日记录,用前一日期的记录填充;超出生命周期或周末的缺失记录不做处理。

示例数据

// 创建示例数据
tmp:([]date:`date$();sym:`symbol$();name:`symbol$();expiration_date:`date$());
// 插入模拟数据
{`tmp insert (x;`ESH10;`someName1;2010.01.10)} each (2010.01.01 + til 31);
{`tmp insert (x;`ESH11;`someName2;2010.01.15)} each (2010.01.01 + til 31);
{`tmp insert (x;`ESH12;`someName3;2010.01.20)} each (2010.01.01 + til 31);
{`tmp insert (x;`ESH13;`someName4;2010.01.16)} each (2010.01.01 + til 31);
{`tmp insert (x;`ESH14;`someName5;2010.01.13)} each (2010.01.01 + til 31);
{`tmp insert (x;`ESH15;`someName6;2010.01.28)} each (2010.01.01 + til 31);

// 删除周末记录
tmp:select from tmp where not (date mod 7) in 0 1

// 删除指定记录模拟缺失情况
tmp:delete from tmp where sym=`ESH10, date=2010.01.05;
tmp:delete from tmp where sym=`ESH11, date=2010.01.22;
tmp:delete from tmp where sym=`ESH12, date=2010.01.10;
tmp:delete from tmp where sym=`ESH15, date=2010.01.06;

需求说明

检查每个symbol的生命周期(该symbol的首次date到expiration_date区间):

  • 区间内的工作日若无对应记录,用前一日期的记录填充;
  • 超出生命周期或属于周末的缺失记录,不做处理。

预期处理逻辑示例

  • ESH10的生命周期为(2010.01.01;2010.01.10),缺失2010.01.05的记录,需用2010.01.04的记录填充;
  • ESH11的生命周期为(2010.01.01;2010.01.15),缺失的2010.01.22超出生命周期,不处理;
  • ESH12缺失的2010.01.10为周末,不处理;
  • ESH15的生命周期为(2010.01.01;2010.01.28),缺失2010.01.06的记录,需用2010.01.05的记录填充。

原未生效代码

.qatest.fill_dates:{[res]
    //lets just get the fields we need
    res1:(select date, root, norm_sym, volume, open_int, voi:?[null volume;open_int;?[null open_int;volume;volume+open_int]], expiration_date from res);
    
    //get life of each symbol
    t1:0!select sd:first date, ed:last expiration_date by root, norm_sym from res1;
    
    raze {[res1;t1]
        //generate daterange for symbol start date and end date
        daterange:.dateutils.date_range[t1[`sd];t1[`ed]];
        //get weekdays only
        daterange:daterange where not (daterange mod 7) in 0 1;
        raze {[r;t;d]
            cnt:count select from r where date=d, norm_sym=t[`norm_sym];
            $[cnt;
                [
                    //no need to copy
                    r
                ];
                [
                    //need to copy from prev date
                    dataToCopy:select from r where date=.dateutils.prev_valid_date[d;`us], norm_sym=t[`norm_sym];
                    dataToCopy:update date:d from dataToCopy;
                    `date xasc r,dataToCopy
                ]
            ]
        }[res1;t1;] each daterange
    }[res1;] each t1
}

可行解决方案

以下是基于Q语言的高效实现,核心思路是按symbol分组生成生命周期内的工作日列表,左连接原数据后用前向填充补全缺失值:

// 定义补全函数
fillMissingData:{[t]
    // 按sym分组,获取每个symbol的首次日期和到期日
    symLifespan:select firstDate:first date, expDate:first expiration_date by sym from t;
    // 生成指定区间内的所有工作日
    generateWorkdays:{[sd;ed]
        dates:sd + til 1 + ed - sd;
        dates where not (dates mod 7) in 0 1
    };
    // 为每个symbol匹配生命周期内的工作日
    symWorkdays:update workdays:generateWorkdays[firstDate;expDate] by sym from symLifespan;
    // 展开所有symbol的工作日记录
    allDates:raze (select sym, date:workdays, expiration_date:expDate from symWorkdays);
    // 左连接原数据,保留所有必要字段
    joined:left join allDates on t;
    // 按sym分组,前向填充缺失的name等字段
    filled:update name:fills name by sym from joined;
    // 按symbol和日期排序
    `sym`date xasc filled
};

// 调用函数处理示例数据
result:fillMissingData[tmp];

输出示例(以ESH10为例)

date        sym     name        expiration_date
2010.01.01  ESH10   someName1   2010.01.10
2010.01.04  ESH10   someName1   2010.01.10
2010.01.05  ESH10   someName1   2010.01.10  // 填充行
2010.01.06  ESH10   someName1   2010.01.10
2010.01.07  ESH10   someName1   2010.01.10
2010.01.08  ESH10   someName1   2010.01.10
2010.01.11  ESH10   someName1   2010.01.10
2010.01.12  ESH10   someName1   2010.01.10

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 23:34:54