mirror of
https://github.com/corda/corda.git
synced 2024-12-24 23:26:48 +00:00
Added more type information to various API endpoints to make it possible to test. Integration test passes.
This commit is contained in:
parent
234ffb141c
commit
008fcf50fd
samples/simm-valuation-demo/src
integration-test/kotlin/net/corda/vega
main/kotlin/net/corda/vega/api
@ -9,28 +9,38 @@ import net.corda.testing.IntegrationTestCategory
|
||||
import net.corda.testing.getHostAndPort
|
||||
import net.corda.testing.http.HttpApi
|
||||
import net.corda.vega.api.PortfolioApi
|
||||
import net.corda.vega.api.PortfolioApiUtils
|
||||
import net.corda.vega.api.SwapDataModel
|
||||
import net.corda.vega.portfolio.Portfolio
|
||||
import org.junit.Test
|
||||
import java.math.BigDecimal
|
||||
import java.time.LocalDate
|
||||
import java.util.*
|
||||
|
||||
class SimmValuationTest: IntegrationTestCategory {
|
||||
private companion object {
|
||||
// SIMM demo can only currently handle one valuation date due to a lack of market data or a market data source.
|
||||
val valuationDate = LocalDate.parse("2016-06-06")
|
||||
val nodeALegalName = "Bank A"
|
||||
val nodeBLegalName = "Bank B"
|
||||
}
|
||||
|
||||
@Test fun `runs SIMM valuation demo`() {
|
||||
driver(isDebug = true) {
|
||||
val nodeBLegalName = "Bank B"
|
||||
val controller = startNode("Controller", setOf(ServiceInfo(SimpleNotaryService.type))).getOrThrow()
|
||||
val nodeAAddr = startNode("Bank A").getOrThrow().config.getHostAndPort("webAddress")
|
||||
startNode("Controller", setOf(ServiceInfo(SimpleNotaryService.type))).getOrThrow()
|
||||
val nodeAAddr = startNode(nodeALegalName).getOrThrow().config.getHostAndPort("webAddress")
|
||||
val nodeBAddr = startNode(nodeBLegalName).getOrThrow().config.getHostAndPort("webAddress")
|
||||
|
||||
val nodeA = HttpApi.fromHostAndPort(nodeAAddr, "api/simmvaluationdemo")
|
||||
val nodeB = HttpApi.fromHostAndPort(nodeBAddr, "api/simmvaluationdemo")
|
||||
|
||||
val parties = getAvailablePartiesFor(nodeA)
|
||||
val nodeB = parties.counterparties.single { it.text == nodeBLegalName}
|
||||
assert(createTradeBetween(nodeA, nodeB))
|
||||
assert(runValuationsBetween(nodeA, nodeB))
|
||||
waitForAllNodesToFinish()
|
||||
val nodeBParty = getAvailablePartiesFor(nodeA).counterparties.single { it.text == nodeBLegalName }
|
||||
val nodeAParty = getAvailablePartiesFor(nodeB).counterparties.single { it.text == nodeALegalName }
|
||||
|
||||
assert(createTradeBetween(nodeA, nodeBParty))
|
||||
assert(tradeExists(nodeB, nodeAParty))
|
||||
assert(runValuationsBetween(nodeA, nodeBParty))
|
||||
assert(valuationExists(nodeB, nodeAParty))
|
||||
}
|
||||
}
|
||||
|
||||
@ -39,12 +49,22 @@ class SimmValuationTest: IntegrationTestCategory {
|
||||
}
|
||||
|
||||
private fun createTradeBetween(api: HttpApi, counterparty: PortfolioApi.ApiParty): Boolean {
|
||||
val trade = SwapDataModel("trade1", "desc", LocalDate.parse("2016-01-01"), "EUR_FIXED_1Y_EURIBOR_3M",
|
||||
LocalDate.parse("2016-01-02"), LocalDate.parse("2020-01-02"), BuySell.BUY, BigDecimal.valueOf(1000), BigDecimal.valueOf(0.1))
|
||||
val trade = SwapDataModel("trade1", "desc", valuationDate, "EUR_FIXED_1Y_EURIBOR_3M",
|
||||
valuationDate, LocalDate.parse("2020-01-02"), BuySell.BUY, BigDecimal.valueOf(1000), BigDecimal.valueOf(0.1))
|
||||
return api.putJson("${counterparty.id}/trades", trade)
|
||||
}
|
||||
|
||||
private fun tradeExists(api: HttpApi, counterparty: PortfolioApi.ApiParty): Boolean {
|
||||
val trades = api.getJson<List<Map<String, Any>>>("${counterparty.id}/trades")
|
||||
return (!trades.isEmpty())
|
||||
}
|
||||
|
||||
private fun runValuationsBetween(api: HttpApi, counterparty: PortfolioApi.ApiParty): Boolean {
|
||||
return api.postJson("${counterparty.id}/trade/TODO/valuations/calculate")
|
||||
return api.postJson("${counterparty.id}/portfolio/valuations/calculate", PortfolioApi.ValuationCreationParams(valuationDate))
|
||||
}
|
||||
|
||||
private fun valuationExists(api: HttpApi, counterparty: PortfolioApi.ApiParty): Boolean {
|
||||
val valuations = api.getJson<PortfolioApiUtils.ValuationsView>("${counterparty.id}/portfolio/valuations")
|
||||
return (valuations.initialMargin.call["total"] != 0.0)
|
||||
}
|
||||
}
|
@ -15,7 +15,16 @@ import java.time.LocalDate
|
||||
* API JSON generation functions for larger JSON outputs.
|
||||
*/
|
||||
class PortfolioApiUtils(private val ownParty: Party) {
|
||||
fun createValuations(state: PortfolioState, portfolio: Portfolio): Any {
|
||||
data class InitialMarginView(val baseCurrency: String, val post: Map<String, Double>, val call: Map<String, Double>, val agreed: Boolean)
|
||||
data class ValuationsView(
|
||||
val businessDate: LocalDate,
|
||||
val portfolio: Map<String, Any>,
|
||||
val marketData: Map<String, Any>,
|
||||
val sensitivities: Map<String, Any>,
|
||||
val initialMargin: InitialMarginView,
|
||||
val confirmation: Map<String, Any>)
|
||||
|
||||
fun createValuations(state: PortfolioState, portfolio: Portfolio): ValuationsView {
|
||||
val valuation = state.valuation!!
|
||||
|
||||
val currency = if (portfolio.trades.isNotEmpty()) {
|
||||
@ -61,10 +70,28 @@ class PortfolioApiUtils(private val ownParty: Party) {
|
||||
|
||||
val processedSensitivities = valuation.totalSensivities.sensitivities.map { it.marketDataName to it.parameterMetadata.map { it.label }.zip(it.sensitivity.toList()).toMap() }.toMap()
|
||||
|
||||
return json {
|
||||
val initialMarginView = InitialMarginView(
|
||||
baseCurrency = currency,
|
||||
post = mapOf(
|
||||
"IRFX" to valuation.margin.first,
|
||||
"commodity" to 0.0,
|
||||
"equity" to 0.0,
|
||||
"credit" to 0.0,
|
||||
"total" to valuation.margin.first
|
||||
),
|
||||
call = mapOf(
|
||||
"IRFX" to valuation.margin.first,
|
||||
"commodity" to 0.0,
|
||||
"equity" to 0.0,
|
||||
"credit" to 0.0,
|
||||
"total" to valuation.margin.first
|
||||
),
|
||||
agreed = true)
|
||||
|
||||
return ValuationsView(
|
||||
businessDate = LocalDate.now(),
|
||||
portfolio = json {
|
||||
obj(
|
||||
"businessDate" to LocalDate.now(),
|
||||
"portfolio" to obj(
|
||||
"trades" to tradeCount,
|
||||
"baseCurrency" to currency,
|
||||
"IRFX" to tradeCount,
|
||||
@ -73,13 +100,17 @@ class PortfolioApiUtils(private val ownParty: Party) {
|
||||
"credit" to 0,
|
||||
"total" to tradeCount,
|
||||
"agreed" to true
|
||||
),
|
||||
"marketData" to obj(
|
||||
)
|
||||
},
|
||||
marketData = json {
|
||||
obj(
|
||||
"yieldCurves" to yieldCurves,
|
||||
"fixings" to fixings,
|
||||
"agreed" to true
|
||||
),
|
||||
"sensitivities" to obj("curves" to processedSensitivities,
|
||||
)
|
||||
},
|
||||
sensitivities = json {
|
||||
obj("curves" to processedSensitivities,
|
||||
"currency" to valuation.currencySensitivies.amounts.toList().map {
|
||||
obj(
|
||||
"currency" to it.currency.code,
|
||||
@ -87,31 +118,16 @@ class PortfolioApiUtils(private val ownParty: Party) {
|
||||
)
|
||||
},
|
||||
"agreed" to true
|
||||
),
|
||||
"initialMargin" to obj(
|
||||
"baseCurrency" to currency,
|
||||
"post" to obj(
|
||||
"IRFX" to valuation.margin.first,
|
||||
"commodity" to 0,
|
||||
"equity" to 0,
|
||||
"credit" to 0,
|
||||
"total" to valuation.margin.first
|
||||
),
|
||||
"call" to obj(
|
||||
"IRFX" to valuation.margin.first,
|
||||
"commodity" to 0,
|
||||
"equity" to 0,
|
||||
"credit" to 0,
|
||||
"total" to valuation.margin.first
|
||||
),
|
||||
"agreed" to true
|
||||
),
|
||||
"confirmation" to obj(
|
||||
)
|
||||
},
|
||||
initialMargin = initialMarginView,
|
||||
confirmation = json {
|
||||
obj(
|
||||
"hash" to state.hash().toString(),
|
||||
"agreed" to true
|
||||
)
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
fun createTradeView(state: IRSState): Any {
|
||||
|
Loading…
Reference in New Issue
Block a user