trd-utils 0.0.39__py3-none-any.whl → 0.0.41__py3-none-any.whl
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.
Potentially problematic release.
This version of trd-utils might be problematic. Click here for more details.
- trd_utils/__init__.py +1 -1
- trd_utils/exchanges/base_types.py +28 -0
- trd_utils/exchanges/bx_ultra/bx_ultra_client.py +14 -4
- {trd_utils-0.0.39.dist-info → trd_utils-0.0.41.dist-info}/METADATA +1 -1
- {trd_utils-0.0.39.dist-info → trd_utils-0.0.41.dist-info}/RECORD +7 -7
- {trd_utils-0.0.39.dist-info → trd_utils-0.0.41.dist-info}/LICENSE +0 -0
- {trd_utils-0.0.39.dist-info → trd_utils-0.0.41.dist-info}/WHEEL +0 -0
trd_utils/__init__.py
CHANGED
|
@@ -50,6 +50,34 @@ class UnifiedPositionInfo(BaseModel):
|
|
|
50
50
|
# not all exchanges support this yet, so use it with caution.
|
|
51
51
|
last_volume: Decimal | None = None
|
|
52
52
|
|
|
53
|
+
def recalculate_pnl(self) -> tuple[Decimal, Decimal]:
|
|
54
|
+
"""
|
|
55
|
+
Recalculates the PnL based on the available data.
|
|
56
|
+
This requires `last_price`, `open_price`, `initial_margin`,
|
|
57
|
+
and `position_leverage` to be set.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
The recalculated (PnL, percentage) as a Decimal, or None if calculation
|
|
61
|
+
is not possible with the current data.
|
|
62
|
+
"""
|
|
63
|
+
if not self.position_leverage:
|
|
64
|
+
self.position_leverage = 1
|
|
65
|
+
|
|
66
|
+
if not all([self.last_price, self.open_price, self.initial_margin]):
|
|
67
|
+
# Not enough data to calculate PnL.
|
|
68
|
+
return None
|
|
69
|
+
|
|
70
|
+
price_change_percentage = (self.last_price - self.open_price) / self.open_price
|
|
71
|
+
if self.position_side == "SHORT":
|
|
72
|
+
# For a short position, profit is made when the price goes down.
|
|
73
|
+
price_change_percentage *= -1
|
|
74
|
+
|
|
75
|
+
pnl_percentage = self.position_leverage * price_change_percentage
|
|
76
|
+
# PnL = Initial Margin * Leverage * Price Change %
|
|
77
|
+
pnl = self.initial_margin * pnl_percentage
|
|
78
|
+
self.position_pnl = pnl
|
|
79
|
+
return (pnl, pnl_percentage)
|
|
80
|
+
|
|
53
81
|
def __str__(self):
|
|
54
82
|
parts = []
|
|
55
83
|
|
|
@@ -83,7 +83,8 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
83
83
|
# region client parameters
|
|
84
84
|
we_api_base_host: str = "\u0061pi-\u0061pp.w\u0065-\u0061pi.com"
|
|
85
85
|
we_api_base_url: str = "https://\u0061pi-\u0061pp.w\u0065-\u0061pi.com/\u0061pi"
|
|
86
|
-
ws_we_api_base_url: str = "wss://ws-market-
|
|
86
|
+
ws_we_api_base_url: str = "wss://ws-market-sw\u0061p.w\u0065-\u0061pi.com/ws"
|
|
87
|
+
f_ws_we_api_base_url: str = "wss://f-ws-\u0061pp.w\u0065-\u0061pi.com/market"
|
|
87
88
|
original_base_host: str = "https://\u0062ing\u0078.co\u006d"
|
|
88
89
|
qq_os_base_host: str = "https://\u0061pi-\u0061pp.\u0071\u0071-os.com"
|
|
89
90
|
qq_os_base_url: str = "https://\u0061pi-\u0061pp.\u0071\u0071-os.com/\u0061pi"
|
|
@@ -283,7 +284,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
283
284
|
|
|
284
285
|
# endregion
|
|
285
286
|
###########################################################
|
|
286
|
-
# region ws-
|
|
287
|
+
# region ws last-candle methods
|
|
287
288
|
async def do_price_subscribe(self) -> None:
|
|
288
289
|
"""
|
|
289
290
|
Subscribes to the price changes coming from the exchange.
|
|
@@ -922,6 +923,9 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
922
923
|
) -> UnifiedTraderPositions:
|
|
923
924
|
perp_positions = []
|
|
924
925
|
std_positions = []
|
|
926
|
+
perp_ex: str = None
|
|
927
|
+
std_ex: str = None
|
|
928
|
+
|
|
925
929
|
try:
|
|
926
930
|
result = await self.get_unified_trader_positions_perp(
|
|
927
931
|
uid=uid,
|
|
@@ -930,7 +934,7 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
930
934
|
perp_positions = result.positions
|
|
931
935
|
except Exception as ex:
|
|
932
936
|
if not no_warn:
|
|
933
|
-
|
|
937
|
+
perp_ex = f"{ex}"
|
|
934
938
|
|
|
935
939
|
try:
|
|
936
940
|
result = await self.get_unified_trader_positions_std(
|
|
@@ -939,7 +943,13 @@ class BXUltraClient(ExchangeBase, IPriceFetcher):
|
|
|
939
943
|
std_positions = result.positions
|
|
940
944
|
except Exception as ex:
|
|
941
945
|
if not no_warn:
|
|
942
|
-
|
|
946
|
+
std_ex = f"{ex}"
|
|
947
|
+
|
|
948
|
+
if not perp_positions and not std_positions:
|
|
949
|
+
if perp_ex:
|
|
950
|
+
logger.warning(f"Failed to fetch perp positions of {uid}: {perp_ex}")
|
|
951
|
+
if std_ex:
|
|
952
|
+
logger.warning(f"Failed to fetch std positions of {uid}: {std_ex}")
|
|
943
953
|
|
|
944
954
|
unified_result = UnifiedTraderPositions()
|
|
945
955
|
unified_result.positions = perp_positions + std_positions
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
trd_utils/__init__.py,sha256=
|
|
1
|
+
trd_utils/__init__.py,sha256=opeJdyFbAssqryQZxqUaYkJDAEZ8cuVWBwxBnzfUbDk,25
|
|
2
2
|
trd_utils/cipher/__init__.py,sha256=V05KNuzQwCic-ihMVHlC8sENaJGc3I8MCb4pg4849X8,1765
|
|
3
3
|
trd_utils/common_utils/float_utils.py,sha256=aYPwJ005LmrRhXAngojwvdDdtRgeb1FfR6hKeQ5ndMU,470
|
|
4
4
|
trd_utils/common_utils/wallet_utils.py,sha256=OX9q2fymP0VfIWTRIRBP8W33cfyjLXimxMgPOsZe-3g,727
|
|
@@ -6,13 +6,13 @@ trd_utils/date_utils/__init__.py,sha256=Erg_E1TfKWNpiuZFm_NXRjCwoRMfxpPS2-mJK6V4
|
|
|
6
6
|
trd_utils/date_utils/datetime_helpers.py,sha256=euIJBr-6PfJzLScOC9xVXd8Re_Gw5CSBPwtHX9_Il4A,596
|
|
7
7
|
trd_utils/exchanges/README.md,sha256=8egE4IPUQ3_UtiGP6GaCg50xq_dp43aGY_X1lKcO6ok,6812
|
|
8
8
|
trd_utils/exchanges/__init__.py,sha256=sZRyp24q0KyMYASshAfsP-AfvsCADTYqqefxiRulPKE,484
|
|
9
|
-
trd_utils/exchanges/base_types.py,sha256=
|
|
9
|
+
trd_utils/exchanges/base_types.py,sha256=MVZvmxmYWgYh4URGVYaalNgY57l0VJX1GC8U18tB0rE,4964
|
|
10
10
|
trd_utils/exchanges/blofin/__init__.py,sha256=X4r9o4Nyjla4UeOBG8lrgtnGYO2aErFMKaJ7yQrFasE,76
|
|
11
11
|
trd_utils/exchanges/blofin/blofin_client.py,sha256=LAAbwXbA7nDxJZFwbXtaNsIZCayEyX3SwfwYdRr3uQs,13079
|
|
12
12
|
trd_utils/exchanges/blofin/blofin_types.py,sha256=bQx0opCgHwcuC-5TxiVA4VQr17A1x7u7QIMdcIrROAg,4315
|
|
13
13
|
trd_utils/exchanges/bx_ultra/__init__.py,sha256=8Ssy-eOemQR32Nv1-FoPHm87nRqRO4Fm2PU5GHEFKfQ,80
|
|
14
14
|
trd_utils/exchanges/bx_ultra/bx_types.py,sha256=7Ga6IYHQNRDbhWXmS1J0NxpcR9HUJ8ZwQGh-1EvNRqM,36687
|
|
15
|
-
trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=
|
|
15
|
+
trd_utils/exchanges/bx_ultra/bx_ultra_client.py,sha256=aWnJjK0KXn_250lOfm3tUk8KZbr3wq9lsRIqcuOLAJk,40196
|
|
16
16
|
trd_utils/exchanges/bx_ultra/bx_utils.py,sha256=PwapomwDW33arVmKIDj6cL-aP0ptu4BYy_lOCqSAPOo,1392
|
|
17
17
|
trd_utils/exchanges/errors.py,sha256=P_NTuc389XL7rFegomP59BydWmHv8ckiGyNU-_l5qNQ,167
|
|
18
18
|
trd_utils/exchanges/exchange_base.py,sha256=Zn5y4bymK53ENVLjYnQadS61SZKs8BGoZ4jfsY4GOcE,7835
|
|
@@ -31,7 +31,7 @@ trd_utils/tradingview/tradingview_client.py,sha256=g_eWYaCRQAL8Kvd-r6AnAdbH7Jha6
|
|
|
31
31
|
trd_utils/tradingview/tradingview_types.py,sha256=z21MXPVdWHAduEl3gSeMIRhxtBN9yK-jPYHfZSMIbSA,6144
|
|
32
32
|
trd_utils/types_helper/__init__.py,sha256=lLbUiW1jUV1gjzTMFLthwkvF0hwauH-F_J2JZq--1U0,67
|
|
33
33
|
trd_utils/types_helper/base_model.py,sha256=dknzoq6iAUOb0n_yhI5mU3So-F_8d5ykGk3EbrERLnM,11763
|
|
34
|
-
trd_utils-0.0.
|
|
35
|
-
trd_utils-0.0.
|
|
36
|
-
trd_utils-0.0.
|
|
37
|
-
trd_utils-0.0.
|
|
34
|
+
trd_utils-0.0.41.dist-info/LICENSE,sha256=J1EP2xt87RjjmsTV1jTjHDQMLIM9FjdwEftTpw8hyv4,1067
|
|
35
|
+
trd_utils-0.0.41.dist-info/METADATA,sha256=VfqukF_Pe-4dpdr8SDsCaYHHcWVdUVq50LOhH943Dgw,1179
|
|
36
|
+
trd_utils-0.0.41.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
37
|
+
trd_utils-0.0.41.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|