联系方式

  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp

您当前位置:首页 >> C/C++编程C/C++编程

日期:2021-05-23 10:52

PART B FINAL PROJECT

LM Advanced Mathematical Finance Module

Part B C++ Spring Term 2021

PROJECT SPRING TERM, PROGRAMMING IN C++

Lecturer Dr Simon Hartley s.hartley@bham.ac.uk

Of School of Mathematics, College of Engineering and Physical Sciences, University of

Birmingham

Due Friday 4

th June 2021, 23:59

Weighting 50% of Part B

INSTRUCTIONS FOR THE SUBMISSION

Submit your code on Canvas as zip:

Submit as a single zip file containing all code for the problem. The source files should compile without errors or warnings on Visual Studio 2019 as installed on the

clusters, and the resulting executables should run without problems. Using debug and x64 build options. You

do not have to submit the executable. You should comment you code and describe what each function does.

If you use another compiler other than Visual Studio, you should take your final code and compile it

on Visual Studio on the remote clusters. Unfortunately, different compilers follow slightly different rules, and even a small difference may cause the code

to fail on Visual Studio. The source code should also be well formatted. This means that opening and closing

brackets should be aligned in a readable way, and we will discuss such styles briefly in the lectures. PLAGIARISM

Obviously, you are not allowed to plagiarise. This means that you are not allowed to directly copy the code from

any online sources or any of your fellow students. Direct group work is also not allowed. While you are allowed

(and even encouraged) to discuss the contents of this module (including problem sheets) with your fellow

students, every one of you needs to write your own code. NUMERICAL OPTION PRICING PROGRAM

Write a program that can price European Options and American Options with different methods: Analytically, with

a Binomial Tree, and with Monte Carlo. When you finish this problem, you should have:

Created a Series of Classes in their own namespace to form a Mathematical Library for Numerical Option

Pricing using STL Library Algorithms, Functions and Containers where possible.

Implement puts and calls for each case. Tested your classes with Example data. Description

In the provided source code(see link) which we have been working on in the Week 10 Labs which uses the c++

class heirachy:(See Diagram)

Source

Monte Carlo European Option

In the labs we created a C++ interitance hierarchy and implemented an algorithm for the Monte Carlo European

Option. Using the example code add a new function to the program for Eurpean Options to match (adding steps to

16ae544 1

a stockpath):

Part 1: Monte Carlo European Option Stratified

Add to the implemented soluion to have a Function to use a Simplified Monte Carlo stratified sampling method. Stratified sampling method is a way to reduce the number of samples needed to converge on a price, reducing

calculation time. This method forces our sample to be taken from different percentile buckets. For example, if we

were to take samples using five different percentile buckets, we would take a uniform random sample between

0.0 and 0.2 and between 0.2 and 0.4 and so on until 1. We then take these stratified uniform samples and convert

them to a normally distributed samples using the cumulative distribution function. Sampling in this way will help

our sampling appear normally distributed much faster. This method is simple to implement for European Options

because only the end point is needed for calculations. Part 2: European Options Analytical Functions Black-Scholes model

Implement the Analytical Solution to the EuropeanPut and EuropeanCall classes. Complete the Analytical

Functions for the European Options put and call using the Black Scholes Method from Week 1Slides02.pdf

Hints

There are assumptions for deriving the Black-Scholes model:

1. It is possible to borrow and lend cash at a known constant risk-free interest rate . 2. The price of the underlying follows a geometric Brownian motion with constant drift and volatility. 3. There are no transaction costs. 4. The stock pays no dividend. 5. All securities are perfectly divisible (i.e. it is possible to buy any fraction of a share). 6. There are no restrictions on short selling. 7. There are no riskless arbitrage opportunities. 8. Security trading is continuous.

The Black-Scholes Equation can be written as:

Inputs:

steps{20}, paths{ 1000 }, expiry{ 1 }, spot{ 1.0 }, rate{ 0.05 }, volatility{ 0.3 },

dividend{ 0.0 }, strike{ 1.05 };

double sum = 0.;

for (int n = 0; n < paths; n++){

// now create a path

double dt = expiry / steps;

stock_Path[steps];

stock_Path[0] = spot;

for (int i = 1; i <= steps; i++){

double phi = random_generator(rng);

stock_Path[i] = stock_Path[i - 1] * exp((myInterestRate - 0.5 * volatility * volatility) * dt + phi * volatility * sqrt(dt));

}

// and calculate S

double S = 0.;

for (int i = 1; i <= K; i++){

S = S + fabs(stock_Path[i] - stock_Path[i - 1]);

}

// add in the payoff to the sum

sum = sum + std::max(S - strike, 0.);

}

return sum / paths * exp(-rate * expiry);

16ae544 2

In the case of the options we are considering those conditions are:

C(S, T) = max(S ? K, 0) // Call

C(S, T) = max(K ? S, 0) // Put

C(0, t) = 0 for all t

C(S, t) → S as S → ∞. where d1 is given by:

and d2 is given by:

and

You can use the cumulative distribution function provided. You need to create a function for the call option, so we

need to think about what arguments need to be supplied and what are the local variables to the function. Supplied data is the asset price, current time both of which may vary, and the parameters for the function are the

strike price, interest rate, volatility and maturity, and we want to return a real number as the answer. Inside the

function,we will need to calculate the value of d1 and d2. Now you need to test the function under different cases. The function will need to account for each of the

following cases:

S = 0

sigma = 0

t = T - check if we are at(or very close to) maturity

t > T - Option Expired

Since all will result in undefined mathematical values given the way that d1 and d2 are calculated. However, returning a value of plus or minus infinity for d1 and d2 does not result in an undetermined value for the

cumulative normal distribution. As the function returns definite values from infinite limits. Using knowledge of the

function we need go through each case and decide what are the appropriate responses.

Case S = 0

Here we must make use of the boundary condition of the problem, which is that the option value is worthless if

the asset value is zero. The only slight caveat here is that you should check whether S is smaller than a very small

number relative to the strike price rather than comparing it with zero. If the comparison is true the function will

stop and return the value for Zero without executing any more code.

Case Sigma = 0

This case is very similar to when t=T. Depending on the sign of the numerator in the calculation for d1 and d2 the

function will either return zero or the asset minus the discounted strike price.

Case t = T

Finally if t and T are almost equal then we are at maturity and we return the payoff. On adding each of these

parts to the code you should test and validate each part using a range of parameters.

Case t > T

There is no sensible value that can be returned in this case so if you add in a check for it you would be looking to

16ae544 3

at least print a warning to the screen. Part 3: European Options Functions Using the Binomial Method

Binomial options pricing model provides a generalizable numerical method for the valuation of options. Was

introduced in Week 2 Slides09.pdf.

The model uses a “discrete-time” (lattice based) model of the varying price over time of the underlying financial

instrument. Our problem, is to compute the value of the option at the root of the tree. We do so by starting at the

leaves and working backward toward the root. Hints

You can use the Binomial tree implementation in the week 11 labs.

For advanced Users may want to consider the Code Samples:

Options Pricing on the GPU

Part 4: Monte Carlo European Option

Create a version of your classes which can use float types instead of doubles and compare the time taken. Hints

The std::chrono provides us the high_resolution_clock which is the most accurate and hence it is used to measure

execution time.

Timing alogritm:

Step 1: Get the timepoint before the function is called

Step 2: Get the timepoint after the function is called

Step 3: Get the difference in timepoints and cast it to required units

Notes for Interest

#include <chrono>

using namespace std::chrono;

// get the timepoint at this instant use function now()

auto start = high_resolution_clock::now();

// After function call

auto stop = high_resolution_clock::now();

// Subtract stop and start timepoints and

// cast it to required unit. Predefined units

// are nanoseconds, microseconds, milliseconds,

// seconds, minutes, hours. Use duration_cast()

// function.

auto duration = duration_cast<microseconds>(stop - start);

// To get the value of duration use the count()

// member function on the duration object

cout << duration.count() << endl;

16ae544 4

Advanced Users may want to look at std::future and std::async from the week 11 lecture 5 and compare the

times. Part 5: Binomial American Option

For the American option another for loop is needed so to compare the immediate payoff to the discounted option

price of its weighted branches.

Optional: Monte Carlo American Option

Add to the American Option to use Longstaff–Schwartz least-squares Monte Carlo method. Hints

Inputs:

T {1.0} // Time to maturity of option

N {10e5} // Height of the binomial tree/Number of timesteps

v {0.2} // Volatility of underlying asset

rate {0.05} // risk-free interest rate

S {1.0} // initial asset price

K {1.0} // Strike Price

q {0.0} // dividend yield

Calculations:

dt = T / N;

Up = exp(v * sqrt(dt));

v0 = (Up*exp(-q * dt) - exp(-r * dt)) / (Up^2 - 1);

v1 = exp(-r * dt) - v0;

// initialize option value array

for i = 0 to N

v[i] = K - S * Up^(2*i - N);

if v[i] < 0 then v[i] = 0;

// for each time step loop backwards in time

for j = N-1 down to 0

for i = 0 to j

// binomial value

v[i] = v0 * v[i+1] + v1 * p[i]

// exercise value

exercise = K - S * up^(2*i - j)

if v[i] < exercise then v[i] = exercise

result = v[0]

16ae544 5

For advanced Users may want to consider the Code Samples:

American Option Pricing with Monte Carlo Simulation

Notes

Here is example data to test and check your algorithms results:

function lsmc_am_put(S, K, r, σ, t, N, P)

Δt = t / N

R = exp(r * Δt)

T = typeof(S * exp(-σ^2 * Δt / 2 + σ * √Δt * 0.1) / R)

X = Array{T}(N+1, P)

for p = 1:P

X[1, p] = x = S

for n = 1:N

x *= R * exp(-σ^2 * Δt / 2 + σ * √Δt * randn())

X[n+1, p] = x

end

end

V = [max(K - x, 0) / R for x in X[N+1, :]]

for n = N-1:-1:1

I = V .!= 0

A = [x^d for d = 0:3, x in X[n+1, :]]

β = A[:, I]' \ V[I]

cV = A' * β

for p = 1:P

ev = max(K - X[n+1, p], 0)

if I[p] && cV[p] < ev

V[p] = ev / R

else

V[p] /= R

end

end

end

return max(mean(V), K - S)

end

16ae544 6

// The data below are from

// "Option pricing formulas", E.G. Haug, McGraw-Hill 1998

// page 2-8, 24, 27

testvalues={

// type, strike, spot, q rate, r rate, t, vol, value, tol

{ "EuropeanOptionData::Call", 65.00, 60.00, 0.00, 0.08, 0.25, 0.30, 2.1334, 1.0e-4},

{ "EuropeanOptionData::Put", 95.00, 100.00, 0.05, 0.10, 0.50, 0.20, 2.4648, 1.0e-4},

{ "EuropeanOptionData::Put", 19.00, 19.00, 0.10, 0.10, 0.75, 0.28, 1.7011, 1.0e-4},

{ "EuropeanOptionData::Call", 19.00, 19.00, 0.10, 0.10, 0.75, 0.28, 1.7011, 1.0e-4},

{ "EuropeanOptionData::Call", 1.60, 1.56, 0.08, 0.06, 0.50, 0.12, 0.0291, 1.0e-4},

{ "EuropeanOptionData::Put", 70.00, 75.00, 0.05, 0.10, 0.50, 0.35, 4.0870, 1.0e-4},

{ "EuropeanOptionData::Call", 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 0.0205, 1.0e-4},

{ "AmericanOptionData::Call", 100.00, 100.00, 0.10, 0.10, 0.50, 0.15, 4.0842, 1.0e-16 },

{ "AmericanOptionData::Call", 100.00, 110.00, 0.10, 0.10, 0.50, 0.15, 10.8087, 1.0e-16 },

{ "AmericanOptionData::Call", 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5106, 1.0e-16 },

{ "AmericanOptionData::Call", 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 15.5689, 1.0e-16 },

{ "AmericanOptionData::Put", 100.00, 90.00, 0.10, 0.10, 0.10, 0.15, 10.0000, 1.0e-16 },

{ "AmericanOptionData::Put", 100.00, 100.00, 0.10, 0.10, 0.10, 0.15, 1.8770, 1.0e-16 },

{ "AmericanOptionData::Put", 100.00, 100.00, 0.10, 0.10, 0.50, 0.35, 9.5104, 1.0e-16 },

{ "AmericanOptionData::Put", 100.00, 110.00, 0.10, 0.10, 0.50, 0.35, 5.882, 1.0e-16 },

{ "AmericanOptionData::Put", 100.00, 100.00, 0.00, 0.00, 0.50, 0.15, 4.2294, 1.0e-16 }

}

16ae544 7

Class Diagram

A simple diagram showing the inheritance relations, classes, member functions and attributes (member variables)

for our Current EuropeanOption Classes Code.

Note

These can be simply generated via MS Visual Studio 2019:

Goto Class View (left pane next to Solution explorer)

Right click solution name

Select view from popup menu

View class diagram

16ae544 8


版权所有:编程辅导网 2021 All Rights Reserved 联系方式:QQ:99515681 微信:codinghelp 电子信箱:99515681@qq.com
免责声明:本站部分内容从网络整理而来,只供参考!如有版权问题可联系本站删除。 站长地图

python代写
微信客服:codinghelp