---
# System prepended metadata

title: Функция estimate (используется на странице)

---

> giveCoinFullInfo = await this.sdk.getCoin(this.giveCoin.toLowerCase())
> giveAmount = Кол-во монет, которые отдают
> getCoinFullInfo = await this.sdk.getCoin(this.getCoin.toLowerCase())

```ts
estimated = sell(this.giveCoinFullInfo, this.giveAmount, this.getCoinFullInfo)
```

> (process.env.baseCoin = 'DEL', если testnet, то 'tDEL')

# Функция estimate (используется на странице)

```ts
public estimate (field) : void {
    let estimated = { success: false, value: '0' } as IEstimated

    if (field === 'giveCoin' || field === 'sellAll') {
      if (field !== 'sellAll') {
        this.mode = 'sell'
      }
      if (this.getCoinFullInfo && this.giveCoinFullInfo && this.giveAmount && this.getCoin && this.giveCoin) {
        estimated = sell(this.giveCoinFullInfo, this.giveAmount, this.getCoinFullInfo)
        // @ts-ignore
        this.getAmount = estimated.success ? this.DecimalNumber(estimated.value).toFixed(18).replace(/^0+(?!\.)|(?:\.|(\..*?))0+$/gm, '$1') : ''
      } else if (!this.giveAmount) {
        this.getAmount = ''
      }
      // @ts-ignore
      this.estimatedGet = estimated
    } else if (field === 'getCoin') {
      this.mode = 'buy'
      if (this.getCoinFullInfo && this.giveCoinFullInfo && this.getAmount && this.getCoin && this.giveCoin) {
        estimated = buy(this.getCoinFullInfo, this.getAmount, this.giveCoinFullInfo)
        // @ts-ignore
        this.giveAmount = estimated.success ? this.DecimalNumber(estimated.value).toFixed(18).replace(/^0+(?!\.)|(?:\.|(\..*?))0+$/gm, '$1') : ''
      } else if (!this.getAmount) {
        this.giveAmount = ''
      }
      // @ts-ignore
      this.estimatedSpend = estimated
    }
  }
```

# math.ts

```ts
import DecimalNumber from 'decimal.js'

interface ICoin {
  crr: string;
  ticker: any;
  reserve: string ;
  maxSupply?: string;
  supply: string
}

DecimalNumber.set({ precision: 100 })

function getAmountFromSatoshi (amount: DecimalNumber.Value): string {
  return new DecimalNumber(amount).times(new DecimalNumber(10).pow(-18)).toFixed()
}

function getCoinFormatted (coinData: { volume: DecimalNumber.Value; reserve: DecimalNumber.Value; crr: DecimalNumber.Value; limitVolume: DecimalNumber.Value; symbol: any; })
  : ICoin {
  return {
    supply: getAmountFromSatoshi(coinData.volume),
    reserve: getAmountFromSatoshi(coinData.reserve),
    crr: new DecimalNumber(coinData.crr).div(100).toFixed(),
    maxSupply: getAmountFromSatoshi(coinData.limitVolume),
    ticker: coinData.symbol
  }
}

/**
 * Sell:
 * Продажа монеты, подсчет получаемых del
 */
export const sellCoin = (coin: ICoin, coinAmount: DecimalNumber.Value): string | boolean => {
  const crr = new DecimalNumber(coin.crr).times(100).toNumber()

  if (new DecimalNumber(coinAmount).eq(new DecimalNumber(0))) {
    return '0'
  }
  if (new DecimalNumber(coinAmount).eq(new DecimalNumber(coin.supply))) {
    return coin.reserve
  }
  if (new DecimalNumber(crr).eq(new DecimalNumber(100))) {
    const ret = new DecimalNumber(coin.reserve).times(new DecimalNumber(coinAmount))
    return ret.div(new DecimalNumber(coin.supply)).toFixed().toString()
  }

  const e1 = new DecimalNumber(coinAmount).div(coin.supply)
  const e2 = new DecimalNumber(1).minus(e1)
  if (e2 < new DecimalNumber(0)) { return false }
  const e3 = e2.pow(new DecimalNumber(100).div(crr))
  const e4 = new DecimalNumber(1).minus(e3)
  return e4.times(coin.reserve).toFixed()
}

/**
 * Sell:
 * Продажа монеты, подсчет необходимых монет
 */
export const sellCoinByDel = (coin: ICoin, delAmount: DecimalNumber.Value): string => {
  // eslint-disable-next-line no-param-reassign
  delAmount = Math.min(parseFloat(coin.reserve), +delAmount)
  const e1 = new DecimalNumber(delAmount).div(coin.reserve)
  const e2 = new DecimalNumber(1).minus(e1).pow(coin.crr)
  const result = new DecimalNumber(1).minus(e2).times(coin.supply) // => coin

  return result.toFixed()
}

/**
 * Buy:
 * Покупка монеты, подсчет получаемых монет
 */
export const buyCoin = (coin: ICoin, delAmount: string | number | DecimalNumber.Value): string => {
  const e1 = new DecimalNumber(delAmount).div(coin.reserve).plus(1).pow(coin.crr)
  const result = new DecimalNumber(e1).minus(1).times(coin.supply) // => coin

  return result.toFixed()
}

/**
 * Buy:
 * Покупка монеты, подсчет необходимых del
 */
export const buyCoinByCoin = (coin: ICoin, coinAmount: number | string): string => {
  const e1 = new DecimalNumber(coinAmount).div(coin.supply).plus(1)
  const e2 = new DecimalNumber(1).div(coin.crr)
  const result = new DecimalNumber(e1).pow(e2).minus(1).times(coin.reserve) // => del

  return result.toFixed()
}

function isLessReserve (spendCoin: { reserve: DecimalNumber.Value; ticker: string; }, amount: DecimalNumber.Value): false | {key: string, coin:string} {
  // console.log('spend-coin', spendCoin);
  // console.log('amount', amount);
  const maxDelSpend = new DecimalNumber(spendCoin.reserve).minus(1000).toFixed()

  if (!amount || new DecimalNumber(amount).gt(maxDelSpend)) {
    return {
      key: 'reserve-limit',
      coin: spendCoin.ticker.toUpperCase()
    }
  }
  return false
}
function isMoreMaxSupply (getCoin:any, amount: DecimalNumber.Value):false | {key: string, coin:string} {
  const available = new DecimalNumber(getCoin.maxSupply).minus(getCoin.supply).toFixed() // => coin

  if (new DecimalNumber(amount).gt(available)) {
    return {
      key: 'more-limit-volume',
      coin: getCoin.ticker.toUpperCase()
    }
  }
  return false
}
// Todo
export function buy (getCoinn: any, amount: string | number, spendCoinn: any) : {success:boolean, value?:string, key?: string, coin?:string} {
  const spendCoin = getCoinFormatted(spendCoinn)
  const getCoin = getCoinFormatted(getCoinn)
  // console.log('buy');
  let estimated: any = ''
  let error: false | {key: string, coin:string} = false

  if (
    // @ts-ignore
    getCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
    estimated = sellCoinByDel(spendCoin, amount) // => coin
    error = isLessReserve(spendCoin, amount)
  } else if (
    // @ts-ignore
    spendCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
    estimated = buyCoinByCoin(getCoin, amount) // => tdel
    error = isMoreMaxSupply(getCoin, amount)
  } else {
    const needDel = buyCoinByCoin(getCoin, amount) // => tdel
    estimated = sellCoinByDel(spendCoin, needDel) // => coin
    error = isMoreMaxSupply(getCoin, amount)
    error = error || isLessReserve(spendCoin, needDel)
  }

  // error = error || isInfluentFunds(estimated, spendCoin);

  if (error) {
    return {
      success: false,
      ...error
    }
  }

  return {
    success: true,
    value: estimated
  }
}

export function sell (spendCoinn: any, amount: string | number | DecimalNumber, getCoinn: any) : {success?:boolean, value?:string, key?: string, coin?:string} {
  const spendCoin = getCoinFormatted(spendCoinn)
  const getCoin = getCoinFormatted(getCoinn)
  // console.log('sell');
  let estimated: any = ''
  let error : any = false

  if (
    // @ts-ignore
    spendCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
    estimated = buyCoin(getCoin, amount) // => coin
    error = isMoreMaxSupply(getCoin, estimated)
  } else if (
    // @ts-ignore
    getCoin.ticker.toLowerCase() === process.env.baseCoin.toLowerCase()) {
    estimated = sellCoin(spendCoin, amount)
    error = isLessReserve(spendCoin, estimated)
  } else {
    const needDel = String(sellCoin(spendCoin, amount)) // => tdel
    estimated = buyCoin(getCoin, needDel) // => coin
    error = isMoreMaxSupply(getCoin, amount)
    error = error || isLessReserve(spendCoin, needDel)
  }

  // error = error || isInfluentFunds(amount, spendCoin);

  if (error) {
    return {
      success: false,
      ...error
    }
  }

  return {
    success: true,
    value: estimated
  }
}
```