Skip to content

Commit 5cd8fa9

Browse files
committed
update utils to use strings and not floats & add derivative functions
1 parent e8c13da commit 5cd8fa9

File tree

1 file changed

+92
-22
lines changed

1 file changed

+92
-22
lines changed

src/injective/utils.py

Lines changed: 92 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,115 @@
11
from decimal import Decimal
2+
23
"""
3-
One thing you may need to pay more attention to is how to deal with decimals in injective exchange.
4-
As we all known, different crypto currecies require diffrent decimal precisions.
5-
Separately, ERC-20 tokens(e.g. INJ) have decimals of 18 or another number(like 6 for USDT and USDC).
6-
So in injective system that means ** having 1 INJ is 1e18 inj ** and that ** 1 USDT is actually 100000 peggy0xdac17f958d2ee523a2206206994597c13d831ec7**.
4+
One thing you may need to pay more attention to is how to deal with decimals on the Injective Exchange.
5+
Different cryptocurrencies may require diffrent decimal precisions. More specifically, ERC-20 tokens(e.g. INJ) have 18 decimals whereas USDT/USC have 6 decimals.
6+
So in our system that means ** having 1 INJ is 1e18 inj ** and that ** 1 USDT is actually 100000 peggy0xdac17f958d2ee523a2206206994597c13d831ec7**.
77
88
For spot markets, a price reflects the ** relative exchange rate ** between two tokens.
9-
If the tokens have the same decimal scale, that's great since the prices
10-
become interpretable e.g. USDT/USDC (both have 6 decimals e.g. for USDT https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract)
9+
If the tokens have the same decimal scale, that's great since the prices become interpretable e.g. USDT/USDC (both have 6 decimals e.g. for USDT https://etherscan.io/address/0xdac17f958d2ee523a2206206994597c13d831ec7#readContract)
1110
or MATIC/INJ (both have 18 decimals) since the decimals cancel out.
12-
Prices however start to look wonky once you have exchanges between two tokens of different decimals, which unfortunately is most pairs with USDT or USDC denominations.
13-
As such, I've created some simple utility functions by keeping a hardcoded dictionary in injective-py and you can aslo achieve such utilities by yourself
11+
Prices however start to look wonky once you have exchanges between two tokens of different decimals, which unfortunately is most pairs with USDT or USDC denominations e.g. INJ/USDT.
12+
As such, I've created some simple utility functions by keeping a hardcoded dictionary in injective-py and you can also achieve such utilities by yourself
1413
(e.g. you can use external API like Alchemy's getTokenMetadata to fetch decimal of base and quote asset).
1514
16-
So for INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6 - 18) = 6.9e-12.
17-
Note that this market also happens to have a MinPriceTickSize of 1e-15.
15+
So for INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6 - 18) = 6.9e-12. Note that this market also happens to have a MinPriceTickSize of 1e-15.
1816
This makes sense since since it's defining the minimum price increment of the relative exchange of INJ to USDT.
17+
1918
Note that this market also happens to have a MinQuantityTickSize of 1e15.
2019
This also makes sense since it refers to the minimum INJ quantity tick size each order must have, which is 1e15/1e18 = 0.001 INJ.
20+
2121
"""
22-
def price_float_to_string(price, base_decimals, quote_decimals, precision=18) -> str:
23-
"""transfer price[float] to string which satisfies what injective exchange backend requires
22+
23+
def spot_price_conversion_to_send(price, base_decimals, quote_decimals, precision=18) -> str:
24+
25+
"""transfer price[string] to string which satisfies the expected format to be sent to the exchange for spot markets
2426
2527
Args:
26-
price ([float]): normal price, you can read it directly in exchange front-end
27-
base_decimals ([int]): decimal of base asset
28-
quote_decimals ([int]): quote asset's decimal
28+
price ([string]): normal price, you can read it directly in exchange front-end
29+
base_decimals ([int]): decimals of base asset
30+
quote_decimals ([int]): decimals of quote asset
2931
precision (int, optional): [description]. Defaults to 18.
3032
Returns:
3133
str: relative price for base asset and quote asset. For INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6 - 18) = 6.9e-12.
3234
"""
35+
3336
scale = Decimal(quote_decimals - base_decimals)
3437
exchange_price = Decimal(price) * pow(10, scale)
3538
price_string = ("{:."+str(precision)+"f}").format(exchange_price)
3639
print("price string :{}".format(price_string))
3740
return price_string
3841

42+
def derivatives_price_conversion_to_send(price, quote_decimals, precision=18) -> str:
43+
44+
"""transfer price[string] to string which satisfies the expected format to be sent to the exchange for derivative markets
45+
46+
Args:
47+
price ([string]): normal price, you can read it directly in exchange front-end
48+
quote_decimals ([int]): decimals of quote asset
49+
precision (int, optional): [description]. Defaults to 18.
50+
Returns:
51+
str: relative price for the quote asset. For INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6) = 6.9e6.
52+
"""
53+
54+
exchange_price = Decimal(price) * pow(10, quote_decimals)
55+
price_string = ("{:."+str(precision)+"f}").format(exchange_price)
56+
print("price string :{}".format(price_string))
57+
return price_string
58+
59+
def derivatives_margin_conversion_to_send(margin, quote_decimals, precision=18) -> str:
60+
61+
"""transfer price[string] to string which satisfies the expected format to be sent to the exchange for derivative markets
62+
63+
Args:
64+
price ([string]): normal price, you can read it directly in exchange front-end
65+
quote_decimals ([int]): decimals of quote asset
66+
precision (int, optional): [description]. Defaults to 18.
67+
Returns:
68+
str: relative price for the quote asset. For INJ/USDT of 6.9, the price you end up getting is 6.9*10 ^ (6) = 6.9e6.
69+
"""
70+
71+
exchange_price = Decimal(margin) * pow(10, quote_decimals)
72+
price_string = ("{:."+str(precision)+"f}").format(exchange_price)
73+
print("price string :{}".format(price_string))
74+
return price_string
75+
76+
def spot_quantity_conversion_to_send(quantity, base_decimals, precision=18) -> str:
3977

40-
def quantity_float_to_string(quantity, base_decimals, precision=18) -> str:
41-
"""transfer quantity[float] to string which satisfies what injective exchange backend requires
78+
"""transfer price[string] to string which satisfies the expected format to be sent to the exchange for spot markets
4279
4380
Args:
4481
quantity ([type]): normal quantity, you can read it in exchange front-end
45-
base_decimals ([type]): decimal of base asset
82+
base_decimals ([type]): decimals of base asset
4683
precision (int, optional): [description]. Defaults to 18.
4784
4885
Returns:
49-
str: acutally quanity of base asset[data type: string] For 1 INJ, the quantity you end up is 1e18 inj
86+
str: actual quantity of base asset[data type: string] For 1 INJ, the quantity you end up getting is 1e18 inj
5087
"""
88+
5189
scale = Decimal(base_decimals)
5290
exchange_quantity = Decimal(quantity) * pow(10, scale)
5391
quantity_string = ("{:."+str(precision)+"f}").format(exchange_quantity)
5492
print("quantity string:{}".format(quantity_string))
5593
return quantity_string
5694

95+
def derivatives_quantity_conversion_to_send(quantity, quote_decimals, precision=18) -> str:
96+
"""transfer price[string] to string which satisfies the expected format to be sent to the exchange for derivative markets
97+
98+
Args:
99+
quantity ([type]): normal quantity, you can read it in exchange front-end
100+
quote_decimals ([type]): decimals of quote asset
101+
precision (int, optional): [description]. Defaults to 18.
102+
103+
Returns:
104+
str: actual quantity of quote asset[data type: string] For 1 USDT, the quantity you end up is 1.000000000000000000 USDT
105+
"""
106+
exchange_quantity = Decimal(quantity)
107+
quantity_string = ("{:."+str(precision)+"f}").format(exchange_quantity)
108+
print("quantity string :{}".format(quantity_string))
109+
return quantity_string
110+
111+
def spot_price_conversion_from_backend(price_string, base_decimals, quote_decimals) -> float:
57112

58-
def price_string_to_float(price_string, base_decimals, quote_decimals) -> float:
59113
"""
60114
Args:
61115
price_string ([type]): price with string data type that injective-exchange backend returns
@@ -66,19 +120,35 @@ def price_string_to_float(price_string, base_decimals, quote_decimals) -> float:
66120
float: actual price what you can read directly from front-end.
67121
For 6.9e-12 inj/peggy0xdac17f958d2ee523a2206206994597c13d831ec7**, the price you end up getting is 6.9 INJ/USDT.
68122
"""
123+
69124
scale = float(base_decimals - quote_decimals)
70125
return float(price_string) * pow(10, scale)
71126

127+
def derivatives_price_conversion_from_backend(price_string, quote_decimals=6) -> float:
128+
129+
"""
130+
Args:
131+
price_string ([type]): price with string data type that injective-exchange backend returns
132+
quote_decimals ([type]): decimals of quote asset. Defaults to 6
133+
134+
Returns:
135+
float: actual price which you can read directly from the front-end.
136+
For 6.9e6 inj/peggy0xdac17f958d2ee523a2206206994597c13d831ec7**, the price you end up getting is 6.9 INJ/USDT.
137+
"""
138+
139+
scale = float(0 - quote_decimals)
140+
return float(price_string) * pow(10, scale)
141+
72142

73-
def quantity_string_to_float(quantity_string, base_decimals) -> float:
143+
def spot_quantity_from_backend(quantity_string, base_decimals) -> float:
74144
"""
75145
76146
Args:
77147
quantity_string ([type]): quantity string that injective-exchange backend returns
78148
base_decimals ([type]): decimal of base asset
79149
80150
Returns:
81-
float: actually quantity, for 1e18 inj, you will get 1 INJ
151+
float: actual quantity, for 1e18 inj, you will get 1 INJ
82152
"""
83153
scale = float(0 - base_decimals)
84154
return float(quantity_string) * pow(10, scale)

0 commit comments

Comments
 (0)