mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Perform sensible currency conversion (#1941)
It is kind of sad to see 1 GBP to be equal to 1 USD and also it looks misleading in the blotter.
This commit is contained in:
parent
44a7d872d8
commit
dcca3179d9
@ -3,8 +3,12 @@ package net.corda.client.jfx.model
|
|||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
import javafx.beans.value.ObservableValue
|
import javafx.beans.value.ObservableValue
|
||||||
import net.corda.core.contracts.Amount
|
import net.corda.core.contracts.Amount
|
||||||
|
import net.corda.finance.CHF
|
||||||
|
import net.corda.finance.EUR
|
||||||
|
import net.corda.finance.GBP
|
||||||
|
import net.corda.finance.USD
|
||||||
import java.math.BigDecimal
|
import java.math.BigDecimal
|
||||||
import java.math.RoundingMode
|
import java.math.MathContext
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,9 +28,24 @@ abstract class ExchangeRate {
|
|||||||
/**
|
/**
|
||||||
* Default implementation of an exchange rate model, which uses a fixed exchange rate.
|
* Default implementation of an exchange rate model, which uses a fixed exchange rate.
|
||||||
*/
|
*/
|
||||||
|
private val usdExchangeRates: Map<Currency, BigDecimal> = mapOf(
|
||||||
|
GBP to BigDecimal(1.31),
|
||||||
|
EUR to BigDecimal(1.18),
|
||||||
|
CHF to BigDecimal(1.01)
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun safeFetchRate(currency: Currency) =
|
||||||
|
usdExchangeRates[currency] ?: throw IllegalArgumentException("No exchange rate for $currency")
|
||||||
|
|
||||||
// TODO hook up an actual oracle
|
// TODO hook up an actual oracle
|
||||||
class ExchangeRateModel {
|
class ExchangeRateModel {
|
||||||
val exchangeRate: ObservableValue<ExchangeRate> = SimpleObjectProperty<ExchangeRate>(object : ExchangeRate() {
|
val exchangeRate: ObservableValue<ExchangeRate> = SimpleObjectProperty<ExchangeRate>(object : ExchangeRate() {
|
||||||
override fun rate(from: Currency, to: Currency) = BigDecimal.ONE
|
override fun rate(from: Currency, to: Currency): BigDecimal =
|
||||||
|
when {
|
||||||
|
from == to -> BigDecimal.ONE
|
||||||
|
USD == to -> safeFetchRate(from)
|
||||||
|
USD == from -> BigDecimal.ONE.divide(safeFetchRate(to), MathContext.DECIMAL64)
|
||||||
|
else -> safeFetchRate(from).divide(safeFetchRate(to), MathContext.DECIMAL64)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package net.corda.client.jfx.model
|
||||||
|
|
||||||
|
import net.corda.core.contracts.Amount
|
||||||
|
import net.corda.finance.CHF
|
||||||
|
import net.corda.finance.GBP
|
||||||
|
import net.corda.finance.RUB
|
||||||
|
import net.corda.finance.USD
|
||||||
|
import org.assertj.core.api.Assertions
|
||||||
|
import org.junit.Test
|
||||||
|
import java.math.BigDecimal
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class ExchangeRateModelTest {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val instance = ExchangeRateModel().exchangeRate.value
|
||||||
|
|
||||||
|
private fun assertEquals(one: Amount<Currency>, another: Amount<Currency>) {
|
||||||
|
assertEquals(one.token, another.token)
|
||||||
|
assertTrue("$one != $another", {(one.toDecimal() - another.toDecimal()).abs() < BigDecimal(0.01) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Test
|
||||||
|
fun `perform fx testing`() {
|
||||||
|
val tenSwissies = Amount(10, BigDecimal.ONE, CHF)
|
||||||
|
assertEquals(instance.exchangeAmount(tenSwissies, CHF), tenSwissies)
|
||||||
|
|
||||||
|
val tenSwissiesInUsd = Amount(101, BigDecimal.ONE.divide(BigDecimal.TEN), USD)
|
||||||
|
assertEquals(instance.exchangeAmount(tenSwissies, USD), tenSwissiesInUsd)
|
||||||
|
|
||||||
|
assertEquals(instance.exchangeAmount(tenSwissiesInUsd, CHF), tenSwissies)
|
||||||
|
|
||||||
|
val tenQuidInSwissies = Amount(1297, BigDecimal.ONE.divide(BigDecimal(100)), CHF)
|
||||||
|
val tenQuid = Amount(10, BigDecimal.ONE, GBP)
|
||||||
|
assertEquals(instance.exchangeAmount(tenQuid, CHF), tenQuidInSwissies)
|
||||||
|
|
||||||
|
assertEquals(instance.exchangeAmount(tenQuidInSwissies, GBP), tenQuid)
|
||||||
|
|
||||||
|
Assertions.assertThatThrownBy { instance.exchangeAmount(tenQuid, RUB) }.isInstanceOf(IllegalArgumentException::class.java)
|
||||||
|
.hasMessage("No exchange rate for RUB")
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user