From 45981c0c77bd5a682c99cf3f36f7097fc8277c72 Mon Sep 17 00:00:00 2001 From: Anatoly Date: Thu, 6 Feb 2025 00:14:21 +0700 Subject: [PATCH] Update convert.go --- hyperliquid/convert.go | 44 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/hyperliquid/convert.go b/hyperliquid/convert.go index fc9f600..911ccb3 100644 --- a/hyperliquid/convert.go +++ b/hyperliquid/convert.go @@ -4,6 +4,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "math" "math/big" "strconv" "strings" @@ -56,8 +57,8 @@ func OrderRequestToWire(req OrderRequest, meta map[string]AssetInfo, isSpot bool return OrderWire{ Asset: assetId, IsBuy: req.IsBuy, - LimitPx: FloatToWire(req.LimitPx, maxDecimals, info.SzDecimals), - SizePx: FloatToWire(req.Sz, maxDecimals, info.SzDecimals), + LimitPx: RoundOrderPrice(req.LimitPx, info.SzDecimals, maxDecimals), + SizePx: RoundOrderSize(req.Sz, info.SzDecimals), ReduceOnly: req.ReduceOnly, OrderType: OrderTypeToWire(req.OrderType), Cloid: req.Cloid, @@ -80,8 +81,8 @@ func ModifyOrderRequestToWire(req ModifyOrderRequest, meta map[string]AssetInfo, Order: OrderWire{ Asset: assetId, IsBuy: req.IsBuy, - LimitPx: FloatToWire(req.LimitPx, maxDecimals, info.SzDecimals), - SizePx: FloatToWire(req.Sz, maxDecimals, info.SzDecimals), + LimitPx: RoundOrderPrice(req.LimitPx, info.SzDecimals, maxDecimals), + SizePx: RoundOrderSize(req.Sz, info.SzDecimals), ReduceOnly: req.ReduceOnly, OrderType: OrderTypeToWire(req.OrderType), }, @@ -143,3 +144,38 @@ func StructToMap(strct any) (res map[string]interface{}, err error) { json.Unmarshal(a, &res) return res, nil } + +// Round the order size to the nearest tick size +func RoundOrderSize(x float64, szDecimals int) string { + newX := math.Round(x*math.Pow10(szDecimals)) / math.Pow10(szDecimals) + // TODO: add rounding + return big.NewFloat(newX).Text('f', szDecimals) +} + +// Round the order price to the nearest tick size +func RoundOrderPrice(x float64, szDecimals int, maxDecimals int) string { + maxSignFigures := 5 + allowedDecimals := maxDecimals - szDecimals + numberOfDigitsInIntegerPart := len(strconv.Itoa(int(x))) + if numberOfDigitsInIntegerPart >= maxSignFigures { + return RoundOrderSize(x, 0) + } + allowedSignFigures := maxSignFigures - numberOfDigitsInIntegerPart + if x < 1 { + text := RoundOrderSize(x, allowedDecimals) + startSignFigures := false + for i := 2; i < len(text); i++ { + if text[i] == '0' && !startSignFigures { + continue + } + startSignFigures = true + allowedSignFigures-- + if allowedSignFigures == 0 { + return text[:i+1] + } + } + return text + } else { + return RoundOrderSize(x, min(allowedSignFigures, allowedDecimals)) + } +}