回测一月效应
这里给出了在标准普尔600小盘股上运用一月效应策略计算收益率的MATLAB代码。(源代码和数据可以从epchan. com/book/ example7_6. m下载。)
clear
load(’IJ R 20080131’);
onewaytcost=0. 0005;% 5bp one way transaction cost
years=.。
year(cellstr(datestr(datenum(cellstr(..
num2str(tday)),'yyyymmdd'))));
months=二
month( cellstr(datestr( datenum (cellstr(..
num2str(tday)),'yyyymmdd'))));
nextdayyear=f wdshif t (1, years);
nextdaymonth=fwdshift(1,months);
lastdayofDec=find (months==12&nextdaymonth==1);
lastdayofJan=find( months==1&nextdaymonth ==2 );
%lastdayofDec从2004年开始,
%所以将2004从lastdayofJan中删掉
IastdayofJan(1) = []; 0 o确定每个IastdayofDec后的lastdayofJan
assert (all(tday(lastdayofJan)> tday(lastdayofDec)));
eoy=find(years? =nextdayyear);%年末指数
eoy(end) _ [] ;%上一个指数不是年末的
%确保eoy日期与lastdayofDec日期匹配
assert (all(tday(eoy)==tday(lastdayofDec)));
annret=.。
(cl(eoy(2:end),:)-cl(eoy(1:end-1),:))./..
cl(eoy(1:end-1),:);%年收益率
]anret=..
(cl(lastdayofJan(2:end),:)-
cl(lastdayofDec(2: end).:))./cl(lastdayofDec(2:end),:);
% ]月收益率
for y=1:size(annret,1)
%选取年收益率可观的股票
hasData=..
find( isf inite(annret( y,:)));
%根据前一年的收益率排序
[foo sortidx]=sort (annret (y . hasData ),fascend');
%买入十分位数(decile)收益率最低的股票,卖出十分位数收益率最高的股票
topN = round (length (hasData)/10);
%组合收益率
portRet=..
(smart mean (janret(y. hasData(sortidx(I:topN))))—..
smart mean (j anret (y, hasData(..
sortidx(end一topN+1 :end)))))/2-2*onewaytcost;
fprintf(1,'Last holding date%i:Portfolio
return=% 7. 4f\n’.tday(lastdayofDec(y+1)).portRet));
end
%这里应该是输出
%最后持有期20051230:组合收益率=-0.0244
%最后持有期20061229:组合收益率=-0.0068
%最后持有期20071231:组合收益率=0.0881
这一程序用到了大量的工具函数。第一个是assert函数,用于确保程序是正确的。
function assert( pred,str)
写若前提条件非真,ASSERT会报错.
%assert (pred, string)
if nargin<2,str=’;end
if ^~ pred
s=sprintf ('assertion violated:% s,str);
error(s);
end
第二个函数足fwdshift函数,与lag1函数相反,是将时间序列函数向前移动一步。
function y=fwdshift(day, x)
assert(day>=0);
y=[x(day+1:end,:,:);..
NaN*ones(day, size(x,2),size(x,3))];