github.com/InjectiveLabs/sdk-go@v1.53.0/client/core/market_test.go (about) 1 package core 2 3 import ( 4 "testing" 5 6 sdkmath "cosmossdk.io/math" 7 8 "github.com/huandu/go-assert" 9 "github.com/shopspring/decimal" 10 ) 11 12 func createINJUSDTSpotMarket() SpotMarket { 13 injToken := createINJToken() 14 usdtToken := createUSDTToken() 15 16 makerFeeRate := decimal.RequireFromString("-0.0001") 17 takerFeeRate := decimal.RequireFromString("0.001") 18 serviceProviderFee := decimal.RequireFromString("0.4") 19 minPriceTickSize := decimal.RequireFromString("0.000000000000001") 20 minQuantityTickSize := decimal.RequireFromString("1000000000000000") 21 minNotional := decimal.RequireFromString("1000000") 22 23 market := SpotMarket{ 24 Id: "0x7a57e705bb4e09c88aecfc295569481dbf2fe1d5efe364651fbe72385938e9b0", 25 Status: "active", 26 Ticker: "INJ/USDT", 27 BaseToken: injToken, 28 QuoteToken: usdtToken, 29 MakerFeeRate: makerFeeRate, 30 TakerFeeRate: takerFeeRate, 31 ServiceProviderFee: serviceProviderFee, 32 MinPriceTickSize: minPriceTickSize, 33 MinQuantityTickSize: minQuantityTickSize, 34 MinNotional: minNotional, 35 } 36 return market 37 } 38 39 func createBTCUSDTPerpMarket() DerivativeMarket { 40 usdtToken := createUSDTToken() 41 42 initialMarginRatio := decimal.RequireFromString("0.095") 43 maintenanceMarginRatio := decimal.RequireFromString("0.025") 44 makerFeeRate := decimal.RequireFromString("-0.0001") 45 takerFeeRate := decimal.RequireFromString("0.001") 46 serviceProviderFee := decimal.RequireFromString("0.4") 47 minPriceTickSize := decimal.RequireFromString("1000000") 48 minQuantityTickSize := decimal.RequireFromString("0.0001") 49 minNotional := decimal.RequireFromString("1000000") 50 51 market := DerivativeMarket{ 52 Id: "0x4ca0f92fc28be0c9761326016b5a1a2177dd6375558365116b5bdda9abc229ce", 53 Status: "active", 54 Ticker: "BTC/USDT PERP", 55 OracleBase: "BTC", 56 OracleQuote: usdtToken.Symbol, 57 OracleType: "bandibc", 58 OracleScaleFactor: 6, 59 InitialMarginRatio: initialMarginRatio, 60 MaintenanceMarginRatio: maintenanceMarginRatio, 61 QuoteToken: usdtToken, 62 MakerFeeRate: makerFeeRate, 63 TakerFeeRate: takerFeeRate, 64 ServiceProviderFee: serviceProviderFee, 65 MinPriceTickSize: minPriceTickSize, 66 MinQuantityTickSize: minQuantityTickSize, 67 MinNotional: minNotional, 68 } 69 return market 70 } 71 72 // Spot market tests 73 74 func TestConvertQuantityToChainFormatForSpotMarket(t *testing.T) { 75 spotMarket := createINJUSDTSpotMarket() 76 originalQuantity := decimal.RequireFromString("123.456789") 77 78 chainValue := spotMarket.QuantityToChainFormat(originalQuantity) 79 expectedValue := originalQuantity.Mul(decimal.New(1, spotMarket.BaseToken.Decimals)) 80 quantizedValue := expectedValue.DivRound(spotMarket.MinQuantityTickSize, 0).Mul(spotMarket.MinQuantityTickSize) 81 quantizedChainFormatValue := sdkmath.LegacyMustNewDecFromStr(quantizedValue.String()) 82 83 assert.Assert(t, quantizedChainFormatValue.Equal(chainValue)) 84 } 85 86 func TestConvertPriceToChainFormatForSpotMarket(t *testing.T) { 87 spotMarket := createINJUSDTSpotMarket() 88 originalPrice := decimal.RequireFromString("123.456789") 89 90 chainValue := spotMarket.PriceToChainFormat(originalPrice) 91 priceDecimals := spotMarket.QuoteToken.Decimals - spotMarket.BaseToken.Decimals 92 expectedValue := originalPrice.Mul(decimal.New(1, priceDecimals)) 93 quantizedValue := expectedValue.DivRound(spotMarket.MinPriceTickSize, 0).Mul(spotMarket.MinPriceTickSize) 94 quantizedChainFormatValue := sdkmath.LegacyMustNewDecFromStr(quantizedValue.String()) 95 96 assert.Assert(t, quantizedChainFormatValue.Equal(chainValue)) 97 } 98 99 func TestConvertNotionalToChainFormatForSpotMarket(t *testing.T) { 100 spotMarket := createINJUSDTSpotMarket() 101 originalNotional := decimal.RequireFromString("123.456789") 102 103 chainValue := spotMarket.NotionalToChainFormat(originalNotional) 104 notionalDecimals := spotMarket.QuoteToken.Decimals 105 expectedValue := originalNotional.Mul(decimal.New(1, notionalDecimals)) 106 chainFormatValue := sdkmath.LegacyMustNewDecFromStr(expectedValue.String()) 107 108 assert.Assert(t, chainFormatValue.Equal(chainValue)) 109 } 110 111 func TestConvertQuantityFromChainFormatForSpotMarket(t *testing.T) { 112 spotMarket := createINJUSDTSpotMarket() 113 expectedQuantity := decimal.RequireFromString("123.456") 114 115 chainFormatQuantity := expectedQuantity.Mul(decimal.New(1, spotMarket.BaseToken.Decimals)) 116 humanReadableQuantity := spotMarket.QuantityFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatQuantity.String())) 117 118 assert.Assert(t, expectedQuantity.Equal(humanReadableQuantity)) 119 } 120 121 func TestConvertPriceFromChainFormatForSpotMarket(t *testing.T) { 122 spotMarket := createINJUSDTSpotMarket() 123 expectedPrice := decimal.RequireFromString("123.456") 124 125 priceDecimals := spotMarket.QuoteToken.Decimals - spotMarket.BaseToken.Decimals 126 chainFormatPrice := expectedPrice.Mul(decimal.New(1, priceDecimals)) 127 humanReadablePrice := spotMarket.PriceFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatPrice.String())) 128 129 assert.Assert(t, expectedPrice.Equal(humanReadablePrice)) 130 } 131 132 func TestConvertNotionalFromChainFormatForSpotMarket(t *testing.T) { 133 spotMarket := createINJUSDTSpotMarket() 134 expectedNotional := decimal.RequireFromString("123.456") 135 136 notionalDecimals := spotMarket.QuoteToken.Decimals 137 chainFormatPrice := expectedNotional.Mul(decimal.New(1, notionalDecimals)) 138 humanReadableNotional := spotMarket.NotionalFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatPrice.String())) 139 140 assert.Assert(t, expectedNotional.Equal(humanReadableNotional)) 141 } 142 143 func TestConvertQuantityFromExtendedChainFormatForSpotMarket(t *testing.T) { 144 spotMarket := createINJUSDTSpotMarket() 145 expectedQuantity := decimal.RequireFromString("123.456") 146 147 chainFormatQuantity := expectedQuantity.Mul(decimal.New(1, spotMarket.BaseToken.Decimals)).Mul(decimal.New(1, AdditionalChainFormatDecimals)) 148 humanReadableQuantity := spotMarket.QuantityFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatQuantity.String())) 149 150 assert.Assert(t, expectedQuantity.Equal(humanReadableQuantity)) 151 } 152 153 func TestConvertPriceFromExtendedChainFormatForSpotMarket(t *testing.T) { 154 spotMarket := createINJUSDTSpotMarket() 155 expectedPrice := decimal.RequireFromString("123.456") 156 157 priceDecimals := spotMarket.QuoteToken.Decimals - spotMarket.BaseToken.Decimals 158 chainFormatPrice := expectedPrice.Mul(decimal.New(1, priceDecimals)).Mul(decimal.New(1, AdditionalChainFormatDecimals)) 159 humanReadablePrice := spotMarket.PriceFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatPrice.String())) 160 161 assert.Assert(t, expectedPrice.Equal(humanReadablePrice)) 162 } 163 164 func TestConvertNotionalFromExtendedChainFormatForSpotMarket(t *testing.T) { 165 spotMarket := createINJUSDTSpotMarket() 166 expectedNotional := decimal.RequireFromString("123.456") 167 168 notionalDecimals := spotMarket.QuoteToken.Decimals 169 chainFormatNotional := expectedNotional.Mul(decimal.New(1, notionalDecimals)).Mul(decimal.New(1, AdditionalChainFormatDecimals)) 170 humanReadableNotional := spotMarket.NotionalFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatNotional.String())) 171 172 assert.Assert(t, expectedNotional.Equal(humanReadableNotional)) 173 } 174 175 // Derivative markets tests 176 177 func TestConvertQuantityToChainFormatForDerivativeMarket(t *testing.T) { 178 derivativeMarket := createBTCUSDTPerpMarket() 179 originalQuantity := decimal.RequireFromString("123.456789") 180 181 chainValue := derivativeMarket.QuantityToChainFormat(originalQuantity) 182 quantizedValue := originalQuantity.DivRound(derivativeMarket.MinQuantityTickSize, 0).Mul(derivativeMarket.MinQuantityTickSize) 183 quantizedChainFormatValue := sdkmath.LegacyMustNewDecFromStr(quantizedValue.String()) 184 185 assert.Assert(t, quantizedChainFormatValue.Equal(chainValue)) 186 } 187 188 func TestConvertPriceToChainFormatForDerivativeMarket(t *testing.T) { 189 derivativeMarket := createBTCUSDTPerpMarket() 190 originalPrice := decimal.RequireFromString("123.456789") 191 192 chainValue := derivativeMarket.PriceToChainFormat(originalPrice) 193 priceDecimals := derivativeMarket.QuoteToken.Decimals 194 expectedValue := originalPrice.Mul(decimal.New(1, priceDecimals)) 195 quantizedValue := expectedValue.DivRound(derivativeMarket.MinPriceTickSize, 0).Mul(derivativeMarket.MinPriceTickSize) 196 quantizedChainFormatValue := sdkmath.LegacyMustNewDecFromStr(quantizedValue.String()) 197 198 assert.Assert(t, quantizedChainFormatValue.Equal(chainValue)) 199 } 200 201 func TestConvertMarginToChainFormatForDerivativeMarket(t *testing.T) { 202 derivativeMarket := createBTCUSDTPerpMarket() 203 originalPrice := decimal.RequireFromString("123.456789") 204 205 chainValue := derivativeMarket.MarginToChainFormat(originalPrice) 206 marginDecimals := derivativeMarket.QuoteToken.Decimals 207 expectedValue := originalPrice.Mul(decimal.New(1, marginDecimals)) 208 quantizedValue := expectedValue.DivRound(derivativeMarket.MinQuantityTickSize, 0).Mul(derivativeMarket.MinQuantityTickSize) 209 quantizedChainFormatValue := sdkmath.LegacyMustNewDecFromStr(quantizedValue.String()) 210 211 assert.Assert(t, quantizedChainFormatValue.Equal(chainValue)) 212 } 213 214 func TestCalculateMarginInChainFormatForDerivativeMarket(t *testing.T) { 215 derivativeMarket := createBTCUSDTPerpMarket() 216 originalQuantity := decimal.RequireFromString("10") 217 originalPrice := decimal.RequireFromString("123.456789") 218 originalLeverage := decimal.RequireFromString("2.5") 219 220 chainValue := derivativeMarket.CalculateMarginInChainFormat(originalQuantity, originalPrice, originalLeverage) 221 decimals := derivativeMarket.QuoteToken.Decimals 222 expectedValue := originalQuantity.Mul(originalPrice).Div(originalLeverage).Mul(decimal.New(1, decimals)) 223 quantizedValue := expectedValue.DivRound(derivativeMarket.MinQuantityTickSize, 0).Mul(derivativeMarket.MinQuantityTickSize) 224 legacyDecimalQuantizedValue := sdkmath.LegacyMustNewDecFromStr(quantizedValue.String()) 225 226 assert.Assert(t, chainValue.Equal(legacyDecimalQuantizedValue)) 227 } 228 229 func TestConvertNotionalToChainFormatForDerivativeMarket(t *testing.T) { 230 derivativeMarket := createBTCUSDTPerpMarket() 231 originalNotional := decimal.RequireFromString("123.456789") 232 233 chainValue := derivativeMarket.NotionalToChainFormat(originalNotional) 234 notionalDecimals := derivativeMarket.QuoteToken.Decimals 235 expectedValue := originalNotional.Mul(decimal.New(1, notionalDecimals)) 236 expectedChainFormatValue := sdkmath.LegacyMustNewDecFromStr(expectedValue.String()) 237 238 assert.Assert(t, expectedChainFormatValue.Equal(chainValue)) 239 } 240 241 func TestConvertQuantityFromChainFormatForDerivativeMarket(t *testing.T) { 242 derivativeMarket := createBTCUSDTPerpMarket() 243 expectedQuantity := decimal.RequireFromString("123.456") 244 245 chainFormatQuantity := expectedQuantity 246 humanReadableQuantity := derivativeMarket.QuantityFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatQuantity.String())) 247 248 assert.Assert(t, expectedQuantity.Equal(humanReadableQuantity)) 249 } 250 251 func TestConvertPriceFromChainFormatForDerivativeMarket(t *testing.T) { 252 derivativeMarket := createBTCUSDTPerpMarket() 253 expectedPrice := decimal.RequireFromString("123.456") 254 255 priceDecimals := derivativeMarket.QuoteToken.Decimals 256 chainFormatPrice := expectedPrice.Mul(decimal.New(1, priceDecimals)) 257 humanReadablePrice := derivativeMarket.PriceFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatPrice.String())) 258 259 assert.Assert(t, expectedPrice.Equal(humanReadablePrice)) 260 } 261 262 func TestConvertMarginFromChainFormatForDerivativeMarket(t *testing.T) { 263 derivativeMarket := createBTCUSDTPerpMarket() 264 expectedMargin := decimal.RequireFromString("123.456") 265 266 marginDecimals := derivativeMarket.QuoteToken.Decimals 267 chainFormatMargin := expectedMargin.Mul(decimal.New(1, marginDecimals)) 268 humanReadablePrice := derivativeMarket.MarginFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatMargin.String())) 269 270 assert.Assert(t, expectedMargin.Equal(humanReadablePrice)) 271 } 272 273 func TestConvertNotionalFromChainFormatForDerivativeMarket(t *testing.T) { 274 derivativeMarket := createBTCUSDTPerpMarket() 275 expectedNotional := decimal.RequireFromString("123.456") 276 277 notionalDecimals := derivativeMarket.QuoteToken.Decimals 278 chainFormatPrice := expectedNotional.Mul(decimal.New(1, notionalDecimals)) 279 humanReadableNotional := derivativeMarket.NotionalFromChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatPrice.String())) 280 281 assert.Assert(t, expectedNotional.Equal(humanReadableNotional)) 282 } 283 284 func TestConvertQuantityFromExtendedChainFormatForDerivativeMarket(t *testing.T) { 285 derivativeMarket := createBTCUSDTPerpMarket() 286 expectedQuantity := decimal.RequireFromString("123.456") 287 288 chainFormatQuantity := expectedQuantity.Mul(decimal.New(1, AdditionalChainFormatDecimals)) 289 humanReadableQuantity := derivativeMarket.QuantityFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatQuantity.String())) 290 291 assert.Assert(t, expectedQuantity.Equal(humanReadableQuantity)) 292 } 293 294 func TestConvertPriceFromExtendedChainFormatForDerivativeMarket(t *testing.T) { 295 derivativeMarket := createBTCUSDTPerpMarket() 296 expectedPrice := decimal.RequireFromString("123.456") 297 298 priceDecimals := derivativeMarket.QuoteToken.Decimals 299 chainFormatPrice := expectedPrice.Mul(decimal.New(1, priceDecimals)).Mul(decimal.New(1, AdditionalChainFormatDecimals)) 300 humanReadablePrice := derivativeMarket.PriceFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatPrice.String())) 301 302 assert.Assert(t, expectedPrice.Equal(humanReadablePrice)) 303 } 304 305 func TestConvertMarginFromExtendedChainFormatForDerivativeMarket(t *testing.T) { 306 derivativeMarket := createBTCUSDTPerpMarket() 307 expectedMargin := decimal.RequireFromString("123.456") 308 309 marginDecimals := derivativeMarket.QuoteToken.Decimals 310 chainFormatMargin := expectedMargin.Mul(decimal.New(1, marginDecimals)).Mul(decimal.New(1, AdditionalChainFormatDecimals)) 311 humanReadablePrice := derivativeMarket.MarginFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatMargin.String())) 312 313 assert.Assert(t, expectedMargin.Equal(humanReadablePrice)) 314 } 315 316 func TestConvertNotionalFromExtendedChainFormatForDerivativeMarket(t *testing.T) { 317 derivativeMarket := createBTCUSDTPerpMarket() 318 expectedNotional := decimal.RequireFromString("123.456") 319 320 notionalDecimals := derivativeMarket.QuoteToken.Decimals 321 chainFormatNotional := expectedNotional.Mul(decimal.New(1, notionalDecimals)).Mul(decimal.New(1, AdditionalChainFormatDecimals)) 322 humanReadableNotional := derivativeMarket.NotionalFromExtendedChainFormat(sdkmath.LegacyMustNewDecFromStr(chainFormatNotional.String())) 323 324 assert.Assert(t, expectedNotional.Equal(humanReadableNotional)) 325 }