bitunix-automated-crypto-trading 3.2.6__py3-none-any.whl → 3.2.8__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 +65 -12
- bitunix_automated_crypto_trading/BitunixSignal.py +25 -73
- bitunix_automated_crypto_trading/config.py +2 -0
- bitunix_automated_crypto_trading/version.py +1 -1
- {bitunix_automated_crypto_trading-3.2.6.dist-info → bitunix_automated_crypto_trading-3.2.8.dist-info}/METADATA +1 -1
- {bitunix_automated_crypto_trading-3.2.6.dist-info → bitunix_automated_crypto_trading-3.2.8.dist-info}/RECORD +9 -9
- {bitunix_automated_crypto_trading-3.2.6.dist-info → bitunix_automated_crypto_trading-3.2.8.dist-info}/WHEEL +0 -0
- {bitunix_automated_crypto_trading-3.2.6.dist-info → bitunix_automated_crypto_trading-3.2.8.dist-info}/entry_points.txt +0 -0
- {bitunix_automated_crypto_trading-3.2.6.dist-info → bitunix_automated_crypto_trading-3.2.8.dist-info}/top_level.txt +0 -0
@@ -18,6 +18,7 @@ class BitunixApi:
|
|
18
18
|
self.api_key = api_key
|
19
19
|
self.secret_key = secret_key
|
20
20
|
self.logger = logger
|
21
|
+
self.settings = settings
|
21
22
|
self.session = requests.Session()
|
22
23
|
self.session.headers.update({
|
23
24
|
'Content-Type': 'application/json',
|
@@ -119,18 +120,70 @@ class BitunixApi:
|
|
119
120
|
response.raise_for_status()
|
120
121
|
return response.json()
|
121
122
|
|
122
|
-
async def PlaceOrder(self, ticker, qty, price, side, positionId=0, tradeSide="OPEN",reduceOnly=False):
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
123
|
+
async def PlaceOrder(self, ticker, qty, price, side, positionId=0, tradeSide="OPEN",reduceOnly=False, takeProfitPrice=0, stopLossPrice=0):
|
124
|
+
datajs = None
|
125
|
+
if takeProfitPrice == 0 or stopLossPrice == 0:
|
126
|
+
data = {
|
127
|
+
"side": side,
|
128
|
+
"orderType":"LIMIT",
|
129
|
+
"qty": qty,
|
130
|
+
"price": price,
|
131
|
+
"symbol": ticker,
|
132
|
+
"tradeSide":tradeSide,
|
133
|
+
"reduceOnly":reduceOnly,
|
134
|
+
"positionId":positionId
|
135
|
+
}
|
136
|
+
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
137
|
+
elif takeProfitPrice == 0:
|
138
|
+
data = {
|
139
|
+
"side": side,
|
140
|
+
"orderType":"LIMIT",
|
141
|
+
"qty": qty,
|
142
|
+
"price": price,
|
143
|
+
"symbol": ticker,
|
144
|
+
"tradeSide":tradeSide,
|
145
|
+
"slPrice": stopLossPrice,
|
146
|
+
"slStopType":'MARK_PRICE',
|
147
|
+
"slStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
148
|
+
"slpOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
149
|
+
"positionId":positionId
|
150
|
+
}
|
151
|
+
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
152
|
+
elif stopLossPrice == 0:
|
153
|
+
data = {
|
154
|
+
"side": side,
|
155
|
+
"orderType":"LIMIT",
|
156
|
+
"qty": qty,
|
157
|
+
"price": price,
|
158
|
+
"symbol": ticker,
|
159
|
+
"tradeSide":tradeSide,
|
160
|
+
"tpPrice": takeProfitPrice,
|
161
|
+
"tpStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
162
|
+
"tppOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
163
|
+
"tpOrderPrice":takeProfitPrice,
|
164
|
+
"positionId":positionId
|
165
|
+
}
|
166
|
+
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
167
|
+
else:
|
168
|
+
data = {
|
169
|
+
"side": side,
|
170
|
+
"orderType":"LIMIT",
|
171
|
+
"qty": qty,
|
172
|
+
"price": price,
|
173
|
+
"symbol": ticker,
|
174
|
+
"tradeSide":tradeSide,
|
175
|
+
"tpPrice": takeProfitPrice,
|
176
|
+
"tpStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
177
|
+
"tppOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
178
|
+
"tpOrderPrice":takeProfitPrice,
|
179
|
+
"slPrice": stopLossPrice,
|
180
|
+
"slStopType": self.settings.PROFIT_LOSS_PRICE_TYPE,
|
181
|
+
"slpOrderType": self.settings.PROFIT_LOSS_ORDER_TYPE,
|
182
|
+
"slOrderPrice": stopLossPrice,
|
183
|
+
"positionId":positionId
|
184
|
+
}
|
185
|
+
datajs = await self._post_authenticated(self.placeOrder_Url,data)
|
186
|
+
|
134
187
|
return datajs
|
135
188
|
|
136
189
|
async def FlashClose(self, positionId):
|
@@ -721,14 +721,36 @@ class BitunixSignal:
|
|
721
721
|
select = False
|
722
722
|
if select:
|
723
723
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
724
|
+
|
724
725
|
price = (bid if side == "BUY" else ask if side == "SELL" else last) if bid<=last<=ask else last
|
726
|
+
|
727
|
+
tp_price=0
|
728
|
+
if self.settings.PROFIT_AMOUNT > 0:
|
729
|
+
tp_price = price * (1 + float(self.settings.PROFIT_AMOUNT)) if side == "BUY" else price * (1 - float(self.settings.PROFIT_AMOUNT))
|
730
|
+
if self.settings.PROFIT_PERCENTAGE > 0 or self.settings.PROFIT_AMOUNT > 0:
|
731
|
+
tp_price = 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)
|
732
|
+
|
733
|
+
lp_price=0
|
734
|
+
if self.settings.LOSS_AMOUNT > 0:
|
735
|
+
lp_price = price * (1 - float(self.settings.LOSS_AMOUNT)) if side == "BUY" else price * (1 + float(self.settings.LOSS_AMOUNT))
|
736
|
+
if self.settings.LOSS_PERCENTAGE > 0 or self.settings.LOSS_AMOUNT > 0:
|
737
|
+
lp_price = 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)
|
738
|
+
|
725
739
|
balance = float(self.portfoliodf["available"].iloc[0]) + float(self.portfoliodf["crossUnrealizedPNL"].iloc[0])
|
726
|
-
qty= str(max(balance * (float(self.settings.ORDER_AMOUNT_PERCENTAGE) / 100) / price * int(self.settings.LEVERAGE),mtv))
|
740
|
+
qty= str(max(balance * (float(self.settings.ORDER_AMOUNT_PERCENTAGE) / 100 ) / price * int(self.settings.LEVERAGE),mtv))
|
727
741
|
|
728
742
|
self.notifications.add_notification(
|
729
743
|
f'{colors.YELLOW} Opening {"long" if side=="BUY" else "short"} position for {row.symbol} with {qty} qty @ {price})'
|
730
744
|
)
|
731
|
-
datajs =
|
745
|
+
datajs = None
|
746
|
+
if tp_price == 0 and lp_price == 0:
|
747
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side)
|
748
|
+
elif tp_price == 0:
|
749
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side, stopLossPrice=lp_price)
|
750
|
+
elif lp_price == 0:
|
751
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side, takeProfitPrice=tp_price)
|
752
|
+
else:
|
753
|
+
datajs = await self.bitunixApi.PlaceOrder(row.symbol, qty, price, side, takeProfitPrice=tp_price, stopLossPrice=lp_price)
|
732
754
|
count=count+1
|
733
755
|
else:
|
734
756
|
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")
|
@@ -746,7 +768,7 @@ class BitunixSignal:
|
|
746
768
|
current_time = time.time() * 1000
|
747
769
|
df=self.orderdf.copy(deep=False)
|
748
770
|
for index, row in df.iterrows():
|
749
|
-
if current_time - int(row.ctime) >
|
771
|
+
if current_time - int(row.ctime) > 6000000000:
|
750
772
|
self.notifications.add_notification(
|
751
773
|
f'{colors.LBLUE} Canceling order {row.orderId}, {row.symbol} {row.qty} created at {row.rtime} '
|
752
774
|
)
|
@@ -780,76 +802,6 @@ class BitunixSignal:
|
|
780
802
|
|
781
803
|
if select and int(self.settings.MAX_AUTO_TRADES)!=0:
|
782
804
|
|
783
|
-
# check take profit amount or accept loss amount
|
784
|
-
if float(self.settings.LOSS_AMOUNT) > 0 and total_pnl < -float(self.settings.LOSS_AMOUNT):
|
785
|
-
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
786
|
-
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
787
|
-
|
788
|
-
self.notifications.add_notification(
|
789
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to stop loss amount for {row.symbol} with {row.qty} qty @ {price})'
|
790
|
-
)
|
791
|
-
datajs = await self.bitunixApi.PlaceOrder(
|
792
|
-
positionId=row.positionId,
|
793
|
-
ticker=row.symbol,
|
794
|
-
qty=row.qty,
|
795
|
-
price=price,
|
796
|
-
side=row.side,
|
797
|
-
tradeSide="CLOSE"
|
798
|
-
)
|
799
|
-
continue
|
800
|
-
|
801
|
-
if float(self.settings.PROFIT_AMOUNT) > 0 and total_pnl > float(self.settings.PROFIT_AMOUNT):
|
802
|
-
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
803
|
-
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
804
|
-
|
805
|
-
self.notifications.add_notification(
|
806
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to take profit amount for {row.symbol} with {row.qty} qty @ {price})'
|
807
|
-
)
|
808
|
-
datajs = await self.bitunixApi.PlaceOrder(
|
809
|
-
positionId=row.positionId,
|
810
|
-
ticker=row.symbol,
|
811
|
-
qty=row.qty,
|
812
|
-
price=price,
|
813
|
-
side=row.side,
|
814
|
-
tradeSide="CLOSE"
|
815
|
-
)
|
816
|
-
continue
|
817
|
-
|
818
|
-
# check take profit percentage or accept loss percentage
|
819
|
-
if float(self.settings.LOSS_PERCENTAGE) > 0 and row['ROI'] < -float(self.settings.LOSS_PERCENTAGE):
|
820
|
-
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
821
|
-
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
822
|
-
|
823
|
-
self.notifications.add_notification(
|
824
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to stop loss percentage for {row.symbol} with {row.qty} qty @ {price})'
|
825
|
-
)
|
826
|
-
datajs = await self.bitunixApi.PlaceOrder(
|
827
|
-
positionId=row.positionId,
|
828
|
-
ticker=row.symbol,
|
829
|
-
qty=row.qty,
|
830
|
-
price=price,
|
831
|
-
side=row.side,
|
832
|
-
tradeSide="CLOSE"
|
833
|
-
)
|
834
|
-
continue
|
835
|
-
|
836
|
-
if float(self.settings.PROFIT_PERCENTAGE) > 0 and row['ROI'] > float(self.settings.PROFIT_PERCENTAGE):
|
837
|
-
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
838
|
-
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
839
|
-
|
840
|
-
self.notifications.add_notification(
|
841
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to take profit percentage for {row.symbol} with {row.qty} qty @ {price})'
|
842
|
-
)
|
843
|
-
datajs = await self.bitunixApi.PlaceOrder(
|
844
|
-
positionId=row.positionId,
|
845
|
-
ticker=row.symbol,
|
846
|
-
qty=row.qty,
|
847
|
-
price=price,
|
848
|
-
side=row.side,
|
849
|
-
tradeSide="CLOSE"
|
850
|
-
)
|
851
|
-
continue
|
852
|
-
|
853
805
|
# Moving average comparison between fast and medium or medium and slow
|
854
806
|
if self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_CLOSE:
|
855
807
|
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_ema_close'] == "SELL":
|
@@ -21,6 +21,8 @@ class Settings(BaseSettings):
|
|
21
21
|
LOSS_PERCENTAGE: float = Field(default=10, ge=0.0)
|
22
22
|
PROFIT_AMOUNT: float = Field(default=0, ge=0.0)
|
23
23
|
LOSS_AMOUNT: float = Field(default=5.0, ge=0.0)
|
24
|
+
PROFIT_LOSS_PRICE_TYPE: str = Field(default="MARK_PRICE")
|
25
|
+
PROFIT_LOSS_ORDER_TYPE: str = Field(default="LIMIT")
|
24
26
|
OPTION_MOVING_AVERAGE: str = Field(default="1h")
|
25
27
|
DELAY_IN_MINUTES_FOR_SAME_TICKER_TRADES: int = Field(default=15, ge=0)
|
26
28
|
BARS: int = Field(default=100, ge=1)
|
@@ -1 +1 @@
|
|
1
|
-
__version__ = "3.2.
|
1
|
+
__version__ = "3.2.8"
|
@@ -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=m9eY6mVax82d1gFvwVkIkn8rgxSBbvRP-7emxUX99eE,13549
|
3
|
+
bitunix_automated_crypto_trading/BitunixSignal.py,sha256=FzYwh43L1VXMrhKNQhX435pazZ933hfhY_FxXc_LrLk,74652
|
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
|
@@ -9,11 +9,11 @@ bitunix_automated_crypto_trading/ThreadManager.py,sha256=Lw5_1EIT0m3AFSv5CIMpnjt
|
|
9
9
|
bitunix_automated_crypto_trading/TickerManager.py,sha256=E6U08wO1LKY4XctB6frtoAmlactMng3xwRrqG59qDt8,43030
|
10
10
|
bitunix_automated_crypto_trading/__init__.py,sha256=1hzk6nX8NnUCr1tsq8oFq1qGCNhNwnwldWE75641Eew,78
|
11
11
|
bitunix_automated_crypto_trading/bitunix.py,sha256=lxwnYARxldA2oU6GdjupilXIlnUh4RX8rQLCOn7x13I,27143
|
12
|
-
bitunix_automated_crypto_trading/config.py,sha256=
|
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.2.
|
16
|
-
bitunix_automated_crypto_trading-3.2.
|
17
|
-
bitunix_automated_crypto_trading-3.2.
|
18
|
-
bitunix_automated_crypto_trading-3.2.
|
19
|
-
bitunix_automated_crypto_trading-3.2.
|
14
|
+
bitunix_automated_crypto_trading/version.py,sha256=SKNhDsZ81Bke2WUvgUQFQ7DVlPfRwWZkO5mgyJWSzxo,21
|
15
|
+
bitunix_automated_crypto_trading-3.2.8.dist-info/METADATA,sha256=M8KtEy_NidCclMGbRkimkMRjthP5ShKLpsEwmZhnv8g,996
|
16
|
+
bitunix_automated_crypto_trading-3.2.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
17
|
+
bitunix_automated_crypto_trading-3.2.8.dist-info/entry_points.txt,sha256=UXREYHuSl2XYd_tOtLIq0zg3d1kX3lixX5SpN8yGBw4,82
|
18
|
+
bitunix_automated_crypto_trading-3.2.8.dist-info/top_level.txt,sha256=uyFzHUCOsp8elnG2Ovor6xXcf7dxRxY-C-Txiwix64Q,33
|
19
|
+
bitunix_automated_crypto_trading-3.2.8.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|