import { Logger } from '../common' import { BigNumberish, tenExponentiate } from './bignumber' import { Rounding } from './constant' import { Currency, currencyEquals } from './currency' import { Fraction } from './fraction' const logger = Logger.from('entity/price') export class Price extends Fraction { public readonly baseCurrency: Currency // input i.e. denominator public readonly quoteCurrency: Currency // output i.e. numerator // used to adjust the raw fraction w/r/t the decimals of the {base,quote}Token public readonly scalar: Fraction // denominator and numerator _must_ be raw, i.e. in the native representation public constructor( baseCurrency: Currency, denominator: BigNumberish, quoteCurrency: Currency, numerator: BigNumberish, ) { super(numerator, denominator) this.baseCurrency = baseCurrency this.quoteCurrency = quoteCurrency this.scalar = new Fraction(tenExponentiate(baseCurrency.decimals), tenExponentiate(quoteCurrency.decimals)) } public get raw(): Fraction { return new Fraction(this.numerator, this.denominator) } public get adjusted(): Fraction { return super.mul(this.scalar) } public invert(): Price { return new Price(this.quoteCurrency, this.numerator, this.baseCurrency, this.denominator) } public mul(other: Price): Price { logger.assert(currencyEquals(this.quoteCurrency, other.baseCurrency), 'mul currency not equals') const fraction = super.mul(other) return new Price(this.baseCurrency, fraction.denominator, other.quoteCurrency, fraction.numerator) } public toSignificant(significantDigits = this.quoteCurrency.decimals, format?: object, rounding?: Rounding): string { return this.adjusted.toSignificant(significantDigits, format, rounding) } public toFixed(decimalPlaces = this.quoteCurrency.decimals, format?: object, rounding?: Rounding): string { return this.adjusted.toFixed(decimalPlaces, format, rounding) } }