Advertisement
Guest User

Untitled

a guest
Mar 23rd, 2017
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.38 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <math.h>
  4. #include <limits>
  5. #include <algorithm>
  6. #include <Eigen/Dense>
  7. #include <Eigen/Geometry>
  8. #include <random>
  9. #include <vector>
  10. #include <time.h>
  11.  
  12. using namespace Eigen;
  13. using namespace std;
  14.  
  15.  
  16. double FM(double T, double r, double q, double sigma, double S0, double K, int M, int N);
  17. MatrixXd generateGaussianNoise(int M, int N); // Generates Normally distributed random numbers
  18. double Black_Scholes(double T, double K, double S0, double r, double sigma);
  19. double phi(long double x);
  20. VectorXd time_vector(double min, double max, int N);
  21. MatrixXd call_payoff(MatrixXd S, double K);
  22.  
  23. int main(){
  24. double r = 0.03; // Riskless interest rate
  25. double q = 0.0; // Divident yield
  26. double sigma = 0.15; // Volatility of stock
  27. int T = 1; // Time (expiry)
  28. int N = 100; // Number of time steps
  29. double K = 100; // Strike price
  30. double S0 = 102; // Initial stock price
  31. int M = 100; // Number of paths // Current issue
  32.  
  33. FM(T,r,q,sigma,S0,K,M,N);
  34.  
  35. return 0;
  36. }
  37.  
  38. MatrixXd generateGaussianNoise(int M, int N){
  39. MatrixXd Z(N,M);
  40. random_device rd;
  41. mt19937 e2(time(0));
  42. normal_distribution<double> dist(0.0, 1.0);
  43. for(int i = 0; i < M; i++){
  44. for(int j = 0; j < N; j++){
  45. Z(i,j) = dist(e2);
  46. }
  47. }
  48. return Z;
  49. }
  50.  
  51. double phi(double x){
  52. return 0.5 * erfc(-x * M_SQRT1_2);
  53. }
  54.  
  55. double Black_Scholes(double T, double K, double S0, double r, double sigma){
  56. double d_1 = (log(S0/K) + (r+sigma*sigma/2.)*(T))/(sigma*sqrt(T));
  57. double d_2 = (log(S0/K) + (r-sigma*sigma/2.)*(T))/(sigma*sqrt(T));
  58. double C = S0*phi(d_1) - phi(d_2)*K*exp(-r*T);
  59. return C;
  60. }
  61.  
  62. VectorXd time_vector(double min, double max, int N){
  63. VectorXd m(N + 1);
  64. double delta = (max-min)/N;
  65. for(int i = 0; i <= N; i++){
  66. m(i) = min + i*delta;
  67. }
  68. return m;
  69. }
  70.  
  71. MatrixXd call_payoff(MatrixXd S, double K){
  72. MatrixXd result(S.rows(),S.cols());
  73. for(int i = 0; i < S.rows(); i++){
  74. for(int j = 0; j < S.cols(); j++){
  75. if(S(i,j) - K > 0){
  76. result(i,j) = S(i,j) - K;
  77. }else{
  78. result(i,j) = 0.0;
  79. }
  80. }
  81. }
  82. return result;
  83. }
  84.  
  85. double FM(double T, double r, double q, double sigma, double S0, double K, int M, int N){
  86. MatrixXd Z = generateGaussianNoise(M,N);
  87. double dt = T/N;
  88. VectorXd t = time_vector(0.0,T,N);
  89.  
  90. // Generate M paths of stock prices
  91. MatrixXd S(M,N+1);
  92. for(int i = 0; i < M; i++){
  93. S(i,0) = S0;
  94. for(int j = 1; j <= N; j++){
  95. S(i,j) = S(i,j-1)*exp((double) (r - q - pow(sigma,2.0))*dt + sigma*sqrt(dt)*(double)Z(i,j-1));
  96. }
  97. }
  98.  
  99. //
  100. // If path i is "alive" at time index j - 1 < N, generate the price for time index j, denoted as S = S_ij
  101. // Case for call option:
  102. // If j = N, the option is expired with value V = exp(-rT)(S-K)^+ and path i is finished
  103. // If j < N, calculate S_c = f_C(S)
  104. // If S > S_c, the option is exercised with value V_i = exp(-rT)(S-K)^+ and path i is stopped. Otherwise,
  105. // the option is held and path continues to live to the next step j+1
  106. //
  107. // Case for put option:
  108. // If j = N, the option is expired with value V = exp(-rT)(K-S)^+ and path i is finished
  109. // If j < N, calculate S_p = f_p(S)
  110. // if S < S_p, the option is exercised with value V_i and path i is stopped. Otherwise,
  111. // the option is held and path continues to live to the next step j+1.
  112.  
  113. // Compute S_c parameters and S_p
  114. double m = 2*r/(pow(sigma,2.0));
  115. double n = 2*(r-q)/(pow(sigma,2.0));
  116. VectorXd k(t.size());
  117. for(int i = 0; i < k.size(); i++){
  118. k(i) = 1.0 - exp((double) -r*(double)(T - t(i))); // Note the t vector (not sure if this is correct)
  119. }
  120. VectorXd Q_2(k.size());
  121. VectorXd Q_1(k.size());
  122. for(int i = 0; i < Q_2.size(); i++){
  123. Q_1(i) = (-1*(n-1) + sqrt((double)(n-1)*(n-1) + (double)4*m/(double)(k(i))))/2.0; // Q_1 < 0
  124. Q_2(i) = (-1*(n-1) + sqrt((double)(n-1)*(n-1) + (double)4*m/(double)(k(i))))/2.0; // Q_2 > 0
  125. }
  126. double d_1 = (log(S0/K) + (r+sigma*sigma/2.)*(T))/(sigma*sqrt(T));
  127. double C_e = Black_Scholes(T, K, S0, r, sigma); // C_e(S) is the European call option price calculated by Black-Scholes
  128. double Delta = exp(-q*T)*phi(d_1);
  129. MatrixXd V(M,N+1);
  130. VectorXd S_c(Q_2.size());
  131. MatrixXd call_fun = call_payoff(S,K);
  132. for(int j = 0; j < N + 1; j++){
  133. for(int i = 0; i < M; i++){
  134. if(j == N){
  135. V(i,j) = exp(-r*T)*call_fun(i,j); //////////////
  136. //cout << "The option is expired with value " << V(i) << " and path " << i << " is finished" << endl;
  137. }
  138. else if(j < N){
  139. S_c(j) = Q_2(j)*(C_e + K)/(Q_2(j) - (1 - Delta));
  140. }
  141. else if (S(i,j) > S_c(j)){
  142. V(i,j) = exp(-r*T)*call_fun(i,j); ///////////////
  143. //cout << "The option is expired with value " << V(i) << " and path " << i << " is finished" << endl;
  144. }
  145. }
  146. }
  147. double Value = 0.0;
  148. for(int i = 0; i < V.rows(); i++){
  149. for(int j = 0; j < V.cols(); j++){
  150. Value += V(i,j);
  151. }
  152. }
  153. Value = 1.0/M * Value;
  154. cout << C_e << endl;
  155. cout << endl;
  156. cout << Value << endl;
  157.  
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement