TermStructCovarianceModelFromLIBORCovarianceModel.java
/*
* (c) Copyright Christian P. Fries, Germany. Contact: email@christian-fries.de.
*
* Created on 22.12.2016
*/
package net.finmath.montecarlo.interestrate.models.covariance;
import net.finmath.montecarlo.interestrate.TermStructureModel;
import net.finmath.montecarlo.interestrate.models.LIBORMarketModelWithTenorRefinement;
import net.finmath.stochastic.RandomVariable;
import net.finmath.time.TimeDiscretization;
/**
* @author Christian Fries
*
* @version 1.0
*/
public class TermStructCovarianceModelFromLIBORCovarianceModel implements TermStructureFactorLoadingsModel {
private final AbstractLIBORCovarianceModelParametric covarianceModel;
/**
* Create a term structure covariance model model implementing TermStructureCovarianceModelInterface
* using a given model implementing AbstractLIBORCovarianceModelParametric.
*
* @param covarianceModel The model implementing AbstractLIBORCovarianceModelParametric.
*/
public TermStructCovarianceModelFromLIBORCovarianceModel(final AbstractLIBORCovarianceModelParametric covarianceModel) {
this.covarianceModel = covarianceModel;
}
@Override
public RandomVariable[] getFactorLoading(final double time, final double periodStart, final double periodEnd, final TimeDiscretization periodDiscretization, final RandomVariable[] realizationAtTimeIndex, final TermStructureModel model) {
final TimeDiscretization liborPeriodDiscretization = covarianceModel.getLiborPeriodDiscretization();
// Cache is really needed.
final RandomVariable[] liborAtTimeIndex = new RandomVariable[liborPeriodDiscretization.getNumberOfTimeSteps()];
for(int componentIndex=0; componentIndex<liborPeriodDiscretization.getNumberOfTimeSteps(); componentIndex++) {
if(liborPeriodDiscretization.getTime(componentIndex) < time) {
liborAtTimeIndex[componentIndex] = null;
}
else {
liborAtTimeIndex[componentIndex] = ((LIBORMarketModelWithTenorRefinement)model).getLIBORForStateVariable(periodDiscretization, realizationAtTimeIndex, liborPeriodDiscretization.getTime(componentIndex), liborPeriodDiscretization.getTime(componentIndex+1));
}
}
final int periodStartIndex = liborPeriodDiscretization.getTimeIndex(periodStart);
final int periodEndIndex = liborPeriodDiscretization.getTimeIndex(periodEnd);
final RandomVariable[] factorLoadings = covarianceModel.getFactorLoading(time, periodStartIndex, liborAtTimeIndex);
if(periodEndIndex > periodStartIndex+1) {
// Need to sum factor loadings
for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].mult(liborPeriodDiscretization.getTimeStep(periodStartIndex));
}
for(int periodIndex = periodStartIndex+1; periodIndex<periodEndIndex; periodIndex++) {
final RandomVariable[] factorLoadingsForPeriod = covarianceModel.getFactorLoading(time, periodStartIndex, liborAtTimeIndex);
final double periodLength = liborPeriodDiscretization.getTimeStep(periodIndex);
for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].addProduct(factorLoadingsForPeriod[factorIndex], periodLength);
}
}
for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].div(periodEnd-periodStart);
}
}
return factorLoadings;
}
@Override
public int getNumberOfFactors() {
return covarianceModel.getNumberOfFactors();
}
}