ostium-python-sdk 2.0.5__tar.gz → 2.0.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/PKG-INFO +7 -1
  2. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/README.md +6 -0
  3. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/formulae.py +61 -27
  4. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/ostium.py +3 -0
  5. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/sdk.py +15 -4
  6. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/subgraph.py +10 -4
  7. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk.egg-info/PKG-INFO +7 -1
  8. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk.egg-info/SOURCES.txt +4 -0
  9. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/setup.py +1 -1
  10. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_funding.py +3 -3
  11. ostium_python_sdk-2.0.6/tests/test_get_opening_fee.py +66 -0
  12. ostium_python_sdk-2.0.6/tests/test_get_trade_value.py +82 -0
  13. ostium_python_sdk-2.0.6/tests/test_max_leverage.py +55 -0
  14. ostium_python_sdk-2.0.6/tests/test_overnight_max_leverage.py +46 -0
  15. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/MANIFEST.in +0 -0
  16. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/__init__.py +0 -0
  17. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/__init__.py +0 -0
  18. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/faucet_testnet_abi.py +0 -0
  19. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/pairs_info_abi.py +0 -0
  20. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/pairs_storage_abi.py +0 -0
  21. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/trading_abi.py +0 -0
  22. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/trading_storage_abi.py +0 -0
  23. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/usdc_abi.py +0 -0
  24. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/abi/vault_abi.py +0 -0
  25. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/balance.py +0 -0
  26. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/config.py +0 -0
  27. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/constants.py +0 -0
  28. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/exceptions.py +0 -0
  29. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/faucet.py +0 -0
  30. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/formulae_wrapper.py +0 -0
  31. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/price.py +0 -0
  32. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/scscript/__init__.py +0 -0
  33. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/scscript/funding.py +0 -0
  34. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk/utils.py +0 -0
  35. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk.egg-info/dependency_links.txt +0 -0
  36. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk.egg-info/requires.txt +0 -0
  37. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/ostium_python_sdk.egg-info/top_level.txt +0 -0
  38. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/pyproject.toml +0 -0
  39. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/requirements-dev.txt +0 -0
  40. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/requirements.txt +0 -0
  41. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/setup.cfg +0 -0
  42. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/__init__.py +0 -0
  43. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_current_total_profit_p.py +0 -0
  44. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_current_total_profit_raw.py +0 -0
  45. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_current_trade_profit_p.py +0 -0
  46. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_current_trade_profit_raw.py +0 -0
  47. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_get_price_impact.py +0 -0
  48. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_get_trade_funding_fee.py +0 -0
  49. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_get_trade_rollover_fee.py +0 -0
  50. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_remove_collateral_from_leverage.py +0 -0
  51. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_remove_collateral_with_collateral.py +0 -0
  52. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_slippage.py +0 -0
  53. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_top_up_with_collateral.py +0 -0
  54. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_top_up_with_leverage.py +0 -0
  55. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_trade_get_sl_price.py +0 -0
  56. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_trade_get_tp_price.py +0 -0
  57. {ostium_python_sdk-2.0.5 → ostium_python_sdk-2.0.6}/tests/test_trade_liquidation_price.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ostium-python-sdk
3
- Version: 2.0.5
3
+ Version: 2.0.6
4
4
  Summary: A python based SDK developed for interacting with Ostium, a leveraged trading application for trading currencies, commodities, indices, crypto and more.
5
5
  Home-page: https://github.com/0xOstium/ostium-python-sdk
6
6
  Author: ami@ostium.io
@@ -106,6 +106,12 @@ pytest -v tests/test_current_trade_profit_raw.py
106
106
  pytest -v tests/test_current_total_profit_raw.py
107
107
  pytest -v tests/test_get_trade_funding_fee.py
108
108
  pytest -v tests/test_get_trade_rollover_fee.py
109
+ pytest -v tests/test_get_trade_value.py
110
+ pytest -v tests/test_get_opening_fee.py
111
+
112
+ pytest -v tests/test_max_leverage.py
113
+ pytest -v tests/test_overnight_max_leverage.py
114
+ pytest -v tests/test_slippage.py
109
115
 
110
116
 
111
117
 
@@ -67,6 +67,12 @@ pytest -v tests/test_current_trade_profit_raw.py
67
67
  pytest -v tests/test_current_total_profit_raw.py
68
68
  pytest -v tests/test_get_trade_funding_fee.py
69
69
  pytest -v tests/test_get_trade_rollover_fee.py
70
+ pytest -v tests/test_get_trade_value.py
71
+ pytest -v tests/test_get_opening_fee.py
72
+
73
+ pytest -v tests/test_max_leverage.py
74
+ pytest -v tests/test_overnight_max_leverage.py
75
+ pytest -v tests/test_slippage.py
70
76
 
71
77
 
72
78
 
@@ -1,13 +1,11 @@
1
1
  from decimal import Decimal, getcontext, ROUND_DOWN
2
- from .constants import MAX_PROFIT_P, MIN_LOSS_P, MAX_STOP_LOSS_P, PRECISION_16, PRECISION_2, PRECISION_6, PRECISION_12, PRECISION_18, LIQ_THRESHOLD_P
2
+ from .constants import MAX_PROFIT_P, MIN_LOSS_P, PRECISION_2, PRECISION_6, PRECISION_18
3
3
  from typing import Dict
4
4
  from .scscript.funding import getPendingAccFundingFees, getTargetFundingRate
5
5
 
6
6
  quantization_6 = Decimal('0.000001')
7
7
  quantization_18 = Decimal('0.000000000000000001')
8
8
 
9
- # v2 (formulae v1.3.3)
10
-
11
9
 
12
10
  def GetTakeProfitPrice(open_price: Decimal, profit_p: Decimal, leverage: Decimal, is_long: bool) -> Decimal:
13
11
  open_price = Decimal(open_price)
@@ -23,8 +21,6 @@ def GetTakeProfitPrice(open_price: Decimal, profit_p: Decimal, leverage: Decimal
23
21
 
24
22
  return Decimal(tp_price if tp_price > 0 else '0')
25
23
 
26
- # v2 (formulae v1.3.3)
27
-
28
24
 
29
25
  def GetStopLossPrice(open_price: Decimal, loss_p: Decimal, leverage: Decimal, is_long: bool) -> Decimal:
30
26
  open_price = Decimal(open_price)
@@ -37,8 +33,6 @@ def GetStopLossPrice(open_price: Decimal, loss_p: Decimal, leverage: Decimal, is
37
33
  sl_price = open_price - price_diff if is_long else open_price + price_diff
38
34
  return sl_price if sl_price > 0 else Decimal('0')
39
35
 
40
- # v2 (formulae v1.3.3)
41
-
42
36
 
43
37
  def CurrentTradeProfitP(
44
38
  open_price: Decimal,
@@ -62,8 +56,6 @@ def CurrentTradeProfitP(
62
56
 
63
57
  return profit_p
64
58
 
65
- # v2 (formulae v1.3.3)
66
-
67
59
 
68
60
  def TopUpWithCollateral(
69
61
  leverage: Decimal,
@@ -73,8 +65,6 @@ def TopUpWithCollateral(
73
65
  new_leverage = (collateral * leverage) / (collateral + added_collateral)
74
66
  return new_leverage
75
67
 
76
- # v2 (formulae v1.3.3)
77
-
78
68
 
79
69
  def TopUpWithLeverage(
80
70
  leverage: Decimal,
@@ -84,8 +74,6 @@ def TopUpWithLeverage(
84
74
  added_c = (collateral * leverage) / desired_leverage - collateral
85
75
  return added_c
86
76
 
87
- # v2 (formulae v1.3.3)
88
-
89
77
 
90
78
  def RemoveCollateralWithCollateral(
91
79
  leverage: Decimal,
@@ -95,8 +83,6 @@ def RemoveCollateralWithCollateral(
95
83
  new_leverage = (collateral * leverage) / (collateral - removed_collateral)
96
84
  return new_leverage
97
85
 
98
- # v2 (formulae v1.3.3)
99
-
100
86
 
101
87
  def RemoveCollateralFromLeverage(
102
88
  leverage: Decimal,
@@ -106,9 +92,8 @@ def RemoveCollateralFromLeverage(
106
92
  added_c = collateral - (collateral * leverage / desired_leverage)
107
93
  return added_c
108
94
 
109
- # tbd - used by SDK
110
- # v2 (formulae v1.3.3)
111
95
 
96
+ # Start of copied v1.2.3
112
97
 
113
98
  def getTradeLiquidationPrice(
114
99
  liqMarginThresholdP: Decimal,
@@ -133,21 +118,42 @@ def getTradeLiquidationPrice(
133
118
  return max(Decimal('0'), liqPrice)
134
119
 
135
120
 
121
+
122
+
136
123
  def getTradeValue(
124
+ liqMarginThresholdP: Decimal, # 25 means 25%
125
+ collateral: Decimal,
126
+ percentProfit: Decimal,
127
+ rolloverFee: Decimal,
128
+ fundingFee: Decimal,
129
+ leverage: Decimal,
130
+ maxLeverage: Decimal,
131
+ ) -> (Decimal, Decimal):
132
+ liqMarginValue = getTradeLiquidationMargin(
133
+ liqMarginThresholdP, collateral, leverage, maxLeverage)
134
+ value = getTradeValuePure(
135
+ collateral, percentProfit, rolloverFee, fundingFee, liqMarginValue)
136
+
137
+ return value, liqMarginValue
138
+
139
+
140
+ def getTradeValuePure(
137
141
  collateral: Decimal,
138
142
  percentProfit: Decimal,
139
143
  rolloverFee: Decimal,
140
- fundingFee: Decimal
144
+ fundingFee: Decimal,
145
+ liqMarginValue: Decimal
141
146
  ) -> Decimal:
142
147
  profitPart = (collateral * percentProfit / Decimal('100')
143
148
  ).quantize(quantization_6, rounding=ROUND_DOWN)
144
149
  value = (collateral + profitPart - rolloverFee - fundingFee)
145
-
150
+ if value <= liqMarginValue:
151
+ return Decimal('0')
146
152
  return value
147
153
 
148
154
 
149
155
  def getTradeLiquidationMargin(
150
- liqMarginThresholdP: Decimal,
156
+ liqMarginThresholdP: Decimal, # 0.25 means 25%
151
157
  collateral: Decimal,
152
158
  leverage: Decimal,
153
159
  maxLeverage: Decimal
@@ -157,7 +163,39 @@ def getTradeLiquidationMargin(
157
163
  return (collateral * rawAdjustedThreshold / Decimal('100')).quantize(quantization_6, rounding=ROUND_DOWN)
158
164
 
159
165
 
160
- # ???
166
+ def getOpeningFee(
167
+ tradeSize: Decimal,
168
+ leverage: Decimal,
169
+ oiDelta: Decimal,
170
+ makerMaxLeverage: Decimal,
171
+ makerFeeP: Decimal,
172
+ takerFeeP: Decimal
173
+ ) -> Decimal:
174
+ makerAmount: Decimal = Decimal(0)
175
+ takerAmount: Decimal = Decimal(0)
176
+
177
+ print(f"tradeSize: {tradeSize}, leverage: {leverage}, oiDelta: {oiDelta}, makerMaxLeverage: {makerMaxLeverage}, makerFeeP: {makerFeeP}, takerFeeP: {takerFeeP}")
178
+ # Base Fee
179
+ if (oiDelta * tradeSize < 0 and leverage <= makerMaxLeverage):
180
+ if (oiDelta * (oiDelta + tradeSize) >= 0):
181
+ makerAmount = abs(tradeSize)
182
+ else:
183
+ makerAmount = abs(oiDelta)
184
+ takerAmount = abs(oiDelta + tradeSize)
185
+ else:
186
+ takerAmount = abs(tradeSize)
187
+
188
+ baseFee: Decimal = (
189
+ (makerFeeP * makerAmount).quantize(quantization_6, rounding=ROUND_DOWN) +
190
+ (takerFeeP * takerAmount).quantize(quantization_6, rounding=ROUND_DOWN)
191
+ ) / Decimal('100')
192
+
193
+ return baseFee.quantize(quantization_6, rounding=ROUND_DOWN)
194
+
195
+
196
+ # End of copied v1.2.3
197
+
198
+
161
199
  def GetCurrentRolloverFee(
162
200
  acc_rollover: str,
163
201
  last_rollover_block: str,
@@ -177,7 +215,6 @@ def GetCurrentRolloverFee(
177
215
  raise Exception(f"Unable to compute Current Rollover Fee: {error}")
178
216
 
179
217
 
180
- # v2 (formulae v1.3.3)
181
218
  def GetTradeRolloverFee(
182
219
  trade_rollover: Decimal,
183
220
  current_rollover: Decimal,
@@ -189,7 +226,7 @@ def GetTradeRolloverFee(
189
226
 
190
227
 
191
228
  # Gets the funding fee (abs) for an open trade (up to this block, aka based on current_funding up till this block)
192
- # v2 (formulae v1.3.3)
229
+
193
230
  def GetTradeFundingFee(
194
231
  trade_funding: Decimal,
195
232
  current_funding: Decimal,
@@ -236,7 +273,7 @@ def GetPriceImpact(
236
273
  # calculates the gross (without fees) profit (abs) of an open trade
237
274
 
238
275
  # calculates the net profit (after fees) of an open trade (abs)
239
- # v2 (formulae v1.3.3)
276
+
240
277
  def CurrentTradeProfitRaw(
241
278
  open_price: Decimal,
242
279
  current_price: Decimal,
@@ -255,8 +292,6 @@ def CurrentTradeProfitRaw(
255
292
  profit = (collateral * profit_p) / Decimal("100")
256
293
  return profit
257
294
 
258
- # v2 (formulae v1.3.3)
259
-
260
295
 
261
296
  def CurrentTotalProfitRaw(
262
297
  open_price: Decimal,
@@ -285,7 +320,6 @@ def CurrentTotalProfitRaw(
285
320
  return total_profit
286
321
 
287
322
 
288
- # v2 (formulae v1.3.3)
289
323
  def CurrentTotalProfitP(total_profit: Decimal, collateral: Decimal) -> Decimal:
290
324
  profit_p = (total_profit * Decimal("100")) / collateral
291
325
  if profit_p <= MIN_LOSS_P:
@@ -65,6 +65,9 @@ class Ostium:
65
65
  if self.verbose:
66
66
  print(message)
67
67
 
68
+ def get_opening_fee(self, trade_size, leverage, pair_id):
69
+ pass
70
+
68
71
  def set_slippage_percentage(self, slippage_percentage):
69
72
  self.slippage_percentage = slippage_percentage
70
73
 
@@ -59,7 +59,10 @@ class OstiumSDK:
59
59
  f"but RPC is connected to chain ID {actual_chain_id}. Please check your RPC_URL."
60
60
  )
61
61
 
62
- print(f"v.UP! network_config: {self.network_config} !!!")
62
+ if self.verbose:
63
+ print(
64
+ f"network_config: {'TESTNET' if self.network_config.is_testnet else 'MAINNET'}")
65
+
63
66
  # Initialize Ostium instance
64
67
  self.ostium = Ostium(
65
68
  self.w3,
@@ -137,12 +140,20 @@ class OstiumSDK:
137
140
 
138
141
  return get_trade_metrics(trade_details, price_data, block_number, pair_max_leverage, liq_margin_threshold_p, verbose=self.verbose)
139
142
 
140
- # either by group of pair or by pair id (e.g: maxLeverage 10000 means 100x )
143
+ # max leverage for overnight trades (Stocks) - 100 means 100x, None if not set
144
+ async def get_pair_overnight_max_leverage(self, pair_id):
145
+ obj = await self.subgraph.get_pair_details(pair_id)
146
+
147
+ maxLeverage = int(obj['overnightMaxLeverage'])/100 if int(
148
+ obj['overnightMaxLeverage']) != 0 else None
149
+ return maxLeverage
150
+
151
+ # either by group of pair or by pair id (e.g: maxLeverage 100 means 100x )
141
152
  async def get_pair_max_leverage(self, pair_id):
142
153
  obj = await self.subgraph.get_pair_details(pair_id)
143
154
 
144
- maxLeverage = obj['maxLeverage'] if int(
145
- obj['group']['maxLeverage']) == 0 else obj['group']['maxLeverage']
155
+ maxLeverage = int(obj['maxLeverage']) / 100 if int(
156
+ obj['group']['maxLeverage']) == 0 else int(obj['group']['maxLeverage']) / 100
146
157
  return maxLeverage
147
158
 
148
159
  async def get_pair_net_rate_percent_per_hours(self, pair_id, period_hours=24):
@@ -26,6 +26,7 @@ class SubgraphClient:
26
26
  from
27
27
  to
28
28
  feed
29
+ overnightMaxLeverage
29
30
  }
30
31
  }
31
32
  """
@@ -43,7 +44,8 @@ class SubgraphClient:
43
44
  pair(id: $pair_id) {
44
45
  id
45
46
  from
46
- to
47
+ to
48
+ overnightMaxLeverage
47
49
  longOI
48
50
  shortOI
49
51
  maxOI
@@ -99,8 +101,7 @@ class SubgraphClient:
99
101
  else:
100
102
  raise ValueError(f"No pair details found for pair ID: {pair_id}")
101
103
 
102
- async def get_liq_margin_threshold_p(self):
103
- self.log(f"Fetching get_liq_margin_threshold_p")
104
+ async def get_liq_margin_threshold_p(self):
104
105
  query = gql(
105
106
  """
106
107
  query metaDatas {
@@ -112,7 +113,12 @@ class SubgraphClient:
112
113
  )
113
114
  result = await self.client.execute_async(query)
114
115
 
115
- return result['metaDatas'][0]['liqMarginThresholdP']
116
+ liq_margin_threshold_p = result['metaDatas'][0]['liqMarginThresholdP']
117
+
118
+ if self.verbose:
119
+ self.log(f"Fetched get_liq_margin_threshold_p: {liq_margin_threshold_p}%")
120
+
121
+ return liq_margin_threshold_p
116
122
 
117
123
  async def get_open_trades(self, address):
118
124
  # self.log(f"Fetching open trades for address: {address}")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ostium-python-sdk
3
- Version: 2.0.5
3
+ Version: 2.0.6
4
4
  Summary: A python based SDK developed for interacting with Ostium, a leveraged trading application for trading currencies, commodities, indices, crypto and more.
5
5
  Home-page: https://github.com/0xOstium/ostium-python-sdk
6
6
  Author: ami@ostium.io
@@ -106,6 +106,12 @@ pytest -v tests/test_current_trade_profit_raw.py
106
106
  pytest -v tests/test_current_total_profit_raw.py
107
107
  pytest -v tests/test_get_trade_funding_fee.py
108
108
  pytest -v tests/test_get_trade_rollover_fee.py
109
+ pytest -v tests/test_get_trade_value.py
110
+ pytest -v tests/test_get_opening_fee.py
111
+
112
+ pytest -v tests/test_max_leverage.py
113
+ pytest -v tests/test_overnight_max_leverage.py
114
+ pytest -v tests/test_slippage.py
109
115
 
110
116
 
111
117
 
@@ -38,9 +38,13 @@ tests/test_current_total_profit_raw.py
38
38
  tests/test_current_trade_profit_p.py
39
39
  tests/test_current_trade_profit_raw.py
40
40
  tests/test_funding.py
41
+ tests/test_get_opening_fee.py
41
42
  tests/test_get_price_impact.py
42
43
  tests/test_get_trade_funding_fee.py
43
44
  tests/test_get_trade_rollover_fee.py
45
+ tests/test_get_trade_value.py
46
+ tests/test_max_leverage.py
47
+ tests/test_overnight_max_leverage.py
44
48
  tests/test_remove_collateral_from_leverage.py
45
49
  tests/test_remove_collateral_with_collateral.py
46
50
  tests/test_slippage.py
@@ -22,7 +22,7 @@ if changelog_path.exists():
22
22
 
23
23
  setup(
24
24
  name="ostium-python-sdk",
25
- version="2.0.5",
25
+ version="2.0.6",
26
26
  packages=find_packages(),
27
27
  install_requires=read_requirements('requirements.txt'),
28
28
  extras_require={
@@ -420,10 +420,10 @@ async def test_oi_delta_negative_scaled_down_spring_factor_shorts_pay_longs():
420
420
 
421
421
  # 2. Expected outputs
422
422
  expected_latest_funding_rate = Decimal(
423
- '-0.004999999382905974') # 004999999444615238
423
+ '-0.004999999444615238')
424
424
  expected_acc_funding_long = Decimal(
425
- '-0.4999999691452734') # 499999972230743300
426
- expected_acc_funding_short = Decimal('0.004999999691452734')
425
+ '-0.499999972230743300')
426
+ expected_acc_funding_short = Decimal('0.004999999722307433')
427
427
  expected_target_fr = Decimal('-0.004876580886315063')
428
428
 
429
429
  # 3. Call function
@@ -0,0 +1,66 @@
1
+ import pytest
2
+ from decimal import Decimal
3
+ from ostium_python_sdk.formulae import getOpeningFee
4
+
5
+ # Global list of all test cases
6
+ test_cases = [
7
+ # CASE-0 - test_Validate_Full_Taker_getOpeningFee
8
+ {
9
+ 'trade_size': Decimal('-10000'),
10
+ 'leverage': Decimal('3'),
11
+ 'oi_delta': Decimal('5000'),
12
+ 'maker_max_leverage': Decimal('10'),
13
+ 'maker_fee_p': Decimal('0.0001'), # 100 / PRECISION_6 => 0.0001
14
+ 'taker_fee_p': Decimal('0.0003'), # 300 / PRECISION_6 => 0.0003
15
+ 'expected_fee': Decimal('0.02')
16
+ },
17
+ # CASE-1 - test_Validate_Negative_OiDelta_Full_Maker_getOpeningFee
18
+ {
19
+ 'trade_size': Decimal('10'), # 10000000 / PRECISION_6
20
+ 'leverage': Decimal('3'), # 300 / PRECISION_2
21
+ 'oi_delta': Decimal('-5000'), # -5000000000 / PRECISION_6
22
+ 'maker_max_leverage': Decimal('10'), # 1000 / PRECISION_2
23
+ 'maker_fee_p': Decimal('0.0001'), # 100 / PRECISION_6
24
+ 'taker_fee_p': Decimal('0.0003'), # 300 / PRECISION_6
25
+ 'expected_fee': Decimal('0.000010')
26
+ },
27
+ # CASE-2 - test_Validate_Negative_OiDelta_Maker_And_Taker_getOpeningFee
28
+ {
29
+ 'trade_size': Decimal('10'), # 10000000 / PRECISION_6
30
+ 'leverage': Decimal('3'), # 300 / PRECISION_2
31
+ 'oi_delta': Decimal('-5'), # -5000000 / PRECISION_6
32
+ 'maker_max_leverage': Decimal('10'), # 1000 / PRECISION_2
33
+ 'maker_fee_p': Decimal('0.0001'), # 100 / PRECISION_6
34
+ 'taker_fee_p': Decimal('0.0003'), # 300 / PRECISION_6
35
+ 'expected_fee': Decimal('0.000020')
36
+ },
37
+ # CASE-3 - test_Validate_Negative_OiDelta_Lower_Fees_getOpeningFee
38
+ {
39
+ 'trade_size': Decimal('10'), # 10000000 / PRECISION_6
40
+ 'leverage': Decimal('3'), # 300 / PRECISION_2
41
+ 'oi_delta': Decimal('-5'), # -5000000 / PRECISION_6
42
+ 'maker_max_leverage': Decimal('10'), # 1000 / PRECISION_2
43
+ 'maker_fee_p': Decimal('0.00005'), # 50 / PRECISION_6
44
+ 'taker_fee_p': Decimal('0.0002'), # 200 / PRECISION_6
45
+ 'expected_fee': Decimal('0.000012')
46
+ }
47
+ ]
48
+
49
+
50
+ @pytest.mark.parametrize("case", test_cases)
51
+ def test_get_opening_fee(case):
52
+ """Test multiple scenarios for getOpeningFee with Pytest."""
53
+
54
+ fee = getOpeningFee(
55
+ tradeSize=case['trade_size'],
56
+ leverage=case['leverage'],
57
+ oiDelta=case['oi_delta'],
58
+ makerMaxLeverage=case['maker_max_leverage'],
59
+ makerFeeP=case['maker_fee_p'],
60
+ takerFeeP=case['taker_fee_p']
61
+ )
62
+
63
+ # Equivalent to assertAlmostEqual(..., places=5) is approx with abs=1e-5
64
+ # or thereabouts. Adjust as needed for your precision.
65
+ assert fee == pytest.approx(case['expected_fee'], abs=1e-5), \
66
+ f"Failed for case: {case}"
@@ -0,0 +1,82 @@
1
+ import pytest
2
+ from decimal import Decimal
3
+ from ostium_python_sdk.formulae import getTradeValue
4
+
5
+ # Global list of all test cases
6
+ test_cases = [
7
+ # CASE-0
8
+ {
9
+ 'liq_margin_threshold_p': Decimal('25'), # 25 (no division needed)
10
+ 'collateral': Decimal('100'), # 100000000 / PRECISION_6
11
+ 'percent_profit': Decimal('1'), # 1000000 / PRECISION_6
12
+ 'rollover_fee': Decimal('0.000001'), # 1 / PRECISION_6
13
+ 'funding_fee': Decimal('0'), # 0 / PRECISION_6
14
+ 'leverage': Decimal('10'), # 1000 / PRECISION_2
15
+ 'max_leverage': Decimal('10'), # 1000 / PRECISION_2
16
+ # 100999999 / PRECISION_6
17
+ 'expected_trade_value': Decimal('100.999999'),
18
+ 'expected_liq_margin_value': Decimal('25'), # 25000000 / PRECISION_6
19
+ },
20
+ # CASE-1
21
+ {
22
+ 'liq_margin_threshold_p': Decimal('25'), # 25 (no division needed)
23
+ 'collateral': Decimal('100'), # 100000000 / PRECISION_6
24
+ 'percent_profit': Decimal('87.769211'), # 87769211 / PRECISION_6
25
+ 'rollover_fee': Decimal('1.395969'), # 1395969 / PRECISION_6
26
+ 'funding_fee': Decimal('2.145623'), # 2145623 / PRECISION_6
27
+ 'leverage': Decimal('10'), # 1000 / PRECISION_2
28
+ 'max_leverage': Decimal('10'), # 1000 / PRECISION_2
29
+ # 184227619 / PRECISION_6
30
+ 'expected_trade_value': Decimal('184.227619'),
31
+ 'expected_liq_margin_value': Decimal('25'), # 25000000 / PRECISION_6
32
+ },
33
+ # CASE-2
34
+ {
35
+ 'liq_margin_threshold_p': Decimal('25'), # 25 (no division needed)
36
+ 'collateral': Decimal('200'), # 200000000 / PRECISION_6
37
+ 'percent_profit': Decimal('99.900994'), # 99900994 / PRECISION_6
38
+ 'rollover_fee': Decimal('2.158825'), # 2158825 / PRECISION_6
39
+ 'funding_fee': Decimal('3.366384'), # 3366384 / PRECISION_6
40
+ 'leverage': Decimal('5'), # 500 / PRECISION_2
41
+ 'max_leverage': Decimal('10'), # 1000 / PRECISION_2
42
+ # 394276779 / PRECISION_6
43
+ 'expected_trade_value': Decimal('394.276779'),
44
+ 'expected_liq_margin_value': Decimal('25'), # 25000000 / PRECISION_6
45
+ },
46
+ # CASE-3 - change liq margin threshold to 20%
47
+ {
48
+ 'liq_margin_threshold_p': Decimal('20'), # 25 (no division needed)
49
+ 'collateral': Decimal('200'), # 200000000 / PRECISION_6
50
+ 'percent_profit': Decimal('99.900994'), # 99900994 / PRECISION_6
51
+ 'rollover_fee': Decimal('2.158825'), # 2158825 / PRECISION_6
52
+ 'funding_fee': Decimal('3.366384'), # 3366384 / PRECISION_6
53
+ 'leverage': Decimal('5'), # 500 / PRECISION_2
54
+ 'max_leverage': Decimal('10'), # 1000 / PRECISION_2
55
+ # 394276779 / PRECISION_6
56
+ 'expected_trade_value': Decimal('394.276779'),
57
+ 'expected_liq_margin_value': Decimal('20'), # 25000000 / PRECISION_6
58
+ }
59
+ ]
60
+
61
+
62
+ @pytest.mark.parametrize("case", test_cases)
63
+ def test_get_trade_value(case):
64
+ """Test multiple scenarios for getTradeValue with Pytest."""
65
+
66
+ trade_value, liq_margin_value = getTradeValue(
67
+ liqMarginThresholdP=case['liq_margin_threshold_p'],
68
+ collateral=case['collateral'],
69
+ percentProfit=case['percent_profit'],
70
+ rolloverFee=case['rollover_fee'],
71
+ fundingFee=case['funding_fee'],
72
+ leverage=case['leverage'],
73
+ maxLeverage=case['max_leverage']
74
+ )
75
+
76
+ # Assert trade value
77
+ assert trade_value == pytest.approx(case['expected_trade_value'], abs=1e-5), \
78
+ f"Trade value failed for case: {case}"
79
+
80
+ # Assert liquidation margin value
81
+ assert liq_margin_value == pytest.approx(case['expected_liq_margin_value'], abs=1e-5), \
82
+ f"Liquidation margin value failed for case: {case}"
@@ -0,0 +1,55 @@
1
+ import os
2
+ import pytest
3
+ from dotenv import load_dotenv
4
+ from ostium_python_sdk import OstiumSDK
5
+ from ostium_python_sdk.config import NetworkConfig
6
+
7
+
8
+ @pytest.fixture(scope="module")
9
+ def sdk():
10
+ # Load environment variables
11
+ load_dotenv()
12
+
13
+ rpc_url = os.getenv('RPC_URL')
14
+ if not rpc_url:
15
+ raise ValueError("RPC_URL not found in .env file")
16
+
17
+ # Initialize SDK with testnet config
18
+ config = NetworkConfig.testnet()
19
+ return OstiumSDK(config)
20
+
21
+
22
+ @pytest.mark.asyncio
23
+ async def test_max_leverage_validation_for_btc_usd(sdk):
24
+ max_leverage = await sdk.get_pair_max_leverage(0)
25
+ print(f"max_leverage: {max_leverage}")
26
+
27
+ assert max_leverage == pytest.approx(50, abs=1e-5), \
28
+ f"Failed get_pair_max_leverage assertion for BTC/USD"
29
+
30
+
31
+ @pytest.mark.asyncio
32
+ async def test_max_leverage_validation_for_eth_usd(sdk):
33
+ max_leverage = await sdk.get_pair_max_leverage(1)
34
+ print(f"max_leverage: {max_leverage}")
35
+
36
+ assert max_leverage == pytest.approx(50, abs=1e-5), \
37
+ f"Failed get_pair_max_leverage assertion for BTC/USD"
38
+
39
+
40
+ @pytest.mark.asyncio
41
+ async def test_max_leverage_validation_for_ftse_usd(sdk):
42
+ max_leverage = await sdk.get_pair_max_leverage(14)
43
+ print(f"max_leverage: {max_leverage}")
44
+
45
+ assert max_leverage == pytest.approx(100, abs=1e-5), \
46
+ f"Failed get_pair_max_leverage assertion for FTSE/USD"
47
+
48
+
49
+ @pytest.mark.asyncio
50
+ async def test_max_leverage_validation_for_tsla_usd(sdk):
51
+ max_leverage = await sdk.get_pair_max_leverage(22)
52
+ print(f"max_leverage: {max_leverage}")
53
+
54
+ assert max_leverage == pytest.approx(100, abs=1e-5), \
55
+ f"Failed get_pair_max_leverage assertion for TSLA/USD"
@@ -0,0 +1,46 @@
1
+ import os
2
+ import pytest
3
+ from dotenv import load_dotenv
4
+ from ostium_python_sdk import OstiumSDK
5
+ from ostium_python_sdk.config import NetworkConfig
6
+
7
+
8
+ @pytest.fixture(scope="module")
9
+ def sdk():
10
+ # Load environment variables
11
+ load_dotenv()
12
+
13
+ rpc_url = os.getenv('RPC_URL')
14
+ if not rpc_url:
15
+ raise ValueError("RPC_URL not found in .env file")
16
+
17
+ # Initialize SDK with testnet config
18
+ config = NetworkConfig.testnet()
19
+ return OstiumSDK(config)
20
+
21
+
22
+ @pytest.mark.asyncio
23
+ async def test_overnight_max_leverage_validation_for_btc_usd(sdk):
24
+ overnight_max_leverage = await sdk.get_pair_overnight_max_leverage(0)
25
+ print(f"overnight_max_leverage: {overnight_max_leverage}")
26
+
27
+ assert overnight_max_leverage == pytest.approx(None, abs=1e-5), \
28
+ f"Failed get_pair_overnight_max_leverage assertion for BTC/USD"
29
+
30
+
31
+ @pytest.mark.asyncio
32
+ async def test_overnight_max_leverage_validation_for_eth_usd(sdk):
33
+ overnight_max_leverage = await sdk.get_pair_overnight_max_leverage(1)
34
+ print(f"overnight_max_leverage: {overnight_max_leverage}")
35
+
36
+ assert overnight_max_leverage == pytest.approx(None, abs=1e-5), \
37
+ f"Failed get_pair_overnight_max_leverage assertion for BTC/USD"
38
+
39
+
40
+ @pytest.mark.asyncio
41
+ async def test_overnight_max_leverage_validation_for_tsla_usd(sdk):
42
+ overnight_max_leverage = await sdk.get_pair_overnight_max_leverage(22)
43
+ print(f"overnight_max_leverage: {overnight_max_leverage}")
44
+
45
+ assert overnight_max_leverage == pytest.approx(10, abs=1e-5), \
46
+ f"Failed get_pair_overnight_max_leverage assertion for TSLA/USD"