mirror of
https://github.com/corda/corda.git
synced 2025-06-14 13:18:18 +00:00
Reformat files in testing
This commit is contained in:
@ -13,7 +13,8 @@ import java.util.concurrent.CompletableFuture.supplyAsync
|
|||||||
|
|
||||||
class AttachmentDemoTest {
|
class AttachmentDemoTest {
|
||||||
// run with a 10,000,000 bytes in-memory zip file. In practice, a slightly bigger file will be used (~10,002,000 bytes).
|
// run with a 10,000,000 bytes in-memory zip file. In practice, a slightly bigger file will be used (~10,002,000 bytes).
|
||||||
@Test fun `attachment demo using a 10MB zip file`() {
|
@Test
|
||||||
|
fun `attachment demo using a 10MB zip file`() {
|
||||||
val numOfExpectedBytes = 10_000_000
|
val numOfExpectedBytes = 10_000_000
|
||||||
driver(isDebug = true, portAllocation = PortAllocation.Incremental(20000)) {
|
driver(isDebug = true, portAllocation = PortAllocation.Incremental(20000)) {
|
||||||
val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<AttachmentDemoFlow>())))
|
val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<AttachmentDemoFlow>())))
|
||||||
|
@ -141,11 +141,12 @@ class FloatingRatePaymentEvent(date: LocalDate,
|
|||||||
val CSVHeader = RatePaymentEvent.CSVHeader + ",FixingDate"
|
val CSVHeader = RatePaymentEvent.CSVHeader + ",FixingDate"
|
||||||
}
|
}
|
||||||
|
|
||||||
override val flow: Amount<Currency> get() {
|
override val flow: Amount<Currency>
|
||||||
// TODO: Should an uncalculated amount return a zero ? null ? etc.
|
get() {
|
||||||
val v = rate.ratioUnit?.value ?: return Amount(0, notional.token)
|
// TODO: Should an uncalculated amount return a zero ? null ? etc.
|
||||||
return Amount(dayCountFactor.times(BigDecimal(notional.quantity)).times(v).toLong(), notional.token)
|
val v = rate.ratioUnit?.value ?: return Amount(0, notional.token)
|
||||||
}
|
return Amount(dayCountFactor.times(BigDecimal(notional.quantity)).times(v).toLong(), notional.token)
|
||||||
|
}
|
||||||
|
|
||||||
override fun toString(): String = "FloatingPaymentEvent $accrualStartDate -> $accrualEndDate : $dayCountFactor : $days : $date : $notional : $rate (fix on $fixingDate): $flow"
|
override fun toString(): String = "FloatingPaymentEvent $accrualStartDate -> $accrualEndDate : $dayCountFactor : $days : $date : $notional : $rate (fix on $fixingDate): $flow"
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun makePartialTX() = TransactionBuilder(DUMMY_NOTARY).withItems(
|
private fun makePartialTX() = TransactionBuilder(DUMMY_NOTARY).withItems(
|
||||||
TransactionState(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE, Cash.PROGRAM_ID, DUMMY_NOTARY))
|
TransactionState(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE, Cash.PROGRAM_ID, DUMMY_NOTARY))
|
||||||
|
|
||||||
private fun makeFullTx() = makePartialTX().withItems(dummyCommand())
|
private fun makeFullTx() = makePartialTX().withItems(dummyCommand())
|
||||||
}
|
}
|
||||||
|
@ -86,7 +86,7 @@ class VisualiserViewModel {
|
|||||||
// top right: 33.0469,64.3209
|
// top right: 33.0469,64.3209
|
||||||
try {
|
try {
|
||||||
return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469)
|
return node.place.coordinate.project(view.mapImage.fitWidth, view.mapImage.fitHeight, 64.3209, 29.8406, -23.2031, 33.0469)
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw Exception("Cannot project ${node.started!!.info.chooseIdentity()}", e)
|
throw Exception("Cannot project ${node.started!!.info.chooseIdentity()}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
|
|||||||
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
|
node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java)
|
||||||
|
|
||||||
val notaryId = node1.rpcOps.notaryIdentities().first()
|
val notaryId = node1.rpcOps.notaryIdentities().first()
|
||||||
|
|
||||||
@InitiatingFlow
|
@InitiatingFlow
|
||||||
class StartDealFlow(val otherParty: Party,
|
class StartDealFlow(val otherParty: Party,
|
||||||
val payload: AutoOffer) : FlowLogic<SignedTransaction>() {
|
val payload: AutoOffer) : FlowLogic<SignedTransaction>() {
|
||||||
|
@ -162,8 +162,10 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean,
|
|||||||
// These are used from the network visualiser tool.
|
// These are used from the network visualiser tool.
|
||||||
private val _allFlowSteps = PublishSubject.create<Pair<SimulatedNode, ProgressTracker.Change>>()
|
private val _allFlowSteps = PublishSubject.create<Pair<SimulatedNode, ProgressTracker.Change>>()
|
||||||
private val _doneSteps = PublishSubject.create<Collection<SimulatedNode>>()
|
private val _doneSteps = PublishSubject.create<Collection<SimulatedNode>>()
|
||||||
@Suppress("unused") val allFlowSteps: Observable<Pair<SimulatedNode, ProgressTracker.Change>> = _allFlowSteps
|
@Suppress("unused")
|
||||||
@Suppress("unused") val doneSteps: Observable<Collection<SimulatedNode>> = _doneSteps
|
val allFlowSteps: Observable<Pair<SimulatedNode, ProgressTracker.Change>> = _allFlowSteps
|
||||||
|
@Suppress("unused")
|
||||||
|
val doneSteps: Observable<Collection<SimulatedNode>> = _doneSteps
|
||||||
|
|
||||||
private var pumpCursor = 0
|
private var pumpCursor = 0
|
||||||
|
|
||||||
|
@ -21,7 +21,8 @@ class IRSSimulationTest {
|
|||||||
unsetCordappPackages()
|
unsetCordappPackages()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test fun `runs to completion`() {
|
@Test
|
||||||
|
fun `runs to completion`() {
|
||||||
LogHelper.setLevel("+messages") // FIXME: Don't manipulate static state in tests.
|
LogHelper.setLevel("+messages") // FIXME: Don't manipulate static state in tests.
|
||||||
val sim = IRSSimulation(false, false, null)
|
val sim = IRSSimulation(false, false, null)
|
||||||
val future = sim.start()
|
val future = sim.start()
|
||||||
|
@ -31,7 +31,7 @@ private class NotaryDemoClientApi(val rpc: CordaRPCOps) {
|
|||||||
private val counterparty by lazy {
|
private val counterparty by lazy {
|
||||||
val parties = rpc.networkMapSnapshot()
|
val parties = rpc.networkMapSnapshot()
|
||||||
parties.fold(ArrayList<PartyAndCertificate>()) { acc, elem ->
|
parties.fold(ArrayList<PartyAndCertificate>()) { acc, elem ->
|
||||||
acc.addAll(elem.legalIdentitiesAndCerts.filter { it.name == BOB.name})
|
acc.addAll(elem.legalIdentitiesAndCerts.filter { it.name == BOB.name })
|
||||||
acc
|
acc
|
||||||
}.single().party
|
}.single().party
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata;
|
package com.opengamma.strata.examples.marketdata;
|
||||||
@ -19,46 +19,46 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class DirectoryMarketDataBuilder extends ExampleMarketDataBuilder {
|
public class DirectoryMarketDataBuilder extends ExampleMarketDataBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The path to the root of the directory structure.
|
* The path to the root of the directory structure.
|
||||||
*/
|
*/
|
||||||
private final Path rootPath;
|
private final Path rootPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance.
|
* Constructs an instance.
|
||||||
*
|
*
|
||||||
* @param rootPath the path to the root of the directory structure
|
* @param rootPath the path to the root of the directory structure
|
||||||
*/
|
*/
|
||||||
public DirectoryMarketDataBuilder(Path rootPath) {
|
public DirectoryMarketDataBuilder(Path rootPath) {
|
||||||
this.rootPath = rootPath;
|
this.rootPath = rootPath;
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
@Override
|
|
||||||
protected Collection<ResourceLocator> getAllResources(String subdirectoryName) {
|
|
||||||
File dir = rootPath.resolve(subdirectoryName).toFile();
|
|
||||||
if (!dir.exists()) {
|
|
||||||
throw new IllegalArgumentException(Messages.format("Directory does not exist: {}", dir));
|
|
||||||
}
|
}
|
||||||
return Arrays.stream(dir.listFiles())
|
|
||||||
.filter(f -> !f.isHidden())
|
|
||||||
.map(ResourceLocator::ofFile)
|
|
||||||
.collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
//-------------------------------------------------------------------------
|
||||||
protected ResourceLocator getResource(String subdirectoryName, String resourceName) {
|
@Override
|
||||||
File file = rootPath.resolve(subdirectoryName).resolve(resourceName).toFile();
|
protected Collection<ResourceLocator> getAllResources(String subdirectoryName) {
|
||||||
if (!file.exists()) {
|
File dir = rootPath.resolve(subdirectoryName).toFile();
|
||||||
return null;
|
if (!dir.exists()) {
|
||||||
|
throw new IllegalArgumentException(Messages.format("Directory does not exist: {}", dir));
|
||||||
|
}
|
||||||
|
return Arrays.stream(dir.listFiles())
|
||||||
|
.filter(f -> !f.isHidden())
|
||||||
|
.map(ResourceLocator::ofFile)
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
return ResourceLocator.ofFile(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean subdirectoryExists(String subdirectoryName) {
|
protected ResourceLocator getResource(String subdirectoryName, String resourceName) {
|
||||||
File file = rootPath.resolve(subdirectoryName).toFile();
|
File file = rootPath.resolve(subdirectoryName).resolve(resourceName).toFile();
|
||||||
return file.exists();
|
if (!file.exists()) {
|
||||||
}
|
return null;
|
||||||
|
}
|
||||||
|
return ResourceLocator.ofFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean subdirectoryExists(String subdirectoryName) {
|
||||||
|
File file = rootPath.resolve(subdirectoryName).toFile();
|
||||||
|
return file.exists();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata;
|
package com.opengamma.strata.examples.marketdata;
|
||||||
@ -18,40 +18,41 @@ import java.util.Locale;
|
|||||||
*/
|
*/
|
||||||
public final class ExampleData {
|
public final class ExampleData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricted constructor.
|
* Restricted constructor.
|
||||||
*/
|
*/
|
||||||
private ExampleData() {
|
private ExampleData() {
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Loads a golden copy of expected results from a text file.
|
|
||||||
*
|
|
||||||
* @param name the name of the results
|
|
||||||
* @return the loaded results
|
|
||||||
*/
|
|
||||||
public static String loadExpectedResults(String name) {
|
|
||||||
String classpathResourceName = String.format(Locale.ENGLISH, "classpath:goldencopy/%s.txt", name);
|
|
||||||
ResourceLocator resourceLocator = ResourceLocator.of(classpathResourceName);
|
|
||||||
try {
|
|
||||||
return resourceLocator.getCharSource().read().trim();
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new UncheckedIOException(name, ex);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
//-------------------------------------------------------------------------
|
||||||
* Loads a trade report template from the standard INI format.
|
|
||||||
*
|
/**
|
||||||
* @param templateName the name of the template
|
* Loads a golden copy of expected results from a text file.
|
||||||
* @return the loaded report template
|
*
|
||||||
*/
|
* @param name the name of the results
|
||||||
public static TradeReportTemplate loadTradeReportTemplate(String templateName) {
|
* @return the loaded results
|
||||||
String resourceName = String.format(Locale.ENGLISH, "classpath:example-reports/%s.ini", templateName);
|
*/
|
||||||
ResourceLocator resourceLocator = ResourceLocator.of(resourceName);
|
public static String loadExpectedResults(String name) {
|
||||||
IniFile ini = IniFile.of(resourceLocator.getCharSource());
|
String classpathResourceName = String.format(Locale.ENGLISH, "classpath:goldencopy/%s.txt", name);
|
||||||
return TradeReportTemplate.load(ini);
|
ResourceLocator resourceLocator = ResourceLocator.of(classpathResourceName);
|
||||||
}
|
try {
|
||||||
|
return resourceLocator.getCharSource().read().trim();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new UncheckedIOException(name, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a trade report template from the standard INI format.
|
||||||
|
*
|
||||||
|
* @param templateName the name of the template
|
||||||
|
* @return the loaded report template
|
||||||
|
*/
|
||||||
|
public static TradeReportTemplate loadTradeReportTemplate(String templateName) {
|
||||||
|
String resourceName = String.format(Locale.ENGLISH, "classpath:example-reports/%s.ini", templateName);
|
||||||
|
ResourceLocator resourceLocator = ResourceLocator.of(resourceName);
|
||||||
|
IniFile ini = IniFile.of(resourceLocator.getCharSource());
|
||||||
|
return TradeReportTemplate.load(ini);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata;
|
package com.opengamma.strata.examples.marketdata;
|
||||||
@ -10,25 +10,26 @@ package com.opengamma.strata.examples.marketdata;
|
|||||||
*/
|
*/
|
||||||
public final class ExampleMarketData {
|
public final class ExampleMarketData {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Root resource directory of the built-in example market data
|
* Root resource directory of the built-in example market data
|
||||||
*/
|
*/
|
||||||
private static final String EXAMPLE_MARKET_DATA_ROOT = "example-marketdata";
|
private static final String EXAMPLE_MARKET_DATA_ROOT = "example-marketdata";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Restricted constructor.
|
* Restricted constructor.
|
||||||
*/
|
*/
|
||||||
private ExampleMarketData() {
|
private ExampleMarketData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
/**
|
|
||||||
* Gets a market data builder for the built-in example market data.
|
/**
|
||||||
*
|
* Gets a market data builder for the built-in example market data.
|
||||||
* @return the market data builder
|
*
|
||||||
*/
|
* @return the market data builder
|
||||||
public static ExampleMarketDataBuilder builder() {
|
*/
|
||||||
return ExampleMarketDataBuilder.ofResource(EXAMPLE_MARKET_DATA_ROOT);
|
public static ExampleMarketDataBuilder builder() {
|
||||||
}
|
return ExampleMarketDataBuilder.ofResource(EXAMPLE_MARKET_DATA_ROOT);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata;
|
package com.opengamma.strata.examples.marketdata;
|
||||||
@ -67,355 +67,358 @@ import static com.opengamma.strata.collect.Guavate.toImmutableList;
|
|||||||
*/
|
*/
|
||||||
public abstract class ExampleMarketDataBuilder {
|
public abstract class ExampleMarketDataBuilder {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(ExampleMarketDataBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(ExampleMarketDataBuilder.class);
|
||||||
|
|
||||||
/** The name of the subdirectory containing historical fixings. */
|
/** The name of the subdirectory containing historical fixings. */
|
||||||
private static final String HISTORICAL_FIXINGS_DIR = "historical-fixings";
|
private static final String HISTORICAL_FIXINGS_DIR = "historical-fixings";
|
||||||
|
|
||||||
/** The name of the subdirectory containing calibrated rates curves. */
|
/** The name of the subdirectory containing calibrated rates curves. */
|
||||||
private static final String CURVES_DIR = "curves";
|
private static final String CURVES_DIR = "curves";
|
||||||
/** The name of the curve groups file. */
|
/** The name of the curve groups file. */
|
||||||
private static final String CURVES_GROUPS_FILE = "groups.csv";
|
private static final String CURVES_GROUPS_FILE = "groups.csv";
|
||||||
/** The name of the curve settings file. */
|
/** The name of the curve settings file. */
|
||||||
private static final String CURVES_SETTINGS_FILE = "settings.csv";
|
private static final String CURVES_SETTINGS_FILE = "settings.csv";
|
||||||
|
|
||||||
/** The name of the directory containing CDS ISDA yield curve, credit curve and static data. */
|
/** The name of the directory containing CDS ISDA yield curve, credit curve and static data. */
|
||||||
private static final String CREDIT_DIR = "credit";
|
private static final String CREDIT_DIR = "credit";
|
||||||
private static final String CDS_YIELD_CURVES_FILE = "cds.yieldCurves.csv";
|
private static final String CDS_YIELD_CURVES_FILE = "cds.yieldCurves.csv";
|
||||||
private static final String SINGLE_NAME_CREDIT_CURVES_FILE = "singleName.creditCurves.csv";
|
private static final String SINGLE_NAME_CREDIT_CURVES_FILE = "singleName.creditCurves.csv";
|
||||||
private static final String SINGLE_NAME_STATIC_DATA_FILE = "singleName.staticData.csv";
|
private static final String SINGLE_NAME_STATIC_DATA_FILE = "singleName.staticData.csv";
|
||||||
private static final String INDEX_CREDIT_CURVES_FILE = "index.creditCurves.csv";
|
private static final String INDEX_CREDIT_CURVES_FILE = "index.creditCurves.csv";
|
||||||
private static final String INDEX_STATIC_DATA_FILE = "index.staticData.csv";
|
private static final String INDEX_STATIC_DATA_FILE = "index.staticData.csv";
|
||||||
|
|
||||||
/** The name of the subdirectory containing simple market quotes. */
|
/** The name of the subdirectory containing simple market quotes. */
|
||||||
private static final String QUOTES_DIR = "quotes";
|
private static final String QUOTES_DIR = "quotes";
|
||||||
/** The name of the quotes file. */
|
/** The name of the quotes file. */
|
||||||
private static final String QUOTES_FILE = "quotes.csv";
|
private static final String QUOTES_FILE = "quotes.csv";
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
/**
|
|
||||||
* Creates an instance from a given classpath resource root location using the class loader
|
|
||||||
* which created this class.
|
|
||||||
* <p>
|
|
||||||
* This is designed to handle resource roots which may physically correspond to a directory on
|
|
||||||
* disk, or be located within a jar file.
|
|
||||||
*
|
|
||||||
* @param resourceRoot the resource root path
|
|
||||||
* @return the market data builder
|
|
||||||
*/
|
|
||||||
public static ExampleMarketDataBuilder ofResource(String resourceRoot) {
|
|
||||||
return ofResource(resourceRoot, ExampleMarketDataBuilder.class.getClassLoader());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance from a given classpath resource root location, using the given class loader
|
* Creates an instance from a given classpath resource root location using the class loader
|
||||||
* to find the resource.
|
* which created this class.
|
||||||
* <p>
|
* <p>
|
||||||
* This is designed to handle resource roots which may physically correspond to a directory on
|
* This is designed to handle resource roots which may physically correspond to a directory on
|
||||||
* disk, or be located within a jar file.
|
* disk, or be located within a jar file.
|
||||||
*
|
*
|
||||||
* @param resourceRoot the resource root path
|
* @param resourceRoot the resource root path
|
||||||
* @param classLoader the class loader with which to find the resource
|
* @return the market data builder
|
||||||
* @return the market data builder
|
*/
|
||||||
*/
|
public static ExampleMarketDataBuilder ofResource(String resourceRoot) {
|
||||||
public static ExampleMarketDataBuilder ofResource(String resourceRoot, ClassLoader classLoader) {
|
return ofResource(resourceRoot, ExampleMarketDataBuilder.class.getClassLoader());
|
||||||
// classpath resources are forward-slash separated
|
|
||||||
String qualifiedRoot = resourceRoot;
|
|
||||||
qualifiedRoot = qualifiedRoot.startsWith("/") ? qualifiedRoot.substring(1) : qualifiedRoot;
|
|
||||||
qualifiedRoot = qualifiedRoot.startsWith("\\") ? qualifiedRoot.substring(1) : qualifiedRoot;
|
|
||||||
qualifiedRoot = qualifiedRoot.endsWith("/") ? qualifiedRoot : qualifiedRoot + "/";
|
|
||||||
URL url = classLoader.getResource(qualifiedRoot);
|
|
||||||
if (url == null) {
|
|
||||||
throw new IllegalArgumentException(Messages.format("Classpath resource not found: {}", qualifiedRoot));
|
|
||||||
}
|
|
||||||
if (url.getProtocol() != null && "jar".equals(url.getProtocol().toLowerCase(Locale.ENGLISH))) {
|
|
||||||
// Inside a JAR
|
|
||||||
int classSeparatorIdx = url.getFile().indexOf("!");
|
|
||||||
if (classSeparatorIdx == -1) {
|
|
||||||
throw new IllegalArgumentException(Messages.format("Unexpected JAR file URL: {}", url));
|
|
||||||
}
|
|
||||||
String jarPath = url.getFile().substring("file:".length(), classSeparatorIdx);
|
|
||||||
File jarFile;
|
|
||||||
try {
|
|
||||||
jarFile = new File(jarPath);
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalArgumentException(Messages.format("Unable to create file for JAR: {}", jarPath), e);
|
|
||||||
}
|
|
||||||
return new JarMarketDataBuilder(jarFile, resourceRoot);
|
|
||||||
} else {
|
|
||||||
// Resource is on disk
|
|
||||||
File file;
|
|
||||||
try {
|
|
||||||
file = new File(url.toURI());
|
|
||||||
} catch (URISyntaxException e) {
|
|
||||||
throw new IllegalArgumentException(Messages.format("Unexpected file location: {}", url), e);
|
|
||||||
}
|
|
||||||
return new DirectoryMarketDataBuilder(file.toPath());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates an instance from a given directory root.
|
|
||||||
*
|
|
||||||
* @param rootPath the root directory
|
|
||||||
* @return the market data builder
|
|
||||||
*/
|
|
||||||
public static ExampleMarketDataBuilder ofPath(Path rootPath) {
|
|
||||||
return new DirectoryMarketDataBuilder(rootPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Builds a market data snapshot from this environment.
|
|
||||||
*
|
|
||||||
* @param marketDataDate the date of the market data
|
|
||||||
* @return the snapshot
|
|
||||||
*/
|
|
||||||
public ImmutableMarketData buildSnapshot(LocalDate marketDataDate) {
|
|
||||||
ImmutableMarketDataBuilder builder = ImmutableMarketData.builder(marketDataDate);
|
|
||||||
loadFixingSeries(builder);
|
|
||||||
loadRatesCurves(builder, marketDataDate);
|
|
||||||
loadQuotes(builder, marketDataDate);
|
|
||||||
loadFxRates(builder);
|
|
||||||
loadCreditMarketData(builder, marketDataDate);
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the rates market lookup to use with this environment.
|
|
||||||
*
|
|
||||||
* @param marketDataDate the date of the market data
|
|
||||||
* @return the rates lookup
|
|
||||||
*/
|
|
||||||
public RatesMarketDataLookup ratesLookup(LocalDate marketDataDate) {
|
|
||||||
SortedMap<LocalDate, CurveGroup> curves = loadAllRatesCurves();
|
|
||||||
return RatesMarketDataLookup.of(curves.get(marketDataDate));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all rates curves.
|
|
||||||
*
|
|
||||||
* @return the map of all rates curves
|
|
||||||
*/
|
|
||||||
public SortedMap<LocalDate, CurveGroup> loadAllRatesCurves() {
|
|
||||||
if (!subdirectoryExists(CURVES_DIR)) {
|
|
||||||
throw new IllegalArgumentException("No rates curves directory found");
|
|
||||||
}
|
|
||||||
ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE);
|
|
||||||
if (curveGroupsResource == null) {
|
|
||||||
throw new IllegalArgumentException(Messages.format(
|
|
||||||
"Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE));
|
|
||||||
}
|
|
||||||
ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE);
|
|
||||||
if (curveSettingsResource == null) {
|
|
||||||
throw new IllegalArgumentException(Messages.format(
|
|
||||||
"Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE));
|
|
||||||
}
|
|
||||||
ListMultimap<LocalDate, CurveGroup> curveGroups =
|
|
||||||
RatesCurvesCsvLoader.loadAllDates(curveGroupsResource, curveSettingsResource, getRatesCurvesResources());
|
|
||||||
|
|
||||||
// There is only one curve group in the market data file so this will always succeed
|
|
||||||
Map<LocalDate, CurveGroup> curveGroupMap = Maps.transformValues(curveGroups.asMap(), groups -> groups.iterator().next());
|
|
||||||
return new TreeMap<>(curveGroupMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
private void loadFixingSeries(ImmutableMarketDataBuilder builder) {
|
|
||||||
if (!subdirectoryExists(HISTORICAL_FIXINGS_DIR)) {
|
|
||||||
log.debug("No historical fixings directory found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Collection<ResourceLocator> fixingSeriesResources = getAllResources(HISTORICAL_FIXINGS_DIR);
|
|
||||||
Map<ObservableId, LocalDateDoubleTimeSeries> fixingSeries = FixingSeriesCsvLoader.load(fixingSeriesResources);
|
|
||||||
builder.addTimeSeriesMap(fixingSeries);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error loading fixing series", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadRatesCurves(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) {
|
|
||||||
if (!subdirectoryExists(CURVES_DIR)) {
|
|
||||||
log.debug("No rates curves directory found");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE);
|
/**
|
||||||
if (curveGroupsResource == null) {
|
* Creates an instance from a given classpath resource root location, using the given class loader
|
||||||
log.error("Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE);
|
* to find the resource.
|
||||||
return;
|
* <p>
|
||||||
|
* This is designed to handle resource roots which may physically correspond to a directory on
|
||||||
|
* disk, or be located within a jar file.
|
||||||
|
*
|
||||||
|
* @param resourceRoot the resource root path
|
||||||
|
* @param classLoader the class loader with which to find the resource
|
||||||
|
* @return the market data builder
|
||||||
|
*/
|
||||||
|
public static ExampleMarketDataBuilder ofResource(String resourceRoot, ClassLoader classLoader) {
|
||||||
|
// classpath resources are forward-slash separated
|
||||||
|
String qualifiedRoot = resourceRoot;
|
||||||
|
qualifiedRoot = qualifiedRoot.startsWith("/") ? qualifiedRoot.substring(1) : qualifiedRoot;
|
||||||
|
qualifiedRoot = qualifiedRoot.startsWith("\\") ? qualifiedRoot.substring(1) : qualifiedRoot;
|
||||||
|
qualifiedRoot = qualifiedRoot.endsWith("/") ? qualifiedRoot : qualifiedRoot + "/";
|
||||||
|
URL url = classLoader.getResource(qualifiedRoot);
|
||||||
|
if (url == null) {
|
||||||
|
throw new IllegalArgumentException(Messages.format("Classpath resource not found: {}", qualifiedRoot));
|
||||||
|
}
|
||||||
|
if (url.getProtocol() != null && "jar".equals(url.getProtocol().toLowerCase(Locale.ENGLISH))) {
|
||||||
|
// Inside a JAR
|
||||||
|
int classSeparatorIdx = url.getFile().indexOf("!");
|
||||||
|
if (classSeparatorIdx == -1) {
|
||||||
|
throw new IllegalArgumentException(Messages.format("Unexpected JAR file URL: {}", url));
|
||||||
|
}
|
||||||
|
String jarPath = url.getFile().substring("file:".length(), classSeparatorIdx);
|
||||||
|
File jarFile;
|
||||||
|
try {
|
||||||
|
jarFile = new File(jarPath);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(Messages.format("Unable to create file for JAR: {}", jarPath), e);
|
||||||
|
}
|
||||||
|
return new JarMarketDataBuilder(jarFile, resourceRoot);
|
||||||
|
} else {
|
||||||
|
// Resource is on disk
|
||||||
|
File file;
|
||||||
|
try {
|
||||||
|
file = new File(url.toURI());
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new IllegalArgumentException(Messages.format("Unexpected file location: {}", url), e);
|
||||||
|
}
|
||||||
|
return new DirectoryMarketDataBuilder(file.toPath());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE);
|
/**
|
||||||
if (curveSettingsResource == null) {
|
* Creates an instance from a given directory root.
|
||||||
log.error("Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE);
|
*
|
||||||
return;
|
* @param rootPath the root directory
|
||||||
}
|
* @return the market data builder
|
||||||
try {
|
*/
|
||||||
Collection<ResourceLocator> curvesResources = getRatesCurvesResources();
|
public static ExampleMarketDataBuilder ofPath(Path rootPath) {
|
||||||
List<CurveGroup> ratesCurves =
|
return new DirectoryMarketDataBuilder(rootPath);
|
||||||
RatesCurvesCsvLoader.load(marketDataDate, curveGroupsResource, curveSettingsResource, curvesResources);
|
|
||||||
|
|
||||||
for (CurveGroup group : ratesCurves) {
|
|
||||||
// add entry for higher level discount curve name
|
|
||||||
group.getDiscountCurves().forEach(
|
|
||||||
(ccy, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve));
|
|
||||||
// add entry for higher level forward curve name
|
|
||||||
group.getForwardCurves().forEach(
|
|
||||||
(idx, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Error loading rates curves", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load quotes
|
|
||||||
private void loadQuotes(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) {
|
|
||||||
if (!subdirectoryExists(QUOTES_DIR)) {
|
|
||||||
log.debug("No quotes directory found");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLocator quotesResource = getResource(QUOTES_DIR, QUOTES_FILE);
|
//-------------------------------------------------------------------------
|
||||||
if (quotesResource == null) {
|
|
||||||
log.error("Unable to load quotes: quotes file not found at {}/{}", QUOTES_DIR, QUOTES_FILE);
|
/**
|
||||||
return;
|
* Builds a market data snapshot from this environment.
|
||||||
|
*
|
||||||
|
* @param marketDataDate the date of the market data
|
||||||
|
* @return the snapshot
|
||||||
|
*/
|
||||||
|
public ImmutableMarketData buildSnapshot(LocalDate marketDataDate) {
|
||||||
|
ImmutableMarketDataBuilder builder = ImmutableMarketData.builder(marketDataDate);
|
||||||
|
loadFixingSeries(builder);
|
||||||
|
loadRatesCurves(builder, marketDataDate);
|
||||||
|
loadQuotes(builder, marketDataDate);
|
||||||
|
loadFxRates(builder);
|
||||||
|
loadCreditMarketData(builder, marketDataDate);
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
/**
|
||||||
Map<QuoteId, Double> quotes = QuotesCsvLoader.load(marketDataDate, quotesResource);
|
* Gets the rates market lookup to use with this environment.
|
||||||
builder.addValueMap(quotes);
|
*
|
||||||
|
* @param marketDataDate the date of the market data
|
||||||
} catch (Exception ex) {
|
* @return the rates lookup
|
||||||
log.error("Error loading quotes", ex);
|
*/
|
||||||
}
|
public RatesMarketDataLookup ratesLookup(LocalDate marketDataDate) {
|
||||||
}
|
SortedMap<LocalDate, CurveGroup> curves = loadAllRatesCurves();
|
||||||
|
return RatesMarketDataLookup.of(curves.get(marketDataDate));
|
||||||
private void loadFxRates(ImmutableMarketDataBuilder builder) {
|
|
||||||
// TODO - load from CSV file - format to be defined
|
|
||||||
builder.addValue(FxRateId.of(Currency.GBP, Currency.USD), FxRate.of(Currency.GBP, Currency.USD, 1.61));
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
private Collection<ResourceLocator> getRatesCurvesResources() {
|
|
||||||
return getAllResources(CURVES_DIR).stream()
|
|
||||||
.filter(res -> !res.getLocator().endsWith(CURVES_GROUPS_FILE))
|
|
||||||
.filter(res -> !res.getLocator().endsWith(CURVES_SETTINGS_FILE))
|
|
||||||
.collect(toImmutableList());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadCreditMarketData(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) {
|
|
||||||
if (!subdirectoryExists(CREDIT_DIR)) {
|
|
||||||
log.debug("No credit curves directory found");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String creditMarketDataDateDirectory = String.format(
|
/**
|
||||||
Locale.ENGLISH,
|
* Gets all rates curves.
|
||||||
"%s/%s",
|
*
|
||||||
CREDIT_DIR,
|
* @return the map of all rates curves
|
||||||
marketDataDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
|
*/
|
||||||
|
public SortedMap<LocalDate, CurveGroup> loadAllRatesCurves() {
|
||||||
|
if (!subdirectoryExists(CURVES_DIR)) {
|
||||||
|
throw new IllegalArgumentException("No rates curves directory found");
|
||||||
|
}
|
||||||
|
ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE);
|
||||||
|
if (curveGroupsResource == null) {
|
||||||
|
throw new IllegalArgumentException(Messages.format(
|
||||||
|
"Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE));
|
||||||
|
}
|
||||||
|
ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE);
|
||||||
|
if (curveSettingsResource == null) {
|
||||||
|
throw new IllegalArgumentException(Messages.format(
|
||||||
|
"Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE));
|
||||||
|
}
|
||||||
|
ListMultimap<LocalDate, CurveGroup> curveGroups =
|
||||||
|
RatesCurvesCsvLoader.loadAllDates(curveGroupsResource, curveSettingsResource, getRatesCurvesResources());
|
||||||
|
|
||||||
if (!subdirectoryExists(creditMarketDataDateDirectory)) {
|
// There is only one curve group in the market data file so this will always succeed
|
||||||
log.debug("Unable to load market data: directory not found at {}", creditMarketDataDateDirectory);
|
Map<LocalDate, CurveGroup> curveGroupMap = Maps.transformValues(curveGroups.asMap(), groups -> groups.iterator().next());
|
||||||
return;
|
return new TreeMap<>(curveGroupMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadCdsYieldCurves(builder, creditMarketDataDateDirectory);
|
//-------------------------------------------------------------------------
|
||||||
loadCdsSingleNameSpreadCurves(builder, creditMarketDataDateDirectory);
|
private void loadFixingSeries(ImmutableMarketDataBuilder builder) {
|
||||||
loadCdsIndexSpreadCurves(builder, creditMarketDataDateDirectory);
|
if (!subdirectoryExists(HISTORICAL_FIXINGS_DIR)) {
|
||||||
}
|
log.debug("No historical fixings directory found");
|
||||||
|
return;
|
||||||
private void loadCdsYieldCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) {
|
}
|
||||||
ResourceLocator cdsYieldCurvesResource = getResource(creditMarketDataDateDirectory, CDS_YIELD_CURVES_FILE);
|
try {
|
||||||
if (cdsYieldCurvesResource == null) {
|
Collection<ResourceLocator> fixingSeriesResources = getAllResources(HISTORICAL_FIXINGS_DIR);
|
||||||
log.debug("Unable to load cds yield curves: file not found at {}/{}", creditMarketDataDateDirectory,
|
Map<ObservableId, LocalDateDoubleTimeSeries> fixingSeries = FixingSeriesCsvLoader.load(fixingSeriesResources);
|
||||||
CDS_YIELD_CURVES_FILE);
|
builder.addTimeSeriesMap(fixingSeries);
|
||||||
return;
|
} catch (Exception e) {
|
||||||
|
log.error("Error loading fixing series", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSource inputSource = cdsYieldCurvesResource.getCharSource();
|
private void loadRatesCurves(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) {
|
||||||
Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> yieldCuves = MarkitYieldCurveDataParser.parse(inputSource);
|
if (!subdirectoryExists(CURVES_DIR)) {
|
||||||
|
log.debug("No rates curves directory found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (IsdaYieldCurveInputsId id : yieldCuves.keySet()) {
|
ResourceLocator curveGroupsResource = getResource(CURVES_DIR, CURVES_GROUPS_FILE);
|
||||||
IsdaYieldCurveInputs curveInputs = yieldCuves.get(id);
|
if (curveGroupsResource == null) {
|
||||||
builder.addValue(id, curveInputs);
|
log.error("Unable to load rates curves: curve groups file not found at {}/{}", CURVES_DIR, CURVES_GROUPS_FILE);
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadCdsSingleNameSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) {
|
ResourceLocator curveSettingsResource = getResource(CURVES_DIR, CURVES_SETTINGS_FILE);
|
||||||
ResourceLocator singleNameCurvesResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE);
|
if (curveSettingsResource == null) {
|
||||||
if (singleNameCurvesResource == null) {
|
log.error("Unable to load rates curves: curve settings file not found at {}/{}", CURVES_DIR, CURVES_SETTINGS_FILE);
|
||||||
log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory,
|
return;
|
||||||
SINGLE_NAME_CREDIT_CURVES_FILE);
|
}
|
||||||
return;
|
try {
|
||||||
|
Collection<ResourceLocator> curvesResources = getRatesCurvesResources();
|
||||||
|
List<CurveGroup> ratesCurves =
|
||||||
|
RatesCurvesCsvLoader.load(marketDataDate, curveGroupsResource, curveSettingsResource, curvesResources);
|
||||||
|
|
||||||
|
for (CurveGroup group : ratesCurves) {
|
||||||
|
// add entry for higher level discount curve name
|
||||||
|
group.getDiscountCurves().forEach(
|
||||||
|
(ccy, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve));
|
||||||
|
// add entry for higher level forward curve name
|
||||||
|
group.getForwardCurves().forEach(
|
||||||
|
(idx, curve) -> builder.addValue(CurveId.of(group.getName(), curve.getName()), curve));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error loading rates curves", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLocator singleNameStaticDataResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_STATIC_DATA_FILE);
|
// load quotes
|
||||||
if (singleNameStaticDataResource == null) {
|
private void loadQuotes(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) {
|
||||||
log.debug("Unable to load single name static data: file not found at {}/{}", creditMarketDataDateDirectory,
|
if (!subdirectoryExists(QUOTES_DIR)) {
|
||||||
SINGLE_NAME_STATIC_DATA_FILE);
|
log.debug("No quotes directory found");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceLocator quotesResource = getResource(QUOTES_DIR, QUOTES_FILE);
|
||||||
|
if (quotesResource == null) {
|
||||||
|
log.error("Unable to load quotes: quotes file not found at {}/{}", QUOTES_DIR, QUOTES_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Map<QuoteId, Double> quotes = QuotesCsvLoader.load(marketDataDate, quotesResource);
|
||||||
|
builder.addValueMap(quotes);
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("Error loading quotes", ex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
private void loadFxRates(ImmutableMarketDataBuilder builder) {
|
||||||
CharSource inputCreditCurvesSource = singleNameCurvesResource.getCharSource();
|
// TODO - load from CSV file - format to be defined
|
||||||
CharSource inputStaticDataSource = singleNameStaticDataResource.getCharSource();
|
builder.addValue(FxRateId.of(Currency.GBP, Currency.USD), FxRate.of(Currency.GBP, Currency.USD, 1.61));
|
||||||
MarkitSingleNameCreditCurveDataParser.parse(builder, inputCreditCurvesSource, inputStaticDataSource);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
throw new RuntimeException(String.format(
|
|
||||||
Locale.ENGLISH,
|
|
||||||
"Unable to read single name spread curves: exception at %s/%s",
|
|
||||||
creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE), ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void loadCdsIndexSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) {
|
|
||||||
ResourceLocator inputCurvesResource = getResource(creditMarketDataDateDirectory, INDEX_CREDIT_CURVES_FILE);
|
|
||||||
if (inputCurvesResource == null) {
|
|
||||||
log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory,
|
|
||||||
INDEX_CREDIT_CURVES_FILE);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ResourceLocator inputStaticDataResource = getResource(creditMarketDataDateDirectory, INDEX_STATIC_DATA_FILE);
|
//-------------------------------------------------------------------------
|
||||||
if (inputStaticDataResource == null) {
|
private Collection<ResourceLocator> getRatesCurvesResources() {
|
||||||
log.debug("Unable to load index static data: file not found at {}/{}", creditMarketDataDateDirectory,
|
return getAllResources(CURVES_DIR).stream()
|
||||||
INDEX_STATIC_DATA_FILE);
|
.filter(res -> !res.getLocator().endsWith(CURVES_GROUPS_FILE))
|
||||||
return;
|
.filter(res -> !res.getLocator().endsWith(CURVES_SETTINGS_FILE))
|
||||||
|
.collect(toImmutableList());
|
||||||
}
|
}
|
||||||
|
|
||||||
CharSource indexCreditCurvesSource = inputCurvesResource.getCharSource();
|
private void loadCreditMarketData(ImmutableMarketDataBuilder builder, LocalDate marketDataDate) {
|
||||||
CharSource indexStaticDataSource = inputStaticDataResource.getCharSource();
|
if (!subdirectoryExists(CREDIT_DIR)) {
|
||||||
MarkitIndexCreditCurveDataParser.parse(builder, indexCreditCurvesSource, indexStaticDataSource);
|
log.debug("No credit curves directory found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
String creditMarketDataDateDirectory = String.format(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
"%s/%s",
|
||||||
|
CREDIT_DIR,
|
||||||
|
marketDataDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
if (!subdirectoryExists(creditMarketDataDateDirectory)) {
|
||||||
/**
|
log.debug("Unable to load market data: directory not found at {}", creditMarketDataDateDirectory);
|
||||||
* Gets all available resources from a given subdirectory.
|
return;
|
||||||
*
|
}
|
||||||
* @param subdirectoryName the name of the subdirectory
|
|
||||||
* @return a collection of locators for the resources in the subdirectory
|
|
||||||
*/
|
|
||||||
protected abstract Collection<ResourceLocator> getAllResources(String subdirectoryName);
|
|
||||||
|
|
||||||
/**
|
loadCdsYieldCurves(builder, creditMarketDataDateDirectory);
|
||||||
* Gets a specific resource from a given subdirectory.
|
loadCdsSingleNameSpreadCurves(builder, creditMarketDataDateDirectory);
|
||||||
*
|
loadCdsIndexSpreadCurves(builder, creditMarketDataDateDirectory);
|
||||||
* @param subdirectoryName the name of the subdirectory
|
}
|
||||||
* @param resourceName the name of the resource
|
|
||||||
* @return a locator for the requested resource
|
|
||||||
*/
|
|
||||||
protected abstract ResourceLocator getResource(String subdirectoryName, String resourceName);
|
|
||||||
|
|
||||||
/**
|
private void loadCdsYieldCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) {
|
||||||
* Checks whether a specific subdirectory exists.
|
ResourceLocator cdsYieldCurvesResource = getResource(creditMarketDataDateDirectory, CDS_YIELD_CURVES_FILE);
|
||||||
*
|
if (cdsYieldCurvesResource == null) {
|
||||||
* @param subdirectoryName the name of the subdirectory
|
log.debug("Unable to load cds yield curves: file not found at {}/{}", creditMarketDataDateDirectory,
|
||||||
* @return whether the subdirectory exists
|
CDS_YIELD_CURVES_FILE);
|
||||||
*/
|
return;
|
||||||
protected abstract boolean subdirectoryExists(String subdirectoryName);
|
}
|
||||||
|
|
||||||
|
CharSource inputSource = cdsYieldCurvesResource.getCharSource();
|
||||||
|
Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> yieldCuves = MarkitYieldCurveDataParser.parse(inputSource);
|
||||||
|
|
||||||
|
for (IsdaYieldCurveInputsId id : yieldCuves.keySet()) {
|
||||||
|
IsdaYieldCurveInputs curveInputs = yieldCuves.get(id);
|
||||||
|
builder.addValue(id, curveInputs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCdsSingleNameSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) {
|
||||||
|
ResourceLocator singleNameCurvesResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE);
|
||||||
|
if (singleNameCurvesResource == null) {
|
||||||
|
log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory,
|
||||||
|
SINGLE_NAME_CREDIT_CURVES_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceLocator singleNameStaticDataResource = getResource(creditMarketDataDateDirectory, SINGLE_NAME_STATIC_DATA_FILE);
|
||||||
|
if (singleNameStaticDataResource == null) {
|
||||||
|
log.debug("Unable to load single name static data: file not found at {}/{}", creditMarketDataDateDirectory,
|
||||||
|
SINGLE_NAME_STATIC_DATA_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
CharSource inputCreditCurvesSource = singleNameCurvesResource.getCharSource();
|
||||||
|
CharSource inputStaticDataSource = singleNameStaticDataResource.getCharSource();
|
||||||
|
MarkitSingleNameCreditCurveDataParser.parse(builder, inputCreditCurvesSource, inputStaticDataSource);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException(String.format(
|
||||||
|
Locale.ENGLISH,
|
||||||
|
"Unable to read single name spread curves: exception at %s/%s",
|
||||||
|
creditMarketDataDateDirectory, SINGLE_NAME_CREDIT_CURVES_FILE), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadCdsIndexSpreadCurves(ImmutableMarketDataBuilder builder, String creditMarketDataDateDirectory) {
|
||||||
|
ResourceLocator inputCurvesResource = getResource(creditMarketDataDateDirectory, INDEX_CREDIT_CURVES_FILE);
|
||||||
|
if (inputCurvesResource == null) {
|
||||||
|
log.debug("Unable to load single name spread curves: file not found at {}/{}", creditMarketDataDateDirectory,
|
||||||
|
INDEX_CREDIT_CURVES_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResourceLocator inputStaticDataResource = getResource(creditMarketDataDateDirectory, INDEX_STATIC_DATA_FILE);
|
||||||
|
if (inputStaticDataResource == null) {
|
||||||
|
log.debug("Unable to load index static data: file not found at {}/{}", creditMarketDataDateDirectory,
|
||||||
|
INDEX_STATIC_DATA_FILE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CharSource indexCreditCurvesSource = inputCurvesResource.getCharSource();
|
||||||
|
CharSource indexStaticDataSource = inputStaticDataResource.getCharSource();
|
||||||
|
MarkitIndexCreditCurveDataParser.parse(builder, indexCreditCurvesSource, indexStaticDataSource);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all available resources from a given subdirectory.
|
||||||
|
*
|
||||||
|
* @param subdirectoryName the name of the subdirectory
|
||||||
|
* @return a collection of locators for the resources in the subdirectory
|
||||||
|
*/
|
||||||
|
protected abstract Collection<ResourceLocator> getAllResources(String subdirectoryName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a specific resource from a given subdirectory.
|
||||||
|
*
|
||||||
|
* @param subdirectoryName the name of the subdirectory
|
||||||
|
* @param resourceName the name of the resource
|
||||||
|
* @return a locator for the requested resource
|
||||||
|
*/
|
||||||
|
protected abstract ResourceLocator getResource(String subdirectoryName, String resourceName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a specific subdirectory exists.
|
||||||
|
*
|
||||||
|
* @param subdirectoryName the name of the subdirectory
|
||||||
|
* @return whether the subdirectory exists
|
||||||
|
*/
|
||||||
|
protected abstract boolean subdirectoryExists(String subdirectoryName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata;
|
package com.opengamma.strata.examples.marketdata;
|
||||||
@ -22,96 +22,96 @@ import java.util.stream.Collectors;
|
|||||||
*/
|
*/
|
||||||
public class JarMarketDataBuilder extends ExampleMarketDataBuilder {
|
public class JarMarketDataBuilder extends ExampleMarketDataBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The JAR file containing the expected structure of resources.
|
* The JAR file containing the expected structure of resources.
|
||||||
*/
|
*/
|
||||||
private final File jarFile;
|
private final File jarFile;
|
||||||
/**
|
/**
|
||||||
* The root path to the resources within the JAR file.
|
* The root path to the resources within the JAR file.
|
||||||
*/
|
*/
|
||||||
private final String rootPath;
|
private final String rootPath;
|
||||||
/**
|
/**
|
||||||
* A cache of JAR entries under the root path.
|
* A cache of JAR entries under the root path.
|
||||||
*/
|
*/
|
||||||
private final ImmutableSet<String> entries;
|
private final ImmutableSet<String> entries;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs an instance.
|
* Constructs an instance.
|
||||||
*
|
*
|
||||||
* @param jarFile the JAR file containing the expected structure of resources
|
* @param jarFile the JAR file containing the expected structure of resources
|
||||||
* @param rootPath the root path to the resources within the JAR file
|
* @param rootPath the root path to the resources within the JAR file
|
||||||
*/
|
*/
|
||||||
public JarMarketDataBuilder(File jarFile, String rootPath) {
|
public JarMarketDataBuilder(File jarFile, String rootPath) {
|
||||||
// classpath resources are forward-slash separated
|
// classpath resources are forward-slash separated
|
||||||
String jarRoot = rootPath.startsWith("/") ? rootPath.substring(1) : rootPath;
|
String jarRoot = rootPath.startsWith("/") ? rootPath.substring(1) : rootPath;
|
||||||
if (!jarRoot.endsWith("/")) {
|
if (!jarRoot.endsWith("/")) {
|
||||||
jarRoot += "/";
|
jarRoot += "/";
|
||||||
}
|
|
||||||
this.jarFile = jarFile;
|
|
||||||
this.rootPath = jarRoot;
|
|
||||||
this.entries = getEntries(jarFile, rootPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
@Override
|
|
||||||
protected Collection<ResourceLocator> getAllResources(String subdirectoryName) {
|
|
||||||
String resolvedSubdirectory = subdirectoryName + "/";
|
|
||||||
return entries.stream()
|
|
||||||
.filter(e -> e.startsWith(resolvedSubdirectory) && !e.equals(resolvedSubdirectory))
|
|
||||||
.map(e -> getEntryLocator(rootPath + e))
|
|
||||||
.collect(Collectors.toSet());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected ResourceLocator getResource(String subdirectoryName, String resourceName) {
|
|
||||||
String fullLocation = String.format(Locale.ENGLISH, "%s%s/%s", rootPath, subdirectoryName, resourceName);
|
|
||||||
try (JarFile jar = new JarFile(jarFile)) {
|
|
||||||
JarEntry entry = jar.getJarEntry(fullLocation);
|
|
||||||
if (entry == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return getEntryLocator(entry.getName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
Messages.format("Error loading resource from JAR file: {}", jarFile), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean subdirectoryExists(String subdirectoryName) {
|
|
||||||
// classpath resources are forward-slash separated
|
|
||||||
String resolvedName = subdirectoryName.startsWith("/") ? subdirectoryName.substring(1) : subdirectoryName;
|
|
||||||
if (!resolvedName.endsWith("/")) {
|
|
||||||
resolvedName += "/";
|
|
||||||
}
|
|
||||||
return entries.contains(resolvedName);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
// Gets the resource locator corresponding to a given entry
|
|
||||||
private ResourceLocator getEntryLocator(String entryName) {
|
|
||||||
return ResourceLocator.of(ResourceLocator.CLASSPATH_URL_PREFIX + entryName);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ImmutableSet<String> getEntries(File jarFile, String rootPath) {
|
|
||||||
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
|
|
||||||
try (JarFile jar = new JarFile(jarFile)) {
|
|
||||||
Enumeration<JarEntry> jarEntries = jar.entries();
|
|
||||||
while (jarEntries.hasMoreElements()) {
|
|
||||||
JarEntry entry = jarEntries.nextElement();
|
|
||||||
String entryName = entry.getName();
|
|
||||||
if (entryName.startsWith(rootPath) && !entryName.equals(rootPath)) {
|
|
||||||
String relativeEntryPath = entryName.substring(rootPath.length() + 1);
|
|
||||||
if (!relativeEntryPath.trim().isEmpty()) {
|
|
||||||
builder.add(relativeEntryPath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
this.jarFile = jarFile;
|
||||||
} catch (Exception e) {
|
this.rootPath = jarRoot;
|
||||||
throw new IllegalArgumentException(
|
this.entries = getEntries(jarFile, rootPath);
|
||||||
Messages.format("Error scanning entries in JAR file: {}", jarFile), e);
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
protected Collection<ResourceLocator> getAllResources(String subdirectoryName) {
|
||||||
|
String resolvedSubdirectory = subdirectoryName + "/";
|
||||||
|
return entries.stream()
|
||||||
|
.filter(e -> e.startsWith(resolvedSubdirectory) && !e.equals(resolvedSubdirectory))
|
||||||
|
.map(e -> getEntryLocator(rootPath + e))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ResourceLocator getResource(String subdirectoryName, String resourceName) {
|
||||||
|
String fullLocation = String.format(Locale.ENGLISH, "%s%s/%s", rootPath, subdirectoryName, resourceName);
|
||||||
|
try (JarFile jar = new JarFile(jarFile)) {
|
||||||
|
JarEntry entry = jar.getJarEntry(fullLocation);
|
||||||
|
if (entry == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return getEntryLocator(entry.getName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
Messages.format("Error loading resource from JAR file: {}", jarFile), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean subdirectoryExists(String subdirectoryName) {
|
||||||
|
// classpath resources are forward-slash separated
|
||||||
|
String resolvedName = subdirectoryName.startsWith("/") ? subdirectoryName.substring(1) : subdirectoryName;
|
||||||
|
if (!resolvedName.endsWith("/")) {
|
||||||
|
resolvedName += "/";
|
||||||
|
}
|
||||||
|
return entries.contains(resolvedName);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
// Gets the resource locator corresponding to a given entry
|
||||||
|
private ResourceLocator getEntryLocator(String entryName) {
|
||||||
|
return ResourceLocator.of(ResourceLocator.CLASSPATH_URL_PREFIX + entryName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImmutableSet<String> getEntries(File jarFile, String rootPath) {
|
||||||
|
ImmutableSet.Builder<String> builder = ImmutableSet.builder();
|
||||||
|
try (JarFile jar = new JarFile(jarFile)) {
|
||||||
|
Enumeration<JarEntry> jarEntries = jar.entries();
|
||||||
|
while (jarEntries.hasMoreElements()) {
|
||||||
|
JarEntry entry = jarEntries.nextElement();
|
||||||
|
String entryName = entry.getName();
|
||||||
|
if (entryName.startsWith(rootPath) && !entryName.equals(rootPath)) {
|
||||||
|
String relativeEntryPath = entryName.substring(rootPath.length() + 1);
|
||||||
|
if (!relativeEntryPath.trim().isEmpty()) {
|
||||||
|
builder.add(relativeEntryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
Messages.format("Error scanning entries in JAR file: {}", jarFile), e);
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
}
|
}
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata.credit.markit;
|
package com.opengamma.strata.examples.marketdata.credit.markit;
|
||||||
@ -44,217 +44,219 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class MarkitIndexCreditCurveDataParser {
|
public class MarkitIndexCreditCurveDataParser {
|
||||||
|
|
||||||
// Markit date format with the month in full caps. e.g. 11-JUL-14
|
// Markit date format with the month in full caps. e.g. 11-JUL-14
|
||||||
private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
|
private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
|
||||||
.parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH);
|
.parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH);
|
||||||
|
|
||||||
enum Columns {
|
enum Columns {
|
||||||
|
|
||||||
Series("Series"),
|
Series("Series"),
|
||||||
Version("Version"),
|
Version("Version"),
|
||||||
Term("Term"),
|
Term("Term"),
|
||||||
RedCode("RED Code"),
|
RedCode("RED Code"),
|
||||||
Maturity("Maturity"),
|
Maturity("Maturity"),
|
||||||
CompositeSpread("Composite Spread"),
|
CompositeSpread("Composite Spread"),
|
||||||
ModelSpread("Model Spread");
|
ModelSpread("Model Spread");
|
||||||
|
|
||||||
private final String columnName;
|
private final String columnName;
|
||||||
|
|
||||||
Columns(String columnName) {
|
Columns(String columnName) {
|
||||||
this.columnName = columnName;
|
this.columnName = columnName;
|
||||||
}
|
|
||||||
|
|
||||||
public String getColumnName() {
|
|
||||||
return columnName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parses the specified sources.
|
|
||||||
*
|
|
||||||
* @param builder the market data builder that the resulting curve and recovery rate items should be loaded into
|
|
||||||
* @param curveSource the source of curve data to parse
|
|
||||||
* @param staticDataSource the source of static data to parse
|
|
||||||
*/
|
|
||||||
public static void parse(
|
|
||||||
ImmutableMarketDataBuilder builder,
|
|
||||||
CharSource curveSource,
|
|
||||||
CharSource staticDataSource) {
|
|
||||||
|
|
||||||
Map<IsdaIndexCreditCurveInputsId, List<Point>> curveData = Maps.newHashMap();
|
|
||||||
Map<MarkitRedCode, StaticData> staticDataMap = parseStaticData(staticDataSource);
|
|
||||||
|
|
||||||
CsvFile csv = CsvFile.of(curveSource, true);
|
|
||||||
for (CsvRow row : csv.rows()) {
|
|
||||||
String seriesText = row.getField(Columns.Series.getColumnName());
|
|
||||||
String versionText = row.getField(Columns.Version.getColumnName());
|
|
||||||
String termText = row.getField(Columns.Term.getColumnName());
|
|
||||||
String redCodeText = row.getField(Columns.RedCode.getColumnName());
|
|
||||||
String maturityText = row.getField(Columns.Maturity.getColumnName());
|
|
||||||
String compositeSpreadText = row.getField(Columns.CompositeSpread.getColumnName());
|
|
||||||
String modelSpreadText = row.getField(Columns.ModelSpread.getColumnName());
|
|
||||||
|
|
||||||
StandardId indexId = MarkitRedCode.id(redCodeText);
|
|
||||||
int indexSeries = Integer.parseInt(seriesText);
|
|
||||||
int indexAnnexVersion = Integer.parseInt(versionText);
|
|
||||||
|
|
||||||
IsdaIndexCreditCurveInputsId id = IsdaIndexCreditCurveInputsId.of(
|
|
||||||
IndexReferenceInformation.of(
|
|
||||||
indexId,
|
|
||||||
indexSeries,
|
|
||||||
indexAnnexVersion));
|
|
||||||
|
|
||||||
Tenor term = Tenor.parse(termText);
|
|
||||||
LocalDate maturity = LocalDate.parse(maturityText, DATE_FORMAT);
|
|
||||||
|
|
||||||
double spread;
|
|
||||||
if (compositeSpreadText.isEmpty()) {
|
|
||||||
if (modelSpreadText.isEmpty()) {
|
|
||||||
// there is no rate for this row, continue
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
// fall back to the model rate is the composite is missing
|
|
||||||
spread = parseRate(modelSpreadText);
|
|
||||||
} else {
|
|
||||||
// prefer the composite rate if it is present
|
|
||||||
spread = parseRate(compositeSpreadText);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<Point> points = curveData.get(id);
|
public String getColumnName() {
|
||||||
if (points == null) {
|
return columnName;
|
||||||
points = Lists.newArrayList();
|
}
|
||||||
curveData.put(id, points);
|
|
||||||
}
|
|
||||||
points.add(new Point(term, maturity, spread));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IsdaIndexCreditCurveInputsId curveId : curveData.keySet()) {
|
/**
|
||||||
MarkitRedCode redCode = MarkitRedCode.from(curveId.getReferenceInformation().getIndexId());
|
* Parses the specified sources.
|
||||||
StaticData staticData = staticDataMap.get(redCode);
|
*
|
||||||
ArgChecker.notNull(staticData, "Did not find a static data record for " + redCode);
|
* @param builder the market data builder that the resulting curve and recovery rate items should be loaded into
|
||||||
CdsConvention convention = staticData.getConvention();
|
* @param curveSource the source of curve data to parse
|
||||||
double recoveryRate = staticData.getRecoveryRate();
|
* @param staticDataSource the source of static data to parse
|
||||||
double indexFactor = staticData.getIndexFactor();
|
*/
|
||||||
// TODO add fromDate handling
|
public static void parse(
|
||||||
|
ImmutableMarketDataBuilder builder,
|
||||||
|
CharSource curveSource,
|
||||||
|
CharSource staticDataSource) {
|
||||||
|
|
||||||
String creditCurveName = curveId.toString();
|
Map<IsdaIndexCreditCurveInputsId, List<Point>> curveData = Maps.newHashMap();
|
||||||
|
Map<MarkitRedCode, StaticData> staticDataMap = parseStaticData(staticDataSource);
|
||||||
|
|
||||||
List<Point> points = curveData.get(curveId);
|
CsvFile csv = CsvFile.of(curveSource, true);
|
||||||
|
for (CsvRow row : csv.rows()) {
|
||||||
|
String seriesText = row.getField(Columns.Series.getColumnName());
|
||||||
|
String versionText = row.getField(Columns.Version.getColumnName());
|
||||||
|
String termText = row.getField(Columns.Term.getColumnName());
|
||||||
|
String redCodeText = row.getField(Columns.RedCode.getColumnName());
|
||||||
|
String maturityText = row.getField(Columns.Maturity.getColumnName());
|
||||||
|
String compositeSpreadText = row.getField(Columns.CompositeSpread.getColumnName());
|
||||||
|
String modelSpreadText = row.getField(Columns.ModelSpread.getColumnName());
|
||||||
|
|
||||||
Period[] periods = points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new);
|
StandardId indexId = MarkitRedCode.id(redCodeText);
|
||||||
LocalDate[] endDates = points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new);
|
int indexSeries = Integer.parseInt(seriesText);
|
||||||
double[] rates = points.stream().mapToDouble(s -> s.getRate()).toArray();
|
int indexAnnexVersion = Integer.parseInt(versionText);
|
||||||
|
|
||||||
IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of(
|
IsdaIndexCreditCurveInputsId id = IsdaIndexCreditCurveInputsId.of(
|
||||||
CurveName.of(creditCurveName),
|
IndexReferenceInformation.of(
|
||||||
periods,
|
indexId,
|
||||||
endDates,
|
indexSeries,
|
||||||
rates,
|
indexAnnexVersion));
|
||||||
convention,
|
|
||||||
indexFactor);
|
|
||||||
|
|
||||||
builder.addValue(curveId, curveInputs);
|
Tenor term = Tenor.parse(termText);
|
||||||
|
LocalDate maturity = LocalDate.parse(maturityText, DATE_FORMAT);
|
||||||
|
|
||||||
IsdaIndexRecoveryRateId recoveryRateId = IsdaIndexRecoveryRateId.of(curveId.getReferenceInformation());
|
double spread;
|
||||||
CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate);
|
if (compositeSpreadText.isEmpty()) {
|
||||||
|
if (modelSpreadText.isEmpty()) {
|
||||||
|
// there is no rate for this row, continue
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// fall back to the model rate is the composite is missing
|
||||||
|
spread = parseRate(modelSpreadText);
|
||||||
|
} else {
|
||||||
|
// prefer the composite rate if it is present
|
||||||
|
spread = parseRate(compositeSpreadText);
|
||||||
|
}
|
||||||
|
|
||||||
builder.addValue(recoveryRateId, cdsRecoveryRate);
|
List<Point> points = curveData.get(id);
|
||||||
}
|
if (points == null) {
|
||||||
}
|
points = Lists.newArrayList();
|
||||||
|
curveData.put(id, points);
|
||||||
|
}
|
||||||
|
points.add(new Point(term, maturity, spread));
|
||||||
|
}
|
||||||
|
|
||||||
// parses the static data file
|
for (IsdaIndexCreditCurveInputsId curveId : curveData.keySet()) {
|
||||||
private static Map<MarkitRedCode, StaticData> parseStaticData(CharSource source) {
|
MarkitRedCode redCode = MarkitRedCode.from(curveId.getReferenceInformation().getIndexId());
|
||||||
CsvFile csv = CsvFile.of(source, true);
|
StaticData staticData = staticDataMap.get(redCode);
|
||||||
|
ArgChecker.notNull(staticData, "Did not find a static data record for " + redCode);
|
||||||
|
CdsConvention convention = staticData.getConvention();
|
||||||
|
double recoveryRate = staticData.getRecoveryRate();
|
||||||
|
double indexFactor = staticData.getIndexFactor();
|
||||||
|
// TODO add fromDate handling
|
||||||
|
|
||||||
Map<MarkitRedCode, StaticData> result = Maps.newHashMap();
|
String creditCurveName = curveId.toString();
|
||||||
for (CsvRow row : csv.rows()) {
|
|
||||||
String redCodeText = row.getField("RedCode");
|
|
||||||
String fromDateText = row.getField("From Date");
|
|
||||||
String conventionText = row.getField("Convention");
|
|
||||||
String recoveryRateText = row.getField("Recovery Rate");
|
|
||||||
String indexFactorText = row.getField("Index Factor");
|
|
||||||
|
|
||||||
MarkitRedCode redCode = MarkitRedCode.of(redCodeText);
|
List<Point> points = curveData.get(curveId);
|
||||||
LocalDate fromDate = LocalDate.parse(fromDateText, DATE_FORMAT);
|
|
||||||
CdsConvention convention = CdsConvention.of(conventionText);
|
|
||||||
double recoveryRate = parseRate(recoveryRateText);
|
|
||||||
double indexFactor = Double.parseDouble(indexFactorText);
|
|
||||||
|
|
||||||
result.put(redCode, new StaticData(fromDate, convention, recoveryRate, indexFactor));
|
Period[] periods = points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new);
|
||||||
}
|
LocalDate[] endDates = points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new);
|
||||||
return result;
|
double[] rates = points.stream().mapToDouble(s -> s.getRate()).toArray();
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of(
|
||||||
/**
|
CurveName.of(creditCurveName),
|
||||||
* Stores the parsed static data.
|
periods,
|
||||||
*/
|
endDates,
|
||||||
private static class StaticData {
|
rates,
|
||||||
|
convention,
|
||||||
|
indexFactor);
|
||||||
|
|
||||||
private LocalDate fromDate;
|
builder.addValue(curveId, curveInputs);
|
||||||
private CdsConvention convention;
|
|
||||||
private double recoveryRate;
|
|
||||||
private double indexFactor;
|
|
||||||
|
|
||||||
private StaticData(LocalDate fromDate, CdsConvention convention, double recoveryRate, double indexFactor) {
|
IsdaIndexRecoveryRateId recoveryRateId = IsdaIndexRecoveryRateId.of(curveId.getReferenceInformation());
|
||||||
this.fromDate = fromDate;
|
CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate);
|
||||||
this.convention = convention;
|
|
||||||
this.recoveryRate = recoveryRate;
|
builder.addValue(recoveryRateId, cdsRecoveryRate);
|
||||||
this.indexFactor = indexFactor;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
// parses the static data file
|
||||||
public LocalDate getFromDate() {
|
private static Map<MarkitRedCode, StaticData> parseStaticData(CharSource source) {
|
||||||
return fromDate;
|
CsvFile csv = CsvFile.of(source, true);
|
||||||
|
|
||||||
|
Map<MarkitRedCode, StaticData> result = Maps.newHashMap();
|
||||||
|
for (CsvRow row : csv.rows()) {
|
||||||
|
String redCodeText = row.getField("RedCode");
|
||||||
|
String fromDateText = row.getField("From Date");
|
||||||
|
String conventionText = row.getField("Convention");
|
||||||
|
String recoveryRateText = row.getField("Recovery Rate");
|
||||||
|
String indexFactorText = row.getField("Index Factor");
|
||||||
|
|
||||||
|
MarkitRedCode redCode = MarkitRedCode.of(redCodeText);
|
||||||
|
LocalDate fromDate = LocalDate.parse(fromDateText, DATE_FORMAT);
|
||||||
|
CdsConvention convention = CdsConvention.of(conventionText);
|
||||||
|
double recoveryRate = parseRate(recoveryRateText);
|
||||||
|
double indexFactor = Double.parseDouble(indexFactorText);
|
||||||
|
|
||||||
|
result.put(redCode, new StaticData(fromDate, convention, recoveryRate, indexFactor));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CdsConvention getConvention() {
|
//-------------------------------------------------------------------------
|
||||||
return convention;
|
|
||||||
|
/**
|
||||||
|
* Stores the parsed static data.
|
||||||
|
*/
|
||||||
|
private static class StaticData {
|
||||||
|
|
||||||
|
private LocalDate fromDate;
|
||||||
|
private CdsConvention convention;
|
||||||
|
private double recoveryRate;
|
||||||
|
private double indexFactor;
|
||||||
|
|
||||||
|
private StaticData(LocalDate fromDate, CdsConvention convention, double recoveryRate, double indexFactor) {
|
||||||
|
this.fromDate = fromDate;
|
||||||
|
this.convention = convention;
|
||||||
|
this.recoveryRate = recoveryRate;
|
||||||
|
this.indexFactor = indexFactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public LocalDate getFromDate() {
|
||||||
|
return fromDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CdsConvention getConvention() {
|
||||||
|
return convention;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getRecoveryRate() {
|
||||||
|
return recoveryRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getIndexFactor() {
|
||||||
|
return indexFactor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getRecoveryRate() {
|
//-------------------------------------------------------------------------
|
||||||
return recoveryRate;
|
|
||||||
|
/**
|
||||||
|
* Stores the parsed data points.
|
||||||
|
*/
|
||||||
|
private static class Point {
|
||||||
|
private final Tenor tenor;
|
||||||
|
|
||||||
|
private final LocalDate date;
|
||||||
|
|
||||||
|
private final double rate;
|
||||||
|
|
||||||
|
private Point(Tenor tenor, LocalDate date, double rate) {
|
||||||
|
this.tenor = tenor;
|
||||||
|
this.date = date;
|
||||||
|
this.rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Tenor getTenor() {
|
||||||
|
return tenor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getRate() {
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public double getIndexFactor() {
|
// Converts from a string percentage rate with a percent sign to a double rate
|
||||||
return indexFactor;
|
// e.g. 0.12% => 0.0012d
|
||||||
|
private static double parseRate(String input) {
|
||||||
|
return Double.parseDouble(input.replace("%", "")) / 100d;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Stores the parsed data points.
|
|
||||||
*/
|
|
||||||
private static class Point {
|
|
||||||
private final Tenor tenor;
|
|
||||||
|
|
||||||
private final LocalDate date;
|
|
||||||
|
|
||||||
private final double rate;
|
|
||||||
|
|
||||||
private Point(Tenor tenor, LocalDate date, double rate) {
|
|
||||||
this.tenor = tenor;
|
|
||||||
this.date = date;
|
|
||||||
this.rate = rate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Tenor getTenor() {
|
|
||||||
return tenor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getDate() {
|
|
||||||
return date;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getRate() {
|
|
||||||
return rate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts from a string percentage rate with a percent sign to a double rate
|
|
||||||
// e.g. 0.12% => 0.0012d
|
|
||||||
private static double parseRate(String input) {
|
|
||||||
return Double.parseDouble(input.replace("%", "")) / 100d;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata.credit.markit;
|
package com.opengamma.strata.examples.marketdata.credit.markit;
|
||||||
@ -19,72 +19,74 @@ import org.joda.convert.FromString;
|
|||||||
* http://www.markit.com/product/reference-data-cds
|
* http://www.markit.com/product/reference-data-cds
|
||||||
*/
|
*/
|
||||||
public final class MarkitRedCode
|
public final class MarkitRedCode
|
||||||
extends TypedString<MarkitRedCode> {
|
extends TypedString<MarkitRedCode> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serialization version.
|
* Serialization version.
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Scheme used in an OpenGamma {@link StandardId} where the value is a Markit RED code.
|
* Scheme used in an OpenGamma {@link StandardId} where the value is a Markit RED code.
|
||||||
*/
|
*/
|
||||||
public static final String MARKIT_REDCODE_SCHEME = "MarkitRedCode";
|
public static final String MARKIT_REDCODE_SCHEME = "MarkitRedCode";
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
/**
|
|
||||||
* Obtains an instance from the specified name.
|
|
||||||
* <p>
|
|
||||||
* RED codes must be 6 or 9 characters long.
|
|
||||||
*
|
|
||||||
* @param name the name of the field
|
|
||||||
* @return a RED code
|
|
||||||
*/
|
|
||||||
@FromString
|
|
||||||
public static MarkitRedCode of(String name) {
|
|
||||||
ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters");
|
|
||||||
return new MarkitRedCode(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts from a standard identifier ensuring the scheme is correct.
|
* Obtains an instance from the specified name.
|
||||||
*
|
* <p>
|
||||||
* @param id standard id identifying a RED code
|
* RED codes must be 6 or 9 characters long.
|
||||||
* @return the equivalent RED code
|
*
|
||||||
*/
|
* @param name the name of the field
|
||||||
public static MarkitRedCode from(StandardId id) {
|
* @return a RED code
|
||||||
Preconditions.checkArgument(id.getScheme().equals(MARKIT_REDCODE_SCHEME));
|
*/
|
||||||
return MarkitRedCode.of(id.getValue());
|
@FromString
|
||||||
}
|
public static MarkitRedCode of(String name) {
|
||||||
|
ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters");
|
||||||
|
return new MarkitRedCode(name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a standard identifier using the correct Markit RED code scheme.
|
* Converts from a standard identifier ensuring the scheme is correct.
|
||||||
*
|
*
|
||||||
* @param name the Markit RED code, 6 or 9 characters long
|
* @param id standard id identifying a RED code
|
||||||
* @return the equivalent standard identifier
|
* @return the equivalent RED code
|
||||||
*/
|
*/
|
||||||
public static StandardId id(String name) {
|
public static MarkitRedCode from(StandardId id) {
|
||||||
ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters");
|
Preconditions.checkArgument(id.getScheme().equals(MARKIT_REDCODE_SCHEME));
|
||||||
return StandardId.of(MARKIT_REDCODE_SCHEME, name);
|
return MarkitRedCode.of(id.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance.
|
* Creates a standard identifier using the correct Markit RED code scheme.
|
||||||
*
|
*
|
||||||
* @param name the RED code
|
* @param name the Markit RED code, 6 or 9 characters long
|
||||||
*/
|
* @return the equivalent standard identifier
|
||||||
private MarkitRedCode(String name) {
|
*/
|
||||||
super(name);
|
public static StandardId id(String name) {
|
||||||
}
|
ArgChecker.isTrue(name.length() == 6 || name.length() == 9, "RED Code must be exactly 6 or 9 characters");
|
||||||
|
return StandardId.of(MARKIT_REDCODE_SCHEME, name);
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
/**
|
||||||
/**
|
* Creates an instance.
|
||||||
* Converts this RED code to a standard identifier.
|
*
|
||||||
*
|
* @param name the RED code
|
||||||
* @return the standard identifier
|
*/
|
||||||
*/
|
private MarkitRedCode(String name) {
|
||||||
public StandardId toStandardId() {
|
super(name);
|
||||||
return StandardId.of(MARKIT_REDCODE_SCHEME, getName());
|
}
|
||||||
}
|
|
||||||
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts this RED code to a standard identifier.
|
||||||
|
*
|
||||||
|
* @return the standard identifier
|
||||||
|
*/
|
||||||
|
public StandardId toStandardId() {
|
||||||
|
return StandardId.of(MARKIT_REDCODE_SCHEME, getName());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata.credit.markit;
|
package com.opengamma.strata.examples.marketdata.credit.markit;
|
||||||
@ -14,96 +14,97 @@ import com.opengamma.strata.product.credit.RestructuringClause;
|
|||||||
*/
|
*/
|
||||||
public enum MarkitRestructuringClause {
|
public enum MarkitRestructuringClause {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Modified-Modified Restructuring 2003.
|
* Modified-Modified Restructuring 2003.
|
||||||
*/
|
*/
|
||||||
MM,
|
MM,
|
||||||
/**
|
/**
|
||||||
* Modified-Modified Restructuring 2014.
|
* Modified-Modified Restructuring 2014.
|
||||||
*/
|
*/
|
||||||
MM14,
|
MM14,
|
||||||
/**
|
/**
|
||||||
* Modified Restructuring 2003.
|
* Modified Restructuring 2003.
|
||||||
*/
|
*/
|
||||||
MR,
|
MR,
|
||||||
/**
|
/**
|
||||||
* Modified Restructuring 2014.
|
* Modified Restructuring 2014.
|
||||||
*/
|
*/
|
||||||
MR14,
|
MR14,
|
||||||
/**
|
/**
|
||||||
* Cum/Old/Full Restructuring 2003.
|
* Cum/Old/Full Restructuring 2003.
|
||||||
*/
|
*/
|
||||||
CR,
|
CR,
|
||||||
/**
|
/**
|
||||||
* Cum/Old/Full Restructuring 2014.
|
* Cum/Old/Full Restructuring 2014.
|
||||||
*/
|
*/
|
||||||
CR14,
|
CR14,
|
||||||
/**
|
/**
|
||||||
* Ex/No restructuring 2003.
|
* Ex/No restructuring 2003.
|
||||||
*/
|
*/
|
||||||
XR,
|
XR,
|
||||||
/**
|
/**
|
||||||
* Ex/No restructuring 2014.
|
* Ex/No restructuring 2014.
|
||||||
*/
|
*/
|
||||||
XR14;
|
XR14;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
/**
|
|
||||||
* Converts Markit code to standard restructuring clause.
|
/**
|
||||||
*
|
* Converts Markit code to standard restructuring clause.
|
||||||
* @return the converted clause
|
*
|
||||||
*/
|
* @return the converted clause
|
||||||
public RestructuringClause translate() {
|
*/
|
||||||
switch (this) {
|
public RestructuringClause translate() {
|
||||||
case MM:
|
switch (this) {
|
||||||
return RestructuringClause.MOD_MOD_RESTRUCTURING_2003;
|
case MM:
|
||||||
case MM14:
|
return RestructuringClause.MOD_MOD_RESTRUCTURING_2003;
|
||||||
return RestructuringClause.MOD_MOD_RESTRUCTURING_2014;
|
case MM14:
|
||||||
case MR:
|
return RestructuringClause.MOD_MOD_RESTRUCTURING_2014;
|
||||||
return RestructuringClause.MODIFIED_RESTRUCTURING_2003;
|
case MR:
|
||||||
case MR14:
|
return RestructuringClause.MODIFIED_RESTRUCTURING_2003;
|
||||||
return RestructuringClause.MODIFIED_RESTRUCTURING_2014;
|
case MR14:
|
||||||
case CR:
|
return RestructuringClause.MODIFIED_RESTRUCTURING_2014;
|
||||||
return RestructuringClause.CUM_RESTRUCTURING_2003;
|
case CR:
|
||||||
case CR14:
|
return RestructuringClause.CUM_RESTRUCTURING_2003;
|
||||||
return RestructuringClause.CUM_RESTRUCTURING_2014;
|
case CR14:
|
||||||
case XR:
|
return RestructuringClause.CUM_RESTRUCTURING_2014;
|
||||||
return RestructuringClause.NO_RESTRUCTURING_2003;
|
case XR:
|
||||||
case XR14:
|
return RestructuringClause.NO_RESTRUCTURING_2003;
|
||||||
return RestructuringClause.NO_RESTRUCTURING_2014;
|
case XR14:
|
||||||
default:
|
return RestructuringClause.NO_RESTRUCTURING_2014;
|
||||||
throw new IllegalStateException("Unmapped restructuring clause. Do not have mapping for " + this);
|
default:
|
||||||
|
throw new IllegalStateException("Unmapped restructuring clause. Do not have mapping for " + this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts restructuring clause to Markit equivalent.
|
* Converts restructuring clause to Markit equivalent.
|
||||||
*
|
*
|
||||||
* @param restructuringClause the clause to convert
|
* @param restructuringClause the clause to convert
|
||||||
* @return the converted clause
|
* @return the converted clause
|
||||||
*/
|
*/
|
||||||
public static MarkitRestructuringClause from(RestructuringClause restructuringClause) {
|
public static MarkitRestructuringClause from(RestructuringClause restructuringClause) {
|
||||||
switch (restructuringClause) {
|
switch (restructuringClause) {
|
||||||
case MOD_MOD_RESTRUCTURING_2003:
|
case MOD_MOD_RESTRUCTURING_2003:
|
||||||
return MM;
|
return MM;
|
||||||
case MOD_MOD_RESTRUCTURING_2014:
|
case MOD_MOD_RESTRUCTURING_2014:
|
||||||
return MM14;
|
return MM14;
|
||||||
case MODIFIED_RESTRUCTURING_2003:
|
case MODIFIED_RESTRUCTURING_2003:
|
||||||
return MR;
|
return MR;
|
||||||
case MODIFIED_RESTRUCTURING_2014:
|
case MODIFIED_RESTRUCTURING_2014:
|
||||||
return MR14;
|
return MR14;
|
||||||
case CUM_RESTRUCTURING_2003:
|
case CUM_RESTRUCTURING_2003:
|
||||||
return CR;
|
return CR;
|
||||||
case CUM_RESTRUCTURING_2014:
|
case CUM_RESTRUCTURING_2014:
|
||||||
return CR14;
|
return CR14;
|
||||||
case NO_RESTRUCTURING_2003:
|
case NO_RESTRUCTURING_2003:
|
||||||
return XR;
|
return XR;
|
||||||
case NO_RESTRUCTURING_2014:
|
case NO_RESTRUCTURING_2014:
|
||||||
return XR14;
|
return XR14;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("Unknown restructuring clause. Do not have mapping for " + restructuringClause);
|
throw new UnsupportedOperationException("Unknown restructuring clause. Do not have mapping for " + restructuringClause);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata.credit.markit;
|
package com.opengamma.strata.examples.marketdata.credit.markit;
|
||||||
@ -14,75 +14,76 @@ import com.opengamma.strata.product.credit.SeniorityLevel;
|
|||||||
*/
|
*/
|
||||||
public enum MarkitSeniorityLevel {
|
public enum MarkitSeniorityLevel {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Senior domestic.
|
* Senior domestic.
|
||||||
*/
|
*/
|
||||||
SECDOM,
|
SECDOM,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Senior foreign.
|
* Senior foreign.
|
||||||
*/
|
*/
|
||||||
SNRFOR,
|
SNRFOR,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subordinate, Lower Tier 2.
|
* Subordinate, Lower Tier 2.
|
||||||
*/
|
*/
|
||||||
SUBLT2,
|
SUBLT2,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subordinate Tier 1.
|
* Subordinate Tier 1.
|
||||||
*/
|
*/
|
||||||
PREFT1,
|
PREFT1,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subordinate, Upper Tier 2.
|
* Subordinate, Upper Tier 2.
|
||||||
*/
|
*/
|
||||||
JRSUBUT2;
|
JRSUBUT2;
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
/**
|
|
||||||
* Converts Markit code to standard seniority level.
|
/**
|
||||||
*
|
* Converts Markit code to standard seniority level.
|
||||||
* @return the converted level
|
*
|
||||||
*/
|
* @return the converted level
|
||||||
public SeniorityLevel translate() {
|
*/
|
||||||
switch (this) {
|
public SeniorityLevel translate() {
|
||||||
case SECDOM:
|
switch (this) {
|
||||||
return SeniorityLevel.SENIOR_SECURED_DOMESTIC;
|
case SECDOM:
|
||||||
case SNRFOR:
|
return SeniorityLevel.SENIOR_SECURED_DOMESTIC;
|
||||||
return SeniorityLevel.SENIOR_UNSECURED_FOREIGN;
|
case SNRFOR:
|
||||||
case SUBLT2:
|
return SeniorityLevel.SENIOR_UNSECURED_FOREIGN;
|
||||||
return SeniorityLevel.SUBORDINATE_LOWER_TIER_2;
|
case SUBLT2:
|
||||||
case PREFT1:
|
return SeniorityLevel.SUBORDINATE_LOWER_TIER_2;
|
||||||
return SeniorityLevel.SUBORDINATE_TIER_1;
|
case PREFT1:
|
||||||
case JRSUBUT2:
|
return SeniorityLevel.SUBORDINATE_TIER_1;
|
||||||
return SeniorityLevel.SUBORDINATE_UPPER_TIER_2;
|
case JRSUBUT2:
|
||||||
default:
|
return SeniorityLevel.SUBORDINATE_UPPER_TIER_2;
|
||||||
throw new IllegalStateException("Unmapped seniority level. Do not have mapping for " + this);
|
default:
|
||||||
|
throw new IllegalStateException("Unmapped seniority level. Do not have mapping for " + this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts seniority level to Markit equivalent.
|
* Converts seniority level to Markit equivalent.
|
||||||
*
|
*
|
||||||
* @param seniorityLevel the level to convert
|
* @param seniorityLevel the level to convert
|
||||||
* @return the converted level
|
* @return the converted level
|
||||||
*/
|
*/
|
||||||
public static MarkitSeniorityLevel from(SeniorityLevel seniorityLevel) {
|
public static MarkitSeniorityLevel from(SeniorityLevel seniorityLevel) {
|
||||||
switch (seniorityLevel) {
|
switch (seniorityLevel) {
|
||||||
case SENIOR_SECURED_DOMESTIC:
|
case SENIOR_SECURED_DOMESTIC:
|
||||||
return SECDOM;
|
return SECDOM;
|
||||||
case SENIOR_UNSECURED_FOREIGN:
|
case SENIOR_UNSECURED_FOREIGN:
|
||||||
return SNRFOR;
|
return SNRFOR;
|
||||||
case SUBORDINATE_LOWER_TIER_2:
|
case SUBORDINATE_LOWER_TIER_2:
|
||||||
return SUBLT2;
|
return SUBLT2;
|
||||||
case SUBORDINATE_TIER_1:
|
case SUBORDINATE_TIER_1:
|
||||||
return PREFT1;
|
return PREFT1;
|
||||||
case SUBORDINATE_UPPER_TIER_2:
|
case SUBORDINATE_UPPER_TIER_2:
|
||||||
return JRSUBUT2;
|
return JRSUBUT2;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Unknown seniority level. Do not have mapping for " + seniorityLevel);
|
throw new IllegalArgumentException("Unknown seniority level. Do not have mapping for " + seniorityLevel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata.credit.markit;
|
package com.opengamma.strata.examples.marketdata.credit.markit;
|
||||||
@ -56,141 +56,141 @@ import java.util.Scanner;
|
|||||||
*/
|
*/
|
||||||
public class MarkitSingleNameCreditCurveDataParser {
|
public class MarkitSingleNameCreditCurveDataParser {
|
||||||
|
|
||||||
// Markit date format with the month in full caps. e.g. 11-JUL-14
|
// Markit date format with the month in full caps. e.g. 11-JUL-14
|
||||||
private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
|
private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
|
||||||
.parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH);
|
.parseCaseInsensitive().appendPattern("dd-MMM-uu").toFormatter(Locale.ENGLISH);
|
||||||
|
|
||||||
// Index used to access the specified columns of string data in the file
|
// Index used to access the specified columns of string data in the file
|
||||||
private static final int DATE = 0;
|
private static final int DATE = 0;
|
||||||
private static final int RED_CODE = 3;
|
private static final int RED_CODE = 3;
|
||||||
private static final int TIER = 4;
|
private static final int TIER = 4;
|
||||||
private static final int CURRENCY = 5;
|
private static final int CURRENCY = 5;
|
||||||
private static final int DOCS_CLAUSE = 6;
|
private static final int DOCS_CLAUSE = 6;
|
||||||
private static final int FIRST_SPREAD_COLUMN = 8;
|
private static final int FIRST_SPREAD_COLUMN = 8;
|
||||||
private static final int RECOVERY = 19;
|
private static final int RECOVERY = 19;
|
||||||
|
|
||||||
private static final List<Tenor> TENORS = ImmutableList.of(
|
private static final List<Tenor> TENORS = ImmutableList.of(
|
||||||
Tenor.TENOR_6M,
|
Tenor.TENOR_6M,
|
||||||
Tenor.TENOR_1Y,
|
Tenor.TENOR_1Y,
|
||||||
Tenor.TENOR_2Y,
|
Tenor.TENOR_2Y,
|
||||||
Tenor.TENOR_3Y,
|
Tenor.TENOR_3Y,
|
||||||
Tenor.TENOR_4Y,
|
Tenor.TENOR_4Y,
|
||||||
Tenor.TENOR_5Y,
|
Tenor.TENOR_5Y,
|
||||||
Tenor.TENOR_7Y,
|
Tenor.TENOR_7Y,
|
||||||
Tenor.TENOR_10Y,
|
Tenor.TENOR_10Y,
|
||||||
Tenor.TENOR_15Y,
|
Tenor.TENOR_15Y,
|
||||||
Tenor.TENOR_20Y,
|
Tenor.TENOR_20Y,
|
||||||
Tenor.TENOR_30Y);
|
Tenor.TENOR_30Y);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the specified sources.
|
* Parses the specified sources.
|
||||||
*
|
*
|
||||||
* @param builder the market data builder that the resulting curve and recovery rate items should be loaded into
|
* @param builder the market data builder that the resulting curve and recovery rate items should be loaded into
|
||||||
* @param curveSource the source of curve data to parse
|
* @param curveSource the source of curve data to parse
|
||||||
* @param staticDataSource the source of static data to parse
|
* @param staticDataSource the source of static data to parse
|
||||||
*/
|
*/
|
||||||
public static void parse(
|
public static void parse(
|
||||||
ImmutableMarketDataBuilder builder,
|
ImmutableMarketDataBuilder builder,
|
||||||
CharSource curveSource,
|
CharSource curveSource,
|
||||||
CharSource staticDataSource) {
|
CharSource staticDataSource) {
|
||||||
|
|
||||||
Map<MarkitRedCode, CdsConvention> conventions = parseStaticData(staticDataSource);
|
Map<MarkitRedCode, CdsConvention> conventions = parseStaticData(staticDataSource);
|
||||||
try (Scanner scanner = new Scanner(curveSource.openStream())) {
|
try (Scanner scanner = new Scanner(curveSource.openStream())) {
|
||||||
while (scanner.hasNextLine()) {
|
while (scanner.hasNextLine()) {
|
||||||
|
|
||||||
String line = scanner.nextLine();
|
String line = scanner.nextLine();
|
||||||
// skip over header rows
|
// skip over header rows
|
||||||
if (line.startsWith("V5 CDS Composites by Convention") ||
|
if (line.startsWith("V5 CDS Composites by Convention") ||
|
||||||
line.trim().isEmpty() ||
|
line.trim().isEmpty() ||
|
||||||
line.startsWith("\"Date\",")) {
|
line.startsWith("\"Date\",")) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
String[] columns = line.split(",");
|
||||||
|
for (int i = 0; i < columns.length; i++) {
|
||||||
|
// get rid of quotes and trim the string
|
||||||
|
columns[i] = columns[i].replaceFirst("^\"", "").replaceFirst("\"$", "").trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalDate valuationDate = LocalDate.parse(columns[DATE], DATE_FORMAT);
|
||||||
|
|
||||||
|
MarkitRedCode redCode = MarkitRedCode.of(columns[RED_CODE]);
|
||||||
|
SeniorityLevel seniorityLevel = MarkitSeniorityLevel.valueOf(columns[TIER]).translate();
|
||||||
|
Currency currency = Currency.parse(columns[CURRENCY]);
|
||||||
|
RestructuringClause restructuringClause = MarkitRestructuringClause.valueOf(columns[DOCS_CLAUSE]).translate();
|
||||||
|
|
||||||
|
double recoveryRate = parseRate(columns[RECOVERY]);
|
||||||
|
|
||||||
|
SingleNameReferenceInformation referenceInformation = SingleNameReferenceInformation.of(
|
||||||
|
redCode.toStandardId(),
|
||||||
|
seniorityLevel,
|
||||||
|
currency,
|
||||||
|
restructuringClause);
|
||||||
|
|
||||||
|
IsdaSingleNameCreditCurveInputsId curveId = IsdaSingleNameCreditCurveInputsId.of(referenceInformation);
|
||||||
|
|
||||||
|
List<Period> periodsList = Lists.newArrayList();
|
||||||
|
List<Double> ratesList = Lists.newArrayList();
|
||||||
|
for (int i = 0; i < TENORS.size(); i++) {
|
||||||
|
String rateString = columns[FIRST_SPREAD_COLUMN + i];
|
||||||
|
if (rateString.isEmpty()) {
|
||||||
|
// no data at this point
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
periodsList.add(TENORS.get(i).getPeriod());
|
||||||
|
ratesList.add(parseRate(rateString));
|
||||||
|
}
|
||||||
|
|
||||||
|
String creditCurveName = curveId.toString();
|
||||||
|
|
||||||
|
CdsConvention cdsConvention = conventions.get(redCode);
|
||||||
|
|
||||||
|
Period[] periods = periodsList.stream().toArray(Period[]::new);
|
||||||
|
LocalDate[] endDates = Lists
|
||||||
|
.newArrayList(periods)
|
||||||
|
.stream()
|
||||||
|
.map(p -> cdsConvention.calculateUnadjustedMaturityDateFromValuationDate(valuationDate, p))
|
||||||
|
.toArray(LocalDate[]::new);
|
||||||
|
|
||||||
|
double[] rates = ratesList.stream().mapToDouble(s -> s).toArray();
|
||||||
|
double unitScalingFactor = 1d; // for single name, we don't do any scaling (no index factor)
|
||||||
|
|
||||||
|
IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of(
|
||||||
|
CurveName.of(creditCurveName),
|
||||||
|
periods,
|
||||||
|
endDates,
|
||||||
|
rates,
|
||||||
|
cdsConvention,
|
||||||
|
unitScalingFactor);
|
||||||
|
|
||||||
|
builder.addValue(curveId, curveInputs);
|
||||||
|
|
||||||
|
IsdaSingleNameRecoveryRateId recoveryRateId = IsdaSingleNameRecoveryRateId.of(referenceInformation);
|
||||||
|
CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate);
|
||||||
|
|
||||||
|
builder.addValue(recoveryRateId, cdsRecoveryRate);
|
||||||
|
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new UncheckedIOException(ex);
|
||||||
}
|
}
|
||||||
String[] columns = line.split(",");
|
|
||||||
for (int i = 0; i < columns.length; i++) {
|
|
||||||
// get rid of quotes and trim the string
|
|
||||||
columns[i] = columns[i].replaceFirst("^\"", "").replaceFirst("\"$", "").trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
LocalDate valuationDate = LocalDate.parse(columns[DATE], DATE_FORMAT);
|
|
||||||
|
|
||||||
MarkitRedCode redCode = MarkitRedCode.of(columns[RED_CODE]);
|
|
||||||
SeniorityLevel seniorityLevel = MarkitSeniorityLevel.valueOf(columns[TIER]).translate();
|
|
||||||
Currency currency = Currency.parse(columns[CURRENCY]);
|
|
||||||
RestructuringClause restructuringClause = MarkitRestructuringClause.valueOf(columns[DOCS_CLAUSE]).translate();
|
|
||||||
|
|
||||||
double recoveryRate = parseRate(columns[RECOVERY]);
|
|
||||||
|
|
||||||
SingleNameReferenceInformation referenceInformation = SingleNameReferenceInformation.of(
|
|
||||||
redCode.toStandardId(),
|
|
||||||
seniorityLevel,
|
|
||||||
currency,
|
|
||||||
restructuringClause);
|
|
||||||
|
|
||||||
IsdaSingleNameCreditCurveInputsId curveId = IsdaSingleNameCreditCurveInputsId.of(referenceInformation);
|
|
||||||
|
|
||||||
List<Period> periodsList = Lists.newArrayList();
|
|
||||||
List<Double> ratesList = Lists.newArrayList();
|
|
||||||
for (int i = 0; i < TENORS.size(); i++) {
|
|
||||||
String rateString = columns[FIRST_SPREAD_COLUMN + i];
|
|
||||||
if (rateString.isEmpty()) {
|
|
||||||
// no data at this point
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
periodsList.add(TENORS.get(i).getPeriod());
|
|
||||||
ratesList.add(parseRate(rateString));
|
|
||||||
}
|
|
||||||
|
|
||||||
String creditCurveName = curveId.toString();
|
|
||||||
|
|
||||||
CdsConvention cdsConvention = conventions.get(redCode);
|
|
||||||
|
|
||||||
Period[] periods = periodsList.stream().toArray(Period[]::new);
|
|
||||||
LocalDate[] endDates = Lists
|
|
||||||
.newArrayList(periods)
|
|
||||||
.stream()
|
|
||||||
.map(p -> cdsConvention.calculateUnadjustedMaturityDateFromValuationDate(valuationDate, p))
|
|
||||||
.toArray(LocalDate[]::new);
|
|
||||||
|
|
||||||
double[] rates = ratesList.stream().mapToDouble(s -> s).toArray();
|
|
||||||
double unitScalingFactor = 1d; // for single name, we don't do any scaling (no index factor)
|
|
||||||
|
|
||||||
IsdaCreditCurveInputs curveInputs = IsdaCreditCurveInputs.of(
|
|
||||||
CurveName.of(creditCurveName),
|
|
||||||
periods,
|
|
||||||
endDates,
|
|
||||||
rates,
|
|
||||||
cdsConvention,
|
|
||||||
unitScalingFactor);
|
|
||||||
|
|
||||||
builder.addValue(curveId, curveInputs);
|
|
||||||
|
|
||||||
IsdaSingleNameRecoveryRateId recoveryRateId = IsdaSingleNameRecoveryRateId.of(referenceInformation);
|
|
||||||
CdsRecoveryRate cdsRecoveryRate = CdsRecoveryRate.of(recoveryRate);
|
|
||||||
|
|
||||||
builder.addValue(recoveryRateId, cdsRecoveryRate);
|
|
||||||
|
|
||||||
}
|
|
||||||
} catch (IOException ex) {
|
|
||||||
throw new UncheckedIOException(ex);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// parses the static data file of RED code to convention
|
// parses the static data file of RED code to convention
|
||||||
private static Map<MarkitRedCode, CdsConvention> parseStaticData(CharSource source) {
|
private static Map<MarkitRedCode, CdsConvention> parseStaticData(CharSource source) {
|
||||||
CsvFile csv = CsvFile.of(source, true);
|
CsvFile csv = CsvFile.of(source, true);
|
||||||
Map<MarkitRedCode, CdsConvention> result = Maps.newHashMap();
|
Map<MarkitRedCode, CdsConvention> result = Maps.newHashMap();
|
||||||
for (CsvRow row : csv.rows()) {
|
for (CsvRow row : csv.rows()) {
|
||||||
String redCodeText = row.getField("RedCode");
|
String redCodeText = row.getField("RedCode");
|
||||||
String conventionText = row.getField("Convention");
|
String conventionText = row.getField("Convention");
|
||||||
result.put(MarkitRedCode.of(redCodeText), CdsConvention.of(conventionText));
|
result.put(MarkitRedCode.of(redCodeText), CdsConvention.of(conventionText));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Converts from a string percentage rate with a percent sign to a double rate
|
// Converts from a string percentage rate with a percent sign to a double rate
|
||||||
// e.g. 0.12% => 0.0012d
|
// e.g. 0.12% => 0.0012d
|
||||||
private static double parseRate(String input) {
|
private static double parseRate(String input) {
|
||||||
return Double.parseDouble(input.replace("%", "")) / 100d;
|
return Double.parseDouble(input.replace("%", "")) / 100d;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2015 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
*/
|
*/
|
||||||
package com.opengamma.strata.examples.marketdata.credit.markit;
|
package com.opengamma.strata.examples.marketdata.credit.markit;
|
||||||
@ -31,104 +31,105 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class MarkitYieldCurveDataParser {
|
public class MarkitYieldCurveDataParser {
|
||||||
|
|
||||||
private static final String DATE = "Valuation Date";
|
private static final String DATE = "Valuation Date";
|
||||||
private static final String TENOR = "Tenor";
|
private static final String TENOR = "Tenor";
|
||||||
private static final String INSTRUMENT = "Instrument Type";
|
private static final String INSTRUMENT = "Instrument Type";
|
||||||
private static final String RATE = "Rate";
|
private static final String RATE = "Rate";
|
||||||
private static final String CONVENTION = "Curve Convention";
|
private static final String CONVENTION = "Curve Convention";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses the specified source.
|
* Parses the specified source.
|
||||||
*
|
*
|
||||||
* @param source the source to parse
|
* @param source the source to parse
|
||||||
* @return the map of parsed yield curve par rates
|
* @return the map of parsed yield curve par rates
|
||||||
*/
|
*/
|
||||||
public static Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> parse(CharSource source) {
|
public static Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> parse(CharSource source) {
|
||||||
// parse the curve data
|
// parse the curve data
|
||||||
Map<IsdaYieldCurveConvention, List<Point>> curveData = Maps.newHashMap();
|
Map<IsdaYieldCurveConvention, List<Point>> curveData = Maps.newHashMap();
|
||||||
CsvFile csv = CsvFile.of(source, true);
|
CsvFile csv = CsvFile.of(source, true);
|
||||||
for (CsvRow row : csv.rows()) {
|
for (CsvRow row : csv.rows()) {
|
||||||
String dateText = row.getField(DATE);
|
String dateText = row.getField(DATE);
|
||||||
String tenorText = row.getField(TENOR);
|
String tenorText = row.getField(TENOR);
|
||||||
String instrumentText = row.getField(INSTRUMENT);
|
String instrumentText = row.getField(INSTRUMENT);
|
||||||
String rateText = row.getField(RATE);
|
String rateText = row.getField(RATE);
|
||||||
String conventionText = row.getField(CONVENTION);
|
String conventionText = row.getField(CONVENTION);
|
||||||
|
|
||||||
Point point = new Point(
|
Point point = new Point(
|
||||||
Tenor.parse(tenorText),
|
Tenor.parse(tenorText),
|
||||||
LocalDate.parse(dateText, DateTimeFormatter.ISO_LOCAL_DATE),
|
LocalDate.parse(dateText, DateTimeFormatter.ISO_LOCAL_DATE),
|
||||||
mapUnderlyingType(instrumentText),
|
mapUnderlyingType(instrumentText),
|
||||||
Double.parseDouble(rateText));
|
Double.parseDouble(rateText));
|
||||||
IsdaYieldCurveConvention convention = IsdaYieldCurveConvention.of(conventionText);
|
IsdaYieldCurveConvention convention = IsdaYieldCurveConvention.of(conventionText);
|
||||||
|
|
||||||
List<Point> points = curveData.get(convention);
|
List<Point> points = curveData.get(convention);
|
||||||
if (points == null) {
|
if (points == null) {
|
||||||
points = Lists.newArrayList();
|
points = Lists.newArrayList();
|
||||||
curveData.put(convention, points);
|
curveData.put(convention, points);
|
||||||
}
|
}
|
||||||
points.add(point);
|
points.add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert the curve data into the result map
|
||||||
|
Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> result = Maps.newHashMap();
|
||||||
|
for (IsdaYieldCurveConvention convention : curveData.keySet()) {
|
||||||
|
List<Point> points = curveData.get(convention);
|
||||||
|
result.put(IsdaYieldCurveInputsId.of(convention.getCurrency()),
|
||||||
|
IsdaYieldCurveInputs.of(
|
||||||
|
CurveName.of(convention.getName()),
|
||||||
|
points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new),
|
||||||
|
points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new),
|
||||||
|
points.stream().map(s -> s.getInstrumentType()).toArray(IsdaYieldCurveUnderlyingType[]::new),
|
||||||
|
points.stream().mapToDouble(s -> s.getRate()).toArray(),
|
||||||
|
convention));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert the curve data into the result map
|
// parse the M/S instrument type flag
|
||||||
Map<IsdaYieldCurveInputsId, IsdaYieldCurveInputs> result = Maps.newHashMap();
|
private static IsdaYieldCurveUnderlyingType mapUnderlyingType(String type) {
|
||||||
for (IsdaYieldCurveConvention convention : curveData.keySet()) {
|
switch (type) {
|
||||||
List<Point> points = curveData.get(convention);
|
case "M":
|
||||||
result.put(IsdaYieldCurveInputsId.of(convention.getCurrency()),
|
return IsdaYieldCurveUnderlyingType.ISDA_MONEY_MARKET;
|
||||||
IsdaYieldCurveInputs.of(
|
case "S":
|
||||||
CurveName.of(convention.getName()),
|
return IsdaYieldCurveUnderlyingType.ISDA_SWAP;
|
||||||
points.stream().map(s -> s.getTenor().getPeriod()).toArray(Period[]::new),
|
default:
|
||||||
points.stream().map(s -> s.getDate()).toArray(LocalDate[]::new),
|
throw new IllegalStateException("Unknown underlying type, only M or S allowed: " + type);
|
||||||
points.stream().map(s -> s.getInstrumentType()).toArray(IsdaYieldCurveUnderlyingType[]::new),
|
}
|
||||||
points.stream().mapToDouble(s -> s.getRate()).toArray(),
|
|
||||||
convention));
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the M/S instrument type flag
|
|
||||||
private static IsdaYieldCurveUnderlyingType mapUnderlyingType(String type) {
|
|
||||||
switch (type) {
|
|
||||||
case "M":
|
|
||||||
return IsdaYieldCurveUnderlyingType.ISDA_MONEY_MARKET;
|
|
||||||
case "S":
|
|
||||||
return IsdaYieldCurveUnderlyingType.ISDA_SWAP;
|
|
||||||
default:
|
|
||||||
throw new IllegalStateException("Unknown underlying type, only M or S allowed: " + type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
|
||||||
/**
|
|
||||||
* Stores the parsed data points.
|
|
||||||
*/
|
|
||||||
private static class Point {
|
|
||||||
private final Tenor tenor;
|
|
||||||
private final LocalDate date;
|
|
||||||
private final IsdaYieldCurveUnderlyingType instrumentType;
|
|
||||||
private final double rate;
|
|
||||||
|
|
||||||
private Point(Tenor tenor, LocalDate baseDate, IsdaYieldCurveUnderlyingType instrumentType, double rate) {
|
|
||||||
this.tenor = tenor;
|
|
||||||
this.date = baseDate.plus(tenor.getPeriod());
|
|
||||||
this.instrumentType = instrumentType;
|
|
||||||
this.rate = rate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Tenor getTenor() {
|
//-------------------------------------------------------------------------
|
||||||
return tenor;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LocalDate getDate() {
|
/**
|
||||||
return date;
|
* Stores the parsed data points.
|
||||||
}
|
*/
|
||||||
|
private static class Point {
|
||||||
|
private final Tenor tenor;
|
||||||
|
private final LocalDate date;
|
||||||
|
private final IsdaYieldCurveUnderlyingType instrumentType;
|
||||||
|
private final double rate;
|
||||||
|
|
||||||
public IsdaYieldCurveUnderlyingType getInstrumentType() {
|
private Point(Tenor tenor, LocalDate baseDate, IsdaYieldCurveUnderlyingType instrumentType, double rate) {
|
||||||
return instrumentType;
|
this.tenor = tenor;
|
||||||
}
|
this.date = baseDate.plus(tenor.getPeriod());
|
||||||
|
this.instrumentType = instrumentType;
|
||||||
|
this.rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
public double getRate() {
|
public Tenor getTenor() {
|
||||||
return rate;
|
return tenor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LocalDate getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IsdaYieldCurveUnderlyingType getInstrumentType() {
|
||||||
|
return instrumentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getRate() {
|
||||||
|
return rate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
|
* <p>
|
||||||
|
* Credit market data for examples.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
|
* Copyright (C) 2016 - present by OpenGamma Inc. and the OpenGamma group of companies
|
||||||
*
|
* <p>
|
||||||
* Please see distribution for license.
|
* Please see distribution for license.
|
||||||
|
* <p>
|
||||||
|
* Market data for examples.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -254,13 +254,14 @@ class PortfolioApi(val rpc: CordaRPCOps) {
|
|||||||
val parties = rpc.networkMapSnapshot()
|
val parties = rpc.networkMapSnapshot()
|
||||||
val notaries = rpc.notaryIdentities()
|
val notaries = rpc.notaryIdentities()
|
||||||
// TODO We are not able to filter by network map node now
|
// TODO We are not able to filter by network map node now
|
||||||
val counterParties = parties.filterNot { it.legalIdentities.any { it in notaries }
|
val counterParties = parties.filterNot {
|
||||||
|| ownParty in it.legalIdentities
|
it.legalIdentities.any { it in notaries }
|
||||||
|
|| ownParty in it.legalIdentities
|
||||||
}
|
}
|
||||||
return AvailableParties(
|
return AvailableParties(
|
||||||
self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name),
|
self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name),
|
||||||
// TODO It will show all identities including service identities.
|
// TODO It will show all identities including service identities.
|
||||||
counterparties = counterParties.flatMap { it.legalIdentitiesAndCerts.map { ApiParty(it.owningKey.toBase58String(), it.name) }}
|
counterparties = counterParties.flatMap { it.legalIdentitiesAndCerts.map { ApiParty(it.owningKey.toBase58String(), it.name) } }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,7 @@ object SimmFlow {
|
|||||||
private val existing: StateAndRef<PortfolioState>?)
|
private val existing: StateAndRef<PortfolioState>?)
|
||||||
: FlowLogic<RevisionedState<PortfolioState.Update>>() {
|
: FlowLogic<RevisionedState<PortfolioState.Update>>() {
|
||||||
constructor(otherParty: Party, valuationDate: LocalDate) : this(otherParty, valuationDate, null)
|
constructor(otherParty: Party, valuationDate: LocalDate) : this(otherParty, valuationDate, null)
|
||||||
|
|
||||||
lateinit var notary: Party
|
lateinit var notary: Party
|
||||||
lateinit var otherPartySession: FlowSession
|
lateinit var otherPartySession: FlowSession
|
||||||
|
|
||||||
@ -318,7 +319,7 @@ object SimmFlow {
|
|||||||
logger.info("Handshake finished, awaiting Simm update")
|
logger.info("Handshake finished, awaiting Simm update")
|
||||||
replyToSession.send(Ack) // Hack to state that this party is ready.
|
replyToSession.send(Ack) // Hack to state that this party is ready.
|
||||||
subFlow(object : StateRevisionFlow.Receiver<PortfolioState.Update>(replyToSession) {
|
subFlow(object : StateRevisionFlow.Receiver<PortfolioState.Update>(replyToSession) {
|
||||||
override fun verifyProposal(stx:SignedTransaction, proposal: Proposal<PortfolioState.Update>) {
|
override fun verifyProposal(stx: SignedTransaction, proposal: Proposal<PortfolioState.Update>) {
|
||||||
super.verifyProposal(stx, proposal)
|
super.verifyProposal(stx, proposal)
|
||||||
if (proposal.modification.portfolio != portfolio.refs) throw StateReplacementException()
|
if (proposal.modification.portfolio != portfolio.refs) throw StateReplacementException()
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import net.corda.vega.contracts.RevisionedState
|
|||||||
*/
|
*/
|
||||||
object StateRevisionFlow {
|
object StateRevisionFlow {
|
||||||
open class Requester<T>(curStateRef: StateAndRef<RevisionedState<T>>,
|
open class Requester<T>(curStateRef: StateAndRef<RevisionedState<T>>,
|
||||||
updatedData: T) : AbstractStateReplacementFlow.Instigator<RevisionedState<T>, RevisionedState<T>, T>(curStateRef, updatedData) {
|
updatedData: T) : AbstractStateReplacementFlow.Instigator<RevisionedState<T>, RevisionedState<T>, T>(curStateRef, updatedData) {
|
||||||
override fun assembleTx(): AbstractStateReplacementFlow.UpgradeTx {
|
override fun assembleTx(): AbstractStateReplacementFlow.UpgradeTx {
|
||||||
val state = originalState.state.data
|
val state = originalState.state.data
|
||||||
val tx = state.generateRevision(originalState.state.notary, originalState, modification)
|
val tx = state.generateRevision(originalState.state.notary, originalState, modification)
|
||||||
|
@ -48,97 +48,97 @@ import static java.util.stream.Collectors.toList;
|
|||||||
*/
|
*/
|
||||||
public class SwapExampleX {
|
public class SwapExampleX {
|
||||||
|
|
||||||
public static final LocalDate VALUATION_DATE = LocalDate.of(2016, 6, 6);
|
public static final LocalDate VALUATION_DATE = LocalDate.of(2016, 6, 6);
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
CurveGroupDefinition curveGroupDefinition = loadCurveGroup();
|
CurveGroupDefinition curveGroupDefinition = loadCurveGroup();
|
||||||
MarketData marketData = loadMarketData();
|
MarketData marketData = loadMarketData();
|
||||||
List<SwapTrade> trades = ImmutableList.of(createVanillaFixedVsLibor3mSwap(), createVanillaFixedVsLibor6mSwap());
|
List<SwapTrade> trades = ImmutableList.of(createVanillaFixedVsLibor3mSwap(), createVanillaFixedVsLibor6mSwap());
|
||||||
CurveCalibrator calibrator = CurveCalibrator.of(1e-9, 1e-9, 100, CalibrationMeasures.PAR_SPREAD);
|
CurveCalibrator calibrator = CurveCalibrator.of(1e-9, 1e-9, 100, CalibrationMeasures.PAR_SPREAD);
|
||||||
ImmutableRatesProvider ratesProvider = calibrator.calibrate(curveGroupDefinition, marketData, ReferenceData.standard());
|
ImmutableRatesProvider ratesProvider = calibrator.calibrate(curveGroupDefinition, marketData, ReferenceData.standard());
|
||||||
MarketDataFxRateProvider fxRateProvider = MarketDataFxRateProvider.of(marketData);
|
MarketDataFxRateProvider fxRateProvider = MarketDataFxRateProvider.of(marketData);
|
||||||
ImmutableRatesProvider combinedRatesProvider = ImmutableRatesProvider.combined(fxRateProvider, ratesProvider);
|
ImmutableRatesProvider combinedRatesProvider = ImmutableRatesProvider.combined(fxRateProvider, ratesProvider);
|
||||||
|
|
||||||
List<ResolvedSwapTrade> resolvedTrades = trades.stream().map(trade -> trade.resolve(ReferenceData.standard())).collect(toList());
|
List<ResolvedSwapTrade> resolvedTrades = trades.stream().map(trade -> trade.resolve(ReferenceData.standard())).collect(toList());
|
||||||
DiscountingSwapProductPricer pricer = DiscountingSwapProductPricer.DEFAULT;
|
DiscountingSwapProductPricer pricer = DiscountingSwapProductPricer.DEFAULT;
|
||||||
|
|
||||||
CurrencyParameterSensitivities totalSensitivities = CurrencyParameterSensitivities.empty();
|
CurrencyParameterSensitivities totalSensitivities = CurrencyParameterSensitivities.empty();
|
||||||
MultiCurrencyAmount totalCurrencyExposure = MultiCurrencyAmount.empty();
|
MultiCurrencyAmount totalCurrencyExposure = MultiCurrencyAmount.empty();
|
||||||
|
|
||||||
for (ResolvedSwapTrade resolvedTrade : resolvedTrades) {
|
for (ResolvedSwapTrade resolvedTrade : resolvedTrades) {
|
||||||
ResolvedSwap swap = resolvedTrade.getProduct();
|
ResolvedSwap swap = resolvedTrade.getProduct();
|
||||||
|
|
||||||
PointSensitivities pointSensitivities = pricer.presentValueSensitivity(swap, combinedRatesProvider).build();
|
PointSensitivities pointSensitivities = pricer.presentValueSensitivity(swap, combinedRatesProvider).build();
|
||||||
CurrencyParameterSensitivities sensitivities = combinedRatesProvider.parameterSensitivity(pointSensitivities);
|
CurrencyParameterSensitivities sensitivities = combinedRatesProvider.parameterSensitivity(pointSensitivities);
|
||||||
MultiCurrencyAmount currencyExposure = pricer.currencyExposure(swap, combinedRatesProvider);
|
MultiCurrencyAmount currencyExposure = pricer.currencyExposure(swap, combinedRatesProvider);
|
||||||
|
|
||||||
totalSensitivities = totalSensitivities.combinedWith(sensitivities);
|
totalSensitivities = totalSensitivities.combinedWith(sensitivities);
|
||||||
totalCurrencyExposure = totalCurrencyExposure.plus(currencyExposure);
|
totalCurrencyExposure = totalCurrencyExposure.plus(currencyExposure);
|
||||||
|
}
|
||||||
|
//PortfolioNormalizer normalizer = new PortfolioNormalizer(Currency.EUR, combinedRatesProvider);
|
||||||
|
//RwamBimmNotProductClassesCalculator calculatorTotal = new RwamBimmNotProductClassesCalculator(
|
||||||
|
// fxRateProvider,
|
||||||
|
// Currency.EUR,
|
||||||
|
// IsdaConfiguration.INSTANCE);
|
||||||
|
//
|
||||||
|
//Triple<Double, Double, Double> margin = BimmAnalysisUtils.computeMargin(
|
||||||
|
// combinedRatesProvider,
|
||||||
|
// normalizer,
|
||||||
|
// calculatorTotal,
|
||||||
|
// totalSensitivities,
|
||||||
|
// totalCurrencyExposure);
|
||||||
|
//
|
||||||
|
//System.out.println(margin);
|
||||||
}
|
}
|
||||||
//PortfolioNormalizer normalizer = new PortfolioNormalizer(Currency.EUR, combinedRatesProvider);
|
|
||||||
//RwamBimmNotProductClassesCalculator calculatorTotal = new RwamBimmNotProductClassesCalculator(
|
|
||||||
// fxRateProvider,
|
|
||||||
// Currency.EUR,
|
|
||||||
// IsdaConfiguration.INSTANCE);
|
|
||||||
//
|
|
||||||
//Triple<Double, Double, Double> margin = BimmAnalysisUtils.computeMargin(
|
|
||||||
// combinedRatesProvider,
|
|
||||||
// normalizer,
|
|
||||||
// calculatorTotal,
|
|
||||||
// totalSensitivities,
|
|
||||||
// totalCurrencyExposure);
|
|
||||||
//
|
|
||||||
//System.out.println(margin);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load the market quotes and FX rates from data files.
|
* Load the market quotes and FX rates from data files.
|
||||||
*/
|
*/
|
||||||
private static MarketData loadMarketData() {
|
private static MarketData loadMarketData() {
|
||||||
Path dataDir = Paths.get("src/test/resources/data");
|
Path dataDir = Paths.get("src/test/resources/data");
|
||||||
Path quotesFile = dataDir.resolve("BIMM-MARKET-QUOTES-20160606.csv");
|
Path quotesFile = dataDir.resolve("BIMM-MARKET-QUOTES-20160606.csv");
|
||||||
Path fxFile = dataDir.resolve("BIMM-FX-RATES-20160606.csv");
|
Path fxFile = dataDir.resolve("BIMM-FX-RATES-20160606.csv");
|
||||||
|
|
||||||
Map<QuoteId, Double> quotes = QuotesCsvLoader.load(VALUATION_DATE, ImmutableList.of(ResourceLocator.ofPath(quotesFile)));
|
Map<QuoteId, Double> quotes = QuotesCsvLoader.load(VALUATION_DATE, ImmutableList.of(ResourceLocator.ofPath(quotesFile)));
|
||||||
Map<FxRateId, FxRate> fxRates = FxRatesCsvLoader.load(VALUATION_DATE, ResourceLocator.ofPath(fxFile));
|
Map<FxRateId, FxRate> fxRates = FxRatesCsvLoader.load(VALUATION_DATE, ResourceLocator.ofPath(fxFile));
|
||||||
return ImmutableMarketData.builder(VALUATION_DATE).addValueMap(quotes).addValueMap(fxRates).build();
|
return ImmutableMarketData.builder(VALUATION_DATE).addValueMap(quotes).addValueMap(fxRates).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the curve group definition from data files.
|
* Loads the curve group definition from data files.
|
||||||
*
|
* <p>
|
||||||
* A curve group maps from curve name to index for forward curves and curve name to currency for discount curves.
|
* A curve group maps from curve name to index for forward curves and curve name to currency for discount curves.
|
||||||
*/
|
*/
|
||||||
private static CurveGroupDefinition loadCurveGroup() {
|
private static CurveGroupDefinition loadCurveGroup() {
|
||||||
Path settingsDir = Paths.get("src/test/resources/settings");
|
Path settingsDir = Paths.get("src/test/resources/settings");
|
||||||
Map<CurveGroupName, CurveGroupDefinition> curveGroups = RatesCalibrationCsvLoader.load(
|
Map<CurveGroupName, CurveGroupDefinition> curveGroups = RatesCalibrationCsvLoader.load(
|
||||||
ResourceLocator.ofPath(settingsDir.resolve("BIMM-groups-EUR.csv")),
|
ResourceLocator.ofPath(settingsDir.resolve("BIMM-groups-EUR.csv")),
|
||||||
ResourceLocator.ofPath(settingsDir.resolve("BIMM-settings-EUR.csv")),
|
ResourceLocator.ofPath(settingsDir.resolve("BIMM-settings-EUR.csv")),
|
||||||
ResourceLocator.ofPath(settingsDir.resolve("BIMM-nodes-EUR.csv")));
|
ResourceLocator.ofPath(settingsDir.resolve("BIMM-nodes-EUR.csv")));
|
||||||
return curveGroups.get(CurveGroupName.of("BIMM"));
|
return curveGroups.get(CurveGroupName.of("BIMM"));
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
private static SwapTrade createVanillaFixedVsLibor3mSwap() {
|
private static SwapTrade createVanillaFixedVsLibor3mSwap() {
|
||||||
return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_3M.createTrade(
|
return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_3M.createTrade(
|
||||||
VALUATION_DATE,
|
VALUATION_DATE,
|
||||||
Tenor.TENOR_4Y,
|
Tenor.TENOR_4Y,
|
||||||
BuySell.BUY,
|
BuySell.BUY,
|
||||||
200_000_000,
|
200_000_000,
|
||||||
0.015,
|
0.015,
|
||||||
ReferenceData.standard());
|
ReferenceData.standard());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SwapTrade createVanillaFixedVsLibor6mSwap() {
|
private static SwapTrade createVanillaFixedVsLibor6mSwap() {
|
||||||
return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_6M.createTrade(
|
return FixedIborSwapConventions.EUR_FIXED_1Y_EURIBOR_6M.createTrade(
|
||||||
VALUATION_DATE,
|
VALUATION_DATE,
|
||||||
Tenor.TENOR_10Y,
|
Tenor.TENOR_10Y,
|
||||||
BuySell.SELL,
|
BuySell.SELL,
|
||||||
100_000_000,
|
100_000_000,
|
||||||
0.013,
|
0.013,
|
||||||
ReferenceData.standard());
|
ReferenceData.standard());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,19 +27,21 @@ import java.util.*
|
|||||||
* Interface for communicating with nodes running the trader demo.
|
* Interface for communicating with nodes running the trader demo.
|
||||||
*/
|
*/
|
||||||
class TraderDemoClientApi(val rpc: CordaRPCOps) {
|
class TraderDemoClientApi(val rpc: CordaRPCOps) {
|
||||||
val cashCount: Long get() {
|
val cashCount: Long
|
||||||
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
|
get() {
|
||||||
val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count)
|
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
|
||||||
return rpc.vaultQueryBy<Cash.State>(countCriteria).otherResults.single() as Long
|
val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count)
|
||||||
}
|
return rpc.vaultQueryBy<Cash.State>(countCriteria).otherResults.single() as Long
|
||||||
|
}
|
||||||
|
|
||||||
val dollarCashBalance: Amount<Currency> get() = rpc.getCashBalance(USD)
|
val dollarCashBalance: Amount<Currency> get() = rpc.getCashBalance(USD)
|
||||||
|
|
||||||
val commercialPaperCount: Long get() {
|
val commercialPaperCount: Long
|
||||||
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
|
get() {
|
||||||
val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count)
|
val count = builder { VaultSchemaV1.VaultStates::recordedTime.count() }
|
||||||
return rpc.vaultQueryBy<CommercialPaper.State>(countCriteria).otherResults.single() as Long
|
val countCriteria = QueryCriteria.VaultCustomQueryCriteria(count)
|
||||||
}
|
return rpc.vaultQueryBy<CommercialPaper.State>(countCriteria).otherResults.single() as Long
|
||||||
|
}
|
||||||
|
|
||||||
fun runIssuer(amount: Amount<Currency>, buyerName: CordaX500Name, sellerName: CordaX500Name) {
|
fun runIssuer(amount: Amount<Currency>, buyerName: CordaX500Name, sellerName: CordaX500Name) {
|
||||||
val ref = OpaqueBytes.of(1)
|
val ref = OpaqueBytes.of(1)
|
||||||
|
@ -31,7 +31,9 @@ class CommercialPaperIssueFlow(private val amount: Amount<Currency>,
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val PROSPECTUS_HASH = SecureHash.parse("decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9")
|
val PROSPECTUS_HASH = SecureHash.parse("decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9")
|
||||||
|
|
||||||
object ISSUING : ProgressTracker.Step("Issuing and timestamping some commercial paper")
|
object ISSUING : ProgressTracker.Step("Issuing and timestamping some commercial paper")
|
||||||
|
|
||||||
fun tracker() = ProgressTracker(ISSUING)
|
fun tracker() = ProgressTracker(ISSUING)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,13 @@ class PredefinedTestNode internal constructor(party: Party, driver: DriverDSLExp
|
|||||||
* for it: you won't have [ALICE_KEY].
|
* for it: you won't have [ALICE_KEY].
|
||||||
*/
|
*/
|
||||||
fun DriverDSLExposedInterface.alice(): PredefinedTestNode = PredefinedTestNode(ALICE, this, null)
|
fun DriverDSLExposedInterface.alice(): PredefinedTestNode = PredefinedTestNode(ALICE, this, null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a plain, entirely stock node pre-configured with the [BOB] identity. Note that a random key will be generated
|
* Returns a plain, entirely stock node pre-configured with the [BOB] identity. Note that a random key will be generated
|
||||||
* for it: you won't have [BOB_KEY].
|
* for it: you won't have [BOB_KEY].
|
||||||
*/
|
*/
|
||||||
fun DriverDSLExposedInterface.bob(): PredefinedTestNode = PredefinedTestNode(BOB, this, null)
|
fun DriverDSLExposedInterface.bob(): PredefinedTestNode = PredefinedTestNode(BOB, this, null)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a plain single node notary pre-configured with the [DUMMY_NOTARY] identity. Note that a random key will be generated
|
* Returns a plain single node notary pre-configured with the [DUMMY_NOTARY] identity. Note that a random key will be generated
|
||||||
* for it: you won't have [DUMMY_NOTARY_KEY].
|
* for it: you won't have [DUMMY_NOTARY_KEY].
|
||||||
|
@ -20,7 +20,8 @@ import java.nio.file.Path
|
|||||||
* Creates and tests a ledger built by the passed in dsl. The provided services can be customised, otherwise a default
|
* Creates and tests a ledger built by the passed in dsl. The provided services can be customised, otherwise a default
|
||||||
* of a freshly built [MockServices] is used.
|
* of a freshly built [MockServices] is used.
|
||||||
*/
|
*/
|
||||||
@JvmOverloads fun ledger(
|
@JvmOverloads
|
||||||
|
fun ledger(
|
||||||
services: ServiceHub = MockServices(),
|
services: ServiceHub = MockServices(),
|
||||||
initialiseSerialization: Boolean = true,
|
initialiseSerialization: Boolean = true,
|
||||||
dsl: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
dsl: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
||||||
@ -40,7 +41,8 @@ import java.nio.file.Path
|
|||||||
*
|
*
|
||||||
* @see LedgerDSLInterpreter._transaction
|
* @see LedgerDSLInterpreter._transaction
|
||||||
*/
|
*/
|
||||||
@JvmOverloads fun transaction(
|
@JvmOverloads
|
||||||
|
fun transaction(
|
||||||
transactionLabel: String? = null,
|
transactionLabel: String? = null,
|
||||||
transactionBuilder: TransactionBuilder = TransactionBuilder(notary = DUMMY_NOTARY),
|
transactionBuilder: TransactionBuilder = TransactionBuilder(notary = DUMMY_NOTARY),
|
||||||
initialiseSerialization: Boolean = true,
|
initialiseSerialization: Boolean = true,
|
||||||
@ -54,6 +56,7 @@ fun testNodeConfiguration(
|
|||||||
myLegalName: CordaX500Name,
|
myLegalName: CordaX500Name,
|
||||||
notaryConfig: NotaryConfig? = null): NodeConfiguration {
|
notaryConfig: NotaryConfig? = null): NodeConfiguration {
|
||||||
abstract class MockableNodeConfiguration : NodeConfiguration // Otherwise Mockito is defeated by val getters.
|
abstract class MockableNodeConfiguration : NodeConfiguration // Otherwise Mockito is defeated by val getters.
|
||||||
|
|
||||||
val nc = spy<MockableNodeConfiguration>()
|
val nc = spy<MockableNodeConfiguration>()
|
||||||
whenever(nc.baseDirectory).thenReturn(baseDirectory)
|
whenever(nc.baseDirectory).thenReturn(baseDirectory)
|
||||||
whenever(nc.myLegalName).thenReturn(myLegalName)
|
whenever(nc.myLegalName).thenReturn(myLegalName)
|
||||||
|
@ -64,7 +64,7 @@ interface RPCDriverExposedDSLInterface : DriverDSLExposedInterface {
|
|||||||
maxFileSize: Int = ArtemisMessagingServer.MAX_FILE_SIZE,
|
maxFileSize: Int = ArtemisMessagingServer.MAX_FILE_SIZE,
|
||||||
maxBufferedBytesPerClient: Long = 10L * ArtemisMessagingServer.MAX_FILE_SIZE,
|
maxBufferedBytesPerClient: Long = 10L * ArtemisMessagingServer.MAX_FILE_SIZE,
|
||||||
configuration: RPCServerConfiguration = RPCServerConfiguration.default,
|
configuration: RPCServerConfiguration = RPCServerConfiguration.default,
|
||||||
ops : I
|
ops: I
|
||||||
): CordaFuture<RpcServerHandle>
|
): CordaFuture<RpcServerHandle>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,8 +110,8 @@ interface RPCDriverExposedDSLInterface : DriverDSLExposedInterface {
|
|||||||
maxBufferedBytesPerClient: Long = 10L * ArtemisMessagingServer.MAX_FILE_SIZE,
|
maxBufferedBytesPerClient: Long = 10L * ArtemisMessagingServer.MAX_FILE_SIZE,
|
||||||
configuration: RPCServerConfiguration = RPCServerConfiguration.default,
|
configuration: RPCServerConfiguration = RPCServerConfiguration.default,
|
||||||
customPort: NetworkHostAndPort? = null,
|
customPort: NetworkHostAndPort? = null,
|
||||||
ops : I
|
ops: I
|
||||||
) : CordaFuture<RpcServerHandle>
|
): CordaFuture<RpcServerHandle>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a Netty RPC client.
|
* Starts a Netty RPC client.
|
||||||
@ -180,16 +180,19 @@ interface RPCDriverExposedDSLInterface : DriverDSLExposedInterface {
|
|||||||
brokerHandle: RpcBrokerHandle
|
brokerHandle: RpcBrokerHandle
|
||||||
): RpcServerHandle
|
): RpcServerHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startInVmRpcClient(
|
inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startInVmRpcClient(
|
||||||
username: String = rpcTestUser.username,
|
username: String = rpcTestUser.username,
|
||||||
password: String = rpcTestUser.password,
|
password: String = rpcTestUser.password,
|
||||||
configuration: RPCClientConfiguration = RPCClientConfiguration.default
|
configuration: RPCClientConfiguration = RPCClientConfiguration.default
|
||||||
) = startInVmRpcClient(I::class.java, username, password, configuration)
|
) = startInVmRpcClient(I::class.java, username, password, configuration)
|
||||||
|
|
||||||
inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startRandomRpcClient(
|
inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startRandomRpcClient(
|
||||||
hostAndPort: NetworkHostAndPort,
|
hostAndPort: NetworkHostAndPort,
|
||||||
username: String = rpcTestUser.username,
|
username: String = rpcTestUser.username,
|
||||||
password: String = rpcTestUser.password
|
password: String = rpcTestUser.password
|
||||||
) = startRandomRpcClient(I::class.java, hostAndPort, username, password)
|
) = startRandomRpcClient(I::class.java, hostAndPort, username, password)
|
||||||
|
|
||||||
inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startRpcClient(
|
inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startRpcClient(
|
||||||
rpcAddress: NetworkHostAndPort,
|
rpcAddress: NetworkHostAndPort,
|
||||||
username: String = rpcTestUser.username,
|
username: String = rpcTestUser.username,
|
||||||
@ -200,7 +203,8 @@ inline fun <reified I : RPCOps> RPCDriverExposedDSLInterface.startRpcClient(
|
|||||||
interface RPCDriverInternalDSLInterface : DriverDSLInternalInterface, RPCDriverExposedDSLInterface
|
interface RPCDriverInternalDSLInterface : DriverDSLInternalInterface, RPCDriverExposedDSLInterface
|
||||||
|
|
||||||
data class RpcBrokerHandle(
|
data class RpcBrokerHandle(
|
||||||
val hostAndPort: NetworkHostAndPort?,/** null if this is an InVM broker */
|
val hostAndPort: NetworkHostAndPort?,
|
||||||
|
/** null if this is an InVM broker */
|
||||||
val clientTransportConfiguration: TransportConfiguration,
|
val clientTransportConfiguration: TransportConfiguration,
|
||||||
val serverControl: ActiveMQServerControl
|
val serverControl: ActiveMQServerControl
|
||||||
)
|
)
|
||||||
@ -253,6 +257,7 @@ private class SingleUserSecurityManager(val rpcUser: User) : ActiveMQSecurityMan
|
|||||||
override fun validateUser(user: String?, password: String?, certificates: Array<out X509Certificate>?): String? {
|
override fun validateUser(user: String?, password: String?, certificates: Array<out X509Certificate>?): String? {
|
||||||
return validate(user, password)
|
return validate(user, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun validateUserAndRole(user: String?, password: String?, roles: MutableSet<Role>?, checkType: CheckType?, address: String?, connection: RemotingConnection?): String? {
|
override fun validateUserAndRole(user: String?, password: String?, roles: MutableSet<Role>?, checkType: CheckType?, address: String?, connection: RemotingConnection?): String? {
|
||||||
return validate(user, password)
|
return validate(user, password)
|
||||||
}
|
}
|
||||||
@ -260,6 +265,7 @@ private class SingleUserSecurityManager(val rpcUser: User) : ActiveMQSecurityMan
|
|||||||
private fun isValid(user: String?, password: String?): Boolean {
|
private fun isValid(user: String?, password: String?): Boolean {
|
||||||
return rpcUser.username == user && rpcUser.password == password
|
return rpcUser.username == user && rpcUser.password == password
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun validate(user: String?, password: String?): String? {
|
private fun validate(user: String?, password: String?): String? {
|
||||||
return if (isValid(user, password)) user else null
|
return if (isValid(user, password)) user else null
|
||||||
}
|
}
|
||||||
@ -303,6 +309,7 @@ data class RPCDriverDSL(
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createInVmRpcServerArtemisConfig(maxFileSize: Int, maxBufferedBytesPerClient: Long): Configuration {
|
fun createInVmRpcServerArtemisConfig(maxFileSize: Int, maxBufferedBytesPerClient: Long): Configuration {
|
||||||
return ConfigurationImpl().apply {
|
return ConfigurationImpl().apply {
|
||||||
acceptorConfigurations = setOf(TransportConfiguration(InVMAcceptorFactory::class.java.name))
|
acceptorConfigurations = setOf(TransportConfiguration(InVMAcceptorFactory::class.java.name))
|
||||||
@ -310,6 +317,7 @@ data class RPCDriverDSL(
|
|||||||
configureCommonSettings(maxFileSize, maxBufferedBytesPerClient)
|
configureCommonSettings(maxFileSize, maxBufferedBytesPerClient)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun createRpcServerArtemisConfig(maxFileSize: Int, maxBufferedBytesPerClient: Long, baseDirectory: Path, hostAndPort: NetworkHostAndPort): Configuration {
|
fun createRpcServerArtemisConfig(maxFileSize: Int, maxBufferedBytesPerClient: Long, baseDirectory: Path, hostAndPort: NetworkHostAndPort): Configuration {
|
||||||
val connectionDirection = ConnectionDirection.Inbound(acceptorFactoryClassName = NettyAcceptorFactory::class.java.name)
|
val connectionDirection = ConnectionDirection.Inbound(acceptorFactoryClassName = NettyAcceptorFactory::class.java.name)
|
||||||
return ConfigurationImpl().apply {
|
return ConfigurationImpl().apply {
|
||||||
@ -321,6 +329,7 @@ data class RPCDriverDSL(
|
|||||||
configureCommonSettings(maxFileSize, maxBufferedBytesPerClient)
|
configureCommonSettings(maxFileSize, maxBufferedBytesPerClient)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val inVmClientTransportConfiguration = TransportConfiguration(InVMConnectorFactory::class.java.name)
|
val inVmClientTransportConfiguration = TransportConfiguration(InVMConnectorFactory::class.java.name)
|
||||||
fun createNettyClientTransportConfiguration(hostAndPort: NetworkHostAndPort): TransportConfiguration {
|
fun createNettyClientTransportConfiguration(hostAndPort: NetworkHostAndPort): TransportConfiguration {
|
||||||
return ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), hostAndPort, null)
|
return ArtemisTcpTransport.tcpTransport(ConnectionDirection.Outbound(), hostAndPort, null)
|
||||||
@ -503,6 +512,7 @@ class RandomRpcUser {
|
|||||||
add(Generator.string())
|
add(Generator.string())
|
||||||
add(Generator.int())
|
add(Generator.int())
|
||||||
}
|
}
|
||||||
|
|
||||||
data class Call(val method: Method, val call: () -> Any?)
|
data class Call(val method: Method, val call: () -> Any?)
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -143,7 +143,8 @@ class InMemoryMessagingNetwork(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** This can be set to an object which can inject artificial latency between sender/recipient pairs. */
|
/** This can be set to an object which can inject artificial latency between sender/recipient pairs. */
|
||||||
@Volatile var latencyCalculator: LatencyCalculator? = null
|
@Volatile
|
||||||
|
var latencyCalculator: LatencyCalculator? = null
|
||||||
private val timer = Timer()
|
private val timer = Timer()
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
@ -327,7 +328,7 @@ class InMemoryMessagingNetwork(
|
|||||||
while (!Thread.currentThread().isInterrupted) {
|
while (!Thread.currentThread().isInterrupted) {
|
||||||
try {
|
try {
|
||||||
pumpReceiveInternal(true)
|
pumpReceiveInternal(true)
|
||||||
} catch(e: InterruptedException) {
|
} catch (e: InterruptedException) {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -452,7 +453,7 @@ class InMemoryMessagingNetwork(
|
|||||||
for (handler in deliverTo) {
|
for (handler in deliverTo) {
|
||||||
try {
|
try {
|
||||||
handler.callback(transfer.toReceivedMessage(), handler)
|
handler.callback(transfer.toReceivedMessage(), handler)
|
||||||
} catch(e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error("Caught exception in handler for $this/${handler.topicSession}", e)
|
log.error("Caught exception in handler for $this/${handler.topicSession}", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,6 @@ class MockNetworkMapCache(serviceHub: ServiceHubInternal) : PersistentNetworkMap
|
|||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
fun deleteRegistration(legalIdentity: Party): Boolean {
|
fun deleteRegistration(legalIdentity: Party): Boolean {
|
||||||
return partyNodes.removeIf { legalIdentity.owningKey in it.legalIdentitiesAndCerts.map { it.owningKey }}
|
return partyNodes.removeIf { legalIdentity.owningKey in it.legalIdentitiesAndCerts.map { it.owningKey } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +247,9 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
|
|||||||
|
|
||||||
// This does not indirect through the NodeInfo object so it can be called before the node is started.
|
// This does not indirect through the NodeInfo object so it can be called before the node is started.
|
||||||
// It is used from the network visualiser tool.
|
// It is used from the network visualiser tool.
|
||||||
@Suppress("unused") val place: WorldMapLocation get() = findMyLocation()!!
|
@Suppress("unused")
|
||||||
|
val place: WorldMapLocation
|
||||||
|
get() = findMyLocation()!!
|
||||||
|
|
||||||
private var dbCloser: (() -> Any?)? = null
|
private var dbCloser: (() -> Any?)? = null
|
||||||
override fun <T> initialiseDatabasePersistence(schemaService: SchemaService, insideTransaction: () -> T) = super.initialiseDatabasePersistence(schemaService) {
|
override fun <T> initialiseDatabasePersistence(schemaService: SchemaService, insideTransaction: () -> T) = super.initialiseDatabasePersistence(schemaService) {
|
||||||
@ -302,7 +304,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
|
|||||||
legalName = MOCK_NET_MAP.name,
|
legalName = MOCK_NET_MAP.name,
|
||||||
notaryIdentity = null,
|
notaryIdentity = null,
|
||||||
advertisedServices = arrayOf(),
|
advertisedServices = arrayOf(),
|
||||||
entropyRoot = BigInteger.valueOf(random63BitValue()),
|
entropyRoot = BigInteger.valueOf(random63BitValue()),
|
||||||
configOverrides = {},
|
configOverrides = {},
|
||||||
start = true
|
start = true
|
||||||
).started!!.apply {
|
).started!!.apply {
|
||||||
|
@ -82,7 +82,9 @@ open class MockServices(
|
|||||||
fun makeTestDatabaseProperties(key: String? = null, value: String? = null): Properties {
|
fun makeTestDatabaseProperties(key: String? = null, value: String? = null): Properties {
|
||||||
val props = Properties()
|
val props = Properties()
|
||||||
props.setProperty("transactionIsolationLevel", "repeatableRead") //for other possible values see net.corda.node.utilities.CordaPeristence.parserTransactionIsolationLevel(String)
|
props.setProperty("transactionIsolationLevel", "repeatableRead") //for other possible values see net.corda.node.utilities.CordaPeristence.parserTransactionIsolationLevel(String)
|
||||||
if (key != null) { props.setProperty(key, value) }
|
if (key != null) {
|
||||||
|
props.setProperty(key, value)
|
||||||
|
}
|
||||||
return props
|
return props
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,10 +156,11 @@ open class MockServices(
|
|||||||
override val contractUpgradeService: ContractUpgradeService get() = throw UnsupportedOperationException()
|
override val contractUpgradeService: ContractUpgradeService get() = throw UnsupportedOperationException()
|
||||||
override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException()
|
override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException()
|
||||||
override val clock: Clock get() = Clock.systemUTC()
|
override val clock: Clock get() = Clock.systemUTC()
|
||||||
override val myInfo: NodeInfo get() {
|
override val myInfo: NodeInfo
|
||||||
val identity = getTestPartyAndCertificate(MEGA_CORP.name, key.public)
|
get() {
|
||||||
return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L)
|
val identity = getTestPartyAndCertificate(MEGA_CORP.name, key.public)
|
||||||
}
|
return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L)
|
||||||
|
}
|
||||||
override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2)
|
override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2)
|
||||||
val mockCordappProvider: MockCordappProvider = MockCordappProvider(CordappLoader.createWithTestPackages(cordappPackages + CordappLoader.testPackages)).start(attachments) as MockCordappProvider
|
val mockCordappProvider: MockCordappProvider = MockCordappProvider(CordappLoader.createWithTestPackages(cordappPackages + CordappLoader.testPackages)).start(attachments) as MockCordappProvider
|
||||||
override val cordappProvider: CordappProvider = mockCordappProvider
|
override val cordappProvider: CordappProvider = mockCordappProvider
|
||||||
|
@ -25,7 +25,8 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC
|
|||||||
/**
|
/**
|
||||||
* Advance this [Clock] by the specified [Duration] for testing purposes.
|
* Advance this [Clock] by the specified [Duration] for testing purposes.
|
||||||
*/
|
*/
|
||||||
@Synchronized fun advanceBy(duration: Duration) {
|
@Synchronized
|
||||||
|
fun advanceBy(duration: Duration) {
|
||||||
delegateClock = offset(delegateClock, duration)
|
delegateClock = offset(delegateClock, duration)
|
||||||
notifyMutationObservers()
|
notifyMutationObservers()
|
||||||
}
|
}
|
||||||
@ -35,7 +36,8 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC
|
|||||||
*
|
*
|
||||||
* This will only be approximate due to the time ticking away, but will be some time shortly after the requested [Instant].
|
* This will only be approximate due to the time ticking away, but will be some time shortly after the requested [Instant].
|
||||||
*/
|
*/
|
||||||
@Synchronized fun setTo(newInstant: Instant) = advanceBy(instant() until newInstant)
|
@Synchronized
|
||||||
|
fun setTo(newInstant: Instant) = advanceBy(instant() until newInstant)
|
||||||
|
|
||||||
@Synchronized override fun instant(): Instant {
|
@Synchronized override fun instant(): Instant {
|
||||||
return delegateClock.instant()
|
return delegateClock.instant()
|
||||||
|
@ -46,6 +46,7 @@ class NodeProcess(
|
|||||||
class Factory(val buildDirectory: Path = Paths.get("build"),
|
class Factory(val buildDirectory: Path = Paths.get("build"),
|
||||||
val cordaJar: Path = Paths.get(this::class.java.getResource("/corda.jar").toURI())) {
|
val cordaJar: Path = Paths.get(this::class.java.getResource("/corda.jar").toURI())) {
|
||||||
val nodesDirectory = buildDirectory / formatter.format(Instant.now())
|
val nodesDirectory = buildDirectory / formatter.format(Instant.now())
|
||||||
|
|
||||||
init {
|
init {
|
||||||
nodesDirectory.createDirectories()
|
nodesDirectory.createDirectories()
|
||||||
}
|
}
|
||||||
@ -95,11 +96,11 @@ class NodeProcess(
|
|||||||
|
|
||||||
private fun startNode(nodeDir: Path): Process {
|
private fun startNode(nodeDir: Path): Process {
|
||||||
val builder = ProcessBuilder()
|
val builder = ProcessBuilder()
|
||||||
.command(javaPath.toString(), "-jar", cordaJar.toString())
|
.command(javaPath.toString(), "-jar", cordaJar.toString())
|
||||||
.directory(nodeDir.toFile())
|
.directory(nodeDir.toFile())
|
||||||
|
|
||||||
builder.environment().putAll(mapOf(
|
builder.environment().putAll(mapOf(
|
||||||
"CAPSULE_CACHE_DIR" to (buildDirectory / "capsule").toString()
|
"CAPSULE_CACHE_DIR" to (buildDirectory / "capsule").toString()
|
||||||
))
|
))
|
||||||
|
|
||||||
return builder.start()
|
return builder.start()
|
||||||
|
@ -117,8 +117,8 @@ fun freePort(): Int = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (
|
|||||||
* to the Node, some other process else could allocate the returned ports.
|
* to the Node, some other process else could allocate the returned ports.
|
||||||
*/
|
*/
|
||||||
fun getFreeLocalPorts(hostName: String, numberToAlloc: Int): List<NetworkHostAndPort> {
|
fun getFreeLocalPorts(hostName: String, numberToAlloc: Int): List<NetworkHostAndPort> {
|
||||||
val freePort = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (prev - 30000 + numberToAlloc) % 10000 }
|
val freePort = freePortCounter.getAndAccumulate(0) { prev, _ -> 30000 + (prev - 30000 + numberToAlloc) % 10000 }
|
||||||
return (freePort .. freePort + numberToAlloc - 1).map { NetworkHostAndPort(hostName, it) }
|
return (freePort..freePort + numberToAlloc - 1).map { NetworkHostAndPort(hostName, it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
@ -147,17 +147,17 @@ fun getTestPartyAndCertificate(name: CordaX500Name, publicKey: PublicKey, trustR
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
inline fun <reified T : Any> T.kryoSpecific(reason: String, function: () -> Unit) = if(!AMQP_ENABLED) {
|
inline fun <reified T : Any> T.kryoSpecific(reason: String, function: () -> Unit) = if (!AMQP_ENABLED) {
|
||||||
function()
|
function()
|
||||||
} else {
|
} else {
|
||||||
loggerFor<T>().info("Ignoring Kryo specific test, reason: $reason" )
|
loggerFor<T>().info("Ignoring Kryo specific test, reason: $reason")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
inline fun <reified T : Any> T.amqpSpecific(reason: String, function: () -> Unit) = if(AMQP_ENABLED) {
|
inline fun <reified T : Any> T.amqpSpecific(reason: String, function: () -> Unit) = if (AMQP_ENABLED) {
|
||||||
function()
|
function()
|
||||||
} else {
|
} else {
|
||||||
loggerFor<T>().info("Ignoring AMQP specific test, reason: $reason" )
|
loggerFor<T>().info("Ignoring AMQP specific test, reason: $reason")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -165,6 +165,7 @@ inline fun <reified T : Any> T.amqpSpecific(reason: String, function: () -> Unit
|
|||||||
* TODO: Should be removed after multiple identities are introduced.
|
* TODO: Should be removed after multiple identities are introduced.
|
||||||
*/
|
*/
|
||||||
fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first()
|
fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first()
|
||||||
|
|
||||||
fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party
|
fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party
|
||||||
/** Returns the identity of the first notary found on the network */
|
/** Returns the identity of the first notary found on the network */
|
||||||
fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first()
|
fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first()
|
||||||
|
@ -6,15 +6,16 @@ import java.time.Duration
|
|||||||
* Ideas borrowed from "io.kotlintest" with some improvements made
|
* Ideas borrowed from "io.kotlintest" with some improvements made
|
||||||
* This is meant for use from Kotlin code use only mainly due to it's inline/reified nature
|
* This is meant for use from Kotlin code use only mainly due to it's inline/reified nature
|
||||||
*/
|
*/
|
||||||
inline fun <reified E : Throwable, R>eventually(duration: Duration, f: () -> R): R {
|
inline fun <reified E : Throwable, R> eventually(duration: Duration, f: () -> R): R {
|
||||||
val end = System.nanoTime() + duration.toNanos()
|
val end = System.nanoTime() + duration.toNanos()
|
||||||
var times = 0
|
var times = 0
|
||||||
while (System.nanoTime() < end) {
|
while (System.nanoTime() < end) {
|
||||||
try {
|
try {
|
||||||
return f()
|
return f()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
when(e) {
|
when (e) {
|
||||||
is E -> {}// ignore and continue
|
is E -> {
|
||||||
|
}// ignore and continue
|
||||||
else -> throw e // unexpected exception type - rethrow
|
else -> throw e // unexpected exception type - rethrow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,14 +78,15 @@ class FlowStackSnapshotFactoryImpl : FlowStackSnapshotFactory {
|
|||||||
return FlowStackSnapshot(Instant.now(), flowClass.name, frames)
|
return FlowStackSnapshot(Instant.now(), flowClass.name, frames)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val StackTraceElement.instrumentedAnnotation: Instrumented? get() {
|
private val StackTraceElement.instrumentedAnnotation: Instrumented?
|
||||||
Class.forName(className).methods.forEach {
|
get() {
|
||||||
if (it.name == methodName && it.isAnnotationPresent(Instrumented::class.java)) {
|
Class.forName(className).methods.forEach {
|
||||||
return it.getAnnotation(Instrumented::class.java)
|
if (it.name == methodName && it.isAnnotationPresent(Instrumented::class.java)) {
|
||||||
|
return it.getAnnotation(Instrumented::class.java)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun removeConstructorStackTraceElements(stackTrace: List<StackTraceElement>): List<StackTraceElement> {
|
private fun removeConstructorStackTraceElements(stackTrace: List<StackTraceElement>): List<StackTraceElement> {
|
||||||
val newStackTrace = ArrayList<StackTraceElement>()
|
val newStackTrace = ArrayList<StackTraceElement>()
|
||||||
|
@ -12,10 +12,13 @@ import kotlin.reflect.jvm.reflect
|
|||||||
|
|
||||||
fun <A : Any, R> measure(a: Iterable<A>, f: (A) -> R) =
|
fun <A : Any, R> measure(a: Iterable<A>, f: (A) -> R) =
|
||||||
measure(listOf(a), f.reflect()!!) { f(uncheckedCast(it[0])) }
|
measure(listOf(a), f.reflect()!!) { f(uncheckedCast(it[0])) }
|
||||||
|
|
||||||
fun <A : Any, B : Any, R> measure(a: Iterable<A>, b: Iterable<B>, f: (A, B) -> R) =
|
fun <A : Any, B : Any, R> measure(a: Iterable<A>, b: Iterable<B>, f: (A, B) -> R) =
|
||||||
measure(listOf(a, b), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1])) }
|
measure(listOf(a, b), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1])) }
|
||||||
|
|
||||||
fun <A : Any, B : Any, C : Any, R> measure(a: Iterable<A>, b: Iterable<B>, c: Iterable<C>, f: (A, B, C) -> R) =
|
fun <A : Any, B : Any, C : Any, R> measure(a: Iterable<A>, b: Iterable<B>, c: Iterable<C>, f: (A, B, C) -> R) =
|
||||||
measure(listOf(a, b, c), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2])) }
|
measure(listOf(a, b, c), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2])) }
|
||||||
|
|
||||||
fun <A : Any, B : Any, C : Any, D : Any, R> measure(a: Iterable<A>, b: Iterable<B>, c: Iterable<C>, d: Iterable<D>, f: (A, B, C, D) -> R) =
|
fun <A : Any, B : Any, C : Any, D : Any, R> measure(a: Iterable<A>, b: Iterable<B>, c: Iterable<C>, d: Iterable<D>, f: (A, B, C, D) -> R) =
|
||||||
measure(listOf(a, b, c, d), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2]), uncheckedCast(it[3])) }
|
measure(listOf(a, b, c, d), f.reflect()!!) { f(uncheckedCast(it[0]), uncheckedCast(it[1]), uncheckedCast(it[2]), uncheckedCast(it[3])) }
|
||||||
|
|
||||||
@ -30,8 +33,8 @@ private fun <R> measure(paramIterables: List<Iterable<Any?>>, kCallable: KCallab
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class MeasureResult<out R>(
|
data class MeasureResult<out R>(
|
||||||
val parameters: List<Pair<String, Any?>>,
|
val parameters: List<Pair<String, Any?>>,
|
||||||
val result: R
|
val result: R
|
||||||
)
|
)
|
||||||
|
|
||||||
fun <A> iterateLexical(iterables: List<Iterable<A>>): Iterable<List<A>> {
|
fun <A> iterateLexical(iterables: List<Iterable<A>>): Iterable<List<A>> {
|
||||||
|
@ -22,32 +22,32 @@ fun initialiseTestSerialization() {
|
|||||||
// Check that everything is configured for testing with mutable delegating instances.
|
// Check that everything is configured for testing with mutable delegating instances.
|
||||||
try {
|
try {
|
||||||
check(SerializationDefaults.SERIALIZATION_FACTORY is TestSerializationFactory)
|
check(SerializationDefaults.SERIALIZATION_FACTORY is TestSerializationFactory)
|
||||||
} catch(e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
SerializationDefaults.SERIALIZATION_FACTORY = TestSerializationFactory()
|
SerializationDefaults.SERIALIZATION_FACTORY = TestSerializationFactory()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
check(SerializationDefaults.P2P_CONTEXT is TestSerializationContext)
|
check(SerializationDefaults.P2P_CONTEXT is TestSerializationContext)
|
||||||
} catch(e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
SerializationDefaults.P2P_CONTEXT = TestSerializationContext()
|
SerializationDefaults.P2P_CONTEXT = TestSerializationContext()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
check(SerializationDefaults.RPC_SERVER_CONTEXT is TestSerializationContext)
|
check(SerializationDefaults.RPC_SERVER_CONTEXT is TestSerializationContext)
|
||||||
} catch(e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
SerializationDefaults.RPC_SERVER_CONTEXT = TestSerializationContext()
|
SerializationDefaults.RPC_SERVER_CONTEXT = TestSerializationContext()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
check(SerializationDefaults.RPC_CLIENT_CONTEXT is TestSerializationContext)
|
check(SerializationDefaults.RPC_CLIENT_CONTEXT is TestSerializationContext)
|
||||||
} catch(e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
SerializationDefaults.RPC_CLIENT_CONTEXT = TestSerializationContext()
|
SerializationDefaults.RPC_CLIENT_CONTEXT = TestSerializationContext()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
check(SerializationDefaults.STORAGE_CONTEXT is TestSerializationContext)
|
check(SerializationDefaults.STORAGE_CONTEXT is TestSerializationContext)
|
||||||
} catch(e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
SerializationDefaults.STORAGE_CONTEXT = TestSerializationContext()
|
SerializationDefaults.STORAGE_CONTEXT = TestSerializationContext()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
check(SerializationDefaults.CHECKPOINT_CONTEXT is TestSerializationContext)
|
check(SerializationDefaults.CHECKPOINT_CONTEXT is TestSerializationContext)
|
||||||
} catch(e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
SerializationDefaults.CHECKPOINT_CONTEXT = TestSerializationContext()
|
SerializationDefaults.CHECKPOINT_CONTEXT = TestSerializationContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@ data class TestLedgerDSLInterpreter private constructor(
|
|||||||
transactionLabel: String?,
|
transactionLabel: String?,
|
||||||
transactionBuilder: TransactionBuilder,
|
transactionBuilder: TransactionBuilder,
|
||||||
dsl: TransactionDSL<TestTransactionDSLInterpreter>.() -> Unit
|
dsl: TransactionDSL<TestTransactionDSLInterpreter>.() -> Unit
|
||||||
) = recordTransactionWithTransactionMap(transactionLabel, transactionBuilder, dsl, nonVerifiedTransactionWithLocations, fillTransaction = true)
|
) = recordTransactionWithTransactionMap(transactionLabel, transactionBuilder, dsl, nonVerifiedTransactionWithLocations, fillTransaction = true)
|
||||||
|
|
||||||
override fun tweak(
|
override fun tweak(
|
||||||
dsl: LedgerDSL<TestTransactionDSLInterpreter,
|
dsl: LedgerDSL<TestTransactionDSLInterpreter,
|
||||||
|
@ -119,7 +119,7 @@ class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : Tr
|
|||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun output(contractClassName: ContractClassName, contractState: ContractState, attachmentConstraint: AttachmentConstraint = AutomaticHashConstraint) =
|
fun output(contractClassName: ContractClassName, contractState: ContractState, attachmentConstraint: AttachmentConstraint = AutomaticHashConstraint) =
|
||||||
_output(contractClassName,null, DUMMY_NOTARY, null, attachmentConstraint, contractState)
|
_output(contractClassName, null, DUMMY_NOTARY, null, attachmentConstraint, contractState)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a command to the transaction.
|
* Adds a command to the transaction.
|
||||||
@ -146,5 +146,5 @@ class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : Tr
|
|||||||
*/
|
*/
|
||||||
fun attachment(contractClassName: ContractClassName) = _attachment(contractClassName)
|
fun attachment(contractClassName: ContractClassName) = _attachment(contractClassName)
|
||||||
|
|
||||||
fun attachments(vararg contractClassNames: ContractClassName) = contractClassNames.forEach { attachment(it)}
|
fun attachments(vararg contractClassNames: ContractClassName) = contractClassNames.forEach { attachment(it) }
|
||||||
}
|
}
|
||||||
|
@ -19,8 +19,7 @@ class DummyDealContract : Contract {
|
|||||||
|
|
||||||
data class State(
|
data class State(
|
||||||
override val participants: List<AbstractParty>,
|
override val participants: List<AbstractParty>,
|
||||||
override val linearId: UniqueIdentifier) : DealState, QueryableState
|
override val linearId: UniqueIdentifier) : DealState, QueryableState {
|
||||||
{
|
|
||||||
constructor(participants: List<AbstractParty> = listOf(),
|
constructor(participants: List<AbstractParty> = listOf(),
|
||||||
ref: String) : this(participants, UniqueIdentifier(ref))
|
ref: String) : this(participants, UniqueIdentifier(ref))
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ import java.util.*
|
|||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun ServiceHub.fillWithSomeTestDeals(dealIds: List<String>,
|
fun ServiceHub.fillWithSomeTestDeals(dealIds: List<String>,
|
||||||
participants: List<AbstractParty> = emptyList(),
|
participants: List<AbstractParty> = emptyList(),
|
||||||
notary: Party = DUMMY_NOTARY) : Vault<DealState> {
|
notary: Party = DUMMY_NOTARY): Vault<DealState> {
|
||||||
val myKey: PublicKey = myInfo.chooseIdentity().owningKey
|
val myKey: PublicKey = myInfo.chooseIdentity().owningKey
|
||||||
val me = AnonymousParty(myKey)
|
val me = AnonymousParty(myKey)
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ fun ServiceHub.fillWithSomeTestLinearStates(numberToCreate: Int,
|
|||||||
linearString: String = "",
|
linearString: String = "",
|
||||||
linearNumber: Long = 0L,
|
linearNumber: Long = 0L,
|
||||||
linearBoolean: Boolean = false,
|
linearBoolean: Boolean = false,
|
||||||
linearTimestamp: Instant = now()) : Vault<LinearState> {
|
linearTimestamp: Instant = now()): Vault<LinearState> {
|
||||||
val myKey: PublicKey = myInfo.chooseIdentity().owningKey
|
val myKey: PublicKey = myInfo.chooseIdentity().owningKey
|
||||||
val me = AnonymousParty(myKey)
|
val me = AnonymousParty(myKey)
|
||||||
val issuerKey = DUMMY_NOTARY_KEY
|
val issuerKey = DUMMY_NOTARY_KEY
|
||||||
@ -196,7 +196,7 @@ fun calculateRandomlySizedAmounts(howMuch: Amount<Currency>, min: Int, max: Int,
|
|||||||
fun <T : LinearState> ServiceHub.consume(states: List<StateAndRef<T>>, notary: Party) {
|
fun <T : LinearState> ServiceHub.consume(states: List<StateAndRef<T>>, notary: Party) {
|
||||||
// Create a txn consuming different contract types
|
// Create a txn consuming different contract types
|
||||||
states.forEach {
|
states.forEach {
|
||||||
val builder = TransactionBuilder(notary = notary).apply {
|
val builder = TransactionBuilder(notary = notary).apply {
|
||||||
addInputState(it)
|
addInputState(it)
|
||||||
addCommand(dummyCommand(notary.owningKey))
|
addCommand(dummyCommand(notary.owningKey))
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ fun <T : LinearState> ServiceHub.consumeAndProduce(states: List<StateAndRef<T>>,
|
|||||||
fun ServiceHub.consumeDeals(dealStates: List<StateAndRef<DealState>>, notary: Party) = consume(dealStates, notary)
|
fun ServiceHub.consumeDeals(dealStates: List<StateAndRef<DealState>>, notary: Party) = consume(dealStates, notary)
|
||||||
fun ServiceHub.consumeLinearStates(linearStates: List<StateAndRef<LinearState>>, notary: Party) = consume(linearStates, notary)
|
fun ServiceHub.consumeLinearStates(linearStates: List<StateAndRef<LinearState>>, notary: Party) = consume(linearStates, notary)
|
||||||
fun ServiceHub.evolveLinearStates(linearStates: List<StateAndRef<LinearState>>, notary: Party) = consumeAndProduce(linearStates, notary)
|
fun ServiceHub.evolveLinearStates(linearStates: List<StateAndRef<LinearState>>, notary: Party) = consumeAndProduce(linearStates, notary)
|
||||||
fun ServiceHub.evolveLinearState(linearState: StateAndRef<LinearState>, notary: Party) : StateAndRef<LinearState> = consumeAndProduce(linearState, notary)
|
fun ServiceHub.evolveLinearState(linearState: StateAndRef<LinearState>, notary: Party): StateAndRef<LinearState> = consumeAndProduce(linearState, notary)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Consume cash, sending any change to the default identity for this node. Only suitable for use in test scenarios,
|
* Consume cash, sending any change to the default identity for this node. Only suitable for use in test scenarios,
|
||||||
@ -254,7 +254,7 @@ fun ServiceHub.consumeCash(amount: Amount<Currency>, to: Party = CHARLIE, notary
|
|||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun ServiceHub.consumeCash(amount: Amount<Currency>, ourIdentity: PartyAndCertificate, to: Party = CHARLIE, notary: Party): Vault.Update<ContractState> {
|
fun ServiceHub.consumeCash(amount: Amount<Currency>, ourIdentity: PartyAndCertificate, to: Party = CHARLIE, notary: Party): Vault.Update<ContractState> {
|
||||||
val update = vaultService.rawUpdates.toFuture()
|
val update = vaultService.rawUpdates.toFuture()
|
||||||
val services = this
|
val services = this
|
||||||
|
|
||||||
// A tx that spends our money.
|
// A tx that spends our money.
|
||||||
|
@ -29,6 +29,7 @@ class HttpApi(val root: URL, val mapper: ObjectMapper = defaultMapper) {
|
|||||||
companion object {
|
companion object {
|
||||||
fun fromHostAndPort(hostAndPort: NetworkHostAndPort, base: String, protocol: String = "http", mapper: ObjectMapper = defaultMapper): HttpApi
|
fun fromHostAndPort(hostAndPort: NetworkHostAndPort, base: String, protocol: String = "http", mapper: ObjectMapper = defaultMapper): HttpApi
|
||||||
= HttpApi(URL("$protocol://$hostAndPort/$base/"), mapper)
|
= HttpApi(URL("$protocol://$hostAndPort/$base/"), mapper)
|
||||||
|
|
||||||
private val defaultMapper: ObjectMapper by lazy {
|
private val defaultMapper: ObjectMapper by lazy {
|
||||||
net.corda.client.jackson.JacksonSupport.createNonRpcMapper()
|
net.corda.client.jackson.JacksonSupport.createNonRpcMapper()
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,8 @@ object DummyLinearStateSchema
|
|||||||
object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSchema.javaClass, version = 1, mappedTypes = listOf(PersistentDummyLinearState::class.java)) {
|
object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSchema.javaClass, version = 1, mappedTypes = listOf(PersistentDummyLinearState::class.java)) {
|
||||||
@Entity
|
@Entity
|
||||||
@Table(name = "dummy_linear_states",
|
@Table(name = "dummy_linear_states",
|
||||||
indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"),
|
indexes = arrayOf(Index(name = "external_id_idx", columnList = "external_id"),
|
||||||
Index(name = "uuid_idx", columnList = "uuid")))
|
Index(name = "uuid_idx", columnList = "uuid")))
|
||||||
class PersistentDummyLinearState(
|
class PersistentDummyLinearState(
|
||||||
/** [ContractState] attributes */
|
/** [ContractState] attributes */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user