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.value.ObservableValue
|
||||
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.RoundingMode
|
||||
import java.math.MathContext
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
@ -24,9 +28,24 @@ abstract class ExchangeRate {
|
||||
/**
|
||||
* 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
|
||||
class ExchangeRateModel {
|
||||
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