/*
Copyright (C)
2008 Praneet Tiwari
2009 Ueli Hofstetter
This source code is release under the BSD License.
This file is part of JQuantLib, a free-software/open-source library
for financial quantitative analysts and developers - http://jquantlib.org/
JQuantLib is free software: you can redistribute it and/or modify it
under the terms of the JQuantLib license. You should have received a
copy of the license along with this program; if not, please email
. The license is also available online at
.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the license for more details.
JQuantLib is based on QuantLib. http://quantlib.org/
When applicable, the original copyright notice follows this notice.
*/
package org.jquantlib.model;
import java.util.ArrayList;
import java.util.List;
import org.jquantlib.lang.annotation.Time;
import org.jquantlib.math.Ops;
import org.jquantlib.math.solvers1D.Brent;
import org.jquantlib.pricingengines.PricingEngine;
import org.jquantlib.quotes.Handle;
import org.jquantlib.quotes.Quote;
import org.jquantlib.termstructures.YieldTermStructure;
import org.jquantlib.util.Observable;
import org.jquantlib.util.Observer;
/**
* Liquid market instrument used during calibration
* @author Praneet Tiwari
*/
// TODO: code review :: license, class comments, comments for access modifiers, comments for @Override
// TODO: code review :: please verify against QL/C++ code
public abstract class CalibrationHelper implements Observer, Observable {
protected double/* @Real */marketValue;
protected Handle volatility_;
protected Handle termStructure_;
protected PricingEngine engine_;
private boolean calibrateVolatility_ = false;
public CalibrationHelper(
final Handle volatility,
final Handle termStructure,
final boolean calibrateVolatility) {
if (System.getProperty("EXPERIMENTAL") == null)
throw new UnsupportedOperationException("Work in progress");
this.volatility_ = volatility;
this.termStructure_ = termStructure;
this.calibrateVolatility_ = calibrateVolatility;
this.volatility_.addObserver(this);
this.termStructure_.addObserver(this);
//XXX:registerWith
//registerWith(termStructure_);
//registerWith(volatility_);
}
//TODO: code review
// abstract double blackPrice (double /*@Volatility*/ volatility);
// ! returns the actual price of the instrument (from volatility)
double/* @Real */marketValue() {
return marketValue;
}
// ! returns the price of the instrument according to the model
public abstract double /* @Real */modelValue();
// ! returns the error resulting from the model valuation
public double /* @Real */calibrationError(){
if(calibrateVolatility_){
final double lowerPrice = blackPrice(0.001);
final double upperPrice = blackPrice(10);
final double modelPrice = modelValue();
double implied;
if(modelPrice <= lowerPrice)
implied = 0.001;
else if(modelPrice >= upperPrice)
implied = 10.0;
else
implied = impliedVolatility(modelPrice, 1e-12, 5000, 0.001, 10);
return implied - volatility_.currentLink().value();
} else
return Math.abs(marketValue() - modelValue())/marketValue();
}
// ! Black volatility implied by the model
public double /* @Volatility */impliedVolatility(final double /* @Real */targetValue, final double /* @Real */accuracy,
final int /* @Size */maxEvaluations, final double /* @Volatility */minVol, final double /* @Volatility */maxVol){
final ImpliedVolatilityHelper f = new ImpliedVolatilityHelper(this, targetValue);
final Brent solver = new Brent();
solver.setMaxEvaluations(maxEvaluations);
return solver.solve(f, accuracy, volatility_.currentLink().value(), minVol, maxVol);
}
public void setPricingEngine(final PricingEngine engine) {
this.engine_ = engine;
}
//
// public abstract methods
//
// TODO: code review :: please verify against QL/C++ code
public abstract void addTimesTo(ArrayList
Ads help maintain this website.