ostium-python-sdk 0.2.100__tar.gz → 0.2.103__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 (34) hide show
  1. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/PKG-INFO +1 -1
  2. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/config.py +3 -3
  3. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/formulae.py +90 -122
  4. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/formulae_wrapper.py +8 -1
  5. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/sdk.py +19 -3
  6. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/subgraph.py +0 -3
  7. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/utils.py +0 -1
  8. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk.egg-info/PKG-INFO +1 -1
  9. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/setup.py +1 -1
  10. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/MANIFEST.in +0 -0
  11. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/README.md +0 -0
  12. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/__init__.py +0 -0
  13. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/abi/__init__.py +0 -0
  14. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/abi/abi.py +0 -0
  15. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/abi/faucet_abi.py +0 -0
  16. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/balance.py +0 -0
  17. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/constants.py +0 -0
  18. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/exceptions.py +0 -0
  19. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/faucet.py +0 -0
  20. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/ostium.py +0 -0
  21. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk/price.py +0 -0
  22. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk.egg-info/SOURCES.txt +0 -0
  23. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk.egg-info/dependency_links.txt +0 -0
  24. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk.egg-info/requires.txt +0 -0
  25. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/ostium_python_sdk.egg-info/top_level.txt +0 -0
  26. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/pyproject.toml +0 -0
  27. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/requirements-dev.txt +0 -0
  28. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/requirements.txt +0 -0
  29. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/setup.cfg +0 -0
  30. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/tests/__init__.py +0 -0
  31. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/tests/test_get_price_impact.py +0 -0
  32. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/tests/test_slippage.py +0 -0
  33. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/tests/test_trade_get_tp_price.py +0 -0
  34. {ostium_python_sdk-0.2.100 → ostium_python_sdk-0.2.103}/tests/test_trade_liquidation_price.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ostium-python-sdk
3
- Version: 0.2.100
3
+ Version: 0.2.103
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
@@ -22,9 +22,9 @@ class NetworkConfig:
22
22
 
23
23
  @classmethod
24
24
  def testnet(cls) -> 'NetworkConfig':
25
- return cls( # tbd
26
-
27
-
25
+ return cls( # tbd
26
+
27
+
28
28
  graph_url="https://subgraph.satsuma-prod.com/391a61815d32/ostium/ost-sep-final/api",
29
29
  contracts={
30
30
  "usdc": "0xe73B11Fb1e3eeEe8AF2a23079A4410Fe1B370548",
@@ -1,7 +1,10 @@
1
- from decimal import Decimal
1
+ from decimal import Decimal, getcontext, ROUND_DOWN
2
2
  from .constants import MAX_PROFIT_P, MAX_STOP_LOSS_P, PRECISION_16, PRECISION_2, PRECISION_6, PRECISION_12, PRECISION_18, LIQ_THRESHOLD_P
3
3
  from typing import Dict
4
+ from .scscript.funding import getPendingAccFundingFees, getTargetFundingRate
4
5
 
6
+ quantization_6 = Decimal('0.000001')
7
+ quantization_18 = Decimal('0.000000000000000001')
5
8
  #
6
9
  # This is a copy-cat of formulae repo originally written in TypeScript
7
10
  #
@@ -75,6 +78,8 @@ def CurrentTradeProfitP(open_price: str, current_price: str, long: bool, leverag
75
78
  return str(e)
76
79
 
77
80
  # tbd - used by SDK
81
+
82
+
78
83
  def GetTradeLiquidationPrice(
79
84
  open_price: str,
80
85
  long: bool,
@@ -149,6 +154,8 @@ def GetTradeRolloverFee(
149
154
  raise Exception(f"Unable to compute Trade Rollover Fee: {error}")
150
155
 
151
156
  # Gets the funding fee (abs) for an open trade (up to this block, aka based on current_funding up till this block)
157
+
158
+
152
159
  def GetTradeFundingFee(
153
160
  trade_funding: str,
154
161
  current_funding: str,
@@ -288,6 +295,8 @@ def CurrentTradeProfitRaw(
288
295
  raise Exception(f"Unable to compute Current Trade Profit Raw: {error}")
289
296
 
290
297
  # calculates the net profit (after fees) of an open trade (abs)
298
+
299
+
291
300
  def CurrentTotalProfitRaw(
292
301
  open_price: str,
293
302
  current_price: str,
@@ -337,65 +346,9 @@ def CurrentTotalProfitP(total_profit: str, collateral: str) -> str:
337
346
  raise Exception(
338
347
  f"Unable to compute Current Total Profit Percentage: {error}")
339
348
 
340
- # given desired TP percentage, like 35, 50, 75, 100, 500 and 900 which is max: gives you the TP price
341
-
342
- def get_target_funding_rate(
343
- normalized_oi_delta: Decimal,
344
- hill_inflection_point: Decimal,
345
- max_fr: Decimal,
346
- hill_pos_scale: Decimal,
347
- hill_neg_scale: Decimal,
348
- ) -> Decimal:
349
- a = Decimal('184')
350
- k = Decimal('16')
351
-
352
- x = a * normalized_oi_delta / PRECISION_2
353
- x2 = x * x * PRECISION_6 # convert to PRECISION_18
354
- hill = x2 * PRECISION_18 / (k * PRECISION_16 + x2)
355
-
356
- if normalized_oi_delta >= 0:
357
- target_fr = hill_pos_scale * hill / PRECISION_2 + hill_inflection_point
358
- else:
359
- target_fr = hill_neg_scale * Decimal('-1') * hill / PRECISION_2 + hill_inflection_point
360
-
361
- if target_fr > PRECISION_18:
362
- target_fr = PRECISION_18
363
- elif target_fr < PRECISION_18 * Decimal('-1'):
364
- target_fr = PRECISION_18 * Decimal('-1')
365
-
366
- return target_fr * max_fr / PRECISION_18
367
-
368
- def exponential_approximation(x: Decimal) -> Decimal:
369
- approx_threshold = Decimal('793231258909201900')
370
-
371
- if abs(x) < approx_threshold:
372
- three_with_precision = PRECISION_18 * 3
373
- numerator = x + three_with_precision
374
- numerator = numerator * numerator / PRECISION_18 + three_with_precision
375
- denominator = x - three_with_precision
376
- denominator = denominator * denominator / PRECISION_18 + three_with_precision
377
-
378
- return numerator * PRECISION_18 / denominator
379
- else:
380
- k = [1648721, 1284025, 1133148, 1064494, 1031743, 1015748, 1007843, 1003915, 1001955, 1000977]
381
- integer_part = abs(x) // PRECISION_18
382
- decimal_part = abs(x) - (integer_part * PRECISION_18)
383
-
384
- approx = PRECISION_6
385
-
386
- for ki in k:
387
- decimal_part = decimal_part * 2
388
- if decimal_part >= PRECISION_18:
389
- approx = approx * Decimal(str(ki)) / PRECISION_6
390
- decimal_part = decimal_part - PRECISION_18
391
- if decimal_part == 0:
392
- break
393
-
394
- return (PRECISION_18 * PRECISION_18 /
395
- (Decimal('2') ** integer_part *
396
- (approx / Decimal('1000') * Decimal('1e15'))) /
397
- Decimal('1e15') * Decimal('1e15'))
398
349
 
350
+ # returns (acc_funding_long, acc_funding_short, latest_funding_rate, target_fr)
351
+ # latest_funding_rate and target_fr are in % per year - how much long pay per year
399
352
  def get_funding_rate(
400
353
  acc_per_oi_long: str,
401
354
  acc_per_oi_short: str,
@@ -412,72 +365,87 @@ def get_funding_rate(
412
365
  spring_factor: str,
413
366
  s_factor_up_scale_p: str,
414
367
  s_factor_down_scale_p: str,
415
- ) -> Dict[str, str]:
416
- # Convert string inputs to Decimal
417
- acc_per_oi_long_dec = Decimal(acc_per_oi_long)
418
- acc_per_oi_short_dec = Decimal(acc_per_oi_short)
419
- last_funding_rate_dec = Decimal(last_funding_rate)
420
- max_funding_fee_per_block_dec = Decimal(max_funding_fee_per_block)
421
- last_update_block_dec = Decimal(last_update_block)
422
- latest_block_dec = Decimal(latest_block)
368
+ verbose: bool = False
369
+ ) -> tuple[int, int, int, int]:
370
+ """
371
+ Calculate funding rates and return as integers multiplied by PRECISION_18
372
+ Returns: (acc_funding_long, acc_funding_short, latest_funding_rate, target_fr)
373
+ """
374
+ def log(message):
375
+ if verbose:
376
+ print(message)
377
+
378
+ # Set decimal precision
379
+ getcontext().prec = 128
380
+ getcontext().rounding = ROUND_DOWN
381
+
382
+ # Convert all inputs to Decimal
423
383
  oi_long_dec = Decimal(oi_long)
424
384
  oi_short_dec = Decimal(oi_short)
425
385
  oi_cap_dec = Decimal(oi_cap)
426
- spring_factor_dec = Decimal(spring_factor)
427
- s_factor_up_scale_p_dec = Decimal(s_factor_up_scale_p)
428
- s_factor_down_scale_p_dec = Decimal(s_factor_down_scale_p)
429
- hill_inflection_point_dec = Decimal(hill_inflection_point)
430
- hill_pos_scale_dec = Decimal(hill_pos_scale)
431
- hill_neg_scale_dec = Decimal(hill_neg_scale)
432
-
433
- # Calculate open interest max
386
+
387
+ log(f"Input values:")
388
+ log(f"OI Long: {oi_long_dec}")
389
+ log(f"OI Short: {oi_short_dec}")
390
+ log(f"OI Cap: {oi_cap_dec}")
391
+ log(f"Last Funding Rate: {last_funding_rate}")
392
+ log(f"Last Update Block: {last_update_block}")
393
+ log(f"Latest Block: {latest_block}")
394
+
395
+ # Calculate normalized OI delta
434
396
  open_interest_max = max(oi_long_dec, oi_short_dec)
435
- denominator = max(oi_cap_dec, open_interest_max)
436
- oi_delta = (oi_long_dec - oi_short_dec) * PRECISION_6 / denominator
437
-
438
- # Get target funding rate
439
- target_fr = get_target_funding_rate(
440
- oi_delta,
441
- hill_inflection_point_dec,
442
- max_funding_fee_per_block_dec,
443
- hill_pos_scale_dec,
444
- hill_neg_scale_dec,
397
+ normalized_oi_delta = ((oi_long_dec - oi_short_dec)
398
+ * PRECISION_6) / max(oi_cap_dec, open_interest_max)
399
+
400
+ log(f"\nCalculated values:")
401
+ log(f"Open Interest Max: {open_interest_max}")
402
+ log(f"Normalized OI Delta: {normalized_oi_delta}")
403
+
404
+ # Get funding values
405
+ acc_funding_long, acc_funding_short, latest_funding_rate, target_fr = getPendingAccFundingFees(
406
+ blockNumber=Decimal(latest_block),
407
+ lastUpdateBlock=Decimal(last_update_block),
408
+ valueLong=Decimal(acc_per_oi_long),
409
+ valueShort=Decimal(acc_per_oi_short),
410
+ openInterestUsdcLong=oi_long_dec,
411
+ openInterestUsdcShort=oi_short_dec,
412
+ OiCap=oi_cap_dec,
413
+ maxFundingFeePerBlock=Decimal(max_funding_fee_per_block),
414
+ lastFundingRate=Decimal(last_funding_rate),
415
+ hillInflectionPoint=Decimal(hill_inflection_point),
416
+ hillPosScale=Decimal(hill_pos_scale),
417
+ hillNegScale=Decimal(hill_neg_scale),
418
+ springFactor=Decimal(spring_factor),
419
+ sFactorUpScale=Decimal(s_factor_up_scale_p),
420
+ sFactorDownScaleP=Decimal(s_factor_down_scale_p),
445
421
  )
446
422
 
447
- # Calculate spring factor
448
- s_factor = Decimal('0')
449
- if last_funding_rate_dec * target_fr >= 0:
450
- if abs(target_fr) > abs(last_funding_rate_dec):
451
- s_factor = spring_factor_dec
452
- else:
453
- s_factor = s_factor_down_scale_p_dec * spring_factor_dec / Decimal('10000')
454
- else:
455
- s_factor = s_factor_up_scale_p_dec * spring_factor_dec / Decimal('10000')
456
-
457
- # Calculate blocks to charge and exponential
458
- num_blocks_to_charge = latest_block_dec - last_update_block_dec
459
- exp = exponential_approximation(s_factor * num_blocks_to_charge * Decimal('-1'))
460
-
461
- # Calculate funding rates
462
- acc_funding_rate = (target_fr * num_blocks_to_charge +
463
- (PRECISION_18 - exp) * (last_funding_rate_dec - target_fr) / s_factor)
464
- fr = target_fr + (last_funding_rate_dec - target_fr) * exp / PRECISION_18
465
-
466
- # Update accumulations
467
- if acc_funding_rate > 0:
468
- if oi_long_dec > 0:
469
- acc_per_oi_long_dec += acc_funding_rate
470
- acc_per_oi_short_dec -= (acc_funding_rate * oi_long_dec / oi_short_dec
471
- if oi_short_dec > 0 else Decimal('0'))
472
- else:
473
- if oi_short_dec > 0:
474
- acc_per_oi_short_dec -= acc_funding_rate
475
- acc_per_oi_long_dec += (acc_funding_rate * oi_short_dec / oi_long_dec
476
- if oi_long_dec > 0 else Decimal('0'))
477
-
478
- return {
479
- 'accFundingLong': str(acc_per_oi_long_dec),
480
- 'accFundingShort': str(acc_per_oi_short_dec),
481
- 'latestFundingRate': str(fr),
482
- 'targetFr': str(target_fr)
483
- }
423
+ log(f"\nIntermediate results:")
424
+ log(f"Acc Funding Long (pre-conversion): {acc_funding_long}")
425
+ log(f"Acc Funding Short (pre-conversion): {acc_funding_short}")
426
+ log(f"Latest Funding Rate (pre-conversion): {latest_funding_rate}")
427
+ log(f"Target Funding Rate (pre-conversion): {target_fr}")
428
+
429
+ acc_funding_long_int = (
430
+ acc_funding_long / PRECISION_18).quantize(quantization_18, rounding=ROUND_DOWN)
431
+ acc_funding_short_int = (
432
+ acc_funding_short / PRECISION_18).quantize(quantization_18, rounding=ROUND_DOWN)
433
+ latest_funding_rate = (
434
+ latest_funding_rate / PRECISION_18).quantize(quantization_18, rounding=ROUND_DOWN)
435
+ target_fr = (target_fr / PRECISION_18).quantize(quantization_18,
436
+ rounding=ROUND_DOWN)
437
+
438
+ log(f"\nFinal results (multiplied by 10^18):")
439
+ log(f"Acc Funding Long: {acc_funding_long_int}")
440
+ log(f"Acc Funding Short: {acc_funding_short_int}")
441
+ log(f"Latest Funding Rate: {latest_funding_rate}")
442
+ log(f"Target Funding Rate: {target_fr}")
443
+
444
+ return (
445
+ acc_funding_long_int,
446
+ acc_funding_short_int,
447
+ ((latest_funding_rate * 10 / 3 * 60) * 60 * 24 * 365 *
448
+ 100).quantize(quantization_6, rounding=ROUND_DOWN),
449
+ ((target_fr * 10 / 3 * 60) * 60 * 24 * 365 *
450
+ 100).quantize(quantization_6, rounding=ROUND_DOWN),
451
+ )
@@ -6,6 +6,8 @@ from .formulae import (PRECISION_18, PRECISION_2, PRECISION_6, GetCurrentRollove
6
6
  from typing import Dict, Union
7
7
 
8
8
  # TBD - Not used by SDK
9
+
10
+
9
11
  def get_liq_price(trade_details, pair_info, block_number):
10
12
  current_funding_fee = GetTradeFundingFee(trade_details['funding'], pair_info['accFundingLong'] if trade_details['isBuy']
11
13
  else pair_info['accFundingShort'], trade_details['collateral'], trade_details['leverage'])
@@ -22,6 +24,8 @@ def get_liq_price(trade_details, pair_info, block_number):
22
24
  return liq_price / PRECISION_18
23
25
 
24
26
  # TBD - used by SDK
27
+
28
+
25
29
  def get_funding_fee_long_short(pair_info, block_number):
26
30
  funding_rate_raw = GetFundingRate(
27
31
  pair_info['accFundingLong'],
@@ -60,6 +64,8 @@ def get_funding_fee_long_short(pair_info, block_number):
60
64
 
61
65
  # TBD - used by SDK
62
66
  # Gets an open trade metrics: such as the open pnl, rollover, funding, liquidation price, price impact, etc.
67
+
68
+
63
69
  def get_trade_metrics(trade_details, price_data, block_number, verbose=False):
64
70
  """
65
71
  Calculate PNL and related metrics for a trade.
@@ -139,7 +145,8 @@ def get_trade_metrics(trade_details, price_data, block_number, verbose=False):
139
145
  liquidation_price = Decimal(liquidation_price) / PRECISION_18
140
146
 
141
147
  if verbose:
142
- print(f"Liquidation price: {liquidation_price} with rollover {rollover_raw} and funding {funding_raw}")
148
+ print(
149
+ f"Liquidation price: {liquidation_price} with rollover {rollover_raw} and funding {funding_raw}")
143
150
 
144
151
  # Calculate price impact
145
152
  is_open = False # Get the price assuming a close
@@ -143,16 +143,31 @@ class OstiumSDK:
143
143
  self.log(f"Pair details: {pair_details}")
144
144
  self.log(f"Block number: {block_number}")
145
145
 
146
+ # Get current price
147
+ last_trade_price = pair_details['lastTradePrice']
148
+ self.log(f"lastTradePrice: {last_trade_price}")
149
+
150
+ long_oi = int(
151
+ (Decimal(pair_details['longOI']) *
152
+ Decimal(last_trade_price) / PRECISION_18 / PRECISION_12)
153
+ )
154
+ short_oi = int(
155
+ (Decimal(pair_details['shortOI']) *
156
+ Decimal(last_trade_price) / PRECISION_18 / PRECISION_12)
157
+ )
158
+
159
+ self.log(f"notional_long_oi: {long_oi}")
160
+ self.log(f"notional_short_oi: {short_oi}")
161
+
146
162
  ret = get_funding_rate(
147
163
  pair_details['curFundingLong'],
148
164
  pair_details['curFundingShort'],
149
165
  pair_details['lastFundingRate'],
150
- # pair_details['lastFundingVelocity'],
151
166
  pair_details['maxFundingFeePerBlock'],
152
167
  pair_details['lastFundingBlock'],
153
168
  block_number,
154
- pair_details['longOI'],
155
- pair_details['shortOI'],
169
+ long_oi, # Needs to be in USD
170
+ short_oi, # Needs to be in USD
156
171
  pair_details['maxOI'],
157
172
  pair_details['hillInflectionPoint'],
158
173
  pair_details['hillPosScale'],
@@ -160,6 +175,7 @@ class OstiumSDK:
160
175
  pair_details['springFactor'],
161
176
  pair_details['sFactorUpScaleP'],
162
177
  pair_details['sFactorDownScaleP'],
178
+ self.verbose
163
179
  )
164
180
 
165
181
  self.log(f"Funding rate: {ret}")
@@ -50,8 +50,6 @@ class SubgraphClient:
50
50
  maxOI
51
51
  makerFeeP
52
52
  takerFeeP
53
- usageFeeP
54
- utilizationThresholdP
55
53
  makerMaxLeverage
56
54
  curFundingLong
57
55
  curFundingShort
@@ -70,7 +68,6 @@ class SubgraphClient:
70
68
  hillInflectionPoint
71
69
  hillPosScale
72
70
  hillNegScale
73
- lastOiDelta
74
71
  springFactor
75
72
  sFactorUpScaleP
76
73
  sFactorDownScaleP
@@ -6,7 +6,6 @@ from ast import literal_eval
6
6
  from .constants import MAX_PROFIT_P, MAX_STOP_LOSS_P
7
7
 
8
8
 
9
-
10
9
  def format_with_precision(number, precision):
11
10
  """
12
11
  Formats a number to a specified decimal precision, removing trailing zeros.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: ostium-python-sdk
3
- Version: 0.2.100
3
+ Version: 0.2.103
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
@@ -19,7 +19,7 @@ if changelog_path.exists():
19
19
 
20
20
  setup(
21
21
  name="ostium-python-sdk",
22
- version="0.2.100",
22
+ version="0.2.103",
23
23
  packages=find_packages(),
24
24
  install_requires=read_requirements('requirements.txt'),
25
25
  extras_require={