Bootstrap

线性插值法的MATLAB实现——对股票非交易日缺失数据进行插值

1.为什么要处理非交易日股票缺失数据

  由于在计算无风险利率时,常常使用国债利率,但国债利率按360天计息,因此股票收益率需要和债券计息相匹配,所以需要对股票缺失数据进行插值。

2.为什么使用线性插值法

  当数据点之间距离很短时,就可以近似认为两点间可以用直线连接。类似微积分的思想,用导数替代微分。

3.线性插值法

  线性插值法,假设两点间以直线连接,则类似1次函数,使用斜率×横坐标来得到纵坐标,即 y y y = k k k x x x
  由于已经知道两端点坐标,所以可以使用 y 1 − y 2 x 1 − x 2 \frac{y_1-y_2}{x_1-x_2} x1x2y1y2得到。对于 x x x,假设两点间想再插两点,例如4月1号是周五,周末为4月2号和3号,4月4号再次开盘,则需要插入两天。由于不知道起始的 x 0 x_0 x0点,因此不能直接用斜率 k × ( x − x 0 k×(x-x_0 k×(xx0)得到中间点的 y y y值,但可以用 y 1 + k × ( x − x 1 y_1+k×(x-x_1 y1+k×(xx1)得到 y y y值。
  因此,线性插值法的最终公式为 y = y 2 − y 1 x 2 − x 1 × ( x − x 1 ) y = \frac{y_2 - y_1}{x_2 - x_1}×(x - x_1) y=x2x1y2y1×(xx1)

4.MATLAB代码实现

function after_insert = insert_number(time, price)  % time是datatime格式的日期数组,price是股价数组
% 建立一个空数组after_insert,行数是首端和尾端间所有日历天数
    % 算出相差的日历天数
    days_between = days(time(end) - time(1)) + 1;
    % 建立数组
    after_insert_time = NaT(days_between, 1);
    after_insert_num = zeros(days_between, 1);
    row = size(time);
% 找出有间断的日期进行插值
    % 找出有间断的日期
    k = 0;  % k是after_insert的行索引,用来插入缺失的日历日期的值
    for i = 1:row - 1
        k = k + 1;
        if days(time(i + 1) - time(i)) > 1  % 如果两个日期间日历天数大于1,就进行插值
       
            for j = 1:days(time(i + 1) - time(i)) - 1
                slope = (price(i + 1) - price(i)) / days(time(i + 1) - time(i));  % 计算斜率
                after_insert_time(k + j) = time(i) + j;  % 插入时间
                after_insert_num(k + j) = price(i) + slope * j;  % 插入数值
            end
            after_insert_time(k) = time(i);
            after_insert_num(k) = price(i);
            k = k + days(time(i + 1) - time(i)) - 1;
        else                                                   % 把原有的数据插入after_insert
            after_insert_time(k) = time(i);
            after_insert_num(k) = price(i);
        end
    end
    % 插入最后一天
    after_insert_time(k + 1) = time(end);
    after_insert_num(k + 1) = price(end);
    after_insert = table(after_insert_time, after_insert_num);
end

5.计算股票收益率的波动率

after_insert = insert_number(time, price);  % 使用刚才的函数
after_insert_price = after_insert.after_insert_num;  % 得到插值后的股价
income_rate = diff(log(after_insert_price));  % 计算对数收益率
sigma = std(income_rate) * sqrt(360)  % 计算收益率的波动率
;