http://quantlib.414.s1.nabble.com/Volatility-Surface-Interpolation-tp5741p5744.html
same strikes (you can see it after the line... "if ( Smiles[i].size()
< numStrikes )" ). Then with that matrix, I interpolate to get the
volatilities at the predefined terms.
So that's the problem, I interpolate linearly... and no bilinearly...
>
> Hi Sebastián,
>
> If I'm reading your volatility matrix right then for the 130 strike
> the variance indeed decreases as time progresses;
> that is the vol^2 * time :
>
> 0.4989**2 * 0.127777777777777 =0.031804043499999803
>
> 0.3775**2 * 0.205555555555555 = 0.029292951388888808
>
> You should check with your source of volatility quotes.
>
> Best,
> Bojan
>
>
>
> "Sebastián Miranda" <
[hidden email]> writes:
>
> > thanks Bojan!!
> >
> > For the example matrix use this:
> >
> > Settlement date: 39482
> >
> > strikes: dates:
> > ------------------------------
> > 130 39493
> > 140 39528
> > 150 39556
> > 160 39619
> > 165 39710
> > 170 39801
> > 175 39983
> > 180 40165
> > 185
> > 190
> > 195
> > 200
> > 210
> > 220
> >
> > dates in years:
> > --------------------------------
> > 0,0305555555555555
> > 0,0305555555555555
> > 0,127777777777777
> > 0,205555555555555
> > 0,380555555555555
> > 0,633333333333333
> > 0,886111111111111
> > 1,39166666666666
> > 1,89722222222222
> >
> >
> > On Feb 4, 2008 12:39 PM, Sebastián Miranda
> > <
[hidden email]> wrote:
> >> Hello,
> >>
> >> I'm trying to interpolate time/strike dependent volatilities using the
> >> BlackVarianceTermStructure.
> >>
> >> I interpolate every term smile to get the volatility matrix and then
> >> interpolate that matrix to get volatilities at given standard times.
> >>
> >> But, when I call the constructor, I get the error:
> >>
> >> QL_REQUIRE(variances_[i][j]>=variances_[i][j-1],
> >> "variance must be non-decreasing");
> >>
> >> Any ideas about where's the error????
> >>
> >> Tankx !!!!
> >>
> >> Sebastián
> >>
> >> ============================================================================
> >> ==
> >> Example Volatility Matrix:
> >>
> >> 0,7335 0,4989 0,3775 0,3467 0,3305 0,3342 0,5698 0,5814
> >> 0,6635 0,4404 0,3730 0,3324 0,3271 0,3275 0,5407 0,5463
> >> 0,5853 0,3983 0,3685 0,3217 0,3237 0,3239 0,5098 0,5138
> >> 0,4948 0,3855 0,3613 0,3225 0,3203 0,3196 0,4770 0,4899
> >> 0,4187 0,3604 0,3448 0,3188 0,3172 0,3175 0,4466 0,4382
> >> 0,4298 0,3545 0,3428 0,3150 0,3140 0,3154 0,4140 0,3796
> >> 0,3915 0,3456 0,3225 0,3135 0,3109 0,3115 0,3785 0,3712
> >> 0,3571 0,3365 0,3143 0,3119 0,3077 0,3076 0,3394 0,3626
> >> 0,4132 0,3206 0,2915 0,3083 0,3059 0,3030 0,3148 0,3401
> >> 0,3823 0,3169 0,2873 0,3046 0,3040 0,2983 0,2882 0,3160
> >> 0,3749 0,3170 0,2870 0,3008 0,2994 0,2921 0,2588 0,2900
> >> 0,3245 0,3183 0,2866 0,2970 0,2948 0,2857 0,2256 0,2613
> >> 0,4503 0,3375 0,2860 0,2939 0,2862 0,2815 0,2063 0,2472
> >> 0,5691 0,3396 0,2853 0,2906 0,2774 0,2772 0,1849 0,2323
> >>
> >>
> >> ============================================================================
> >> ==
> >> The code:
> >>
> >> void cargarBBDD( vector< MaturitySmileData > ACUMULADOR ){
> >> // ==============================================================
> >> // FECHA INICIAL DEL CALCULO -> Atentos a los históricos
> >> Date fechaINICIAL = ACUMULADOR[0].subyacente.settlementDate;
> >> // Date fechaINICIAL = Date::todaysDate();
> >> // ==============================================================
> >> typedef map<double, double> Smile;
> >> typedef map<double,double>::iterator Iterador;
> >> const unsigned int numVenc = ACUMULADOR.size();
> >> std::vector<Date> maturities(numVenc);
> >> // Monto set ordenado con todos los strikes.
> >> std::set< double > strikesSet;
> >> std::vector< Smile > Smiles;
> >> for ( unsigned int i = 0; i < numVenc ; i++){
> >> Smile tmpSmile__;
> >> Iterador iterSmile;
> >> Iterador iter_;
> >> iter_ = ACUMULADOR[i].callSmile.begin();
> >> while (iter_ != ACUMULADOR[i].callSmile.end() ){
> >> strikesSet.insert( iter_->first );
> >> tmpSmile__.insert( *iter_ );
> >> iter_++;
> >> }
> >> iter_ = ACUMULADOR[i].putSmile.begin();
> >> while (iter_ != ACUMULADOR[i].putSmile.end() ){
> >> strikesSet.insert( iter_->first );
> >> iterSmile = tmpSmile__.find( iter_->first );
> >> if (iterSmile == tmpSmile__.end() ){
> >> tmpSmile__.insert( *iter_ ) ;
> >> } else{ //! Si ya tenemos este strike para las Calls,
> >> promediamos ambos.
> >> if( fabs(iter_->second - iterSmile->second)
> >> > 0.02) {
> >> string MegError = "Error promediando curva -> ";
> >> MegError += "RIC: " +
> >> ACUMULADOR[i].subyacente.RIC + "\t Vencimiento. "+ ACUMULADOR[i].vencimiento ;
> >> MegError += "\n Vol. Call:\t" +
> >> boost::lexical_cast<std::string>( (*iterSmile).second );
> >> MegError += "\n Vol. Put:\t" +
> >> boost::lexical_cast<std::string>( (*iter_).second );
> >> MegError += "\n
> >> --------------------------------";
> >> MegError += "\n DIFERENCIA:\t" +
> >> boost::lexical_cast<std::string>(fabs((*iter_).second - (*iterSmile).second) );
> >> VOLCAR_LOG( MegError );
> >> }
> >> iterSmile->second = ((*iter_).second +
> >> (*iterSmile).second) / 2;
> >> }
> >> iter_++;
> >> }// end while
> >> Smiles.push_back(tmpSmile__);
> >> }; // end for numVenc
> >> const unsigned int numStrikes = strikesSet.size();
> >> vector< double> strikes( strikesSet.begin(), strikesSet.end());
> >> Matrix volatilidades( numStrikes, numVenc );
> >> for ( unsigned int i = 0; i < numVenc ; i++){
> >> maturities[i] = ACUMULADOR[i].maturity;
> >> Iterador iter_;
> >> // Si no tiene todos los strikes, interpolamos.
> >> if ( Smiles[i].size() < numStrikes ){
> >>
> >> const unsigned int s_ = Smiles[i].size();
> >> Matrix vols_( s_ , 1);
> >> std::vector<Date> dates_(1);
> >> dates_[0] = ACUMULADOR[i].maturity;
> >> // Cargo las volas
> >> iter_ = Smiles[i].begin();
> >> vector< double> strikesTMP;
> >> int j = 0;
> >> while ( iter_ != Smiles[i].end() ){
> >> strikesTMP.push_back( (*iter_).first ) ;
> >> vols_[j][0] = (*iter_).second ; j++;
> >> iter_++;
> >> };
> >> // Montamos el Smile con lo que tenemos y lo interpolamos.
> >> boost::shared_ptr<BlackVolTermStructure>
> >> curvaVolas(new
> >> BlackVarianceSurface( fechaINICIAL, dates_,
> >> strikesTMP, vols_, dayCounter ));
> >> for (unsigned int j = 0 ; j < numStrikes ; j++){
> >> volatilidades[j][i] =
> >> curvaVolas->blackVol(fechaINICIAL, strikes[j] , true );
> >> std::cout << "Vol " << j << " " << i << "\t"
> >> << volatilidades[j][i] << "\n";
> >> };
> >> /*
> >> set< double >::iterator itrK_ ;
> >> itrK_ = strikesSet.begin();
> >> int indx_ = 0;
> >> while ( itrK_ != strikesSet.end() ){
> >> volatilidades[indx_][i] =
> >> curvaVolas->blackVol(fechaINICIAL, *itrK_ , true );
> >> indx_++;
> >> itrK_++;
> >> };*/
> >>
> >> } else{ // Si tiene todos los strikes, no necesitamos interpolar nada.
> >> iter_ = Smiles[i].begin();
> >> int j = 0;
> >> while ( iter_ != Smiles[i].end() ){
> >> volatilidades[j][i] = (*iter_).second ;
> >> std::cout << "Vol " << j << " " << i << "\t" <<
> >> volatilidades[j][i] << "\n";
> >> j++; iter_++; };
> >> };
> >>
> >> };
> >>
> >> // Volatility Surface
> >> // HERE IS THE PROBLEM
> >> *********************************************************
> >> boost::shared_ptr<BlackVolTermStructure> SupVolatilidad(new
> >> BlackVarianceSurface( fechaINICIAL, maturities, strikes,
> >> volatilidades, dayCounter ));
> >> // HERE IS THE PROBLEM
> >> *********************************************************
> >>
> >> // Interpolamos
> >> const int numStrikesSTD = 13;
> >> const int numTermsSTD = 8;
> >> double strikesSTD[] = { 0.8,
> >>
> >> 0.85,
> >>
> >> 0.9,
> >>
> >> 0.95,
> >>
> >> 0.975,
> >>
> >> 0.9875,
> >>
> >> 1.0,
> >>
> >> 1.0125,
> >>
> >> 1.025,
> >>
> >> 1.05,
> >>
> >> 1.1,
> >>
> >> 1.15,
> >>
> >> 1.2 };
> >> Date termsSTD[] = {fechaINICIAL +
> >> 1*Months,
> >>
> >> fechaINICIAL + 3*Months,
> >>
> >> fechaINICIAL + 6*Months,
> >>
> >> fechaINICIAL + 1*Years,
> >>
> >> fechaINICIAL + 2*Years,
> >>
> >> fechaINICIAL + 3*Years,
> >>
> >> fechaINICIAL + 4*Years,
> >>
> >> fechaINICIAL + 5*Years };
> >> // Superficie de Volatilidades interpolada.
> >> double volasBBDD[numStrikesSTD][numTermsSTD];
> >> for (unsigned int i = 0 ; i < numStrikesSTD ; i++){
> >> double strike__ = strikesSTD[i] *
> >> ACUMULADOR[0].subyacente.spot;
> >> for (unsigned int j = 0 ; j < numTermsSTD ; j++){
> >> volasBBDD[i][j] =
> >> SupVolatilidad->blackVol(termsSTD[j], strike__ , true );
> >> };
> >> };
> >> string dia =
> >> boost::lexical_cast<std::string>(fechaINICIAL.dayOfMonth());
> >> dia = ( dia.length() == 1 )? "0" + dia : dia ;
> >> int mes__ = fechaINICIAL.month();
> >> string mes = boost::lexical_cast<std::string>(mes__);
> >> mes = ( mes.length() == 1 )? "0" + mes : mes ;
> >> std::string query = "";
> >> query += "INSERT INTO `advisory`.`tsupvolas` VALUES ";
> >> for (unsigned int i = 0 ; i < numStrikesSTD ; i++){
> >> query += "( " + ACUMULADOR[0].subyacente.ID + ",'" +
> >> boost::lexical_cast<std::string>(fechaINICIAL.year());
> >> query += mes + dia + "'," +
> >> boost::lexical_cast<std::string>(strikesSTD[i]) + "," ;
> >> query +=
> >> boost::lexical_cast<std::string>(ACUMULADOR[0].subyacente.spot);
> >> for (unsigned int j = 0 ; j < numTermsSTD ; j++){
> >> query += "," +
> >> boost::lexical_cast<std::string>(volasBBDD[i][j]);
> >> };
> >> query += ") ";
> >> query += (i + 1 == numStrikesSTD)? "" : ",";
> >> };
> >> query += "; ";
> >> // INSERTAMOS EN LA BBDD
> >> res = consultaSQL(query);
> >> //int filas = mysql_affected_rows();
> >> //string staus= ( filas == numStrikesSTD)?
> >> ACUMULADOR[0].subyacente.RIC + " insertado OK." :
> >> ACUMULADOR[0].subyacente.RIC + " Error Inserción.";
> >> mysql_free_result(res);
> >> // boost::lexical_cast<std::string>
> >> };
> >>
> >
> > -------------------------------------------------------------------------
> > This SF.net email is sponsored by: Microsoft
> > Defy all challenges. Microsoft(R) Visual Studio 2008.
> >
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/_______________________________________________> > QuantLib-users mailing list
> >
[hidden email]
> >
https://lists.sourceforge.net/lists/listinfo/quantlib-users>
>
> --
> Bojan Nikolic
>
Defy all challenges. Microsoft(R) Visual Studio 2008.