dev
dart 48 lines 1.42 KB
Raw
1 import 'package:cw_core/amount/money.dart';
2 import 'package:cw_core/currency.dart';
3
4 class ExchangeRate {
5 const ExchangeRate({required this.base, required this.quote});
6
7 /// The currency being priced (e.g. BTC in a BTC/USD pair).
8 final Currency base;
9
10 /// The price of one whole unit of [base], in the quote currency
11 /// (e.g. 45000 USD in a BTC/USD pair).
12 final Money quote;
13
14 /// Converts [amount] between the base and quote currencies.
15 ///
16 /// Results are truncated toward zero.
17 ///
18 /// Throws an [ArgumentError] if [amount]'s currency is not part of
19 /// this pair.
20 Money convert(Money amount) {
21 if (base == quote.currency && base == amount.currency) {
22 return amount;
23 }
24
25 if (amount.currency == base) {
26 final scale = BigInt.from(10).pow(amount.decimals);
27
28 return quote.isZero
29 ? Money.zero(quote.currency)
30 : Money(amount.amount * quote.amount ~/ scale, quote.currency, quote.decimals);
31 }
32
33 if (amount.currency == quote.currency) {
34 if (quote.isZero) {
35 return Money.zero(base);
36 }
37
38 final numerator = amount.amount * BigInt.from(10).pow(base.decimals + quote.decimals);
39 final denominator = quote.amount * BigInt.from(10).pow(amount.decimals);
40
41 return Money(numerator ~/ denominator, base);
42 }
43
44 throw ArgumentError(
45 "Unable to convert ${amount.currency.symbol} in ${base.symbol}/${quote.currency.symbol} pair",
46 );
47 }
48 }