Skip to content

Commit bd094ba

Browse files
committed
Working on MC Simulation SDC+C
1 parent 9e3bf00 commit bd094ba

File tree

3 files changed

+59
-79
lines changed

3 files changed

+59
-79
lines changed

src/main/java/net/finmath/smartcontract/simulation/LiborMarketModelCalibration.java renamed to src/main/java/net/finmath/smartcontract/simulation/LiborMarketModelCalibrator.java

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,11 @@
99
import java.util.HashMap;
1010
import java.util.Locale;
1111
import java.util.Map;
12-
import java.util.Optional;
13-
import java.util.stream.Stream;
14-
1512

1613
import net.finmath.exception.CalculationException;
17-
import net.finmath.marketdata.calibration.CalibratedCurves;
1814
import net.finmath.marketdata.model.AnalyticModel;
19-
import net.finmath.marketdata.model.AnalyticModelFromCurvesAndVols;
20-
import net.finmath.marketdata.model.curves.Curve;
21-
import net.finmath.marketdata.model.curves.CurveInterpolation;
2215
import net.finmath.marketdata.model.curves.DiscountCurve;
23-
import net.finmath.marketdata.model.curves.DiscountCurveInterpolation;
2416
import net.finmath.marketdata.model.curves.ForwardCurve;
25-
import net.finmath.marketdata.model.curves.ForwardCurveFromDiscountCurve;
26-
import net.finmath.marketdata.model.curves.ForwardCurveInterpolation;
27-
import net.finmath.marketdata.model.curves.ForwardCurveWithFixings;
28-
import net.finmath.marketdata.model.curves.CurveInterpolation.ExtrapolationMethod;
29-
import net.finmath.marketdata.model.curves.CurveInterpolation.InterpolationEntity;
30-
import net.finmath.marketdata.model.curves.CurveInterpolation.InterpolationMethod;
3117
import net.finmath.montecarlo.BrownianMotion;
3218
import net.finmath.montecarlo.BrownianMotionFromMersenneRandomNumbers;
3319
import net.finmath.montecarlo.RandomVariableFromArrayFactory;
@@ -37,7 +23,7 @@
3723
import net.finmath.montecarlo.interestrate.LIBORMonteCarloSimulationFromLIBORModel;
3824
import net.finmath.montecarlo.interestrate.models.LIBORMarketModelFromCovarianceModel;
3925
import net.finmath.montecarlo.interestrate.models.covariance.AbstractLIBORCovarianceModelParametric;
40-
import net.finmath.montecarlo.interestrate.models.covariance.BlendedLocalVolatilityModel;
26+
import net.finmath.montecarlo.interestrate.models.covariance.DisplacedLocalVolatilityModel;
4127
import net.finmath.montecarlo.interestrate.models.covariance.LIBORCorrelationModel;
4228
import net.finmath.montecarlo.interestrate.models.covariance.LIBORCorrelationModelExponentialDecay;
4329
import net.finmath.montecarlo.interestrate.models.covariance.LIBORCovarianceModelFromVolatilityAndCorrelation;
@@ -50,33 +36,34 @@
5036
import net.finmath.optimizer.OptimizerFactoryLevenbergMarquardt;
5137
import net.finmath.optimizer.SolverException;
5238
import net.finmath.optimizer.LevenbergMarquardt.RegularizationMethod;
53-
import net.finmath.smartcontract.valuation.marketdata.curvecalibration.CalibrationResult;
54-
import net.finmath.time.Period;
55-
import net.finmath.time.Schedule;
56-
import net.finmath.time.ScheduleFromPeriods;
57-
import net.finmath.time.ScheduleGenerator;
39+
import net.finmath.smartcontract.simulation.InterestRateAnalyticCalibrator.CURVE_NAME;
5840
import net.finmath.time.TimeDiscretizationFromArray;
59-
import net.finmath.time.businessdaycalendar.BusinessdayCalendar;
6041
import net.finmath.time.businessdaycalendar.BusinessdayCalendarExcludingTARGETHolidays;
61-
import net.finmath.time.daycount.DayCountConvention_ACT_360;
6242
import net.finmath.time.daycount.DayCountConvention_ACT_365;
6343

64-
public class LiborMarketModelCalibration {
44+
public class LiborMarketModelCalibrator {
6545

6646
private static DecimalFormat formatterValue = new DecimalFormat(" ##0.0000%;-##0.0000%", new DecimalFormatSymbols(Locale.ENGLISH));
6747
private static DecimalFormat formatterDeviation = new DecimalFormat(" 0.00000E00;-0.00000E00", new DecimalFormatSymbols(Locale.ENGLISH));
6848

6949
public static LocalDate REFERENCE_DATE = LocalDate.of(2025, Month.OCTOBER, 30);
70-
public static int NUMBER_OF_PATHS = 10000;
71-
public static int NUMBER_OF_FACTORS = 4;
72-
public static double LIBOR_TIME_HORIZON = 5.0;
50+
public static int NUMBER_OF_PATHS = 5000;
51+
public static int NUMBER_OF_FACTORS = 5;
52+
public static double LIBOR_TIME_HORIZON = 6.0;
7353
public static double LIBOR_PERIOD_LENGTH = 0.5;
74-
public static double SIMULATION_TIME_STEP= 0.5;
54+
public static double SIMULATION_TIME_STEP= 0.0025;
7555

7656

77-
public static void main(String[] args) throws CloneNotSupportedException, CalculationException {
57+
public static void main(String[] args) throws CloneNotSupportedException, CalculationException, SolverException {
58+
59+
/* Initialize IRA calibrator*/
60+
InterestRateAnalyticCalibrator calibrator = new InterestRateAnalyticCalibrator();
61+
calibrator.addFixingItem(CURVE_NAME.EURIBOR06M, REFERENCE_DATE, 0.02127);
7862
// Create the forward and discount curve (initial value of the LIBOR market model)
79-
final AnalyticModel curveModel = calibrateCurves().orElseThrow().getCalibratedModel();
63+
double[] forwardCurveQuotes = new double[] {0.02113,0.02102,0.02087,0.02074,0.02054,0.02046,0.02068,0.02141,0.022105,0.022825,0.02349,0.02413,0.02474,0.02533,0.02588,0.026395,0.027295,0.02825,0.02884,0.02879,0.028615};
64+
double[] discountCurveQuotes = new double[] {0.01931,0.0192885,0.019292,0.0192995,0.0193025,0.019294,0.0192815,0.0192525,0.019192,0.019129,0.0190685,0.019008,0.018942,0.0188925,0.0188515,0.018821,0.0187145,0.018719,0.01881,0.018953,0.019661,0.020461,0.0212175,0.021926,0.0226005,0.023262,0.023891,0.0244875,0.025499,0.0266305,0.027421,0.027506,0.027422};
65+
AnalyticModel curveModel = calibrator.getCalibratedModel(REFERENCE_DATE, discountCurveQuotes, forwardCurveQuotes);
66+
8067
// Create a set of calibration products.
8168
final ArrayList<String> calibrationItemNames = new ArrayList<>();
8269
final ArrayList<CalibrationProduct> calibrationProducts = new ArrayList<>();
@@ -158,7 +145,7 @@ public static void main(String[] args) throws CloneNotSupportedException, Calcul
158145
final double weight = 1.0;
159146

160147

161-
calibrationProducts.add(createCalibrationItem(weight, exercise, swapPeriodLength, numberOfPeriods, moneyness, targetVolatility, targetVolatilityType, curveModel.getForwardCurve(FORWARD_EUR_6M), curveModel.getDiscountCurve(DISCOUNT_EUR_OIS)));
148+
calibrationProducts.add(createCalibrationItem(weight, exercise, swapPeriodLength, numberOfPeriods, moneyness, targetVolatility, targetVolatilityType, curveModel.getForwardCurve(InterestRateAnalyticCalibrator.FORWARD_EUR_6M), curveModel.getDiscountCurve(InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS)));
162149
calibrationItemNames.add(atmExpiries[i]+"\t"+atmTenors[i]);
163150
}
164151

@@ -172,17 +159,19 @@ public static void main(String[] args) throws CloneNotSupportedException, Calcul
172159
final BrownianMotion brownianMotion = new BrownianMotionFromMersenneRandomNumbers(timeDiscretizationFromArray, NUMBER_OF_FACTORS, NUMBER_OF_PATHS, 31415 /* seed */);
173160

174161
// Create a volatility model: Piecewise constant volatility
175-
LIBORVolatilityModel volatilityModel = new LIBORVolatilityModelPiecewiseConstant(new RandomVariableFromArrayFactory(), timeDiscretizationFromArray, liborPeriodDiscretization, new TimeDiscretizationFromArray(0.00, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0, 40.0), new TimeDiscretizationFromArray(0.00, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0, 40.0), new double[]{0.50 / 100}, true);
162+
//LIBORVolatilityModel volatilityModel = new LIBORVolatilityModelPiecewiseConstant(new RandomVariableFromArrayFactory(), timeDiscretizationFromArray, liborPeriodDiscretization, new TimeDiscretizationFromArray(0.00, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0, 40.0), new TimeDiscretizationFromArray(0.00, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0, 40.0), new double[]{0.50 / 100}, true);
163+
final LIBORVolatilityModel volatilityModel = new LIBORVolatilityModelPiecewiseConstant(timeDiscretizationFromArray, liborPeriodDiscretization, new TimeDiscretizationFromArray(0.00, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0, 40.0), new TimeDiscretizationFromArray(0.00, 1.0, 2.0, 5.0, 10.0, 20.0, 30.0, 40.0), 0.50 / 100);
176164

177165
// Create a correlation model
178-
LIBORCorrelationModel correlationModel = new LIBORCorrelationModelExponentialDecay(timeDiscretizationFromArray, liborPeriodDiscretization, NUMBER_OF_FACTORS, 0.05, true);
166+
final LIBORCorrelationModel correlationModel = new LIBORCorrelationModelExponentialDecay(timeDiscretizationFromArray, liborPeriodDiscretization, NUMBER_OF_FACTORS, 0.05, false);
179167

180168
// Create a covariance model
181-
AbstractLIBORCovarianceModelParametric covarianceModelParametric = new LIBORCovarianceModelFromVolatilityAndCorrelation(timeDiscretizationFromArray, liborPeriodDiscretization, volatilityModel, correlationModel);
182-
183-
// Create blended local volatility model with fixed parameter 0.0 (that is "lognormal").
184-
AbstractLIBORCovarianceModelParametric covarianceModelBlended = new BlendedLocalVolatilityModel(new RandomVariableFromArrayFactory(), covarianceModelParametric, 0.5, true);
169+
final AbstractLIBORCovarianceModelParametric covarianceModelParametric = new LIBORCovarianceModelFromVolatilityAndCorrelation(timeDiscretizationFromArray, liborPeriodDiscretization, volatilityModel, correlationModel);
185170

171+
// Create blended local volatility model with fixed parameter (0=lognormal, > 1 = almost a normal model).
172+
//AbstractLIBORCovarianceModelParametric covarianceModelBlended = new BlendedLocalVolatilityModel(new RandomVariableFromArrayFactory(), covarianceModelParametric, 4.0, true);
173+
final AbstractLIBORCovarianceModelParametric covarianceModelDisplaced = new DisplacedLocalVolatilityModel(covarianceModelParametric, 1.0/0.25, false /* isCalibrateable */);
174+
186175
// Set model properties
187176
final Map<String, Object> properties = new HashMap<>();
188177
// Choose the simulation measure
@@ -199,9 +188,9 @@ public static void main(String[] args) throws CloneNotSupportedException, Calcul
199188
RegularizationMethod.LEVENBERG, lambda,
200189
maxIterations, accuracy, numberOfThreads);
201190

202-
final double[] parameterStandardDeviation = new double[covarianceModelBlended.getParameterAsDouble().length];
203-
final double[] parameterLowerBound = new double[covarianceModelBlended.getParameterAsDouble().length];
204-
final double[] parameterUpperBound = new double[covarianceModelBlended.getParameterAsDouble().length];
191+
final double[] parameterStandardDeviation = new double[covarianceModelDisplaced.getParameterAsDouble().length];
192+
final double[] parameterLowerBound = new double[covarianceModelDisplaced.getParameterAsDouble().length];
193+
final double[] parameterUpperBound = new double[covarianceModelDisplaced.getParameterAsDouble().length];
205194
Arrays.fill(parameterStandardDeviation, 0.20/100.0);
206195
Arrays.fill(parameterLowerBound, 0.0);
207196
Arrays.fill(parameterUpperBound, Double.POSITIVE_INFINITY);
@@ -224,10 +213,10 @@ public static void main(String[] args) throws CloneNotSupportedException, Calcul
224213
final LIBORMarketModel liborMarketModelCalibrated = LIBORMarketModelFromCovarianceModel.of(
225214
liborPeriodDiscretization,
226215
curveModel,
227-
curveModel.getForwardCurve(FORWARD_EUR_6M),
228-
curveModel.getDiscountCurve(DISCOUNT_EUR_OIS),
216+
curveModel.getForwardCurve(InterestRateAnalyticCalibrator.FORWARD_EUR_6M),
217+
curveModel.getDiscountCurve(InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS),
229218
new RandomVariableFromArrayFactory(),
230-
covarianceModelBlended,
219+
covarianceModelDisplaced,
231220
calibrationItemsLMM, properties);
232221

233222

src/main/java/net/finmath/smartcontract/simulation/SDCCollateralizedHistoricalSimulation.java

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ public static void main(String args[]) throws Exception {
3434
MarketDataLoader forwardCurveLoader = new MarketDataLoader(Path.of("D:\\Papers\\MarketData\\20251203-20150101_6M.csv"));
3535
List<MarketDataSnapshot> forwardCurveSnapshots = forwardCurveLoader.load(businessdayCalendar);
3636

37-
MarketDataSnapshot initialForwardRates = forwardCurveSnapshots.get(0);
37+
int valuationStartIndex = 1100;
38+
MarketDataSnapshot initialForwardRates = forwardCurveSnapshots.get(valuationStartIndex);
3839
final LocalDate startDate = initialForwardRates.getValuationDate();
3940

4041
/*Generate 6M Payer Swap with notional 1 */
@@ -43,12 +44,8 @@ public static void main(String args[]) throws Exception {
4344
final Schedule schedulePay = ScheduleGenerator.createScheduleFromConventions(startDate, 2, "0D", maturityKey, "annual", "E30/360", "first", "modfollow", businessdayCalendar, -2, 0);
4445
/* Product starts at Par */
4546
final double fixRate = initialForwardRates.getQuotes()[11]; // TBSEUREUR03MEUR06M05Y
46-
//final Swap swap = new Swap(scheduleRec, InterestRateAnalyticCalibrator.FORWARD_EUR_6M, 0.0, InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS, // receiver leg
47-
// schedulePay, "", fixRate, InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS, false); // payer leg
48-
49-
50-
final Swap swap = new Swap(schedulePay, "", fixRate, InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS, // receiver leg
51-
scheduleRec, InterestRateAnalyticCalibrator.FORWARD_EUR_6M, 0.0, InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS, false); // payer leg
47+
final Swap swap = new Swap(scheduleRec, InterestRateAnalyticCalibrator.FORWARD_EUR_6M, 0.0, InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS, // receiver leg
48+
schedulePay, "", fixRate, InterestRateAnalyticCalibrator.DISCOUNT_EUR_OIS, false); // payer leg
5249

5350
// Get combined payment dates, as legs can have different payment dates, e.g. fix leg pays only annually while float leg pays semi-annually
5451
TreeSet<LocalDate> paymentDates = getPaymentDates(scheduleRec, schedulePay);
@@ -59,17 +56,17 @@ public static void main(String args[]) throws Exception {
5956
double fundingSpread = 0.005;
6057

6158
// Get last scenario index based on maturity
62-
int lastValuationIndex = getLastValuationIndex(forwardCurveSnapshots, paymentDates.last());
59+
int valuationEndIndex = getLastValuationIndex(forwardCurveSnapshots, paymentDates.last());
6360

64-
int numberOfMarginIncrements = 10;
61+
int numberOfMarginIncrements = 20;
6562
List<Double> margin = new ArrayList<>(numberOfMarginIncrements);
6663
List<Double> cashFlow = new ArrayList<>(numberOfMarginIncrements);
6764
List<Double> funding = new ArrayList<>(numberOfMarginIncrements);
6865
// Loop over increasing margin limits
6966
for (int j = 0; j <= numberOfMarginIncrements; j++) {
7067
// Margin limits
71-
double marginFloor = j * 0.0001;
72-
double marginCap = j * 0.0001;
68+
double marginFloor = j * 0.0005;
69+
double marginCap = j * 0.0005;
7370

7471
/* Initialize calibrator*/
7572
InterestRateAnalyticCalibrator calibrator = new InterestRateAnalyticCalibrator();
@@ -87,7 +84,7 @@ public static void main(String args[]) throws Exception {
8784
double collateralAccount = valuePrevious;
8885

8986
//System.out.printf(headerFormat, "Valuation Date", "Value V(t)", "Value Change Y_i", "Capped Change X_i", "Gap Amount Z_i", "Gap Account D_i", "Coll Account C_i", "Net Cashflow A_k");
90-
for (int i = 1; i < lastValuationIndex; i++) {
87+
for (int i = valuationStartIndex + 1; i < valuationEndIndex; i++) {
9188
LocalDate valuationDateCurrent = forwardCurveSnapshots.get(i).getValuationDate();
9289
// We need the 6m Fixings for the fixing dates of the swap
9390
if (fixingDates.contains(valuationDateCurrent)) {

0 commit comments

Comments
 (0)