net.finmath.smartcontract.demo.VisualiserSDC Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of finmath-smart-derivative-contract Show documentation
Show all versions of finmath-smart-derivative-contract Show documentation
Project to support the implementation a of smart derivative contract.
package net.finmath.smartcontract.demo;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.FlowPane;
import net.finmath.marketdata.products.Swap;
import net.finmath.plots.*;
import net.finmath.smartcontract.product.IRSwapGenerator;
import net.finmath.smartcontract.valuation.marketdata.curvecalibration.CalibrationDataset;
import net.finmath.smartcontract.valuation.marketdata.curvecalibration.CalibrationParserDataItems;
import net.finmath.smartcontract.valuation.oracle.SmartDerivativeContractSettlementOracle;
import net.finmath.smartcontract.valuation.oracle.interestrates.ValuationOraclePlainSwap;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.text.DecimalFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Visualization of the settlement using Smart Derivative Contract with a 10Y swap,
* using a valuation oracle with historic market data.
* For details see the corresponding white paper at SSRN.
*
* @author Christian Fries
* @author Peter Kohl-Landgraf
* @author Björn Paffen
* @author Stefanie Weddigen
*/
@SuppressWarnings("java:S125")
public class VisualiserSDC {
private static final String COUNTERPART = "Counterpart";
private List seriesMarketValues;
private Plot2DBarFX plotMarginAccounts;
private Plot2DFX plotMarketValue;
/**
* Run the demo.
*
* @param args Not used.
* @throws Exception General exception.
*/
public static void main(final String[] args) throws Exception {
final LocalDate startDate = LocalDate.of(2008, 1, 1);
final LocalDate maturity = LocalDate.of(2012, 1, 3);
final String fileName = "timeseriesdatamap.json";
final List scenarioList = CalibrationParserDataItems.getScenariosFromJsonFile(fileName).stream().filter(s -> s.getDate().toLocalDate().isAfter(startDate)).filter(s -> s.getDate().toLocalDate().isBefore(maturity)).toList();
// CSV Method returns same List
// final List scenarioList = IRScenarioGenerator.getScenariosFromCSVFile(fileName,providedDateFormat).stream().filter(S->S.getDate().toLocalDate().isAfter(startDate)).filter(S->S.getDate().toLocalDate().isBefore(maturity)).collect(Collectors.toList());
final double notional = 1.0E7;
final String maturityKey = "5Y";
final String forwardCurveKey = "forward-EUR-6M";
final String discountCurveKey = "discount-EUR-OIS";
final LocalDate productStartDate = scenarioList.get(0).getDate().toLocalDate().minusDays(170);
final double fixRate = scenarioList.get(0).getDataPoints().stream()
.filter(datapoint -> datapoint.getSpec().getCurveName().equals("Euribor6M") &&
datapoint.getSpec().getProductName().equals("Swap-Rate") &&
datapoint.getSpec().getMaturity().equals("5Y")).mapToDouble(e -> e.getQuote()).findAny().getAsDouble();
final Swap swap = IRSwapGenerator.generateAnalyticSwapObject(productStartDate, maturityKey, notional, fixRate, false, forwardCurveKey, discountCurveKey);
final ValuationOraclePlainSwap oracle = new ValuationOraclePlainSwap(Map.of("value",swap), scenarioList);
final SmartDerivativeContractSettlementOracle margin = new SmartDerivativeContractSettlementOracle(oracle);
final List scenarioDates = scenarioList.stream().map(scenario -> scenario.getDate()).sorted().collect(Collectors.toList());
final VisualiserSDC sdcVisual = new VisualiserSDC();
sdcVisual.start();
Double marketValue = 0.0;
final double marginBuffer = 120000;
sdcVisual.updateWithValue(scenarioDates.get(0), marginBuffer, 0, null, 0);
Thread.sleep(1000);
for (int i = 0; i < scenarioDates.size(); i++) {
final double marginCall = i > 0 ? margin.getMargin(scenarioDates.get(i - 1), scenarioDates.get(i)).get("value").doubleValue() : 0.0;
// double marginCall = i==0. ? oracle.getValue(scenarioDates.get(0)) : oracle.getValue(scenarioDates.get(i)) - oracle.getValue(scenarioDates.get(i-1));//90*(new Random()).nextDouble()-45;
System.out.println(i + "\t" + DateTimeFormatter.ofPattern("dd.MM.yyyy").format(scenarioDates.get(i)) + "\t" + marginCall);
marketValue += marginCall;
sdcVisual.updateWithValue(scenarioDates.get(i), marginBuffer, i /* Date index */, marketValue, marginCall);
// The null will result in no update for the market value plot
Thread.sleep(500);
sdcVisual.updateWithValue(scenarioDates.get(i), marginBuffer, i, null, 0);
}
}
public void start() {
seriesMarketValues = new ArrayList<>();
plotMarginAccounts = new Plot2DBarFX(null,
"Smart Contract Accounts (settlement)",
"Account",
"Value",
new DecimalFormat("####.00"),
0.0,
3.0E5,
2.5E4, false);
plotMarginAccounts.setIsSeriesStacked(true);
plotMarketValue = new Plot2DFX();
plotMarketValue.setIsLegendVisible(false);
plotMarketValue.setTitle("Market Value");
plotMarketValue.setXAxisLabel("Date");
plotMarketValue.setYAxisLabel("Market Value");
SwingUtilities.invokeLater(() -> {
// This method is invoked on Swing thread
final JFrame frame = new JFrame("Smart Derivative Contract: Settlement Visualization");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
frame.setSize(1600, 600);
// frame.setSize(960, 540+22);
Platform.runLater(() -> {
final FlowPane root = new FlowPane();
root.getChildren().addAll(new Group(plotMarginAccounts.get()), plotMarketValue.get());
final Scene scene = new Scene(root, 1600, 600);
scene.getStylesheets().add("barchart.css");
fxPanel.setScene(scene);
});
});
}
void updateWithValue(final LocalDateTime date, final double base, final double x, final Double value, final double increment) throws InterruptedException {
final List marginBase = new ArrayList<>();
marginBase.add(new Category2D("We", base + Math.min(0, +increment)));
marginBase.add(new Category2D(COUNTERPART, base + Math.min(0, -increment)));
final List marginRemoved = new ArrayList<>();
marginRemoved.add(new Category2D("We", -Math.min(0, +increment)));
marginRemoved.add(new Category2D(COUNTERPART, -Math.min(0, -increment)));
final List marginExcessed = new ArrayList<>();
marginExcessed.add(new Category2D("We", Math.max(0, +increment)));
marginExcessed.add(new Category2D(COUNTERPART, Math.max(0, -increment)));
final List plotables = new ArrayList<>();
plotables.add(new PlotableCategories() {
@Override
public String getName() {
return "Margin";
}
@Override
public GraphStyle getStyle() {
return new GraphStyle(new Ellipse2D.Float(-1.0f, -1.0f, 2.0f, 2.0f), new BasicStroke(1.0f), new Color(0.0f, 0.0f, 1.0f));
}
@Override
public List getSeries() {
return marginBase;
}
});
plotables.add(new PlotableCategories() {
@Override
public String getName() {
return "Pay";
}
@Override
public GraphStyle getStyle() {
return null;
}
@Override
public List getSeries() {
return marginRemoved;
}
});
plotables.add(new PlotableCategories() {
@Override
public String getName() {
return "Receive";
}
@Override
public GraphStyle getStyle() {
return null;
// return new GraphStyle(new Ellipse2D.Float(-1.0f,-1.0f,2.0f,2.0f), new BasicStroke(1.0f), new Color(0.0f, 0.0f, 1.0f));
}
@Override
public List getSeries() {
return marginExcessed;
}
});
plotMarginAccounts.update(plotables);
if (value != null) {
final List plotables2 = new ArrayList<>();
plotables2.add(new Plotable2D() {
@Override
public String getName() {
return "Market Value";
}
@Override
public GraphStyle getStyle() {
return new GraphStyle(new Ellipse2D.Float(-3.0f, -3.0f, 6.0f, 6.0f), new BasicStroke(1.0f), new Color(1.0f, 0.0f, 0.0f));
}
@Override
public List getSeries() {
return seriesMarketValues;
}
});
seriesMarketValues.add(new Point2D(x, value));
plotMarketValue.update(plotables2);
plotMarketValue.setTitle("Market Value (01.05.2008-" + date.format(DateTimeFormatter.ofPattern("dd.MM.yyyy")) + ")");
}
Thread.sleep(500);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy