C++ Programming MFE Spring 2011 Assignment 5 Due: March 19, 2011
C++ Programming MFE Spring 2011 Assignment 5 Due: March 19, 2011
Student name:
Student ID:
You should submit this assignment electronically to [email protected] . To each question, the following should be submitted: A Zip-file of your project (including all source code). The project must compile without errors when pressing Ctrl-F7, and run when pressing Ctrl-F5. Instructions for how to create a Zip-file for project are provided at the end of assignment 2. Programs should be well commented, in line with good C++ programming practice, so that the GSI can easily understand the code. In addition, you should include examples of program executions, either snapshots of the screen, or files should you decide to use file input and output. Any additional questions posed in the assignment should also be answered. Finally, you should submit this front page, with answers to the questions. The best is if you can collect this additional material in one Word file, with this page as a front page. Please contact the GSI if you have any questions about the submission format!
ANSWERS TO QUESTIONS:
Part II b:
c:_________________________________________________________________
d:_________________________________________________________________
e:_________________________________________________________________
a:_________________________________________________________________
b:_________________________________________________________________
Instructions
In this assignment you will practice Object oriented programming Classes Using library classes C++ programming for derivative pricing File I/O
The theory behind the assignment is covered in class, so please check the class material before delving into the programming. Classes and File I/O are covered in lecture 5-6, object oriented programming in lecture 7, useful library classes in lecture 8 and derivative pricing (binomial tree and Black Scholes) in lecture 9. For all the programs, you should follow the C++ programming guidelines, i.e., your classes should contain both header files and .cpp files, you should make extensive use of comments, etc. The assignment grade will be based both on the functionality of your program (i.e., that it works) and its style (i.e., that it follows good C++ programming practice). In this assignment you must use I/O to and from files. Terminal input and screen snapshots are not allowed. Neither are other interfaces, e.g., Excel. The first question is quite short and should be straightforward to solve. The second question is a full project assignment and is extensive. It will take a significant amount of time to complete. Also, as you will see, the instructions for the second question are much less specified compared with the other assignments. This is on purpose: For the final project assignment you get the chance to show that you have mastered all the steps of developing an OOP C++ solution to an advanced problem! A final word of advice: You may note that the issues that arise in the project assignment are different from what you have experienced so far. Until now, once the program has compiled without errors, it has been fairly straightforward to clean up the last errors and bugs. As the size and complexity of a program grow, a large part of the challenge is shifted to the phase after the program compiles without errors, but it still does not work (because of wrong output, crashes, etc). In large scale projects, the vast majority of the time is spent on this phase, which requires a different skill set. You will find out how useful the debugger is. You may also wish to insert manual check points in your program while debugging it, where you output suspicious data to the screen or a file.
Rectangl
Circle
Square
Ellipse
Not allowed
Each object has a position, which can be represented by a coordinate in the (x,y) plane. For example, the place of a circle can be represented by the coordinate of its center. The place of a square can, e.g., be represented by the coordinate of its lower left corner. Further, each object has a size. The size of a circle can be represented by its radius, whereas two numbers are needed to represent the size of a rectangle its lengths in the x and y direction respectively. Moreover, there are several common fundamental properties that any closed curve has, e.g., an
area and a circumference (i.e., the length of the curve).1 It also has a parametric representation, which can be defined as a (non-unique) function p, which takes a number between 0 and 1 and returns a coordinate, such that the whole curve can be drawn by plotting all p(a) for all a between 0 and 1. For example, a circle with center at (x,y) and radius r has the parametric representation () = ( + cos(2) , + sin(2)).
a) Define classes for a coordinate and for generic closed curves. You may use the following declarations if you wish
class coordinate { public: coordinate() {} coordinate(double xin,double yin) {x=xin;y=yin;} double x; double y; }; class closedcurve { public: closedcurve(); ~closedcurve(); double area(); double circumference(); coordinate place(double a); };
b) Define child classes ellipse, circle, rectangle and square. The class hierarchy should be as follows:
class ellipse: public closedcurve { } class circle: public ellipse { } class rectangle: public closedcurve { } class square:public rectangle { }
In fact, these properties are not as well defined for general curves as one may expect. Those of you who ever took a class in measure theory may remember the issues of defining the area concept for general cases. Fortunately, this is not an issue for the smooth curves that we study.
These definitions capture the fact that all these objects are closed curves, that a circle is a special case of an ellipse and that a square is a special case of a rectangle. Implement constructors and destructors, as well as the methods for area and circumference for each of these four object types. The formulas for these methods are standard (e.g., the area of a circle is r2), except for the formula for the circumference of an ellipse, which is nontrivial. There are many methods to approximate the circumference of a general ellipse, with major radius of length a and minor radius of length b. One such formula, that you can use, is the ln 2) ( so-called Hlder approximation, 4( + )1/ , where = ln(2) (feel free to use other approximations). Although this formula is, in fact, exact for the case where the ellipse is a circle, the precision will be much lower than the standard formula for the circles circumference, 2r. You are therefore recommended to use the latter formula for circle objects. c) Implement the method, coordinate place(double a), for the parametric representation, which takes a number between 0 and 1, and returns the coordinate of the curve, for each of the four types of objects. The formulas for rectangles and squares are easy and the formula for the circle was described above. For the ellipse, one parameterization is: () = ( + cos(2) , + sin(2)), where rx and ry are the radiuses in the x and y direction respectively. d) Add a method void printcurve(int N,char Name[]) to the closedcurve class, which takes a number of points, N, and a file name, Name, as arguments and outputs (x,y) coordinates for N points on the curve to a file with name Name. For example, in the figures below, the resulting points from a square and a circle were printed to files, using N=200 points. The points were then imported to Excel, and shown using a scatter chart. When implementing the method, use the ofstream class. Remember to add #include <fstream> and using namespace std; in the header. Tip: A format that Excel understands is the comma-separated, .csv, format. Numbers in columns are separated by a comma, and rows by endl. For example, the square below was saved in a file named Square.csv, the first few lines of the file being: 2, 2 2.06, 2 2.12, 2 If you have implemented your class hierarchy correctly you should only have to write one method, which works for any object of type closedcurve.
6 5 4 3 2 1 0 0 2 4 6
5 4 3 2 1 0 0 2 4 6
e) Implement a less-than (<) operator for the class that compares the area of one curve to another. As with printcurve above, you should only need to implement a single method. f) Write a program that uses the curve class hierarchy. The program should define several different objects, output their area, circumference, etc. It should also use the printcurve function. Please provide charts of a couple of objects, similar to the ones above. g) Incorporate virtual functions to get late binding of objects (if you havent done so yet). Write a program that asks the user what type of object is needed, e.g., a circle or a square, and then calculates the area of that object. In the spirit of true polymorphism, only one object should be defined in the program. You are allowed to use terminal input and output in this exercise. For example, the program could execute as follows:
This will be the base class for both stock and options classes. b) Create a Stock class that inherits from Asset. This class should return the stock price as the value for getValue(). You should define a method to set the stock value as well. In the exercises below, use this class instead of passing stock prices as parameters. It may also be natural to have other stock attributes in this class.
c) Define four Asset child classes: a. AmericanCall a call option with early exercise b. EuropeanCall - a call option with exercise only allowed at option expiration c. AmericanPut - a put option with early exercise d. EuropeanPut - a put option with exercise only allowed at option expiration. It is up to you to decide upon a suitable class inheritance structure. You will also probably find it useful to create one or more parent classes to encapsulate functionality.
Each option class should (eventually) implement its own getValue() function based on the type of option and whether early exercise is allowed. You will need the binomial tree from Part II to implement getValue() for American style options. You may find it useful to initially make these functions dummies (i.e. ones that return a constant) until the binomial tree is implemented.
d) Add a BlackScholesValue function to EuropeanCall and EuropeanPut that implements the closed form solution of each. Note: since we will not be varying the risk-free rate or stock volatility, this method might also be useful for getValue() for this options.2
e) For the option classes, create a method ValueSpots(double strike, double sigma, double r, double T, double lowerSpotPrice, double upperSpotPrice, int numberOfSpots, char Name[]) that writes numberOfSpots option values to a file whose name is specified by Name. The function should start with a stock price of lowerSpotPrice and ending with upperSpotPrice. The spot prices should be equally spaced. Each line of the file should have the following format: <option_type>, Strike, Spot, Sigma, T, r, Price where <option_type> is a two character description of the option type. Use EC for a European Call, EP for a European Put, AC for an American Call and AP for an American Put. For example, assume for a European Put with stock spot price of $81 you calculate the put value to be $22.12. Then the line in your file would be: EP, 100, 81, 0.4, 1.0, 0.05, 22.12 Execute the function for both European Puts and Calls with Strike $100, Sigma = 40%, risk-free rate = 5% and T = 1 Year, varying the spots from $75 to $125, thereby generating 51 values. Include the output file ValueSpots.csv with your homework submission.3
It can be shown that the American call option that does not pay dividends in a Black-Scholes world can also be priced with Black-Scholes formula. We ignore this fact, since it requires analysis outside of the scope of the course, and use the binomial tree method for the American call option. Interested students may verify that the two methods indeed produce the same answer. 3 A sample output file, ValueSpotsSample.csv has been included with the homework.
f) Create a function ValueOptions(char inName[], char outName[]) that reads a text file with option specifications and writes the option values in the same format as in the previous exercise. inName[] contains the input file name. outName contains the output file name. Each line of the input file will have the following formats: <option_type>, Strike, Spot, Sigma, T, r Run the function for the input file ValueOptionsInput.csv which has been included with the homework. Notice that only European put and call values are requested in the file. Include the output file ValueOptionsOutput.csv with your homework submission.
Part II a) Implement a binomial tree class with a method that calculates the value of an option passed in to the class. The binomial tree should not rely on specific features of the different types of options. That is, the binomial tree should be shielded from specific knowledge of the options it is pricing. You may, e.g., have a method, valueOption() that handles any type of equity option passed to it. Tip: The vector<double> template class is useful in implementing the binomial tree solver. Tip: You may find it useful to implement a getPayout(S,t) method for your option classes that return exercise payout (if any) for stock spot value S and time t.
b) Find the tree depth (i.e., the number of steps in the tree) needed to value an (at-the-money) European call with strike and spot of $90, sigma of 25%, risk-free rate of 9% and time to maturity of 6 months to within one penny of the BlackScholes() price.
c) Compare the values of European and American puts by varying the strike price from $80 to $110 in increments of $1 for a spot of $100, sigma of 0.3, risk-free rate of 8% and T = 2 years. Write the European and American put values to a comma-separated value (csv) file. Each line should contain Strike, European price and American price. When is the difference in value between the two options the largest? *Can you figure out why? d) When analyzing an asset, we are often interested in a securitys sensitivities. That is, how the value of a security changes when the value something else changes. For equity options, we speak in terms of the so-called Greeks which define sensitivities to the underlying stock price, volatility, interest rates and so on. The most important Greek is Delta, the options sensitivity (first derivative) to changes in the underlying stock price. Implement a function in the Binomial Tree class that approximates Delta (there are closed form solutions for European calls and puts which will help validate your work). A simple approximation (and sufficient for this homework) can be made by looking at the nodes of the binary tree one time step forward. Sup, Vup S 0, V
Sdown, Vdown
In the diagram above, S represents the underlying stock price and V represents the option value at the node on the binomial tree. Delta can be approximated as: = MFE C++ Programming, Spring 2011, Assignment 5 12
Create a function ValueDelta(char inName[], char outName[]) that reads a text file with option specifications and writes the option values as well as Delta. The inName[] file contains the input file name. The outName file contains the output file name. As before, each line of the input file will have the following formats: <option_type>, Strike, Spot, Sigma, T, r Each line of the output file should have the following format: <option_type>, Strike, Spot, Sigma, T, r, Price, Delta
Run the function for the input file ValueDeltaInput.csv which has been included with the assignment. What is the maximum Delta you see for a call and for a put? What are the minimums? *Why dont the Deltas change sign for a given option?4 Challenge question*: Gamma, the second derivative of the option value with respect to stock price can be similarly approximated using the three values of the second level of the binomial tree. As an optional challenge (not required), try approximating Gamma as well. There are online sources that will point you in the right direction if you get stuck. e) Add an ExerciseBoundary() method to your binomial tree class that returns the early exercise boundary for an American option. For the purposes of the homework, the exercise boundary is the maximum (or possibly minimum) value of the underlying stock for which early exercise is warranted at each time t from 0 to time of maturity. The boundary will typically take on different values for different t, i.e., in different parts of the tree. Tip: It is easy to keep track of the exercise boundary while calculating the option price in the binomial tree. You may therefore want to extend your generic price calculating function to take care of the exercise boundary at the same time.5 1. Calculate the exercise boundary, for an American put with spot $90, strike $100, sigma 0.25, risk-free rate 5%, and T = 1 year using a binomial tree with 100 time steps. 2. Calculate the exercise boundary for an American put with spot $90, strike $100, sigma 0.45, risk-free rate 5%, and T = 1 year using a binomial tree with 100 time steps. The only difference between the two puts above is the underlying stocks volatility. For which put is the exercise boundary higher? *Why do you think this is the case?
4
Hint: In a Black-Scholes world, an interpretation of Delta is that it represents the number of shares needed (along with a risk-free bond position) to replicate the option. 5 It is sufficient for this exercise to return maximum spot value of nodes on the binomial tree at each time step for which early exercise is warranted. If no early exercise node is found for a time step, then have your program print NONE.
Part III*
This section is optional. It contains a challenge question, for students who are interested in extensions of the binomial tree method to more advanced options. Complete the rest of the assignment before moving on to this part. There is no penalty of not doing part III. So far, we have only considered vanilla puts and calls. Now, we are going to move on to more complicated fare and look at how vanilla options can be combined into other types of options. Consider a form of chooser option that gives the holder the right to choose between a call and a put at any time up until expiration. For example, a chooser could be constructed with a European call and a European put with equal strikes as the options to choose between. Traditionally, the holder of a chooser must make the choice at a specified time t. For our chooser, we will allow the option holder to choose at any time. We also will not require the strikes always match. Create a ChooserOption class that works with either European or American options. You should be able to mix and match calls and puts that have the same underlying stock and time to maturity but whose strikes may not be the same. You may find it useful to have the constructor of the class take a call object and a put object as parameters. a) Create a chooser with European call and put and chooser with American calls and puts. The strike prices will match for each of the underlying options. Compare the value of the European chooser to the American chooser by varying the strike price from $85 to $115 in increments of $1 for a spot of $100, sigma of 0.45, risk-free rate of 2% and T = 1 year. Write the European chooser and American chooser values to a comma-separated value (csv) file. Each line should contain: Strike, EuropeanChooserPrice, AmericanChooserPrice You should find that the American chooser is worth more than the European chooser. Is the difference consistent across strikes? If not, is the difference greater for higher strikes or lower strikes with the spot price fixed? *Why do you think this is the case? b) Now, compare the values of an American chooser with those of an American call and an American put. Set the strike price for the calls at $110 and the strikes for the puts at $90 and vary the spot price from $50 to $150 in increments of $1 with a sigma of 0.45, risk-free rate of 2% and T = 2 years. Write the American chooser values, combined call and put values, call values and put values to a comma-separated value (csv) file. Each line should contain: Spot, ChooserPrice, CallPrice+PutPrice, CallPrice, PutPrice Is the chooser more or less expensive than buying a call and a put? Is this always the case? *What is the intuition behind this relationship?