finmath / finmath-lib Goto Github PK
View Code? Open in Web Editor NEWMathematical Finance Library: Algorithms and methodologies related to mathematical finance.
License: Apache License 2.0
Mathematical Finance Library: Algorithms and methodologies related to mathematical finance.
License: Apache License 2.0
The unit test net.finmath.marketdata.model.volatilities.CapletVolatilitiesParametricCalibrationTest can run in a time out on Travis (depends on the machine we get on Travis):
Running calibration test using quoting convention VOLATILITYNORMAL for calibration objective function.
Given a discount curve:
DiscountCurveNelsonSiegelSvensson [timeScaling=1.0, parameter=[0.02, -0.01, 0.14, -0.1, 4.0, 3.0], toString()=AbstractCurve [name=EUR, referenceDate=2014-07-15]]
Quaterly forward with fixing in 1.0 requested from forward curve is 0.016235670732787796
Quaterly forward with fixing in 1.0 calculated from that discount curve is 0.016235670732787796No output has been received in the last 10m0s, this potentially indicates a stalled build or something wrong with the build itself.
Check the details on how to adjust your build configuration on: https://docs.travis-ci.com/user/common-build-problems/#Build-times-out-because-no-output-was-receivedThe build has been terminated
There should be an AbstractDiscountCurve class that e.g. implements getDiscountCurve(double) = getDiscountCurve(model, double) instead having to implement that in each subclass
I have a concern regarding the present version of the implementation of both the Heston and Bates models. So far I was not complaining because we only had BlackScholes in the library and everything is fine in that case. Introducing more advanced models implies that one has to pay more attention.
Currently it is possible to choose quite freely the domain of integration, this implies that the characteristic function may explode in finite time, which results in non-sense option prices.
There is a vast literature on the topic. Prominent examples are given by Andersen and Piterbarg
https://link.springer.com/article/10.1007/s00780-006-0011-7
and Keller-Ressel
http://onlinelibrary.wiley.com/doi/10.1111/j.1467-9965.2010.00423.x/abstract
In concrete terms, to obtain a situation where you get in trouble with the current implementation try the following:
In net.finmath.fouriermethod.products.AbstractProductFourierTransform
Set some very nasty value in lineOfIntegration like
final double lineOfIntegration = 10.5 * getIntegrationDomainImagUpperBound()+getIntegrationDomainImagLowerBound();
and set the maturity of the option to 10 years. You should see option prices going to infinity.
To solve the issue without getting mad there is a trick: the use of the Cauchy residue theorem. To this you have to change the following lines in EuropeanOption
@OverRide
public double getIntegrationDomainImagLowerBound() {
return -1;
}
/* (non-Javadoc)
* @see net.finmath.fouriermethod.products.AbstractProductFourierTransform#getDomainImagUpperBound()
*/
@Override
public double getIntegrationDomainImagUpperBound() {
return 0;
}
But since we change the countour of integration, we have to add the residue term in front of the integral, so in AbstractProductFourierMethod you need to do something like
return residueTerm + integrator.integrate(integrand) / 2.0 / Math.PI;
and then you must provide in the interface a method getResidueTerm which provides the right residue (the residue depends on the contour you choose on the complex plane). In case we choose IntegrationDomainBound in (-1,0) the residue Term is simply the value of the asset today or, equivalently, the characteristic function of the asset computed at the point -1, which gives the martingale property of the asset.
Financially speaking, instead of transforming a call Option, you transform a covered call Position.
This is the best way to guarantee that your model does not become numerically unstable when you consider vanilla call/put options:
By definition of characteristic function you have that 0 and -1 are always good points: 0, by definition of characteristic function returns you 1 for the ch. Function while -1 is simply a statement of the martingale property of the (discounted) asset.
For more precise formulas please see the following paper by Roger Lee
https://www.math.uchicago.edu/~rl/dft.pdf
In net.finmath.functions.AnalyticFormulas
I can find functions to calculate different option values for call options using black-scholes.
But there is no function to calculate the option value of a put option?
Am I missing something?
There's a suggestion to merge both packages in one. Consider to make maven-like project structure and probably use maven to project build.
main/src/java
main/test/java
as an example of directory structure in project. A problem you have now is that finmath-experiments
depends on finmath-lib
but finmath-lib
is included into the the former as a compiled jar
. Hence they are separated somewhat, but I'm not sure it was the purpose.
The method getQuantile of RandomVariable does not comply with the JavaDoc of the interface RandomVariableInterface. The implementation should be changed to comply with the interpretation of returning x such that P(X < x) = alpha for a given alpha.
If a start date of a schedule is 29.02, it should be specified if the generator rolls 3M to 29.05 or to 31.05 (END-of-MONTH). Same applied to 30.04, which should go to 31.07 or 30.07 depending on "useEndOfMonth".
Please, convert your custom READ ME.txt
file to a README.md
which will be displayed by default on project page.
Hi Christian, I have a suggestion:
Let us compare
net.finmath.fouriermethods.models.BlackScholesModel.java
and
net.finmath.montecarlo.assetderivativevaluation.BlackScholesModel.java
These two classes provide model specific information to different numerical methods, but a BlackScholes model is a BlackScholes model. The one in our Fourier methods package is merely providing the characteristic function. So I think that these two functionalities could be unified in a unique BlackScholes model class that provides:
public CharacteristicFunctionInterface apply(double time)
plus all other method from net.finmath.montecarlo.assetderivativevaluation.BlackScholesModel.java
If you consider the case of the Heston model, you have then a nice feature, we can calibrate our Heston model to a book of vanillas and then we can directly send the calibrated clone to the Monte Carlo engine to price exotics.
Hi,
just adopted the lib. It's solving an optimisation problem that kept tripping up Apache Maths Common. Thanks!
Quick suggestion. You have a releases page for the project. This includes the source for each tagged release version.
It is possible to configure Travis to push the compiled jars to the release folder:
https://docs.travis-ci.com/user/deployment/releases/
Here's an example of a repo that includes compiled jars in the release:
https://github.com/ngageoint/geopackage-android/releases
Oh, while I'm begging... At very low cost (effort), it would be straightforward for you to modify your maven build to construct javadoc and source jar files.
The setter setParameter should be replaced by the getter getCloneWithModifiedParameter - as it is implemented in covariance models and other parts of the library.
The Heston model characteristic function in net.finmath.fouriermethod.models
does not Handle the limit case xi=0. The implementation results in NAN due to a 0 / 0. This should be fixed. The case xi=0.0001 (or smaller) works and converges to the Black-Scholes value.
Hi Christian,
Some classes (e.g. LinearAlgebra, CalibrationSpec and LIBORMarketModelStandard) control default behaviours with some embedded variables. Those variable values can be changed only with code changes.
May I modify related classes, so that those variable values can be changed with some system properties? I will keep the code backward compatible.
Best regards,
William
hi!
I want to distrubute the optimizers (especially the LevenbergMarquardt) to different nodes in my hazelcast cluster. Therefore I would like to ask you if you could implement the Serializable interface to your optimizers.
Thanks and all the best
KIC
The structure of this parts need to be revisited. Issues I see at the moment:
Models feature a riskFreeRate and dividendYield. It makes much more sense to use DiscountCurve (standalone, without any AnalyticModel overkill) for the purpose and refactor the characteristic function as fundamental transform, using the terminology of Alan Lewis.
Secondly, I can currently instantiate a Heston model where the correlation is 3, or the starting istantaneous variance is negative, which does not make any sense. Anyway I can do that because parameters are doubles currently. Models need to be equipped with constraint classes for the parameters and the library should complain when I feed it with nonsense.
In Quantlib this is solved e.g. in the Class HestonModel where in the constructor you see something like
arguments_[3] = ConstantParameter(process->rho(),BoundaryConstraint(-1.0, 1.0));
Hi,
I am looking – as a relative beginner to Java – at your finmath package, specifically to build a SABR swaption grid.
I am confused by your conventions though.
In the code to getValue in SABRVolatilityCube.java you have
if(termination<maturity) {
throw new IllegalArgumentException("Termination has to be larger (or equal) maturity. Was termination="+termination+", maturity="+maturity);
}
Therefore termination must be an absolute number, not relative to maturity.
But all the code does next is call the data tables:
final double underlying = underlyingTable.getValue(maturity, termination);
final double sabrRho = rhoTable.getValue(maturity, termination);
final double baseVol = baseVolTable.getValue(maturity, termination);
final double sabrVolvol = volvolTable.getValue(maturity, termination);
and DataTableLinear is defined with termination being relative to maturity:
* @param maturities The maturities of the points as offset with respect to the reference date.
* @param terminations The terminations of the points as offset with respect to the maturity date.
So for example a 5y-2y swaption cannot be accessed. Have I missed something?
Regards
Paul
From this file:
/*
* (c) Copyright Christian P. Fries, Germany. All rights reserved. Contact: [email protected].
*
* Created on 25.01.2004
*/
That would appear to contradict the Apache license this project is distributed under.
Hi,
I am testing finmath with the newest release of Eclipse, Eclipse 2018-12. I started from a fresh install and installed the Maven-Git SCM. After that I imported the project from Import /Maven / Check out project from SCM.
Import works, unfortunately alle test classes are not working because Junit is not recognized.
Junit is mentioned among the dependencies but it is in "dark grey". I looked for multiple solutions on Stackoverflow but nothing worked so far. The best I could understand is that this is related to a new option in Eclipse Photon https://stackoverflow.com/questions/51372670/eclipse-maven-dependency-jar-grayed-out-cant-import-classes-from-it/52946385
Hi,
I am trying to hack the Schedule generator in order to replicate the coupon of a Credit Default Swap according to the ISDA model. This is what I got so far. Any help in finding bugs/wrong reasonings etc is appreciated.
My source is the following document by ISDA: https://www.isda.org/a/vGiDE/amend-single-name-on-the-run-frequency-faq-revised-as-of-12-10.pdf
Here is my code:
package schedule;
import java.time.LocalDate;
import java.time.Month;
import java.util.StringTokenizer;
import net.finmath.time.Schedule;
import net.finmath.time.ScheduleGenerator;
import net.finmath.time.businessdaycalendar.BusinessdayCalendarExcludingTARGETHolidays;
import net.finmath.time.businessdaycalendar.BusinessdayCalendar.DateOffsetUnit;
public class ScheduleTest {
public static void main(String[] args) {
/*
* Today is
*/
LocalDate referenceDate = LocalDate.of(2015, 12, 20);
ScheduleTest test = new ScheduleTest();
String tenor = "5Y";
System.out.println(test.getPreviousRollDate(referenceDate).getDayOfWeek());
System.out.println(test.getFirstImmDateAfterRoll(referenceDate).getDayOfWeek());
System.out.println("Maturity Date of the CDS: this is an unadjusted IMM Date");
LocalDate unadjustedMaturityDate = test.getMaturityDate(referenceDate, tenor);
System.out.println(unadjustedMaturityDate);
System.out.println(unadjustedMaturityDate.getDayOfWeek());
BusinessdayCalendarExcludingTARGETHolidays cal = new BusinessdayCalendarExcludingTARGETHolidays();
if(cal.isBusinessday(unadjustedMaturityDate)==false) {
System.out.println(unadjustedMaturityDate + " is not a good business day.");
}
Schedule schedule = ScheduleGenerator.createScheduleFromConventions(
test.getPreviousRollDate(referenceDate)/* referenceDate */,
test.getFirstImmDateAfterRoll(referenceDate)/* startDate */,
test.getMaturityDate(referenceDate, tenor) /* maturity */,
"quarterly" /* frequency */,
"act/360" /* daycountConvention */,
"first" /* shortPeriodConvention */,
"following",
new BusinessdayCalendarExcludingTARGETHolidays(),
0,
0);
System.out.println(schedule);
}
/**
/**
LocalDate rollDate = getPreviousRollDate(tradeDate);
//Roll month is march
if(rollDate.getMonth().equals(Month.MARCH)) {
//The first Imm Date is 20 June of the same year
return LocalDate.of(rollDate.getYear(), Month.JUNE, 20);
}else {
//The roll month is September, hence the first IMM date is 20 December.
return LocalDate.of(rollDate.getYear(), Month.DECEMBER, 20);
}
}
public LocalDate getMaturityDate(LocalDate tradeDate, String dateOffsetCode) {
dateOffsetCode = dateOffsetCode.trim();
StringTokenizer tokenizer = new StringTokenizer(dateOffsetCode);
LocalDate maturityDate = getFirstImmDateAfterRoll(tradeDate);
while(tokenizer.hasMoreTokens()) {
String maturityCodeSingle = tokenizer.nextToken();
String[] maturityCodeSingleParts = maturityCodeSingle.split("(?<=[0-9|\\.])(?=[A-Z|a-z])");
if(maturityCodeSingleParts.length == 2) {
int maturityValue = Integer.valueOf(maturityCodeSingleParts[0]);
DateOffsetUnit dateOffsetUnit = DateOffsetUnit.getEnum(maturityCodeSingleParts[1]);
switch(dateOffsetUnit) {
case DAYS:
{
maturityDate = maturityDate.plusDays(maturityValue);
break;
}
case WEEKS:
{
maturityDate = maturityDate.plusWeeks(maturityValue);
break;
}
case MONTHS:
{
maturityDate = maturityDate.plusMonths(maturityValue);
break;
}
case YEARS:
{
maturityDate = maturityDate.plusYears(maturityValue);
break;
}
default:
throw new IllegalArgumentException("Cannot handle dateOffsetCode '" + dateOffsetCode + "'.");
}
}
else {
throw new IllegalArgumentException("Cannot handle dateOffsetCode '" + dateOffsetCode + "'.");
}
}
return maturityDate;
}
}
Hi,
How should I build a Bermudan Option on a general swap in the LMM? For example a swap paying CMS v Libor. The BermudanSwaption class assumes a Fixed/Libor swap.
Thanks
Paul
Hello,
Is it possible to have implied volatilty for a put ?
AnalyticFormulas.blackScholesOptionImpliedVolatility
Currently it is only available for a call.
Thanks,
Luc
While 3.2.0 is available as OSGi bundle, 3.2.2 to 3.2.6 is not. This should be changed.
(reported by osx2000)
If an exception occurs in a multi-threaded Monte-Carlo simulation inside ProcessEulerScheme the root cause shown in the output of the stack trace. This should be fixed.
TimeDiscretization states that it will round times to a certain tick size in the Javadoc. This is done inconsistently between the different constructors:
The ellipsis/double array constructor will not round the given times to tick size.
The other constructors (boxed Double array, Set and ArrayList) will do that.
All constructors fail to remove duplicates though.
A unit test for the missing rounding can look like this:
public class TimeDiscretizationTest {
private static double getHalfTickMore(double a) {
return a + 0.5 / (365.0 * 24.0);
}
@Test
public void testTickRoundingOfUnboxedArrayConstruction() {
double a = 4.2;
double identicalToA = getHalfTickMore(a);
TimeDiscretization discretization = new TimeDiscretization(a, identicalToA);
Assert.assertEquals(discretization.getTime(0), discretization.getTime(1), 0.0);
}
@Test
public void testTickRoundingOfBoxedArrayConstruction() {
double a = 4.2;
double identicalToA = getHalfTickMore(a);
TimeDiscretization discretization = new TimeDiscretization(new Double[] { a, identicalToA});
Assert.assertEquals(discretization.getTime(0), discretization.getTime(1), 0.0);
}
}
There is another inconsistency: The interface Set<>
is accepted but List<>
is not, although its implementation ArrayList<>
is.
I will try and perform a pull request with the following fixes and unit tests soon:
discretization
should only contain 1 time point.Iterable<>
should be acceptedHere are some other features that might be useful:
TimeDiscretizationInterface
as these are actually quite common operations (the SDE process time discretization must contain the LIBOR period discretization in the LIBORMarketModel for example). The implementation of this for TimeDiscretization
would depend on the correct rounding and duplicate removal.Travis currently only performs the default maven build. Add a travis integration job for both, Java 8 and Java 6.
The library should provide a mechanism for the interaction between market data (Observables) and products (Observers). You can find a tentative implementation of the Observer pattern at the following link: https://github.com/AlessandroGnoatto/mafinlib
This implementation is thread safe with an exception.
The next Feature would then be lazy recalculation happening only to the products which are notified.
The unit test net.finmath.montecarlo.interestrate.products.indices.LIBORIndexTest may take very long. Could be a memory problem. Some profiling should be done here.
Sample Output:
2.00 2.50 0.000013 0.000212
2.00 2.25 0.000019 0.000212
2.00 3.00 0.000024 0.000212
2.50 3.00 0.000013 0.000212
2.50 3.25 0.000034 0.000212
2.50 3.50 0.000023 0.000212
2.00 4.00 0.000039 0.000212
2.00 5.00 0.000050 0.000212
2.25 2.50 -0.000006 0.000212
4.00 5.00 -0.000007 0.000212-0.000147 0.001414
2.00 20.00 -0.000168[INFO] Tests run: 60, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 4,007.218 s - in net.finmath.montecarlo.interestrate.products.indices.LIBORIndexTest
Hi. Thanks for the library!
Just a quick note that the Kotlin reference (1.2.0 from 2017) is somewhat outdated. I just spent quite a while debugging an issue, which turned out to be this 'elderly' Kotlin (indirectly referenced through a component and thus hidden in the dependency tree) quietly overtaking a directly referenced Kotlin 1.3 - and breaking the web server due to missing API. The Maven workaround is to exclude the Kotlin dependency of finmath but I figured I'd drop a related note here. Cheers.
Hi
I have been trying to run the curve calibration test script in kotlin but the editor does not give me any option to run the test.
Any idea why that might be?
finmath-lib/src/test/kotlin/net/finmath/marketdata/model/curves/CalibrationMultiCurveKotlinTest.kt
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.