Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 40 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
40
Dung lượng
1,1 MB
Nội dung
is private, and so we will not be able to get or set the value of it from outside the object itself. We can, however, set the value of strOptionSym through the constructor method known as the New() subroutine. So New() is called the constructor method. Any time an object is instantiated, or born, using the New keyword, the object’s constructor method executes. In this case the public subroutine New() accepts a string and sets the value of strOptionSym, our private member variable, equal to it. By requiring that an option symbol be passed to the constructor method, we prevent ourselves, or any other programmer using this class, from creating a new option object without a symbol. Also notice that we can get the value of strOptionSym through the public property Symbol, which has a Get method within it. Public properties provide us with access to private member variables through Get and Set methods. Notice, however, that our Symbol property is ReadOnly, implying that once the strOptionSym member variable is set via the New() method, it cannot be changed. Creating a reference type, such as an object, out of a class is a two-stage process. First, we declare the name of the object, which will actually then be a variable that holds a reference to the location of the object in memory. Second, we create an instance of a class using the New keyword. This is when the constructor method will run. Here is an example of showing the two-stage process: Dim myOption As StockOption myOption = New StockOption("IBMDP") Alternatively, we can accomplish the process using one line of code: Dim myOption As New StockOption("IBMDP") In different situations it will be advantageous to use one or the other of these two methods. We will use both methods over the course of the book. As with variables, it is important to pay close attention to the scope of your reference types, which will dictate in many cases the method of instantiation. Objects 113 Team-LRN Step 4 In the Form1 code window, add the following code to the Form1_Load event: Private Sub Form1_Load(ByVal sender As ) Handles MyBase.Load Dim myOption As New StockOption("IBMDP") Label1.Text = myOption.Symbol End Sub Now when the program is running, myOption is the object, whereas StockOption is the class. We set the value of strOption- Symbol by passing a string into the constructor, New(), as shown. Step 5 Run the program (see Figure 7.1). The content of this program is not earth-shattering of course, but congratulate yourself nonetheless; you have just created your first class, your first object, and your first object-oriented program. Of course, a stock option consists of a lot more data and functionality than just a symbol. Also, as we saw in our abstraction of a stock option, some of this other data might not be set from the outside, but rather calculated internally. For example, we would obviously prefer to have the option object derive the strike price internally from the option symbol rather than require that we set it explicitly from the outside. Let’s take a look at the fully developed StockOption class found on the CD. Step 6 Clear the StockOption class of the previous definition and paste in the full StockOption class code from the StockOption.txt file found on the CD. F I G U R E 7.1 114 Introduction to VB.NET Team-LRN Step 7 Add three labels to your form and change the Form_Load event code to: Private Sub Form1_Load(ByVal sender As ) Handles MyBase.Load Dim MyOption As StockOption 5 New StockOption("IBMDP") Label1.Text = MyOption.Underlying Label2.Text = MyOption.ExpMonth Label3.Text = MyOption.Strike Label4.Text = MyOption.BSPrice End Sub Step 8 Run the program (see Figure 7.2). Once we have completely turned our model into computer code, we say that the class has been encapsulated. A major benefit of OOP is that because the data and methods encapsulated in classes are so closely tied together, we do not need to pass arguments back and forth as inputs to procedures. Rather, member functions can access member variables directly wit hin their definitions. In the StockOption class code, notice that the member methods, such as SetStrikePrice, are able to access the member variables directly. Also notice that the BlackScholesPrice() method, which contains a method definition setting the price of all StockOption objects to 1.11, is overridable. This means that method definitions in classes that inherit from the StockOption class may override the definition in the base, or parent, StockOption class. F I G U R E 7.2 Objects 115 Team-LRN INHERITANCE The best way to understand inheritance is to continue the StockOption object example. A stock option, through abstraction and encapsulation into a class and then instantiation, can be an object in VB.NET. This object built on the StockOption class contains only those properties and methods that are common to all stock options. Certainly the method of calculating the price is not common to all stock options. We calculate the price of a call differently than we calculate the price of a put. A call option is a stock option. As such, it has methods that are not common to all stock options, such as calculation of its price. So rather than create a whole new CallOption class, we can create a derived, or child, class, called CallOption, that inherits all the properties and methods from the base, or parent, StockOption class. The CallOption class then may have some added properties or functionalities, such as pricing algorithms that are unique to call options on stocks. Likewise, we could create a PutOption class that inherits from the base StockOption class and has its own specific functionalities added on. Continuing on then, an American call option is a call option. So we could create a derived class called AmerCallOption that inherits all the properties and methods from the base CallOption class and so on. For the purposes of this book, however, we will stop with the CallOption class. A derived class can add functionality beyond that of the base class, and it can also override methods of its base class. That is, a derived class may replace a member function definition of the base class with its own new definition. In such cases, the base class definition should indicate which if any methods may be overridden in derived classes using the Overridable inheritance modifier. Here is a table of the inheritance modifiers: Inheritance Modifier Description MustInherit Indicates an abstract class that cannot be instantiated, only inherited MustOverride Must be overridden in the derived class. Necessitates a MustInherit class Overridable May be overridden in the derived class NotOverridable Prevents overriding in derived classes Overrides Indicates overriding a base class definition Shadows Has the same name as a method in the base class 116 Introduction to VB.NET Team-LRN In our program, let’s create a derived class CallOption that will inherit all the member variables and methods from the base, StockOption class. Step 9 In your program, add another class module and to it add the following code: Public Class CallOption Inherits StockOption Public Sub New(ByVal strSymbol As String) MyBase.New(strSymbol) End Sub Protected Overrides Sub BlackScholesPrice() Dim d1 As Double, d2 As Double, Nd1 As Double, Nd2 As Double d1 = (Math.Log(dblStock / dblStrike) + (dblInterestRate + _ (dblSigma ^ 2) / 2) * dblTimeTillExp) / _ (dblSigma * Math.Sqrt(dblTimeTillExp)) d2 = d1 - dblSigma * Math.Sqrt(dblTimeTillExp) Nd1 = NormCDF(d1) Nd2 = NormCDF(d2) dblBSPrice = dblStock * Nd1 - dblStrike * _ Math.Exp(-dblInterestRate * dblTimeTillExp) * Nd2 End Sub End Class In the derived class CallOption, the BlackScholesCall() method definition overrides the definition in the base StockOption class. Again, notice that the procedure in the CallOption class called BlackScholesPrice() is a member function and, therefore, has direct access to the member variables. Also, because constructor methods are not inherited, we needed to add a New() method to our derived CallOption class that explicitly calls the constructor of the base class using the MyBase keyword. The MyBase keyword always references the base class within any derived class. Step 10 Change the Form_Load event code to: Private Sub Form1_Load(ByVal sender As ) Handles MyBase.Load Dim MyCallOption As CallOption = New CallOption("IBMDP") Label1.Text = MyCallOption.Underlying Label2.Text = MyCallOption.ExpMonth Label3.Text = MyCallOption.Strike MyCallOption.IntRate50.1 ’ default IntRate = .1 Objects 117 Team-LRN MyCallOption.StockPrice = 80 MyCallOption.Volatility = 0.25 Label4.Text = Format(MyCallOption.BSPrice, "#.0000") End Sub Step 11 Run the program (see Figure 7.3). As we mentioned before, your program will have a different price from the one shown in Figure 7.3 since the time till expiration changes as time moves forward. Also, the StockOption class sets the IntRate ¼ .1 by default, and so in future programs we will not need to set it explicitly. POLYMORPHISM Polymorphism allows us to have one method name, or function name, used in different derived classes, but yet have different implementations, or functionalities, associated with that name depending on the class. In our CallOption class above, and the PutOption class also found on the CD, for example, we have inherited a BlackScholesPrice() method from the parent Stock- Option class, but yet each of the derived classes has its own method for calculation since the equations for Black-Scholes call and put pricing are different. EVENTS Events allow an object, called the publisher or source, to notify other objects, called the subscribers or receivers, when something F I G U R E 7.3 118 Introduction to VB.NET Team-LRN happens. The most intuitive event is the button Click event. When the user clicks a button, the Click event fires, and as we have seen, we can write code that will execute when this happens. Creating events in VB.NET is really quite easy. Here are the four steps tocreate an event: 1. Create an event member in the publisher class. 2. Within the subscriber class, create an instance of the publisher using the WithEvents keyword. 3. Fire the event in the publisher using the RaiseEvent key- word. 4. Create a method in the subscriber that will run when the event is fired using the Handles keyword. We will not review events further. So for more information on events, we refer you to the VB.NET help files. ACCESS MODIFIERS In the complete StockOption class, we have changed all the Private access modifiers to Protected, because Private member variables and Private methods are not accessible in derived classes. Take a look at the BlackScholesPrice() method: Protected Overridable Sub BlackScholesPrice() Protected member variables and methods are accessible in derived classes. So since we intended tocreate a derived class, CallOption, from our base class StockOption, we needed to use the Protected access modifier. Here are the access modifiers for classes: Access Modifier Scope Public Accessible anywhere Private Accessible only by methods of the class. Derived class methods cannot access Private properties or methods Protected Accessible by base class and derived class methods Friend Accessible by base class methods, derived class methods, and certain other classes Shared Shared members are callable directly from the class without requiring an instance of the class Objects 119 Team-LRN OVERLOADING The complete StockOption class also contains two New() methods. This is an example of method overloading. We can create as many methods with the same name in a single class as are needed as long as the lists of input arguments are different from one another, either in number of arguments or in the data types of the arguments. Methods other than New() that are overloaded must include the Overloads keyword. Although not illustrated in the code for StockOption, an example would be: Public Overloads Function NormCDF(ByVal x As Integer) As Double where this function overloads the original NormCDF() function because it differs in its parameter list. Public Overloads Function NormCDF(ByVal x As Double) As Double NOTHING Because the name of an object is really a variable holding a reference to the location of the object in memory, we can assign a value of Nothing to the object, which allows the .NET garbage collector to dispose of the unused memory. This method disposes of the instance of the object, but not the name of the object. MyOption = Nothing CALCULATING AT-THE-MONEY VOLATILITY Very rarely, if ever, in financial markets can we look at an at-the-money (ATM) option and calculate its implied volatility. Yet in our discussions about markets, we often talk in terms of ATM volatility. Quantitative research papers frequently use time series of ATM volatility, and what’s more, many mathematical models assume the reader understands that volatility means at-the-money volatility. But what is ATM volatility if it cannot be observed in the marketplace? The answer is that ATM volatility is a value we must calculate from the implied volatilities of the puts and calls with the strikes surrounding the ATM value—those 120 Introduction to VB.NET Team-LRN nearest, above and below, the price of the underlying symbol. Furthermore, since time is always moving forward and expirations are continuously drawing nearer, we have to include volatilities for the nearby and second nearby expirations to come up with a constant-maturity ATM volatility. That is, if we wish to refer to an ATM volatility that is, for example, 30 calendar days out (which is somewhat difficult to envision since only on 1 day a month will an expiration be exactly 30 days away), we need a mathematical construct to interpolate between options in the nearby and second nearby expirations. In this section we will use the Chicago Board Options Exchange’s market volatility index (VIX) methodology for calculating ATM volatility. As described by Robert Whaley in his paper “The Investor Fear Gauge” (2000), the VIX represents the ATM volatility for the S&P 100 (OEX) index. The CBOE computes the value of the VIX from the prices of eight puts and calls with the strikes nearest, above and below, the price of the underlying security for the nearby and second nearby expirations (Whaley, 2000, p. 1). The implied volatilities derived from these eight options are then weighted to form a 30-calendar- day, 22-trading-day, constant-maturity, ATM implied volatility for the OEX index. The prices used for these eight options will be the midpoints between the respective bids and offers. While the implied volatilities for these eight options should be calculated using a cash dividend–adjusted binomial method to account for the facts that OEX index options are American style and that the underlying index portfolio pays discrete cash dividends, we will use the traditional Black-Scholes model for European options to derive all required implied volatilities. Forecasting dividends for the 100 stocks that make up the index is beyond the scope of this book. As you can imagine, this will, of course, lead to small deviations from the value of the actual VIX. If it happens that the implied volatilities for these eight options are calculated using calendar days, then each must be converted to a trading-day implied volatility. If the number of calendar days to expiration is Days C and the number of trading days till expiration is Days T , then Days T is calculated as Objects 121 Team-LRN follows: Days T ¼ Days C À 2 Áint(Days C =7) To convert calendar-day volatilities to trading-day volatilities, we multiply the eight by the square root of the ratio of the number of calendar days to the number of trading days thusly: s T ¼ s C ffiffiffiffiffiffiffi N C N T r ! Fortunately, the StockOption class already assumes trading days for time to expiration, and so we will not need to make this adjustment. In practice, the risk-free interest rate we should use in the calculation is the continuous yield of the T-bill with the maturity most closely matching the option’s expiration. If the time till expiration is shorter than 30 days, however, the 30 day T-bill rate is used. The StockOption class sets the default interest rate to .1, and we will just use that. The calculations will be clearer if we look at an example. Let’s assume today is February 3 and the OEX index is at 435.70. The options with the nearest strikes above and below would be the 435s and 440s. If we take the midpoints of the bids and asks of the puts and calls for the next two expirations, February 16 and March 16, for both these strikes, we will have eight option prices and eight trading-day volatilities, as shown in Figure 7.4. Now we need to average the eight implied volatilities to arrive at a single ATM volatility 22 days hence, denoted by the gray X in Figure 7.5. First we average the call and put volatilities in each of the quadrants, respectively, to reduce the number of volatilities to four. In Figure 7.5, the subscript N refers to the nearby expiration and S to the second nearby, and subscript A and B mean above and below the current price of the underlying. In the upcoming formulas, P stands for the price of the underlying, and X means the strike price, so that X A refers to the strike price above the price of the underlying security and X B to the strike price below. Also in upcoming formulas, N refers to the number of trading days, so that 122 Introduction to VB.NET Team-LRN [...]... constructor function New() Then create a VB .NET Windows application that creates an object based upon the Stock class using user-entered values Override the ToString() method to print out the ticker and the price in a label In VB .NET, the overridable ToString() method is inherited by every class by default ToString() allows us to simply print out a string representation of an object Within your Stock... the following code to the Button1_Click event to read in the price of the underlying IBM stock and create eight put and call objects and set their MarketPrices and StockPrices Dim UnderlyingPrice As Double = txtUnderlyingPrice.Text Dim CallNB As New CallOption(txtCallNB.Text) CallNB.MarketPrice = txtCallNBprice.Text CallNB.StockPrice = UnderlyingPrice Team-LRN Introduction to VB .NET 126 F I G U R E... As mentioned earlier, the StockOption class already calculates the time till expiration usingtrading days as opposed to calendar days, and so no conversion of the volatilities will be necessary Step 5 Once these eight option objects are created, we need to average the call and put volatilities in each of the quadrants, respectively, to reduce the number of volatilities to four For this we will need... option using this method is 6.6468, which rounds to 6.65 Figure 8.5 shows a map of the values of dblBinomTree()() We can increase the accuracy of our pricing model by increasing the number of steps, N For example, if we change N to 20, so that t ¼ 0.25/20 ¼ 0.0125, the value of the call option is 6.19 F I G U R E 8.5 Team-LRN 148 Introduction to VB .NET SUMMARY In this chapter, we have looked at how to create. .. data feed and set blnMoreData to True if more data was read End While PASSING ARRAYS TO FUNCTIONS Visual Basic. NET allows us to pass arrays to functions as input arguments and also return them from functions as output arguments, or return values Here is an example of the basic syntax for passing arrays to and from functions: Sub Main() Dim dblReturns As Double() = New Double(9) {0.0203, -0.0136, 0.0012,... = 0 To dblLength Team-LRN Arrays 141 dblTotalReturn += InArray(x) Next x Return dblTotalReturn / (dblLength + 1) End Function Because arrays are always passed to functions by reference, it is important to remember that certain operations performed on those arrays, such as matrix transposition and inversion, will actually destroy the original matrix To avoid this situation, it may be necessary to first... toward more positive values Negative skewness indicates an asymmetric tail extending toward negative values We can calculate the kurtosis: ( ) n X Ri À R4 n(n þ 1) 3(n À 1)2 À Kurtosis ¼ (n À 2)(n À 3) (n À 1)(n À 2)(n À 3) i¼1 s This returns the kurtosis of a data set Kurtosis characterizes the relative peakedness or flatness of a distribution compared with the normal distribution Positive kurtosis... of different lengths In memory a jagged array is really stored as an array of arrays Here is how to declare a jagged array in one line: Dim dblBinomTree As Double()() = New Double(2)() {} Binomial trees are valuable tools in derivatives pricing, and there are several methods for building binomial trees in code using Team-LRN Introduction to VB .NET 136 arrays Some methods only require a single-dimensional... txtCallSBprice.Text CallSB.StockPrice = UnderlyingPrice Dim PutSB As New PutOption(txtPutSB.Text) PutSB.MarketPrice = txtPutSBprice.Text PutSB.StockPrice = UnderlyingPrice Dim CallSA As New CallOption(txtCallSA.Text) CallSA.MarketPrice = txtCallSAprice.Text CallSA.StockPrice = UnderlyingPrice Dim PutSA As New PutOption(txtPutSA.Text) PutSA.MarketPrice = txtPutSAprice.Text PutSA.StockPrice = UnderlyingPrice... expiration is found using sS ¼ sS,B XA À P P À XB þ sS,A XA À XB X A À XB as shown in Figure 7.6 Third and last, we average the two remaining volatilities to arrive at a constant-maturity 22 trading hence, using VIX ¼ sN NS À 22 22 À NN þ sS NS À NN N S À NN as shown in Figure 7.7 (These calculations are all taken from Whaley, 2000, p 12ff.) Now let’s create a VB .NET Windows application . formulas, N refers to the number of trading days, so that 122 Introduction to VB .NET Team-LRN N N and N S refer to the number of trading days till the nearby and second nearby expirations, respectively. Second. inherited MustOverride Must be overridden in the derived class. Necessitates a MustInherit class Overridable May be overridden in the derived class NotOverridable Prevents overriding in derived. ticker in the constructor function New(). Then create a VB .NET Windows application that creates an object based upon the Stock class using user-entered values. Override the ToString() method to print