decred.org/dcrdex@v1.0.5/dex/calc/convert.go (about)

     1  // This code is available on the terms of the project LICENSE.md file,
     2  // also available online at https://blueoakcouncil.org/license/1.0.0.
     3  
     4  package calc
     5  
     6  import (
     7  	"math/big"
     8  
     9  	"decred.org/dcrdex/dex"
    10  )
    11  
    12  // RateEncodingFactor is used when encoding an exchange rate as an integer.
    13  // https://github.com/decred/dcrdex/blob/master/spec/comm.mediawiki#Rate_Encoding
    14  const RateEncodingFactor = 1e8
    15  
    16  var (
    17  	bigRateConversionFactor = big.NewInt(RateEncodingFactor)
    18  )
    19  
    20  // BaseToQuote computes a quote asset amount based on a base asset amount
    21  // and an integer representation of the price rate. That is,
    22  //
    23  //	quoteAmt = rate * baseAmt / atomsPerCoin
    24  func BaseToQuote(rate uint64, base uint64) (quote uint64) {
    25  	bigRate := big.NewInt(int64(rate))
    26  	bigBase := big.NewInt(int64(base))
    27  	bigBase.Mul(bigBase, bigRate)
    28  	bigBase.Div(bigBase, bigRateConversionFactor)
    29  	return bigBase.Uint64()
    30  }
    31  
    32  // QuoteToBase computes a base asset amount based on a quote asset amount
    33  // and an integer representation of the price rate. That is,
    34  //
    35  //	baseAmt = quoteAmt * atomsPerCoin / rate
    36  func QuoteToBase(rate uint64, quote uint64) (base uint64) {
    37  	if rate == 0 {
    38  		return 0 // caller handle rate==0, but don't panic
    39  	}
    40  	bigRate := big.NewInt(int64(rate))
    41  	bigQuote := big.NewInt(int64(quote))
    42  	bigQuote.Mul(bigQuote, bigRateConversionFactor)
    43  	bigQuote.Div(bigQuote, bigRate)
    44  	return bigQuote.Uint64()
    45  }
    46  
    47  // ConventionalRate converts an exchange rate in message-rate encoding to a
    48  // conventional exchange rate, using the base and quote assets' UnitInfo.
    49  func ConventionalRate(msgRate uint64, baseInfo, quoteInfo dex.UnitInfo) float64 {
    50  	return ConventionalRateAlt(msgRate, baseInfo.Conventional.ConversionFactor, quoteInfo.Conventional.ConversionFactor)
    51  }
    52  
    53  // ConventionalRateAlt converts an exchange rate in message-rate encoding to a
    54  // conventional exchange rate using the base and quote assets' conventional
    55  // conversion factors.
    56  func ConventionalRateAlt(msgRate uint64, baseFactor, quoteFactor uint64) float64 {
    57  	return float64(msgRate) / RateEncodingFactor * float64(baseFactor) / float64(quoteFactor)
    58  }
    59  
    60  // MessageRate converts an exchange rate in conventional encoding to one
    61  // in message-rate encoding using the base and quote assets' UnitInfo.
    62  func MessageRate(conventionalRate float64, baseInfo, quoteInfo dex.UnitInfo) uint64 {
    63  	return MessageRateAlt(conventionalRate, baseInfo.Conventional.ConversionFactor, quoteInfo.Conventional.ConversionFactor)
    64  }
    65  
    66  // MessageRateAlt converts an exchange rate in conventional encoding to one
    67  // in message-rate encoding using the base and quote assets' conventional
    68  // conversion factors.
    69  func MessageRateAlt(conventionalRate float64, baseFactor, quoteFactor uint64) uint64 {
    70  	return uint64(conventionalRate * RateEncodingFactor / float64(baseFactor) * float64(quoteFactor))
    71  }