00001
00002
00003 #include ".\volsurface.h"
00004
00005
00006
00007 volsurface::volsurface(Real stockPrice, Date today, valarray<Real> strikes, valarray<Date> maturities, yieldCurve yCurve, valarray<valarray<Real> > callputprices, valarray<valarray<bool> > iscallputprices)
00008 : _stockPrice(stockPrice),
00009 _today(today),
00010 _strikes(strikes),
00011 _maturities(maturities),
00012 _yieldCurve(yCurve),
00013 _callputprices(callputprices),
00014 _volsurfconst(false),
00015 _iscallputprices(iscallputprices)
00016 {
00017 }
00018
00019 volsurface::volsurface(Real stockPrice, Date today, yieldCurve yCurve, volsurfaceparams ¶ms)
00020 : _stockPrice(stockPrice),
00021 _today(today),
00022 _strikes(params.strikes),
00023 _maturities(params.maturities),
00024 _yieldCurve(yCurve),
00025 _callputprices(params.callputprices),
00026 _volsurfconst(false),
00027 _iscallputprices(params.iscallputprices)
00028 {
00029 }
00030
00031
00032 volsurface::volsurface(Real constantvol)
00033 : _volsurfconst(true),
00034 _constantvol(constantvol)
00035 {
00036 }
00037
00038 volsurface::volsurface(void)
00039 : _volsurfconst(true),
00040 _constantvol(0)
00041 {
00042 }
00043
00044 volsurface::volsurface(valarray<valarray<Real> > volsurf)
00045 : _impliedvolsurface(volsurf)
00046 {
00047 }
00048
00049
00050 volsurface::~volsurface(void)
00051 {
00052 }
00053
00054
00055 Real volsurface::invertBSformula(Real r, Real maturity, Real stockPrice, Real strike, Real callputPrice, bool isacall)
00056 {
00057 if (isacall){
00058 BlackScholes bs = BlackScholes(stockPrice, callputPrice, false, r, strike, maturity, Call);
00059 return bs.getVolatility();
00060 }
00061 else{
00062 BlackScholes bs = BlackScholes(stockPrice, callputPrice, false, r, strike, maturity, Put);
00063 return bs.getVolatility();
00064 }
00065
00066 }
00067
00068 void volsurface::setvolsurface()
00069 {
00070 if(_volsurfconst){
00071 int N=10;
00072 _impliedvolsurface.resize(N);
00073 valarray<Real> temp(N);
00074 int i;
00075 for(i=0;i<10;i++)
00076 temp[i]=_constantvol;
00077 for(i=0;i<10;i++){
00078 _impliedvolsurface[i].resize(10);
00079 _impliedvolsurface[i]=temp;
00080 }
00081
00082 }
00083 else{
00084 int i=_callputprices.size();
00085 int j=_callputprices[1].size();
00086
00087 valarray<Real> temp(j);
00088 _impliedvolsurface.resize(i);
00089
00090
00091
00092 int k,l;
00093 Date maturity;
00094 Real timetomaturity;
00095 Real r;
00096
00097 for(k=0;k<i;k++){
00098 maturity=_maturities[k];
00099 timetomaturity=_today.dayCount(maturity);
00100 r=_yieldCurve.spotRate(timetomaturity);
00101
00102 for(l=0;l<j;l++){
00103 temp[l]=invertBSformula(r, timetomaturity, _stockPrice, _strikes[l], _callputprices[k][l], _iscallputprices[k][l]);
00104 }
00105
00106 _impliedvolsurface[k].resize(j);
00107 _impliedvolsurface[k]=temp;
00108 }
00109 valarray<Real> vecmaturity(i);
00110 for(k=0;k<i;k++){
00111 vecmaturity[k]=_today.dayCount(_maturities[k]);
00112 }
00113
00114 _interpolvolsurf=interpolator(vecmaturity, _strikes, _impliedvolsurface);
00115 }
00116 }
00117
00118 valarray<valarray<Real> > volsurface::getvolsurface(){
00119 return _impliedvolsurface;
00120 }
00121
00122 Real volsurface::volatility(Real K, Date T){
00123 if(_volsurfconst)
00124 return _constantvol;
00125 else{
00126 Real timetomaturity=_today.dayCount(T);
00127 return _interpolvolsurf.interpolate(timetomaturity, K);
00128 }
00129
00130 }
00131 Real volsurface::variance(Real K, Date T){
00132 if(_volsurfconst)
00133 return _constantvol*_constantvol;
00134 else{
00135 Real vol=volatility(K,T);
00136 return vol*vol;
00137 }
00138 }
00139 Real volsurface::forwardVolatility(Real K, Date t, Date T){
00140 Real v1=variance(K,t);
00141 Real v2=variance(K,T);
00142 Real timetoT=_today.dayCount(T);
00143 Real timetot=_today.dayCount(t);
00144 Real v12=(timetoT*v2 - timetot*v1)/(timetoT - timetot);
00145 return sqrt(v12);
00146 }
00147
00148 volsurface volsurface::forwardvolsurface(Date t){
00149
00150 Integer i=0;
00151 Integer N =_maturities.size();
00152
00153 while((i<N)&&(_maturities[i]<t)){
00154 i++;
00155 }
00156 valarray<valarray<Real> > fwdvs;
00157 if (i<N){
00158 fwdvs.resize(N-i);
00159 Integer j,k;
00160 Integer M = _strikes.size();
00161 valarray<Real> temp(M);
00162 valarray<Date> maturities(M);
00163 for(j=0;j<N-i;j++){
00164 for(k=0;k<M;k++)
00165 temp[k]=forwardVolatility(_strikes[k], t, _maturities[j+i]);
00166 fwdvs[j].resize(M);
00167 fwdvs[j] = temp;
00168 maturities[j] = _maturities[j+i];
00169 }
00170
00171 volsurface forwardvd(fwdvs);
00172 return forwardvd;
00173 }
00174 else{
00175 fwdvs.resize(1);
00176 Integer M = _strikes.size();
00177 fwdvs[1].resize(M);
00178 fwdvs[1] = _impliedvolsurface[N-1];
00179 volsurface forwardvd(fwdvs);
00180 return forwardvd;
00181 }
00182
00183 }
00184
00185 volsurface volsurface::shiftedYCvolsurface(Real shift){
00186
00187 yieldCurve shiftedyc = _yieldCurve.shiftZCBRateCurve(shift);
00188 volsurface shiftedvs(_stockPrice, _today, _strikes, _maturities, shiftedyc, _callputprices, _iscallputprices);
00189 shiftedvs.setvolsurface();
00190
00191 return shiftedvs;
00192 }
00193
00194 volsurface volsurface::shiftedvolsurface(Real shift){
00195
00196 Integer M = _strikes.size();
00197 Integer N = _maturities.size();
00198 Integer j,k;
00199
00200 valarray<valarray<Real> > shiftedvs;
00201 valarray<Real> temp(M);
00202
00203 for(j=0;j<N;j++){
00204 for(k=0;k<M;k++)
00205 temp[k] = _impliedvolsurface[j][k] + shift;
00206 shiftedvs[j].resize(M);
00207 shiftedvs[j] = temp;
00208 }
00209 volsurface shiftedvolsurf(shiftedvs);
00210
00211 return shiftedvolsurf;
00212 }