This repository has been archived by the owner on May 11, 2023. It is now read-only.
/
price_tick_conversions.go
69 lines (63 loc) · 2 KB
/
price_tick_conversions.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package utils
import (
"math/big"
"github.com/daoleno/uniswap-sdk-core/entities"
"github.com/KyberNetwork/promm-sdk-go/constants"
)
/**
* Returns a price object corresponding to the input tick and the base/quote token
* Inputs must be tokens because the address order is used to interpret the price represented by the tick
* @param baseToken the base token of the price
* @param quoteToken the quote token of the price
* @param tick the tick for which to return the price
*/
func TickToPrice(baseToken *entities.Token, quoteToken *entities.Token, tick int) (*entities.Price, error) {
sqrtRatioX96, err := GetSqrtRatioAtTick(tick)
if err != nil {
return nil, err
}
ratioX192 := new(big.Int).Mul(sqrtRatioX96, sqrtRatioX96)
sorted, err := baseToken.SortsBefore(quoteToken)
if err != nil {
return nil, err
}
if sorted {
return entities.NewPrice(baseToken, quoteToken, constants.Q192, ratioX192), nil
}
return entities.NewPrice(baseToken, quoteToken, ratioX192, constants.Q192), nil
}
/**
* Returns the first tick for which the given price is greater than or equal to the tick price
* @param price for which to return the closest tick that represents a price less than or equal to the input price,
* i.e. the price of the returned tick is less than or equal to the input price
*/
func PriceToClosestTick(price *entities.Price, baseToken, quoteToken *entities.Token) (int, error) {
sorted, err := baseToken.SortsBefore(quoteToken)
if err != nil {
return 0, err
}
var sqrtRatioX96 *big.Int
if sorted {
sqrtRatioX96 = EncodeSqrtRatioX96(price.Numerator, price.Denominator)
} else {
sqrtRatioX96 = EncodeSqrtRatioX96(price.Denominator, price.Numerator)
}
tick, err := GetTickAtSqrtRatio(sqrtRatioX96)
if err != nil {
return 0, err
}
nextTickPrice, err := TickToPrice(baseToken, quoteToken, tick+1)
if err != nil {
return 0, err
}
if sorted {
if !price.LessThan(nextTickPrice.Fraction) {
tick++
}
} else {
if !price.GreaterThan(nextTickPrice.Fraction) {
tick++
}
}
return tick, nil
}