Find Instruction
Find Instruction
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?
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
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
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
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
Everything between the FIND and END FIND gets executed with each function evaluation. With your code:
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:
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.
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.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.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
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
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
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.
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.