我基本上复制了Matlab示例文件BermudanSwaption.m中的代码,以便根据某些给定的市场数据校准Hull White one factor模型。当我使用大约30个或更少交换的子集作为我的校准集时,我能够得到一个内部解决方案。但是当我使用更多的乐器时,我得到一个奇怪的错误:
以下是代码:
ValuationDate = '10-01-2014';
Settle = datenum(ValuationDate);
% Zero rate data is market data, bootstrapped from Bloomberg and Reuters quotes
CurveDates = [735874;
735882;
735906;
735936;
735950;
736040;
736133;
736224;
736314;
736424;
736606;
736788;
736971;
737153;
737336;
737518;
737701;
737884;
738069;
738251;
738433;
738615;
738797;
738979;
739162;
739345;
739528;
739710;
739893;
740075;
740260;
740442;
740624;
740806;
740989;
741171;
741354;
741536;
741719;
741901;
742084;
742269;
742451;
742633;
742815;
742997;
743180;
743362;
743545;
743728;
743911;
744093;
744278;
744460;
744642;
744824;
745006;
745189;
745372;
745554;
745737;
745919;
746102;
746284;
746469;
746651;
746833;
747015;
747198;
747380;
747563;
747745;
747928;
748111;
748296;
748478;
748660;
748842;
749024;
749206;
749389;
749572;
749755;
749937;
750120;
750302;
750487];
ZeroRates = 1.0e-03*[0.0172;
0.0188;
0.0191;
0.0221;
0.0249;
0.0244;
0.0269;
0.0333;
0.0423;
0.0571;
0.0789;
0.1021;
0.1253;
0.1435;
0.1617;
0.1749;
0.1881;
0.1973;
0.2064;
0.2158;
0.2253;
0.2311;
0.2370;
0.2429;
0.2488;
0.2547;
0.2607;
0.2640;
0.2672;
0.2706;
0.2738;
0.2772;
0.2807;
0.2842;
0.2877;
0.2913;
0.2948;
0.2964;
0.2979;
0.2995;
0.3011;
0.3026;
0.3043;
0.3060;
0.3077;
0.3095;
0.3112;
0.3118;
0.3125;
0.3132;
0.3138;
0.3146;
0.3152;
0.3160;
0.3167;
0.3175;
0.3183;
0.3186;
0.3189;
0.3192;
0.3196;
0.3199;
0.3202;
0.3206;
0.3209;
0.3213;
0.3217;
0.3217;
0.3216;
0.3216;
0.3216;
0.3216;
0.3216;
0.3216;
0.3216;
0.3216;
0.3216;
0.3217;
0.3217;
0.3218;
0.3218;
0.3219;
0.3219;
0.3220;
0.3220;
0.3221;
0.3221];
Compounding = 2;
RateSpec = intenvset('Compounding', 2,'ValuationDate', ValuationDate,'StartDates', ValuationDate,'EndDates', CurveDates,'Rates', ZeroRates);
InstrumentMaturity = datenum('12-Sep-2044');
% Swaption Vol data from Bloomberg
SwaptionBlackVol = [ 0.5940 0.5550 0.4450 0.3710 0.3400 0.3110 0.2910 0.2750 0.2630 0.2520 0.2250 0.2140 0.2080 0.2050;
0.5630 0.5470 0.4420 0.3690 0.3360 0.3090 0.2900 0.2740 0.2630 0.2520 0.2260 0.2150 0.2090 0.2060;
0.5760 0.5330 0.4400 0.3730 0.3410 0.3150 0.2970 0.2820 0.2700 0.2590 0.2330 0.2220 0.2170 0.2140;
0.5840 0.5020 0.4240 0.3730 0.3480 0.3240 0.3060 0.2920 0.2810 0.2710 0.2430 0.2300 0.2230 0.2190;
0.5630 0.4750 0.4100 0.3700 0.3450 0.3230 0.3070 0.2940 0.2830 0.2740 0.2470 0.2330 0.2260 0.2210;
0.5510 0.4520 0.3980 0.3660 0.3410 0.3220 0.3070 0.2950 0.2850 0.2760 0.2500 0.2360 0.2290 0.2240;
0.4630 0.4010 0.3660 0.3440 0.3250 0.3100 0.2990 0.2890 0.2790 0.2720 0.2470 0.2320 0.2260 0.2210;
0.4230 0.3750 0.3480 0.3290 0.3140 0.3030 0.2930 0.2840 0.2760 0.2690 0.2420 0.2300 0.2240 0.2190;
0.3700 0.3470 0.3280 0.3110 0.2960 0.2880 0.2800 0.2730 0.2680 0.2620 0.2360 0.2240 0.2190 0.2150;
0.3420 0.3250 0.3100 0.2970 0.2850 0.2770 0.2700 0.2640 0.2590 0.2540 0.2280 0.2180 0.2140 0.2110;
0.3230 0.3010 0.2900 0.2810 0.2720 0.2650 0.2590 0.2540 0.2500 0.2470 0.2230 0.2130 0.2090 0.2060;
0.3010 0.2860 0.2760 0.2670 0.2580 0.2530 0.2480 0.2450 0.2420 0.2390 0.2160 0.2060 0.2030 0.2000;
0.2850 0.2750 0.2650 0.2560 0.2480 0.2440 0.2400 0.2370 0.2350 0.2320 0.2100 0.2000 0.1970 0.1940;
0.2710 0.2600 0.2510 0.2440 0.2380 0.2340 0.2310 0.2290 0.2260 0.2240 0.2040 0.1940 0.1910 0.1890;
0.2580 0.2470 0.2400 0.2350 0.2300 0.2270 0.2240 0.2210 0.2190 0.2170 0.1980 0.1890 0.1860 0.1840;
0.2460 0.2370 0.2320 0.2270 0.2240 0.2210 0.2180 0.2150 0.2130 0.2110 0.1980 0.1840 0.1820 0.1800;
0.2040 0.1980 0.1950 0.1920 0.1900 0.1890 0.1890 0.1880 0.1880 0.1870 0.1720 0.1660 0.1640 0.1620;
0.1790 0.1750 0.1740 0.1730 0.1730 0.1710 0.1710 0.1700 0.1690 0.1690 0.1530 0.1510 0.1500 0.1480;
0.1650 0.1650 0.1660 0.1670 0.1680 0.1670 0.1670 0.1680 0.1680 0.1680 0.1550 0.1580 0.1560 0.1530;
0.1530 0.1570 0.1590 0.1620 0.1640 0.1650 0.1660 0.1670 0.1680 0.1690 0.1560 0.1650 0.1620 0.1590];
% The tenors for the underlying swaps and the options on them
SwaptionExerciseDates = cellstr(['1M ';'2M ';'3M '; '6M ';'9M ';'1Y ';'18M';'2Y ';'3Y ';'4Y ';'5Y ';'6Y ';'7Y ';'8Y ';'9Y ';'10Y';'15Y';'20Y';'25Y';'30Y']);
SwaptionTenors = cellstr(['1Y ';
'2Y ';
'3Y ';
'4Y ';
'5Y ';
'6Y ';
'7Y ';
'8Y ';
'9Y ';
'10Y';
'15Y';
'20Y';
'25Y';
'30Y']);
testmat = zeros(length(SwaptionExerciseDates),1);
% Here I construct a matrix of exercise dates
for i = 1:length(SwaptionExerciseDates)
if SwaptionExerciseDates{i}(end)=='Y'
testmat(i) = addtodate(Settle,str2double(SwaptionExerciseDates{i}(1:end-1)),'year');
elseif SwaptionExerciseDates{i}(end)=='M'
testmat(i)=addtodate(Settle,str2double(SwaptionExerciseDates{i}(1:end-1)),'month');
end
end
EurExDates= testmat;
EurExDatesFull = repmat(testmat,1,length(SwaptionTenors));
testmat2 = zeros(length(SwaptionExerciseDates),length(SwaptionTenors));
% Here I construct a matix of maturity dates
for i = 1:size(EurExDatesFull,1)
for j = 1:size(EurExDatesFull,2)
if SwaptionTenors{j}(end)=='Y'
testmat2(i,j) = addtodate(EurExDatesFull(i,j),str2double(SwaptionTenors{j}(1:end-1)),'year');
elseif SwaptionTenors{j}(end)=='M'
testmat2(i,j)= addtodate(EurExDatesFull(i,j),str2double(SwaptionTenors{j}(1:end-1)),'month');
end
end
end
EurMatFull = testmat2;
% I construct an index of all the swaptions that I intend to use for calibration
relidx = find(EurMatFull <= InstrumentMaturity);
SwaptionBlackPrices = zeros(size(SwaptionBlackVol));
SwaptionStrike = zeros(size(SwaptionBlackVol));
% back out the swaption strikes and prices from the implied vol data.
for iSwaption=1:length(SwaptionExerciseDates)
for iTenor=1:length(SwaptionTenors)
[~,SwaptionStrike(iSwaption,iTenor)] = swapbyzero(RateSpec,[NaN 0],Settle, EurMatFull(iSwaption,iTenor),...
'StartDate',EurExDatesFull(iSwaption,iTenor),'LegReset',[1 2],'Basis',2);
SwaptionBlackPrices(iSwaption,iTenor) = swaptionbyblk(RateSpec,'call', SwaptionStrike(iSwaption,iTenor),Settle, ...
EurExDatesFull(iSwaption,iTenor), EurMatFull(iSwaption,iTenor),SwaptionBlackVol(iSwaption,iTenor));
end
end
TimeSpec = hwtimespec(Settle,daysadd(Settle,30*(1:370),6), 12);
% construct an index of some random collection of instruments
B = (214:224);
HW1Fobjfun4 = @(x) SwaptionBlackPrices(relidx(B)) - ...
swaptionbyhw(hwtree(hwvolspec(ValuationDate,testmat,x(2),testmat,x(1),'spline'), RateSpec, TimeSpec), 'call',SwaptionStrike(relidx(B)),EurExDatesFull(relidx(B)), 0,EurExDatesFull(relidx(B)), EurMatFull(relidx(B)),'Basis',2, 'SwapReset',12);
options = optimset('disp','iter','MaxFunEvals',1000,'TolFun',1e-5);
x0 = [.1 .01];
lb = [0 0];
ub = [1 1];
HW1Fparams = lsqnonlin(HW1Fobjfun4,x0,lb,ub,options)
在结果中,当我只使用编号为214:224的仪器时,我能够找到局部最小值:HW1Fparams(1)= 0.0801,HW1Fparams(2)= 0.0002
然而,当我使用乐器说150:224时,我收到以下错误:
“下标索引必须是实数正整数或逻辑”cummswapcfbytrintree中的错误(第23行)
这是一个Matlab创建的文件。有谁知道这里出了什么问题?如何在错误中诊断/调试是在一些Matlab创建的文件中。检查哪个变量或哪个索引被赋予零值或双值的常用技术不再适用于我。感谢。