《量化投資:以MATLAB為工具》

MATLAB技術論壇

 找回密碼
 注冊賬號
查看: 2977|回復: 17
打印 上一主題 下一主題
收起左側

[源碼] [原創]基于Matlab和C++的MBS(抵押支持債券)蒙特卡羅模擬定價

  [復制鏈接]
跳轉到指定樓層
樓主
發表于 2015-5-4 21:57:27 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 fantuanxiaot 于 2015-5-4 22:01 編輯

按揭抵押債券(Mortgage Backed Securities,MBS),又名抵押支持債券,是一種便于按揭債權交易的標準化債券,是最早的資產證券化商品,由美國吉利美(Ginnie Mae)于1970年首創。美國的住房專業銀行及儲蓄機構將貸出的住房抵押貸款中符合一定條件的貸款集中起來,形成一個抵押貸款的集合體(pool),利用貸款集合體定期發生的本金及利息的現金流入來發行證券,并由政府機構或政府背景的金融機構對該證券進行擔保,以便貸款機構能夠及時套現,從30年或更長貸款期限中解脫出來。抵押集合體所產生的本金、利息以及債務風險原封不動地轉移支付給MBS的投資者。因此,MBS也被稱為過手證券(pass-through securities)。
美國的過手抵押證券主要有吉利美(美國政府國民抵押貸款協會)擔保的過手證券、房地美(美國聯邦住宅貸款抵押公司FHLMC)的參政書、房利美(美國聯邦國民抵押協會FNMA)的抵押支持債券,以及民間性質的抵押過手債券等。

MATLAB代碼如下:
  1. function MBS_MC_Pricing(MC_Times)
  2. %%  MBS_Value,MBS_VAR分別為MBS的價值和方差
  3. %%  基于Matlab的MBS蒙特卡羅模擬定價
  4. %%  MBS具有路徑依賴性
  5. %%  舉例說明
  6. %%  by fantuanxiaot
  7. %%  基礎參數的設定
  8. %  基本假設:平均加權時間假設10年
  9. WAM=10;
  10. %  二叉樹的規模
  11. N=WAM+1;
  12. %  蒙特卡羅模擬的次數
  13. %  MC_Times=1000;
  14. %  本金
  15. Principal=1e5;
  16. %  期權調整價差
  17. OAS=0.02;
  18. %  初始的一年期即期利率(Spot Rate)
  19. %  初始的再融資利率(Refinancing Rate)
  20. %  利息支付利率或者轉付率
  21. %  加權平均票面利率
  22. rand('seed',100);
  23. InitialSpotRate=0.06;
  24. InitialRefinancingRate=0.08;
  25. PT_Rate=0.075;
  26. WAC_Rate=0.08;
  27. %%  首先構建利率的二叉樹
  28. %%  liv二叉樹模型基于RendleMan和Bartter模型
  29. u=1.05;
  30. d=1/u;
  31. SpotRate=zeros(N);
  32. DiscountRate=zeros(N);
  33. for i=1:N
  34.     for j=1:i
  35.         SpotRate(j,i)=InitialSpotRate*u^(i-j)*d^(j-1);
  36.         DiscountRate(j,i)=SpotRate(j,i)+OAS;
  37.     end
  38. end
  39. %  參數:MBS平均價值和標準差
  40. MBS_Vector=zeros(MC_Times,1);
  41. MBS_Value=0;
  42. MBS_STD=0;
  43. %  二叉樹路徑起始點
  44. BinTree_Index=1;
  45. %  計算的貼現率
  46. DiscountRate_Vector=[];
  47. %%  蒙特卡羅計算MBS
  48. for i=1:MC_Times
  49.     %  剩余的本金
  50.     Residual_Principal=Principal;
  51.     %  再融資利率
  52.     RefinancingRate=InitialRefinancingRate;
  53.     %  計算的貼現率  
  54.     DiscountRate_Vector=[];
  55.     %  二叉樹路徑起始點
  56.     BinTree_Index=1;
  57.     %  計劃償還本金
  58.     SchedualPrincipal=0;
  59.     %  預計提前償還本金
  60.     ExpectedPrePrincipal=0;
  61.     %  現金流
  62.     CashFlow=zeros(WAM,1);
  63.     for j=1:WAM
  64.         Residual_Principal=Residual_Principal-(SchedualPrincipal+ExpectedPrePrincipal);
  65.         %  利率的隨機模擬路徑
  66.         if j==1
  67.             DiscountRate_Vector=[DiscountRate_Vector DiscountRate(1,1)];
  68.             if randn>0
  69.                 RefinancingRate=RefinancingRate*u;
  70.             else
  71.                 RefinancingRate=RefinancingRate*d;
  72.             end
  73.         elseif j>1
  74.             if randn>0
  75.                 BinTree_Index=BinTree_Index-1;
  76.                 if BinTree_Index<1
  77.                     BinTree_Index=1;
  78.                 end
  79.                 RefinancingRate=RefinancingRate*u;
  80.                 DiscountRate_Vector=[DiscountRate_Vector DiscountRate(BinTree_Index,j)];
  81.             else
  82.                 BinTree_Index=BinTree_Index+1;
  83.                 if BinTree_Index>j
  84.                     BinTree_Index=j;
  85.                 end
  86.                 RefinancingRate=RefinancingRate*d;
  87.                 DiscountRate_Vector=[DiscountRate_Vector DiscountRate(BinTree_Index,j)];
  88.             end
  89.         end
  90.         %  利息支付
  91.         Interest=PT_Rate*Residual_Principal;
  92.         %  計算月末或年末的貸款償還余額
  93.         Payment=CaCuPayment(Residual_Principal,WAM-j+1,WAC_Rate);
  94.         %  計算償還本金
  95.         SchedualPrincipal=Payment-Residual_Principal*WAC_Rate;
  96.         if Residual_Principal>SchedualPrincipal
  97.             CPR_Rate=CaCuCPR(WAC_Rate,RefinancingRate);
  98.             ExpectedPrePrincipal=CPR_Rate*(Residual_Principal-SchedualPrincipal);
  99.             if j<=N-1
  100.                 CashFlow(j)=Interest+SchedualPrincipal+ExpectedPrePrincipal;
  101.             else
  102.                 CashFlow(j)=Interest+Residual_Principal;
  103.             end
  104.         end
  105.     end
  106.     MBS_Vector(i)=CaCuMBS(CashFlow,DiscountRate_Vector);
  107. end
  108. MBS_Value=mean(MBS_Vector);
  109. MBS_STD=std(MBS_Vector);
  110. disp(['蒙特卡羅模擬次數為:',num2str(MC_Times)])
  111. disp(['MBS的本金為:',num2str(Principal),'元'])
  112. disp(['MBS的價值為:',num2str(MBS_Value),'元'])
  113. disp(['基于蒙特卡羅模擬的MBS價值標準差:',num2str(MBS_STD)])
  114. fprintf('\n')
  115. end
  116. %%  計算MBS價值
  117. function result=CaCuMBS(CashFlow,DiscountRate_Vector)
  118. result=0;
  119. for i=1:length(CashFlow)
  120.     result=result+CashFlow(i)/(1+DiscountRate_Vector(i))^i;
  121. end
  122. end
  123. %%  計算月末或者年末抵押償還的金額
  124. function result=CaCuPayment(Payment,Time,WAC_Rate)
  125. %  Time是剩余的月份
  126. %  Payment是剩余的抵押貸款償還的金額
  127. result=WAC_Rate*Payment/(1-1/(1+WAC_Rate)^Time);
  128. end

  129. %%  CPR條件提前償還率的計算
  130. %%  建立提前還款模型
  131. function CPRresult=CaCuCPR(WAC_Rate,RefinancingRate)
  132. %  CPR由差價來決定
  133. CPR_Minus=WAC_Rate-RefinancingRate;
  134. %  判斷條件
  135. if CPR_Minus<=0
  136.     CPRresult=0.05;
  137. elseif CPR_Minus>0 && CPR_Minus<=0.5/100
  138.     CPRresult=0.1;
  139. elseif CPR_Minus>0.5/100 && CPR_Minus<=0.01
  140.     CPRresult=0.2;
  141. elseif CPR_Minus>0.01 && CPR_Minus<=1.25/100
  142.     CPRresult=0.3;
  143. elseif CPR_Minus>1.25/100 && CPR_Minus<=2/100
  144.     CPRresult=0.4;
  145. elseif CPR_Minus>0.02 && CPR_Minus<=2.5/100
  146.     CPRresult=0.5;
  147. elseif CPR_Minus>0.025 && CPR_Minus<=0.3
  148.     CPRresult=0.6;
  149. else
  150.     CPRresult=0.7;
  151. end
  152. end
  153. %%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  154. %%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
復制代碼

蒙特卡羅模擬效果如下:



C++的代碼如下:

首先構建一個MBS類:
”MBS.h“
  1. //  構建MBS的類
  2. //  by fantuanxiaot
  3. #ifndef _MBS_H_
  4. #define _MBS_H_
  5. //  判別Visual C++的版本
  6. #if _MSC_VER>1000
  7. #pragma once
  8. #endif
  9. #include <vector>
  10. #include <Matrix.h>
  11. #include <MatrixIO.h>
  12. #include <cmath>
  13. #include <random>
  14. #include <iostream>
  15. //  MBS的類
  16. using namespace std;
  17. using namespace Numeric_lib;
  18. class MBS
  19. {
  20. private:
  21.         //  期權調整價差
  22.         double OAS;
  23.         //  MBS面值
  24.         double Principal;
  25.         //  加權平均到期時間
  26.         int WAM;
  27.         //  蒙特卡羅模擬的次數
  28.         int MC_Times;
  29.         //  初始的一年期即期收益率
  30.         double InitialSpotRate;
  31.         //  初始的再融資收益率
  32.         double InitialRefinancingRate;
  33.         //  利息支付利率或者轉付率
  34.         double PT_Rate;
  35.         //  加權平均票面利率
  36.         double WAC_Rate;
  37. public:
  38.         ~MBS(){}
  39.         MBS(double OAS1,double Principal1,int WAM1,int MC_Times1,double InitialSpotRate1,
  40.                 double InitialRefinancingRate1,double PT_Rate1,double WAC_Rate1)
  41.         {
  42.                 OAS=OAS1;
  43.                 Principal=Principal1;
  44.                 WAM=WAM1;
  45.                 MC_Times=MC_Times1;
  46.                 InitialSpotRate=InitialSpotRate1;
  47.                 InitialRefinancingRate=InitialRefinancingRate1;
  48.                 PT_Rate=PT_Rate1 ;
  49.                 WAC_Rate=WAC_Rate1;
  50.         }
  51.         double CaCuCPR(double WAC_Rate,double RefinancingRate);
  52.         double CaCuPayment(double Payment,int Time,double WAC_Rate);
  53.         double CaCuMBS(vector<double> CashFlow,vector<double> DiscountRate_Vector);
  54.         double MEAN(vector<double>);
  55.         double STD(vector<double>);
  56.         void CaCuMBSPricing();
  57. };
  58. #endif
復制代碼
隨后寫入函數:
"MBSModel.cpp"
  1. #include "MBS.h"
  2. //  內置函數
  3. double MBS::CaCuCPR(double WAC_Rate,double RefinancingRate)
  4. {
  5.         double CPRresult;
  6.         double CPR_Minus=WAC_Rate-RefinancingRate;
  7.         //  判斷條件
  8.         if (CPR_Minus<=0.0)
  9.         {CPRresult=0.05;}
  10.         else if (CPR_Minus>0.0 && CPR_Minus<=0.5/100)
  11.         {CPRresult=0.1;}
  12.         else if (CPR_Minus>0.5/100 && CPR_Minus<=0.01)
  13.         {CPRresult=0.2;}
  14.         else if (CPR_Minus>0.01 && CPR_Minus<=1.25/100)
  15.     {CPRresult=0.3;}
  16.         else if (CPR_Minus>1.25/100 && CPR_Minus<=2.0/100)
  17.     {CPRresult=0.4;}
  18.         else if (CPR_Minus>0.02 && CPR_Minus<=2.5/100)
  19.     {CPRresult=0.5;}
  20.         else if (CPR_Minus>0.025 && CPR_Minus<=0.3)
  21.     {CPRresult=0.6;}
  22.         else
  23.     {CPRresult=0.7;}
  24.         return CPRresult;
  25. }
  26. double MBS::CaCuPayment(double Payment,int Time,double WAC_Rate)
  27. {
  28.         return(WAC_Rate*Payment/(1.0-1.0/pow((1+WAC_Rate),Time)));
  29. }
  30. double MBS::CaCuMBS(vector<double> CashFlow,vector<double> DiscountRate_Vector)
  31. {
  32.         double result=0;
  33.         for(int i=0;i<=CashFlow.size()-1;i++)
  34.         {
  35.                 result=result+CashFlow[i]/pow(1+DiscountRate_Vector[i],i+1);
  36.         }
  37.         return result;
  38. }
  39. double MBS::MEAN(vector<double> A)
  40. {
  41.         double sum=0.0;
  42.         for(int i=0;i<=A.size()-1;i++)
  43.         {
  44.                 sum=sum+A[i];
  45.         }
  46.         return(sum/A.size());
  47. }
  48. double MBS::STD(vector<double> A)
  49. {
  50.         double sum=0.0;
  51.         for(int i=0;i<=A.size()-1;i++)
  52.         {
  53.                 sum=sum+pow(A[i]-MEAN(A),2);
  54.         }
  55.         return(sqrt(sum/A.size()));
  56. }
  57. void MBS::CaCuMBSPricing()
  58. {
  59.         double u=1.05;
  60.         double d=1/u;
  61.         //  利率二叉樹的規模
  62.         double N=WAM+1;
  63.         //  首先構建利率的二叉樹
  64.         Matrix<double,2> SpotRate(N,N);
  65.         Matrix<double,2> DiscountRate(N,N);
  66.         for(int i=0;i<=N-1;i++)
  67.         {
  68.                 for(int j=0;j<=i;j++)
  69.                 {
  70.                         SpotRate[j][i]=InitialSpotRate*pow(u,i-j)*pow(d,j);
  71.                         DiscountRate[j][i]=SpotRate[j][i]+OAS;
  72.                 }
  73.         }
  74.         //  參數:MBS平均價值和標準差
  75.         vector<double> MBS_Vector(MC_Times);
  76.         double MBS_Value=0;
  77.         double MBS_STD=0;
  78.         //  二叉樹路徑起始點
  79.         int BinTree_Index=0;
  80.         //  計算的貼現率
  81.         vector<double> DiscountRate_Vector(WAM);
  82.         //  計算現金流
  83.         vector<double> CashFlow(WAM);
  84.         //  蒙特卡羅計算MBS
  85.         //  剩余的本金
  86.     double Residual_Principal=Principal;
  87.     //  再融資利率
  88.     double RefinancingRate=InitialRefinancingRate;
  89.     //  計劃償還本金
  90.     double SchedualPrincipal=0.0;
  91.     //  預計提前償還本金
  92.     double ExpectedPrePrincipal=0.0;
  93.         //  產生隨機數
  94.         default_random_engine generator;
  95.         //  產生均勻分布的隨機數
  96.         uniform_real_distribution<double> unif_dis(0,1);
  97.         //  利息
  98.         double Interest=0.0;
  99.         //  支付
  100.         double Payment=0.0;
  101.         //  CPR利率
  102.         double CPR_Rate=0.0;
  103.         for(int i=0;i<=MC_Times-1;i++)
  104.         {
  105.                 //  數據的重置
  106.                 Residual_Principal=Principal;
  107.                 SchedualPrincipal=0.0;
  108.                 ExpectedPrePrincipal=0.0;
  109.                 for(int m=0;m<=WAM-1;m++)
  110.                 {
  111.                         CashFlow[m]=0.0;
  112.                         DiscountRate_Vector[m]=0.0;
  113.                 }
  114.                 RefinancingRate=InitialRefinancingRate;
  115.                 BinTree_Index=0;
  116.                 for(int j=0;j<=WAM-1;j++)
  117.                 {
  118.                         Residual_Principal=Residual_Principal-(SchedualPrincipal+ExpectedPrePrincipal);
  119.                         //  利率的隨機模擬
  120.                         if(j==0)
  121.                         {
  122.                                 DiscountRate_Vector[j]=(DiscountRate[0][0]);
  123.                                 if (unif_dis(generator)>=0.5)
  124.                                 {
  125.                                         RefinancingRate=RefinancingRate*u;
  126.                                 } else
  127.                                 {
  128.                                         RefinancingRate=RefinancingRate*d;
  129.                                 }
  130.                         } else if(j>=1)
  131.                         {
  132.                                 if (unif_dis(generator)>=0.5)
  133.                                 {
  134.                                         BinTree_Index--;
  135.                                         if(BinTree_Index<0) BinTree_Index=0;
  136.                                         RefinancingRate=RefinancingRate*u;
  137.                                         DiscountRate_Vector[j]=DiscountRate[BinTree_Index][j];
  138.                                 } else
  139.                                 {
  140.                                         BinTree_Index++;
  141.                                         if(BinTree_Index>j) BinTree_Index=j;
  142.                                         RefinancingRate=RefinancingRate*d;
  143.                                         DiscountRate_Vector[j]=DiscountRate[BinTree_Index][j];
  144.                                 }
  145.                         }
  146.                         //  利息支付
  147.            Interest=PT_Rate*Residual_Principal;
  148.                    //  計算月末或年末的貸款償還余額
  149.                    Payment=CaCuPayment(Residual_Principal,WAM-j,WAC_Rate);
  150.                    //  計算償還本金
  151.                    SchedualPrincipal=Payment-Residual_Principal*WAC_Rate;
  152.                    if(Residual_Principal>SchedualPrincipal)
  153.                    {
  154.                            CPR_Rate=CaCuCPR(WAC_Rate,RefinancingRate);
  155.                            ExpectedPrePrincipal=CPR_Rate*(Residual_Principal-SchedualPrincipal);
  156.                            if (j<=WAM-2)
  157.                            {
  158.                                    CashFlow[j]=(Interest+SchedualPrincipal+ExpectedPrePrincipal);
  159.                            } else
  160.                            {
  161.                                    CashFlow[j]=(Interest+Residual_Principal);
  162.                            }
  163.                    }
  164.                 }
  165.                 MBS_Vector[i]=CaCuMBS(CashFlow,DiscountRate_Vector);
  166.         }
  167.         MBS_Value=MEAN(MBS_Vector);
  168.         MBS_STD=STD(MBS_Vector);
  169.         cout<<"蒙特卡羅模擬的次數為"<<MC_Times<<endl;
  170.         cout<<"MBS的本金為:"<<Principal<<"元"<<endl;
  171.         cout<<"MBS的價值為:"<<MBS_Value<<"元"<<endl;
  172.         cout<<"基于蒙特卡羅模擬的MBS價值標準差"<<MBS_STD<<endl;
  173.         cout<<endl;
  174. }
復制代碼
最后是調試:
“Main.cpp”
  1. #include "MBS.h"
  2. int main()
  3. {
  4.         int WAM=10;
  5.         //  期權調整價差
  6.         double OAS=0.02;
  7.         //  MBS面值
  8.         double Principal=100000;
  9.         //  蒙特卡羅模擬的次數
  10.         int MC_Times1=10;
  11.         int MC_Times2=100;
  12.         int MC_Times3=1000;
  13.         int MC_Times4=10000;
  14.         //  初始的一年期即期收益率
  15.         double InitialSpotRate=0.06;
  16.         //  初始的再融資收益率
  17.         double InitialRefinancingRate=0.08;
  18.         //  利息支付利率或者轉付率
  19.         double PT_Rate=0.075;
  20.         //  加權平均票面利率
  21.         double WAC_Rate=0.08;
  22.         MBS MBS1(OAS,Principal,WAM,MC_Times1,InitialSpotRate,InitialRefinancingRate,PT_Rate,WAC_Rate);
  23.         MBS MBS2(OAS,Principal,WAM,MC_Times2,InitialSpotRate,InitialRefinancingRate,PT_Rate,WAC_Rate);
  24.         MBS MBS3(OAS,Principal,WAM,MC_Times3,InitialSpotRate,InitialRefinancingRate,PT_Rate,WAC_Rate);
  25.         MBS MBS4(OAS,Principal,WAM,MC_Times4,InitialSpotRate,InitialRefinancingRate,PT_Rate,WAC_Rate);
  26.         MBS1.CaCuMBSPricing();
  27.         MBS2.CaCuMBSPricing();
  28.         MBS3.CaCuMBSPricing();
  29.         MBS4.CaCuMBSPricing();
  30.         return 0;
  31. }
復制代碼

效果如下:


所有源碼:
MBS_Model(抵押支持債券).zip (309.96 KB, 下載次數: 8)

評分

參與人數 1威望 +6 貝殼 +18 收起 理由
faruto + 6 + 18 感謝您分享自己珍貴的資料

查看全部評分

推薦
發表于 2015-8-14 08:54:47 | 只看該作者
好激動~可以用matlab這么高大上的工具來測試學過的知識~~
回復 支持 反對

使用道具 舉報

推薦
發表于 2016-4-3 16:03:45 | 只看該作者
基于Matlab和C++的MBS(抵押支持債券)蒙特卡羅模擬定價
回復 支持 反對

使用道具 舉報

推薦
發表于 2016-11-19 11:12:56 | 只看該作者
給力,原來可以用MATLAB干的這么好!!
回復 支持 反對

使用道具 舉報

沙發
發表于 2015-5-5 18:36:23 | 只看該作者
好東西 fantuanxiaot出品 必屬精品

評分

參與人數 1貝殼 +5 收起 理由
fantuanxiaot + 5

查看全部評分

回復 支持 反對

使用道具 舉報

板凳
發表于 2015-5-13 17:17:02 | 只看該作者
回復 支持 反對

使用道具 舉報

地板
發表于 2015-6-17 11:09:27 | 只看該作者
這個需要什么toolbox嗎?
回復 支持 反對

使用道具 舉報

5
發表于 2015-7-30 11:00:36 | 只看該作者
回復 支持 反對

使用道具 舉報

7
發表于 2015-8-10 14:47:13 | 只看該作者
回復 支持 反對

使用道具 舉報

10
發表于 2015-11-3 22:08:50 | 只看該作者
哈哈哈哈好東西!謝謝!
回復 支持 反對

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 注冊賬號

本版積分規則

QQ|網站地圖|MATLAB技術論壇|Simulink仿真論壇 ( 蜀ICP備19014457號 

GMT+8, 2020-10-20 02:47 , Processed in 0.066658 second(s), 24 queries , Gzip On, MemCached On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回復 返回頂部 返回列表
彩票河北20选5走势图 山东群英会开奖走势图 好彩1最新预测 辽宁11走势图基本走势 什么是股票融资余额 广西快三遗漏表 江西时时彩交流群 北京11选五前三组奖金 福建快三跨度号码 股票指数点位 全国股票配资平台排名 本周短线股票推荐 福建快三形态走势图 如何配股 明日股票涨跌 甘肃泳坛夺金开奖号码 云南时时彩最新开奖结果查询