#include #include #include #include #include using namespace std; double cap_price(int& N, double& dT, double& v, double& K, double& notional, int& n) { int l, i, j, k; double T[1000]; // payment dates double W[1000]; // Wiener process double C[1000]={0}; // caplet price double L[100][100]; // Libor double B[100][100]; // bond price double sum=0, prod; double V; double total; double average; // cap price double ones[1000][1]; double alea; for(i=0; i<=1000; i++) { ones[i][1]=0.5; // initial Libor rates } for (l=1; l<=N; l++) // calculate N cap prices (Monte Carlo) { W[1] = 0; for (k=1; k<=n; k++) { T[k] = k*dT; srand(time(NULL)); alea=(rand() % (1001))/1000.0; if (k=1; i--) { for (k=1; k<=i-1; k++) { for (j=i+1; j<=n; j++) { sum = sum + (dT*v*L[j][k])/(1+dT*L[j][k]); } L[i][k+1] = L[i][k] - sum * v * L[i][k] * dT + v * L[i][k] * (W[k+1] - W[k]); } } for (k=1; k<=n+1; k++) { prod = 1; for (j=k; j<=n+1; j++) { prod = prod*(1/(1 + dT*L[j][k])); } B[n+1][k] = prod; //calculation of the numeraires } V = 0; for (i=1; i<=n-1; i++) { if (L[i][i]-K > 0) C[i+1] = (L[i][i] - K)/B[n+1][i+1]; //calculation of the numeraire rebased //caplet payoffs } for (i=1; i<=n-1; i++) { V = V + C[i+1]; //a single numeraire rebased cap value } if (l==1) total = V; else total = total + V; } average = total/N; //final estimate numeraire rebased //value of the cap return notional*average; } double dcap_price(int& N, double& dT, double& v, double& K1, double& K2, double& trigger, double& notional, int& n) { int l, i, j, k; double T[1000]; // payment dates double W[1000]; // Wiener process double C[1000]={0}; // caplet price double L[100][100]; // Libor double B[100][100]; // bond price double sum=0, prod; double V; double total; double average; // cap price double ones[1000][1]; double alea; double K[1000]; // strike dual strike price for(i=0; i<=1000; i++) { ones[i][1]=0.5; // initial Libor rates } for (l=1; l<=N; l++) // calculate N cap prices (Monte Carlo) { W[1] = 0; for (k=1; k<=n; k++) { T[k] = k*dT; srand(time(NULL)); alea=(rand() % (1001))/1000.0; if (k=1; i--) { for (k=1; k<=i-1; k++) { for (j=i+1; j<=n; j++) { sum = sum + (dT*v*L[j][k])/(1+dT*L[j][k]); } L[i][k+1] = L[i][k] - sum * v * L[i][k] * dT + v * L[i][k] * (W[k+1] - W[k]); } } for (k=1; k<=n+1; k++) { prod = 1; for (j=k; j<=n+1; j++) { prod = prod*(1/(1 + dT*L[j][k])); } B[n+1][k] = prod; //calculation of the numeraires } V = 0; for (i=1; i<=n-1; i++) { if (L[i][i] 0) C[i+1] = (L[i][i] - K[i])/B[n+1][i+1]; //calculation of the numeraire rebased //caplet payoffs } for (i=1; i<=n-1; i++) { V = V + C[i+1]; //a single numeraire rebased cap value } if (l==1) total = V; else total = total + V; } average = total/N; //final estimate numeraire rebased //value of the cap return notional*average; } double kcap_price(int& N, double& dT, double& v, double& K, double& trigger, double& notional, int& n) { int l, i, j, k; double T[1000]; // payment dates double W[1000]; // Wiener process double C[1000]={0}; // caplet price double L[100][100]; // Libor double B[100][100]; // bond price double sum=0, prod; double V; double total; double average; // cap price double ones[1000][1]; double alea; double K1[1000]; for(i=0; i<=1000; i++) { ones[i][1]=0.5; // initial Libor rates } for (l=1; l<=N; l++) // calculate N cap prices (Monte Carlo) { W[1] = 0; for (k=1; k<=n; k++) { T[k] = k*dT; srand(time(NULL)); alea=(rand() % (1001))/1000.0; if (k=1; i--) { for (k=1; k<=i-1; k++) { for (j=i+1; j<=n; j++) { sum = sum + (dT*v*L[j][k])/(1+dT*L[j][k]); } L[i][k+1] = L[i][k] - sum * v * L[i][k] * dT + v * L[i][k] * (W[k+1] - W[k]); } } for (k=1; k<=n+1; k++) { prod = 1; for (j=k; j<=n+1; j++) { prod = prod*(1/(1 + dT*L[j][k])); } B[n+1][k] = prod; //calculation of the numeraires } V = 0; for (i=1; i<=n-1; i++) { if (L[i][i] 0) C[i+1] = (L[i][i] - K1[i])/B[n+1][i+1]; //calculation of the numeraire rebased //caplet payoffs } for (i=1; i<=n-1; i++) { V = V + C[i+1]; //a single numeraire rebased cap value } if (l==1) total = V; else total = total + V; } average = total/N; //final estimate numeraire rebased //value of the cap return notional*average; } int main() { int N = 1000000; // number of samplings double dT=0.5; //delta double v=0.2; // volatility double K=0.4; // strike cap rate double notional=100; // notional int n=4; // number of payments double K1=0.4; // cap rate 1 of dual strike cap double K2=0.5; // cap rate 2 of dual strike cap double trigger=0.7; // trigger of exotic caps int a; cout << "You want to calculate the price of one of the following caps:" << endl << endl; cout << "Choose 1: plain vanilla cap" << endl; cout << "Choose 2: dual strike cap" << endl; cout << "Choose 3: knock-out cap" << endl << endl; cin >> a; cout << endl << endl; switch (a) { case 1: { cout << "Plain vanilla cap price: " << cap_price(N, dT, v, K, notional, n) << endl << endl; } break; case 2: { cout << "Dual strike cap price: " << dcap_price(N, dT, v, K1, K2, trigger, notional, n) << endl << endl; } break; case 3: { cout << "Knock-out cap price: " << kcap_price(N, dT, v, K, trigger, notional, n) << endl << endl; } break; } system("pause"); return 0; }