bitunix-automated-crypto-trading 3.2.9__py3-none-any.whl → 3.3.1__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.
- bitunix_automated_crypto_trading/BitunixApi.py +12 -12
- bitunix_automated_crypto_trading/BitunixSignal.py +54 -21
- bitunix_automated_crypto_trading/version.py +1 -1
- {bitunix_automated_crypto_trading-3.2.9.dist-info → bitunix_automated_crypto_trading-3.3.1.dist-info}/METADATA +1 -1
- {bitunix_automated_crypto_trading-3.2.9.dist-info → bitunix_automated_crypto_trading-3.3.1.dist-info}/RECORD +8 -8
- {bitunix_automated_crypto_trading-3.2.9.dist-info → bitunix_automated_crypto_trading-3.3.1.dist-info}/WHEEL +0 -0
- {bitunix_automated_crypto_trading-3.2.9.dist-info → bitunix_automated_crypto_trading-3.3.1.dist-info}/entry_points.txt +0 -0
- {bitunix_automated_crypto_trading-3.2.9.dist-info → bitunix_automated_crypto_trading-3.3.1.dist-info}/top_level.txt +0 -0
@@ -120,9 +120,9 @@ class BitunixApi:
|
|
120
120
|
response.raise_for_status()
|
121
121
|
return response.json()
|
122
122
|
|
123
|
-
async def PlaceOrder(self, ticker, qty, price, side, positionId=0, tradeSide="OPEN",reduceOnly=False,
|
123
|
+
async def PlaceOrder(self, ticker, qty, price, side, positionId=0, tradeSide="OPEN",reduceOnly=False, tpPrice=0, tpOrderPrice=0, slPrice=0, slOrderPrice=0):
|
124
124
|
datajs = None
|
125
|
-
if
|
125
|
+
if tpPrice == 0 and slPrice == 0:
|
126
126
|
data = {
|
127
127
|
"side": side,
|
128
128
|
"orderType":"LIMIT",
|
@@ -134,7 +134,7 @@ class BitunixApi:
|
|
134
134
|
"positionId":positionId
|
135
135
|
}
|
136
136
|
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
137
|
-
elif
|
137
|
+
elif tpPrice == 0:
|
138
138
|
data = {
|
139
139
|
"side": side,
|
140
140
|
"orderType":"LIMIT",
|
@@ -142,14 +142,14 @@ class BitunixApi:
|
|
142
142
|
"price": price,
|
143
143
|
"symbol": ticker,
|
144
144
|
"tradeSide":tradeSide,
|
145
|
-
"slPrice":
|
146
|
-
"slStopType":'MARK_PRICE',
|
145
|
+
"slPrice": slPrice,
|
147
146
|
"slStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
148
147
|
"slOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
148
|
+
"slOrderPrice": slOrderPrice,
|
149
149
|
"positionId":positionId
|
150
150
|
}
|
151
151
|
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
152
|
-
elif
|
152
|
+
elif slPrice == 0:
|
153
153
|
data = {
|
154
154
|
"side": side,
|
155
155
|
"orderType":"LIMIT",
|
@@ -157,10 +157,10 @@ class BitunixApi:
|
|
157
157
|
"price": price,
|
158
158
|
"symbol": ticker,
|
159
159
|
"tradeSide":tradeSide,
|
160
|
-
"tpPrice":
|
160
|
+
"tpPrice": tpPrice,
|
161
161
|
"tpStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
162
162
|
"tpOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
163
|
-
"tpOrderPrice":
|
163
|
+
"tpOrderPrice":tpOrderPrice,
|
164
164
|
"positionId":positionId
|
165
165
|
}
|
166
166
|
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
@@ -172,14 +172,14 @@ class BitunixApi:
|
|
172
172
|
"price": price,
|
173
173
|
"symbol": ticker,
|
174
174
|
"tradeSide":tradeSide,
|
175
|
-
"tpPrice":
|
175
|
+
"tpPrice": tpPrice,
|
176
176
|
"tpStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
177
177
|
"tpOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
178
|
-
"tpOrderPrice":
|
179
|
-
"slPrice":
|
178
|
+
"tpOrderPrice":tpOrderPrice,
|
179
|
+
"slPrice": slPrice,
|
180
180
|
"slStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
181
181
|
"slOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
182
|
-
"slOrderPrice":
|
182
|
+
"slOrderPrice": slOrderPrice,
|
183
183
|
"positionId":positionId
|
184
184
|
}
|
185
185
|
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
@@ -3,6 +3,8 @@ import pandas as pd
|
|
3
3
|
import json
|
4
4
|
import asyncio
|
5
5
|
from datetime import datetime, timedelta, timezone
|
6
|
+
from decimal import Decimal
|
7
|
+
|
6
8
|
from collections import defaultdict
|
7
9
|
import traceback
|
8
10
|
import time
|
@@ -664,7 +666,18 @@ class BitunixSignal:
|
|
664
666
|
|
665
667
|
return round(duration_minutes)
|
666
668
|
|
667
|
-
|
669
|
+
async def str_precision(self,num):
|
670
|
+
num_decimal = Decimal(str(num)) # Convert to Decimal to preserve precision
|
671
|
+
decimal_places = abs(num_decimal.as_tuple().exponent) # Get original decimal places
|
672
|
+
return f"{num:.{decimal_places}f}" # Format with the original precision
|
673
|
+
|
674
|
+
async def increment_by_last_decimal(self, value_str):
|
675
|
+
value = Decimal(value_str)
|
676
|
+
# Count number of decimal places
|
677
|
+
decimal_places = abs(value.as_tuple().exponent)
|
678
|
+
increment = Decimal(f'1e-{decimal_places}')
|
679
|
+
return float(value + increment)
|
680
|
+
|
668
681
|
|
669
682
|
async def calculate_candles(self, timeframe, duration_minutes):
|
670
683
|
|
@@ -703,14 +716,17 @@ class BitunixSignal:
|
|
703
716
|
#open position upto a max of max_auto_trades from the signal list
|
704
717
|
df=self.signaldf.copy(deep=False)
|
705
718
|
for index, row in df.iterrows():
|
706
|
-
|
707
|
-
# Calculate the duration in minutes since the position was opened
|
708
719
|
await asyncio.sleep(5)
|
720
|
+
data=None
|
721
|
+
# Calculate the duration in minutes since the position was opened
|
709
722
|
data = await self.bitunixApi.GetPositionHistoryData({'symbol': row['symbol']})
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
723
|
+
duration_minutes = None
|
724
|
+
if data and 'positionList' in data and len(data['positionList']) > 0:
|
725
|
+
xtime = float(data['positionList'][0]['mtime'])
|
726
|
+
mtime = pd.to_datetime(xtime, unit='ms').tz_localize('UTC').tz_convert(cst).strftime('%Y-%m-%d %H:%M:%S')
|
727
|
+
duration_minutes = await self.get_duration(mtime)
|
728
|
+
self.logger.info(f"row.symbol: {row.symbol} , duration_minutes: {duration_minutes}, last trade time: {mtime if duration_minutes is not None else 'N/A'}")
|
729
|
+
if duration_minutes is None or duration_minutes > self.settings.DELAY_IN_MINUTES_FOR_SAME_TICKER_TRADES:
|
714
730
|
side = "BUY" if row[f'{period}_barcolor'] == self.green and row[f'{period}_trend'] == "BUY" else "SELL" if row[f'{period}_barcolor'] == self.red and row[f'{period}_trend'] == "SELL" else ""
|
715
731
|
if side != "":
|
716
732
|
select = True
|
@@ -721,37 +737,54 @@ class BitunixSignal:
|
|
721
737
|
if self.pendingOrders and len(self.pendingOrders['orderList']) == 1:
|
722
738
|
select = False
|
723
739
|
if select:
|
740
|
+
balance = float(self.portfoliodf["available"].iloc[0]) + float(self.portfoliodf["crossUnrealizedPNL"].iloc[0])
|
741
|
+
|
724
742
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
725
743
|
|
726
744
|
price = (bid if side == "BUY" else ask if side == "SELL" else last) if bid<=last<=ask else last
|
745
|
+
qty= str(max(balance * (float(self.settings.ORDER_AMOUNT_PERCENTAGE) / 100 ) / price * int(self.settings.LEVERAGE),mtv))
|
727
746
|
|
728
|
-
|
747
|
+
decimal_places = abs(Decimal(str(price)).as_tuple().exponent)
|
748
|
+
|
749
|
+
tpPrice=0
|
750
|
+
tpOrderPrice=0
|
729
751
|
if self.settings.PROFIT_AMOUNT > 0:
|
730
|
-
|
752
|
+
tpPrice = (price * qty + float(self.settings.PROFIT_AMOUNT))/qty if side == "BUY" else (price * qty - float(self.settings.PROFIT_AMOUNT))/qty
|
753
|
+
tpPrice = Decimal(await self.str_precision(tpPrice))
|
754
|
+
tpPrice =float(str(tpPrice.quantize(Decimal(f'1e-{decimal_places}'))))
|
755
|
+
tpOrderPrice = await self.increment_by_last_decimal(str(tpPrice))
|
731
756
|
if self.settings.PROFIT_PERCENTAGE > 0 or self.settings.PROFIT_AMOUNT > 0:
|
732
|
-
|
757
|
+
tpPrice = price * (1 + float(self.settings.PROFIT_PERCENTAGE) / 100 / self.settings.LEVERAGE) if side == "BUY" else price * (1 - float(self.settings.PROFIT_PERCENTAGE) / 100 / self.settings.LEVERAGE)
|
758
|
+
tpPrice = Decimal(await self.str_precision(tpPrice))
|
759
|
+
tpPrice = float(str(tpPrice.quantize(Decimal(f'1e-{decimal_places}'))))
|
760
|
+
tpOrderPrice = await self.increment_by_last_decimal(await self.str_precision(tpPrice))
|
733
761
|
|
734
|
-
|
762
|
+
slPrice=0
|
763
|
+
slOrderPrice=0
|
735
764
|
if self.settings.LOSS_AMOUNT > 0:
|
736
|
-
|
765
|
+
slPrice = (price * qty - float(self.settings.LOSS_AMOUNT))/qty if side == "BUY" else (price * qty + float(self.settings.LOSS_AMOUNT))/qty
|
766
|
+
slPrice = Decimal(await self.str_precision(slPrice))
|
767
|
+
slPrice = float(str(slPrice.quantize(Decimal(f'1e-{decimal_places}'))))
|
768
|
+
slOrderPrice = await self.increment_by_last_decimal(str(slPrice))
|
737
769
|
if self.settings.LOSS_PERCENTAGE > 0 or self.settings.LOSS_AMOUNT > 0:
|
738
|
-
|
770
|
+
slPrice = price * (1 - float(self.settings.LOSS_PERCENTAGE) / 100 / self.settings.LEVERAGE) if side == "BUY" else price * (1 + float(self.settings.LOSS_PERCENTAGE) / 100 / self.settings.LEVERAGE)
|
771
|
+
slPrice = Decimal(await self.str_precision(slPrice))
|
772
|
+
slPrice = float(str(slPrice.quantize(Decimal(f'1e-{decimal_places}'))))
|
773
|
+
slOrderPrice = await self.increment_by_last_decimal(await self.str_precision(slPrice))
|
739
774
|
|
740
|
-
balance = float(self.portfoliodf["available"].iloc[0]) + float(self.portfoliodf["crossUnrealizedPNL"].iloc[0])
|
741
|
-
qty= str(max(balance * (float(self.settings.ORDER_AMOUNT_PERCENTAGE) / 100 ) / price * int(self.settings.LEVERAGE),mtv))
|
742
775
|
|
743
776
|
self.notifications.add_notification(
|
744
777
|
f'{colors.YELLOW} Opening {"long" if side=="BUY" else "short"} position for {row.symbol} with {qty} qty @ {price})'
|
745
778
|
)
|
746
779
|
datajs = None
|
747
|
-
if
|
780
|
+
if tpPrice == 0 and slPrice == 0:
|
748
781
|
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side)
|
749
|
-
elif
|
750
|
-
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side,
|
751
|
-
elif
|
752
|
-
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side,
|
782
|
+
elif tpPrice == 0:
|
783
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side, slPrice=slPrice, slOrderPrice=slOrderPrice)
|
784
|
+
elif slPrice == 0:
|
785
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side, tpPrice=tpPrice, tpOrderPrice=tpOrderPrice)
|
753
786
|
else:
|
754
|
-
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side,
|
787
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side, tpPrice=tpPrice, tpOrderPrice=tpOrderPrice, slPrice=slPrice, slOrderPrice=slOrderPrice)
|
755
788
|
count=count+1
|
756
789
|
else:
|
757
790
|
self.logger.info(f"Skipping {row.symbol} as it has been opened for less than {self.settings.DELAY_IN_MINUTES_FOR_SAME_TICKER_TRADES} minutes")
|
@@ -1 +1 @@
|
|
1
|
-
__version__ = "3.
|
1
|
+
__version__ = "3.3.1"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
bitunix_automated_crypto_trading/AsyncThreadRunner.py,sha256=bNIM_1xRYQOFEsIn74EX6qVpC59-GMhhr2CeiPr_GWg,3253
|
2
|
-
bitunix_automated_crypto_trading/BitunixApi.py,sha256=
|
3
|
-
bitunix_automated_crypto_trading/BitunixSignal.py,sha256=
|
2
|
+
bitunix_automated_crypto_trading/BitunixApi.py,sha256=P5lAToQDl-q8yjLD0bH3G8ajY_fxx3XKet0rS9UP7Pg,13504
|
3
|
+
bitunix_automated_crypto_trading/BitunixSignal.py,sha256=AbOhi9ehn_QY7ZAVlU_fnIUNKWoVKuy7VLZIE2v75kU,77286
|
4
4
|
bitunix_automated_crypto_trading/BitunixWebSocket.py,sha256=uiqAcis3u-ct07tjaTiC87ujzvcAtVRZ31CMiTBDW_M,11309
|
5
5
|
bitunix_automated_crypto_trading/DataFrameHtmlRenderer.py,sha256=Pqdzhh_nfIxFEZH9L_R5QXB8moDPbgeTGT_hmBkHWMg,2899
|
6
6
|
bitunix_automated_crypto_trading/NotificationManager.py,sha256=exs6REABBA1omTeTGuUuECzxs5dGqdyL7oI8WyxS6Xc,798
|
@@ -11,9 +11,9 @@ bitunix_automated_crypto_trading/__init__.py,sha256=1hzk6nX8NnUCr1tsq8oFq1qGCNhN
|
|
11
11
|
bitunix_automated_crypto_trading/bitunix.py,sha256=lxwnYARxldA2oU6GdjupilXIlnUh4RX8rQLCOn7x13I,27143
|
12
12
|
bitunix_automated_crypto_trading/config.py,sha256=7h8GvMH1SFuFPhKM3azA2pVS0w2CRzKtUankhI-IKHY,5655
|
13
13
|
bitunix_automated_crypto_trading/logger.py,sha256=NHnA5JZdUFkTAhB7i-1iCAwrdf1fxhDuRvJUkbKPi9Y,2923
|
14
|
-
bitunix_automated_crypto_trading/version.py,sha256=
|
15
|
-
bitunix_automated_crypto_trading-3.
|
16
|
-
bitunix_automated_crypto_trading-3.
|
17
|
-
bitunix_automated_crypto_trading-3.
|
18
|
-
bitunix_automated_crypto_trading-3.
|
19
|
-
bitunix_automated_crypto_trading-3.
|
14
|
+
bitunix_automated_crypto_trading/version.py,sha256=vFVFOckEr44mXptQFYzU0w8rn7ILjARfK9BoWOrTJxA,21
|
15
|
+
bitunix_automated_crypto_trading-3.3.1.dist-info/METADATA,sha256=pjC1qj0p9YPnHNXbIfllgnuedbaHWH61mk9tgBqrHJo,996
|
16
|
+
bitunix_automated_crypto_trading-3.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
17
|
+
bitunix_automated_crypto_trading-3.3.1.dist-info/entry_points.txt,sha256=UXREYHuSl2XYd_tOtLIq0zg3d1kX3lixX5SpN8yGBw4,82
|
18
|
+
bitunix_automated_crypto_trading-3.3.1.dist-info/top_level.txt,sha256=uyFzHUCOsp8elnG2Ovor6xXcf7dxRxY-C-Txiwix64Q,33
|
19
|
+
bitunix_automated_crypto_trading-3.3.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|