加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

把同比、环比时间序列(例如CPI,PPI等)转换成定基指数序列的函数

(2009-08-10 21:23:21)
标签:

杂谈

分类: MSN搬家

% 把同比、环比时间序列(例如PPI,PPI等)转换成定基指数序列的函数。
% 寇文红,2009年5月26日于隆安公寓。10月27日修改

% 用途:
% 国家统计局公布的CPI、PPI、工业增加值等都是同比月度序列(有时有环比),没有原始绝对量数据。
% 这些同比序列是用原始绝对量序列直接计算来的,而原始数据中包含了趋势性、周期性、季节性、不规则性(其中包括异常值)等四个部分。
% 因此这些同比序列:
%(1)依赖于过去12月的数据。隐含假定每年的季节模式不变。这是不对的。
%(2)包含移动假日效应(例如春节效应)、季节性、以及每月交易日数目不同带来的影响。
%(3)容易掩盖趋势变化,用这种数据来观察经济趋势转折点不准确,一般要趋势变动几个月后到半年才能看出来,错过时机。
% 由于不能对同比序列进行季节调整,而应该对原始序列进行季节调整,但是我国的原始序列不可得。因此
% 本程序的目的是把同比(环比)序列转化成定基指数序列,然后对其进行季节性调整。

% 转换方法:
% 把环比数据分四种情况:A,有齐全的环比;B,有环比,有缺失,但至少有一个周期齐全;C,有环比但没有一个周期齐全;D,没有环比。
% 把同比数据分两种情况:a,有同比(不管是否齐全);b,无同比数据。
% 这样一共有八种组合,可以分出三种转换方法:
%(1)Aa,Ba,有环比,环比数据至少有一个周期(例如2000年)是齐全的。另外还有同比(不管同比是否齐全)。这在中国最常见,例如CPI和PPI数据。
    这时可令(例如)2000年1月=100,用环比数据计算出2000年2-12月的指数,再用同比数据计算出其他各年各月的数据。
    但是,由于我国的同比、环比数据往往不匹配,即用方法1,2计算得到的指数,再倒算环比,和原始的环比数据往往对不上。差别相当大。
    对此,如果我们假设“同比数据不失真”,那么必定有“环比数据失真”,这意味着方法1中用环比数据来计算基年的数据是有问题的,即人为地引入了干扰
    。很多人在有环比数据的情况下,宁愿采用下面的方法2,即完全用同比数据构造指数(例如张鸣芳,2009,p.95),
    也许就是因为他们认为环比数据不准。但是这种方法也是饮鸩止渴,是我见过的最愚蠢的方法,因为这样最初引入的误差永远不能消除。
%(2)Ca,Da,有环比数据,但每个周期都不齐全,等同于没有环比。有同比数据(不管是否齐全)。
    这时令第1年之前1年各月都为100,再依次推出其他各年各月的指数。这是很多人的做法,他们认为这样开始几年的误差较大,
    但不断衰减的,几年之后就可忽略不计。其实不是这样。推导一下就可以知道,最初那年引入的误差是永远也不会消失的。
%(3)Aa,Ab,有环比数据,且各月数据齐全,无缺失值。这时可令第base个数据为100,再依次推出以后各月数据。
    但是,对于中国的数据,环比常常有缺失。即使无缺失,同比和环比也往往不匹配,导致用方法1和3得到的指数不一致。
    因此我们建议尽量使用同比数据来计算,即首选方法1,其次是方法2,再次是方法3.
    也就是说,对于Aa的情况,尽量用方法1.只有对于Ab的情况,才采用方法3.
%(4)其他可能性Bb,Cb,Db:没有同比也没有齐全的环比,这时候无法转换。

% 用户输入:
% 在调用本函数之前,需要用户设定的参数有6个:
% (1)时间date
% (2)环比序列mom
% (3)同比序列yoy,如果没有可以设定yoy=[];
% (4)per,如果取0,表示原始的yoy和mom已经是百分比,只要加1即可;如果不取0,则表示原始yoy和mom是百分点数,需要除以100换算成百分比再加1。
    由于我国统计局公布的同比序列都是百分点数,因此本函数中,只要用户不选择per==0,那么不管per等于多少,都默认为需要除以100。
% (5)approach,可以等于1,2,3,对应上述三种算法。用户必须根据自己数据的情况来选择approach的值。
% (6)base,表示把第base个观测所在月份作为基期(=100),用户必须根据自己数据的情况来选择base的值。原始数据最好从某年1月开始,base对应某年的1月份。


function index=function_to_switch_yoy_and_mom_ts_to_common_base_index(date,mom,yoy,per,approach,base)
if per==0
    yoy=yoy+1;
    mom=mom+1;
else
    yoy=yoy/100+1;
    mom=mom/100+1;
end

obs=length(date); 
if base>obs
    error('傻帽,你设定的base太大了,base应该小于观测的数目')
else
end

index=zeros(obs,1);                       %用来存放转换好的指数序列。
    
if approach==1
    index(base)=100;
    for i=1:11
        index(base+i)=index(base+i-1)*mom(base+i);
    end   
    for i=0:11
        for j=1:(base/12+1)
            if (base+i)-12*j>0
                index(base+i-12*j)=index(base+i-12*(j-1))/yoy(base+i-12*(j-1));
            else
            end
        end
        for j=1:(obs-base)/12
            if (base+i)+12*j<obs||(base+i)+12*j==obs
                index(base+i+12*j)=index(base+i+12*(j-1))*yoy(base+i+12*j);
            else
            end
        end
    end
   
elseif approach==2
    if base~=1
        disp('对于这种方法,我们推荐以第一年之前的那一年为基期,不管用户选择base为多少,都强制地令base==1')
        base=1;
    else
    end   
    for i=1:12
        index(i)=100*yoy(i);
    end   
    for i=0:11
        for j=1:obs/12
            if base+i+12*j<obs||base+i+12*j==obs
                index(base+i+12*j)=index(base+i+12*(j-1))*yoy(base+i+12*j);
            else
            end
        end
    end
   
elseif approach==3
    disp('对于中国的数据,我们不推荐采用这种方法,推荐首选方法1,其次方法2,再次才是这种方法')
    index(base)=100;   
    for i=1:base-1
        index(base-i)=index(base-i+1)/mom(base-i);
    end   
    for i=1:obs-base
        index(base+i)=index(base+i-1)*mom(base+i);
    end
   
else
    error('参数approach的值应当是1,2,或3。你个大傻帽!');
end

disp('tmd统计局这帮混蛋,你们编造的这些烂数据,使我们不得不浪费多少时间和精力来寻求真相啊!');

%程序写完之后,卫平认为有两个缺点:一是一次只能处理一个序列。我的看法是反正中国的经济序列长度各不相同,想批量处理也不可能;
%二是他认为循环太多,降低了计算速度,应该多用MATLAB内嵌的函数。他作了修改,出了一个循环少的。
%我觉得像我这样的大脑也就能想出这样的方法了,聪明的方法是他那种智商的人想的,哈哈,我是学不来的。
%就是这次学了,下次遇到另一个问题肯定还是用笨办法。好在现在CPU比较好,中国的经济序列又都不长......哈哈

 

 

 

 

 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有