mirror of
https://github.com/corda/corda.git
synced 2025-04-07 19:34:41 +00:00
Rewrite ExchangeRate to use BigDecimal
Rewrite ExchangeRate to use BigDecimal for the quantity multiplication, to ensure that there is no loss of precision during the conversion process. The previous version using double-precision floating point maths inherently means that the precision is not fixed, but is floating. Change ExchangeRate to an abstract class rather than an interface, so the functions on it can be implemented directly rather than being extension functions, to improve Java compatibility.
This commit is contained in:
parent
574c476709
commit
b1df11acfa
@ -3,25 +3,30 @@ package net.corda.client.jfx.model
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
import javafx.beans.value.ObservableValue
|
||||
import net.corda.core.contracts.Amount
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
import java.util.*
|
||||
|
||||
|
||||
interface ExchangeRate {
|
||||
fun rate(from: Currency, to: Currency): Double
|
||||
}
|
||||
|
||||
fun ExchangeRate.exchangeAmount(amount: Amount<Currency>, to: Currency) =
|
||||
Amount(exchangeDouble(amount, to).toLong(), to)
|
||||
|
||||
fun ExchangeRate.exchangeDouble(amount: Amount<Currency>, to: Currency) =
|
||||
rate(amount.token, to) * amount.quantity
|
||||
|
||||
/**
|
||||
* This model provides an exchange rate from arbitrary currency to arbitrary currency.
|
||||
* TODO hook up an actual oracle
|
||||
*/
|
||||
abstract class ExchangeRate {
|
||||
/**
|
||||
* Convert the given amount of a currency into the target currency.
|
||||
*
|
||||
* @return the original amount converted to an amount in the target currency.
|
||||
*/
|
||||
fun exchangeAmount(amount: Amount<Currency>, to: Currency) = Amount.fromDecimal(amount.toDecimal().multiply(rate(amount.token, to)), to)
|
||||
|
||||
abstract fun rate(from: Currency, to: Currency): BigDecimal
|
||||
}
|
||||
|
||||
/**
|
||||
* Default implementation of an exchange rate model, which uses a fixed exchange rate.
|
||||
*/
|
||||
// TODO hook up an actual oracle
|
||||
class ExchangeRateModel {
|
||||
val exchangeRate: ObservableValue<ExchangeRate> = SimpleObjectProperty<ExchangeRate>(object : ExchangeRate {
|
||||
override fun rate(from: Currency, to: Currency) = 1.0
|
||||
val exchangeRate: ObservableValue<ExchangeRate> = SimpleObjectProperty<ExchangeRate>(object : ExchangeRate() {
|
||||
override fun rate(from: Currency, to: Currency) = BigDecimal.ONE
|
||||
})
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ object AmountBindings {
|
||||
return EasyBind.combine(observableCurrency, observableExchangeRate) { currency, exchangeRate ->
|
||||
Pair<Currency, (Amount<Currency>) -> Long>(
|
||||
currency,
|
||||
{ (quantity, _, token) -> (exchangeRate.rate(token, currency) * quantity).toLong() }
|
||||
{ amount -> exchangeRate.exchangeAmount(amount, currency).quantity }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user