Skip to content

Commit

Permalink
Merge pull request #85 from Julius278/feature/619
Browse files Browse the repository at this point in the history
Feature/619
  • Loading branch information
Julius278 authored Aug 30, 2024
2 parents c167527 + 90379ce commit 3429d5c
Show file tree
Hide file tree
Showing 3 changed files with 265 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package net.finmath.smartcontract.settlement;

import net.finmath.smartcontract.model.ExceptionId;
import net.finmath.smartcontract.model.MarketDataList;
import net.finmath.smartcontract.model.SDCException;
import net.finmath.smartcontract.product.SmartDerivativeContractDescriptor;
import net.finmath.smartcontract.product.xml.SDCXMLParser;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

public class SettlementGenerator {

private static final Logger logger = LoggerFactory.getLogger(SettlementGenerator.class);

private Settlement settlement;

public SettlementGenerator generateInitialSettlementXml(String marketDataXml, SmartDerivativeContractDescriptor sdc){
generateSettlement(marketDataXml, Settlement.SettlementType.INITIAL, sdc, BigDecimal.ZERO);
return this.settlementValuePrevious(BigDecimal.ZERO);
}

public SettlementGenerator generateRegularSettlementXml(String marketDataXml, SmartDerivativeContractDescriptor sdc, BigDecimal marginValue){
return generateSettlement(marketDataXml, Settlement.SettlementType.REGULAR, sdc, marginValue);
}

private SettlementGenerator generateSettlement(String marketDataXml, Settlement.SettlementType settlementType, SmartDerivativeContractDescriptor sdc, BigDecimal marginValue){
MarketDataList marketDataList = SDCXMLParser.unmarshalXml(marketDataXml, MarketDataList.class);
settlement = new Settlement();
settlement.setTradeId(sdc.getDltTradeId());
settlement.setSettlementType(settlementType);
settlement.setCurrency(sdc.getCurrency());
settlement.setMarginValue(marginValue);
settlement.setSettlementTime(ZonedDateTime.now());
settlement.setMarketData(marketDataList);

return this;
}

public SettlementGenerator marginLimits(List<BigDecimal> marginLimits){
settlement.setMarginLimits(marginLimits);
return this;
}

public SettlementGenerator settlementValue(BigDecimal settlementValue){
settlement.setSettlementValue(settlementValue);
return this;
}

public SettlementGenerator settlementValuePrevious(BigDecimal settlementValuePrevious){
settlement.setSettlementValuePrevious(settlementValuePrevious);
return this;
}

public SettlementGenerator settlementTimeNext(ZonedDateTime settlementTimeNext){
settlement.setSettlementTimeNext(settlementTimeNext);
return this;
}

public SettlementGenerator settlementValueNext(BigDecimal settlementValueNext){
settlement.setSettlementValueNext(settlementValueNext);
return this;
}

public String build(){
String settlementString = SDCXMLParser.marshalClassToXMLString(settlement);
if(allFieldsSet(settlement))
return settlementString;
else{
logger.error("missing input for settlement, settlement string so far: {}", settlementString);
throw new SDCException(ExceptionId.SDC_WRONG_INPUT, "settlement input incomplete", 400);
}
}

private static boolean allFieldsSet(Settlement settlement){
return Arrays.stream(settlement.getClass().getDeclaredFields())
.peek(f -> f.setAccessible(true))
.map(f -> getFieldValue(f, settlement))
.allMatch(Objects::nonNull);
}

private static Object getFieldValue(Field field, Object target) {
try {
return field.get(target);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package net.finmath.smartcontract.valuation.marketdata.generators;

import com.neovisionaries.ws.client.WebSocket;
import io.reactivex.rxjava3.functions.Consumer;
import net.finmath.smartcontract.model.MarketDataList;
import net.finmath.smartcontract.product.SmartDerivativeContractDescriptor;
import net.finmath.smartcontract.valuation.marketdata.curvecalibration.CalibrationDataItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

public class MarketDataGeneratorLauncher {

private static final Logger logger = LoggerFactory.getLogger(MarketDataGeneratorLauncher.class);

private MarketDataGeneratorLauncher() {}

public static MarketDataList instantiateMarketDataGeneratorWebsocket(Properties connectionProperties, SmartDerivativeContractDescriptor sdc) {
AtomicReference<MarketDataList> marketDataList = new AtomicReference<>(new MarketDataList());
AtomicBoolean finished = new AtomicBoolean(false);

logger.info("launching MarketDataGeneratorWebsocket");
List<CalibrationDataItem.Spec> mdItemList;
WebSocketConnector connector;
WebSocket socket;
MarketDataGeneratorWebsocket emitter;
try {
mdItemList = sdc.getMarketdataItemList();

// Init Websockect Connection
connector = new WebSocketConnector(connectionProperties);
socket = connector.getWebSocket();
emitter = new MarketDataGeneratorWebsocket(connector.getAuthJson(), connector.getPosition(), mdItemList);
socket.addListener(emitter);
socket.connect();

final Consumer<MarketDataList> marketDataWriter = s -> {
logger.info("websocket open: {}", socket.isOpen());
marketDataList.set(s);
finished.set(true);

emitter.closeStreamsAndLogoff(socket);
socket.sendClose();
};
emitter.asObservable().take(1).subscribe(marketDataWriter);
while (!finished.get()) {
logger.info("Waiting for Market Data List to finish retrieving");
Thread.sleep(1000);
}
return marketDataList.get();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package net.finmath.smartcontract.settlement;

import net.finmath.smartcontract.model.SDCException;
import net.finmath.smartcontract.product.SmartDerivativeContractDescriptor;
import net.finmath.smartcontract.product.xml.SDCXMLParser;
import org.junit.jupiter.api.Test;
import org.xml.sax.SAXException;

import javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.ZonedDateTime;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

class SettlementGeneratorTest {

@Test
void generateInitialSettlement() throws IOException, ParserConfigurationException, SAXException {
InputStream inputStream = SettlementGeneratorTest.class.getClassLoader().getResourceAsStream("net/finmath/smartcontract/valuation/historicalMarketData/marketdata_2008-05-02.xml");
String marketDataString = new String(inputStream.readAllBytes());

inputStream = SettlementGeneratorTest.class.getClassLoader().getResourceAsStream("net.finmath.smartcontract.product.xml/smartderivativecontract_with_rics.xml");
String productString = new String(inputStream.readAllBytes());
SmartDerivativeContractDescriptor sdc = SDCXMLParser.parse(productString);

String settlementString = new SettlementGenerator().generateInitialSettlementXml(marketDataString, sdc)
.marginLimits(List.of(BigDecimal.ONE, BigDecimal.ZERO))
.settlementValue(BigDecimal.ZERO)
//.settlementValuePrevious(BigDecimal.ZERO)
.settlementTimeNext(ZonedDateTime.now())
.settlementValueNext(BigDecimal.ZERO)
.build();

System.out.println(settlementString);

assertTrue(settlementString.contains("ESTRSWP3Y"));
assertTrue(settlementString.contains("ESTRSWP1W"));
assertTrue(settlementString.contains("INITIAL"));
assertFalse(settlementString.contains("REGULAR"));
assertTrue(settlementString.contains("<marginValue>0</marginValue>"));
assertTrue(settlementString.contains("<marketData>"));
assertTrue(settlementString.contains("<requestTimeStamp>"));
assertTrue(settlementString.contains("<item>"));
assertTrue(settlementString.contains("<value>"));
assertTrue(settlementString.contains("<settlementTimeNext>"));
assertTrue(settlementString.contains("<settlementValueNext>"));
assertTrue(settlementString.contains("<settlementValuePrevious>"));
assertTrue(settlementString.contains("<settlementValue>"));
assertTrue(settlementString.contains("<marginLimits>"));
}

@Test
void generateRegularSettlement() throws IOException, ParserConfigurationException, SAXException {
InputStream inputStream = SettlementGeneratorTest.class.getClassLoader().getResourceAsStream("net/finmath/smartcontract/valuation/historicalMarketData/marketdata_2008-05-02.xml");
String marketDataString = new String(inputStream.readAllBytes());

inputStream = SettlementGeneratorTest.class.getClassLoader().getResourceAsStream("net.finmath.smartcontract.product.xml/smartderivativecontract_with_rics.xml");
String productString = new String(inputStream.readAllBytes());
SmartDerivativeContractDescriptor sdc = SDCXMLParser.parse(productString);

String settlementString = new SettlementGenerator().generateRegularSettlementXml(marketDataString, sdc, BigDecimal.ONE)
.marginLimits(List.of(BigDecimal.ONE, BigDecimal.ZERO))
.settlementValue(BigDecimal.ZERO)
.settlementValuePrevious(BigDecimal.ZERO)
.settlementTimeNext(ZonedDateTime.now())
.settlementValueNext(BigDecimal.ZERO)
.build();

System.out.println(settlementString);

assertTrue(settlementString.contains("ESTRSWP3Y"));
assertTrue(settlementString.contains("ESTRSWP1W"));
assertTrue(settlementString.contains("REGULAR"));
assertFalse(settlementString.contains("INITIAL"));
assertTrue(settlementString.contains("<marginValue>1</marginValue>"));
assertTrue(settlementString.contains("<marketData>"));
assertTrue(settlementString.contains("<requestTimeStamp>"));
assertTrue(settlementString.contains("<item>"));
assertTrue(settlementString.contains("<value>"));
assertTrue(settlementString.contains("<settlementTimeNext>"));
assertTrue(settlementString.contains("<settlementValueNext>"));
assertTrue(settlementString.contains("<settlementValuePrevious>"));
assertTrue(settlementString.contains("<settlementValue>"));
assertTrue(settlementString.contains("<marginLimits>"));
}

@Test
void generateIncompleteSettlement_Exception() throws IOException, ParserConfigurationException, SAXException {
InputStream inputStream = SettlementGeneratorTest.class.getClassLoader().getResourceAsStream("net/finmath/smartcontract/valuation/historicalMarketData/marketdata_2008-05-02.xml");
String marketDataString = new String(inputStream.readAllBytes());

inputStream = SettlementGeneratorTest.class.getClassLoader().getResourceAsStream("net.finmath.smartcontract.product.xml/smartderivativecontract_with_rics.xml");
String productString = new String(inputStream.readAllBytes());
SmartDerivativeContractDescriptor sdc = SDCXMLParser.parse(productString);

SettlementGenerator generator = new SettlementGenerator().generateRegularSettlementXml(marketDataString, sdc, BigDecimal.ONE)
.marginLimits(List.of(BigDecimal.ONE, BigDecimal.ZERO))
.settlementValue(BigDecimal.ZERO)
.settlementValuePrevious(BigDecimal.ZERO)
.settlementTimeNext(ZonedDateTime.now());
//.settlementValueNext(BigDecimal.ZERO);

assertThrows(SDCException.class, generator::build);
}
}

0 comments on commit 3429d5c

Please sign in to comment.