Page 1 of 1

Find Instruction

Posted: Sun May 09, 2010 8:27 pm
by John_Val
I want to fit an option pricing model to set of prices via NLLS, for the date May 07. For May 07 I have 10 call prices and 10 put prices for 4 different maturities. So, there are a total of 80 prices.
For the estimation I have to set up the full sum of squared errors, not just supply the variables and formula and letting RATS create the sum.
Am I able to do this using the Find instruction?

Re: Find Instruction

Posted: Mon May 10, 2010 9:47 am
by TomDoan
You certainly could use FIND for that, though that's usually the last choice, since it doesn't know anything about the structure of the problem. If the data doesn't have the correct structure for NLLS, it's possible that you can use NLSYSTEM with CV=%IDENTITY(4) instead. That will minimize the sum of squared errors across 20 data points and 4 formulas.

Re: Find Instruction

Posted: Mon May 10, 2010 12:59 pm
by John_Val
I am going to try with just one maturity , 20 prices, using find. I wrote the code below, but the program breaks down and I get a not responding message.
Callerr is the sum of squared errors for Call prices and Puterr is the same but for put prices. If you could look to see where I am going wrong.



all 10
open data OptionPrice1.dat
data(format=free,org=columns) / Cmay Pmay
print / cmay pmay
ENTRY CMAY PMAY
1 2.99 0.00
2 1.99 0.01
3 1.02 0.02
4 0.19 0.17
5 0.02 1.04
6 0.01 2.01
7 0.01 2.98
8 0.01 4.00
9 0.01 4.90
10 0.00 0.00

nonlin a1 sigma1 sigma2 mu1 mu2
dec real d1 d2 d3 d4 a1 sigma1 sigma2 mu1 mu2 Error callerr puterr

find(method=bfgs) minimum Error
com a1=0.1
com sigma1 = .12
com sigma2 = .17
com mu1 = 0.12
com mu2 = 0.15


com d1 = (1/sigma1)*(mu1+sigma1**2-log(4))
com d2 = d1-sigma1
com d3 = (1/sigma2)*(mu2+sigma2**2-log(4))
com d4 = d3-sigma2

com Callerr = 0
do i =1,10
com Callerr = Callerr + ( Cmay(i)- ( a1*(exp(mu1+0.5*sigma1**2)*%CDF(d1) - 4*%CDF(d2) ) + (1-a1)*( exp(mu2+0.5*sigma1**2)*%CDF(d3) - 4*%CDF(d4) ) ) )**2
end do i

com Puterr = 0
do i =1,10
com Puterr = Puterr + ( Pmay(i)- ( a1*( -exp(mu1+0.5*sigma1**2)*%CDF(-d1) - 4*%CDF(-d2) ) + (1-a1)*( -exp(mu2+0.5*sigma2**2)*%CDF(-d3) - 4*%CDF(-d4) ) ) )**2
end do i

com Error = Puterr + callerr
end find

Re: Find Instruction

Posted: Mon May 10, 2010 6:14 pm
by TomDoan
Everything between the FIND and END FIND gets executed with each function evaluation. With your code:

Code: Select all

find(method=bfgs) minimum Error
com a1=0.1
com sigma1 = .12
com sigma2 = .17
com mu1 = 0.12
com mu2 = 0.15
 etc.
you're overwriting your parameter values with your guess values every time, which won't work. Shift those COMPUTEs outside the FIND, and you should be OK, that is:

Code: Select all

com a1=0.1
com sigma1 = .12
com sigma2 = .17
com mu1 = 0.12
com mu2 = 0.15
find(method=bfgs) minimum Error
 etc.
However, isn't there something wrong with:

com Callerr = Callerr + ( Cmay(i)- ( a1*(exp(mu1+0.5*sigma1**2)*%CDF(d1) - 4*%CDF(d2) ) + (1-a1)*( exp(mu2+0.5*sigma1**2)*%CDF(d3) - 4*%CDF(d4) ) ) )**2

There's nothing in your pricing formula (for both puts and calls) that depends upon (i) so that's just going to try to (indirectly) fit the two sample means with five parameters, so the model isn't identified as written.

Re: Find Instruction

Posted: Wed May 12, 2010 5:03 pm
by John_Val
I am randomizing over inital values, for example over 50 draws. When I use bfgs the program breaks down most of the time if the max iter is to high. When bfgs does work it always gives negative function values, even though this is a least squares estimation. When I use simplex or genetic the estimation goes smoothly and I always get function values that are positive. What could be the problem?

com var = 0.5
com draws = 20
dec real d1 d2 d3 d4 a1 sigma1 sigma2 mu1 mu2 Error callerr puterr

dec vec[vec] param(draws)
dec vec func(draws)
do i=1,draws

nonlin a1 sigma1 sigma2 mu1 mu2
com a1=%ran(var);com sigma1 = %ran(var);com sigma2 = %ran(var);com mu1 = %ran(var);com mu2 = %ran(var)

find(method=bfgs,iter=150,noprint) minimum Error

com Callerr = 0
do j =1,10
com d1 = (1/sigma1)*(mu1+sigma1**2-log(j))
com d2 = d1-sigma1
com d3 = (1/sigma2)*(mu2+sigma2**2-log(j))
com d4 = d3-sigma2
com Callerr = Callerr + ( Cmay(j)- ( a1*(exp(mu1+0.5*sigma1**2)*%CDF(d1) - j*%CDF(d2) ) + (1-a1)*( exp(mu2+0.5*sigma1**2)*%CDF(d3) - j*%CDF(d4) ) ) )**2
end do

com Puterr = 0
do j =1,10
com d1 = (1/sigma1)*(mu1+sigma1**2-log(j))
com d2 = d1-sigma1
com d3 = (1/sigma2)*(mu2+sigma2**2-log(j))
com d4 = d3-sigma2
com Puterr = Puterr + ( Pmay(j)- ( a1*( -exp(mu1+0.5*sigma1**2)*%CDF(-d1) - j*%CDF(-d2) ) + (1-a1)*( -exp(mu2+0.5*sigma2**2)*%CDF(-d3) - j*%CDF(-d4) ) ) )**2
end do

com Error = Puterr + callerr
end find

com param(i) = %beta
com func(i) = %funcval
end do

Re: Find Instruction

Posted: Wed May 12, 2010 5:54 pm
by TomDoan
You're randomizing into possibly negative values of sigma1 and sigma2, which isn't a good idea. Use some scale of %rangamma instead for those.

BFGS converts all optimization problems to maximizations (in this case by flipping the sign). It's easier to do that than to work through all the changes in logic to convert a hill-climbing algorithm to a hill-descending one. Simplex and genetic are naturally minimizers, so they will take your function as given. Regardless, the %FUNCVAL should be corrected to be positive regardless of algorithm.

Some problems aren't suited to derivative-based optimizers. Certainly, I wouldn't expect BFGS to do well starting from negative values of sigma's because the function behaves badly at sigma=0, so it would be hard to cross the boundary. Genetic and simplex are more likely to skip right over that on a earlier trial.