bitunix-automated-crypto-trading 3.1.9__py3-none-any.whl → 3.2.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/BitunixSignal.py +69 -22
- bitunix_automated_crypto_trading/TickerManager.py +12 -9
- bitunix_automated_crypto_trading/bitunix.py +14 -6
- bitunix_automated_crypto_trading/config.py +6 -0
- bitunix_automated_crypto_trading/version.py +1 -0
- {bitunix_automated_crypto_trading-3.1.9.dist-info → bitunix_automated_crypto_trading-3.2.1.dist-info}/METADATA +1 -1
- {bitunix_automated_crypto_trading-3.1.9.dist-info → bitunix_automated_crypto_trading-3.2.1.dist-info}/RECORD +10 -9
- {bitunix_automated_crypto_trading-3.1.9.dist-info → bitunix_automated_crypto_trading-3.2.1.dist-info}/WHEEL +0 -0
- {bitunix_automated_crypto_trading-3.1.9.dist-info → bitunix_automated_crypto_trading-3.2.1.dist-info}/entry_points.txt +0 -0
- {bitunix_automated_crypto_trading-3.1.9.dist-info → bitunix_automated_crypto_trading-3.2.1.dist-info}/top_level.txt +0 -0
@@ -92,7 +92,7 @@ class BitunixSignal:
|
|
92
92
|
self.lastTickerDataTime = time.time()
|
93
93
|
|
94
94
|
#sqllite database connection
|
95
|
-
self.connection = sqlite3.connect(
|
95
|
+
self.connection = sqlite3.connect(self.settings.DATABASE)
|
96
96
|
|
97
97
|
async def update_settings(self, settings):
|
98
98
|
self.settings = settings
|
@@ -260,7 +260,7 @@ class BitunixSignal:
|
|
260
260
|
if self.settings.VERBOSE_LOGGING:
|
261
261
|
self.logger.info(f"GetTickerData: elapsed time {time.time()-start}")
|
262
262
|
if self.settings.BENCHMARK:
|
263
|
-
self.connection = sqlite3.connect(
|
263
|
+
self.connection = sqlite3.connect(self.settings.DATABASE)
|
264
264
|
self.cursor = self.connection.cursor()
|
265
265
|
self.cursor.execute("INSERT INTO benchmark (process_name, time) VALUES (?, ?)", ("GetTickerData", time.time()-start))
|
266
266
|
self.connection.commit()
|
@@ -398,7 +398,7 @@ class BitunixSignal:
|
|
398
398
|
self.notifications.add_notification("AutoTradeProcess or GetTickerData is not running")
|
399
399
|
os._exit(1)
|
400
400
|
break
|
401
|
-
await asyncio.sleep(
|
401
|
+
await asyncio.sleep(300)
|
402
402
|
|
403
403
|
async def GetportfolioData(self):
|
404
404
|
start=time.time()
|
@@ -438,11 +438,17 @@ class BitunixSignal:
|
|
438
438
|
ask=self.positiondf['symbol'].map(lambda sym: self.tickerObjects.get(sym).get_ask()),
|
439
439
|
askcolor=self.positiondf['symbol'].map(lambda sym: self.tickerObjects.get(sym).askcolor)
|
440
440
|
)
|
441
|
-
#self.positiondf['roi']= round((self.positiondf['last'].astype(float) * self.positiondf['qty'].astype(float) - \
|
442
|
-
# self.positiondf['avgOpenPrice'].astype(float) * self.positiondf['qty'].astype(float)) / \
|
443
|
-
# (self.positiondf['avgOpenPrice'].astype(float) * self.positiondf['qty'].astype(float) / (self.settings.LEVERAGE/100)) * 10000 , 2)
|
444
441
|
except Exception as e:
|
445
442
|
pass
|
443
|
+
|
444
|
+
self.positiondf['markprice']= (self.positiondf['bid'] + self.positiondf['ask']) / 2
|
445
|
+
self.positiondf = self.positiondf.astype({"unrealizedPNL": float, "realizedPNL": float, "markprice": float, "last": float, "qty": float, "avgOpenPrice": float})
|
446
|
+
self.positiondf['ROI'] = self.positiondf.apply(
|
447
|
+
lambda row: round((row['unrealizedPNL'] / (row['qty'] * row['avgOpenPrice'])) * 100 * self.settings.LEVERAGE,2),
|
448
|
+
axis=1
|
449
|
+
)
|
450
|
+
#print(self.positiondf[['symbol', 'ROI','markprice', 'qty', 'avgOpenPrice']].head())
|
451
|
+
|
446
452
|
self.positiondf['charts'] = self.positiondf.apply(self.add_charts_button, axis=1)
|
447
453
|
self.positiondf['bitunix'] = self.positiondf.apply(self.add_bitunix_button, axis=1)
|
448
454
|
self.positiondf['action'] = self.positiondf.apply(self.add_close_button, axis=1)
|
@@ -499,6 +505,12 @@ class BitunixSignal:
|
|
499
505
|
self.positionHistoryData = await self.bitunixApi.GetPositionHistoryData()
|
500
506
|
if self.positionHistoryData and 'positionList' in self.positionHistoryData:
|
501
507
|
self.positionHistorydf = pd.DataFrame(self.positionHistoryData['positionList'], columns=["symbol", "side","realizedPNL", "ctime", "mtime","maxQty", "closePrice","fee", "funding"])
|
508
|
+
self.positionHistorydf = self.positionHistorydf.astype({"realizedPNL": float, "maxQty": float, "closePrice": float})
|
509
|
+
self.positionHistorydf['ROI'] = self.positionHistorydf.apply(
|
510
|
+
lambda row: round((row['realizedPNL'] / (row['maxQty'] * row['closePrice'])) * 100 * self.settings.LEVERAGE,2),
|
511
|
+
axis=1
|
512
|
+
)
|
513
|
+
|
502
514
|
self.positionHistorydf['ctime'] = pd.to_datetime(self.positionHistorydf['ctime'].astype(float), unit='ms').dt.tz_localize('UTC').dt.tz_convert(cst).dt.strftime('%Y-%m-%d %H:%M:%S')
|
503
515
|
self.positionHistorydf['mtime'] = pd.to_datetime(self.positionHistorydf['mtime'].astype(float), unit='ms').dt.tz_localize('UTC').dt.tz_convert(cst).dt.strftime('%Y-%m-%d %H:%M:%S')
|
504
516
|
self.positionHistorydf['charts'] = self.positionHistorydf.apply(self.add_charts_button, axis=1)
|
@@ -506,7 +518,7 @@ class BitunixSignal:
|
|
506
518
|
|
507
519
|
else:
|
508
520
|
self.positionHistorydf = pd.DataFrame()
|
509
|
-
self.positionHistorydfStyle= self.positionHistorydfrenderer.render_html(self.positionHistorydf)
|
521
|
+
self.positionHistorydfStyle= self.positionHistorydfrenderer.render_html(self.positionHistorydf[["symbol", "side", "ROI", "realizedPNL", "ctime", "mtime", "maxQty", "closePrice", "fee", "funding", "charts", "bitunix"]])
|
510
522
|
|
511
523
|
except Exception as e:
|
512
524
|
self.logger.info(f"Function: GetPositionHistoryData, {e}, {e.args}, {type(e).__name__}")
|
@@ -569,7 +581,7 @@ class BitunixSignal:
|
|
569
581
|
f"{period}_ema_open", f"{period}_ema_close", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", f"{period}_trendline", f"{period}_candle_trend", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low"]
|
570
582
|
columns2=["qty", "side", "unrealizedPNL", "realizedPNL", "ctime", "avgOpenPrice", "bid", "bidcolor", "last", "lastcolor", "ask", "askcolor", "charts", "bitunix", "action", "add", "reduce"]
|
571
583
|
if set(columns).issubset(self.signaldf_full.columns) and set(columns2).issubset(self.positiondf.columns):
|
572
|
-
columnOrder= ['symbol', "side",
|
584
|
+
columnOrder= ['symbol', "side", "ROI", "unrealizedPNL", "realizedPNL", f"{period}_trend", f"{period}_cb", f"{period}_barcolor",
|
573
585
|
f"{period}_bos",
|
574
586
|
f"{period}_ema_open", f"{period}_ema_close", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", f"{period}_trendline", f"{period}_adx", f"{period}_candle_trend", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low", "qty", "ctime", "avgOpenPrice", "bid", "bidcolor", "last", "lastcolor", "ask", "askcolor", "charts", "bitunix", "action", "add", "reduce"]
|
575
587
|
self.positiondf2 = pd.merge(self.positiondf, self.signaldf_full[["symbol", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low",
|
@@ -714,13 +726,13 @@ class BitunixSignal:
|
|
714
726
|
|
715
727
|
if select and int(self.settings.MAX_AUTO_TRADES)!=0:
|
716
728
|
|
717
|
-
# check take
|
729
|
+
# check take profit amount or accept loss amount
|
718
730
|
if float(self.settings.LOSS_AMOUNT) > 0 and total_pnl < -float(self.settings.LOSS_AMOUNT):
|
719
731
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
720
732
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
721
733
|
|
722
734
|
self.notifications.add_notification(
|
723
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to stop loss for {row.symbol} with {row.qty} qty @ {price})'
|
735
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to stop loss amount for {row.symbol} with {row.qty} qty @ {price})'
|
724
736
|
)
|
725
737
|
datajs = await self.bitunixApi.PlaceOrder(
|
726
738
|
positionId=row.positionId,
|
@@ -737,7 +749,42 @@ class BitunixSignal:
|
|
737
749
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
738
750
|
|
739
751
|
self.notifications.add_notification(
|
740
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to take profit for {row.symbol} with {row.qty} qty @ {price})'
|
752
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to take profit amount for {row.symbol} with {row.qty} qty @ {price})'
|
753
|
+
)
|
754
|
+
datajs = await self.bitunixApi.PlaceOrder(
|
755
|
+
positionId=row.positionId,
|
756
|
+
ticker=row.symbol,
|
757
|
+
qty=row.qty,
|
758
|
+
price=price,
|
759
|
+
side=row.side,
|
760
|
+
tradeSide="CLOSE"
|
761
|
+
)
|
762
|
+
continue
|
763
|
+
|
764
|
+
# check take profit percentage or accept loss percentage
|
765
|
+
if float(self.settings.LOSS_PERCENTAGE) > 0 and row['ROI'] < -float(self.settings.LOSS_PERCENTAGE):
|
766
|
+
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
767
|
+
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
768
|
+
|
769
|
+
self.notifications.add_notification(
|
770
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to stop loss percentage for {row.symbol} with {row.qty} qty @ {price})'
|
771
|
+
)
|
772
|
+
datajs = await self.bitunixApi.PlaceOrder(
|
773
|
+
positionId=row.positionId,
|
774
|
+
ticker=row.symbol,
|
775
|
+
qty=row.qty,
|
776
|
+
price=price,
|
777
|
+
side=row.side,
|
778
|
+
tradeSide="CLOSE"
|
779
|
+
)
|
780
|
+
continue
|
781
|
+
|
782
|
+
if float(self.settings.PROFIT_PERCENTAGE) > 0 and row['ROI'] > float(self.settings.PROFIT_PERCENTAGE):
|
783
|
+
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
784
|
+
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
785
|
+
|
786
|
+
self.notifications.add_notification(
|
787
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to take profit percentage for {row.symbol} with {row.qty} qty @ {price})'
|
741
788
|
)
|
742
789
|
datajs = await self.bitunixApi.PlaceOrder(
|
743
790
|
positionId=row.positionId,
|
@@ -888,12 +935,12 @@ class BitunixSignal:
|
|
888
935
|
|
889
936
|
# BOS
|
890
937
|
if self.settings.BOS_STUDY and self.settings.BOS_CHECK_ON_CLOSE:
|
891
|
-
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_bos'] == "SELL" and total_pnl
|
938
|
+
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_bos'] == "SELL" and total_pnl < 0:
|
892
939
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
893
940
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
894
941
|
|
895
942
|
self.notifications.add_notification(
|
896
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} bos for {row.symbol} with {row.qty} qty @ {price})'
|
943
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} bos revrsal for {row.symbol} with {row.qty} qty @ {price})'
|
897
944
|
)
|
898
945
|
datajs = await self.bitunixApi.PlaceOrder(
|
899
946
|
positionId=row.positionId,
|
@@ -905,11 +952,11 @@ class BitunixSignal:
|
|
905
952
|
)
|
906
953
|
continue
|
907
954
|
|
908
|
-
if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_bos'] == "BUY" and total_pnl
|
955
|
+
if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_bos'] == "BUY" and total_pnl <0:
|
909
956
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
910
957
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
911
958
|
self.notifications.add_notification(
|
912
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} bos for {row.symbol} with {row.qty} qty @ {price})'
|
959
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} bos reversal for {row.symbol} with {row.qty} qty @ {price})'
|
913
960
|
)
|
914
961
|
datajs = await self.bitunixApi.PlaceOrder(
|
915
962
|
positionId=row.positionId,
|
@@ -923,12 +970,12 @@ class BitunixSignal:
|
|
923
970
|
|
924
971
|
# TrendLine
|
925
972
|
if self.settings.TRENDLINE_STUDY and self.settings.TRENDLINE_CHECK_ON_CLOSE:
|
926
|
-
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_trendline'] == "SELL" and total_pnl
|
973
|
+
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_trendline'] == "SELL" and total_pnl < 0:
|
927
974
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
928
975
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
929
976
|
|
930
977
|
self.notifications.add_notification(
|
931
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} trendline
|
978
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} trendline reversalfor {row.symbol} with {row.qty} qty @ {price})'
|
932
979
|
)
|
933
980
|
datajs = await self.bitunixApi.PlaceOrder(
|
934
981
|
positionId=row.positionId,
|
@@ -940,11 +987,11 @@ class BitunixSignal:
|
|
940
987
|
)
|
941
988
|
continue
|
942
989
|
|
943
|
-
if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_trendline'] == "BUY" and total_pnl
|
990
|
+
if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_trendline'] == "BUY" and total_pnl < 0:
|
944
991
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
945
992
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
946
993
|
self.notifications.add_notification(
|
947
|
-
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} trendline for {row.symbol} with {row.qty} qty @ {price})'
|
994
|
+
f'{colors.CYAN} Closing {"long" if side=="BUY" else "short"} position due to {period} trendline reversal for {row.symbol} with {row.qty} qty @ {price})'
|
948
995
|
)
|
949
996
|
datajs = await self.bitunixApi.PlaceOrder(
|
950
997
|
positionId=row.positionId,
|
@@ -992,7 +1039,7 @@ class BitunixSignal:
|
|
992
1039
|
|
993
1040
|
# candle reversed
|
994
1041
|
if self.settings.CANDLE_TREND_STUDY and self.settings.CANDLE_TREND_REVERSAL_CHECK_ON_CLOSE:
|
995
|
-
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_barcolor'] == self.red and self.signaldf_full.at[row.symbol, f'{period}_cb'] > 1 and self.signaldf_full.at[row.symbol, f'{period}_candle_trend'] == "BULLISH":
|
1042
|
+
if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_barcolor'] == self.red and self.signaldf_full.at[row.symbol, f'{period}_cb'] > 1 and self.signaldf_full.at[row.symbol, f'{period}_candle_trend'] == "BULLISH" and total_pnl < 0:
|
996
1043
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
997
1044
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
998
1045
|
|
@@ -1009,7 +1056,7 @@ class BitunixSignal:
|
|
1009
1056
|
)
|
1010
1057
|
continue
|
1011
1058
|
|
1012
|
-
if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_barcolor'] == self.green and self.signaldf_full.at[row.symbol, f'{period}_cb'] > 1 and self.signaldf_full.at[row.symbol, f'{period}_candle_trend'] == "BULLISH":
|
1059
|
+
if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_barcolor'] == self.green and self.signaldf_full.at[row.symbol, f'{period}_cb'] > 1 and self.signaldf_full.at[row.symbol, f'{period}_candle_trend'] == "BULLISH" and total_pnl < 0:
|
1013
1060
|
last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
|
1014
1061
|
price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
|
1015
1062
|
|
@@ -1038,7 +1085,7 @@ class BitunixSignal:
|
|
1038
1085
|
if self.settings.VERBOSE_LOGGING:
|
1039
1086
|
self.logger.info(f"AutoTradeProcess: elapsed time {time.time()-start}")
|
1040
1087
|
if self.settings.BENCHMARK:
|
1041
|
-
self.connection = sqlite3.connect(
|
1088
|
+
self.connection = sqlite3.connect(self.settings.DATABASE)
|
1042
1089
|
self.cursor = self.connection.cursor()
|
1043
1090
|
self.cursor.execute("INSERT INTO benchmark (process_name, time) VALUES (?, ?)", ("AutoTradeProcess", time.time()-start))
|
1044
1091
|
self.connection.commit()
|
@@ -87,13 +87,17 @@ class Interval:
|
|
87
87
|
df['ma_slow_angle'] = np.degrees(np.arctan(df['ma_slow_slope']))
|
88
88
|
df.fillna({'ma_slow_slope':0}, inplace=True)
|
89
89
|
df.fillna({'ma_slow_angle':0}, inplace=True)
|
90
|
+
|
91
|
+
df['ma_spread'] = (df['ma_fast'] - df['ma_slow']).diff()
|
92
|
+
df.fillna({'ma_spread':0}, inplace=True)
|
93
|
+
df.fillna({'ma_spread':0}, inplace=True)
|
90
94
|
|
91
95
|
if self.settings.EMA_CROSSING:
|
92
96
|
if df is not None and len(df) >= 2:
|
93
|
-
if df['ma_medium'].iloc[-2] <= df['ma_slow'].iloc[-2] and df['ma_medium'].iloc[-1] > df['ma_slow'].iloc[-1]:
|
97
|
+
if df['ma_medium'].iloc[-2] <= df['ma_slow'].iloc[-2] and df['ma_medium'].iloc[-1] > df['ma_slow'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
94
98
|
self.ema_open_signal = "BUY"
|
95
99
|
self.ema_close_signal = "BUY"
|
96
|
-
elif df['ma_medium'].iloc[-2] >= df['ma_slow'].iloc[-2] and df['ma_medium'].iloc[-1] < df['ma_slow'].iloc[-1]:
|
100
|
+
elif df['ma_medium'].iloc[-2] >= df['ma_slow'].iloc[-2] and df['ma_medium'].iloc[-1] < df['ma_slow'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
97
101
|
self.ema_open_signal = "SELL"
|
98
102
|
self.ema_close_signal = "SELL"
|
99
103
|
else:
|
@@ -101,18 +105,18 @@ class Interval:
|
|
101
105
|
self.ema_close_signal = "HOLD"
|
102
106
|
|
103
107
|
if self.settings.EMA_CLOSE_ON_FAST_MEDIUM:
|
104
|
-
if df['ma_fast'].iloc[-2] <= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
|
108
|
+
if df['ma_fast'].iloc[-2] <= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
105
109
|
self.ema_close_signal = "BUY"
|
106
|
-
elif df['ma_fast'].iloc[-2] >= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1]:
|
110
|
+
elif df['ma_fast'].iloc[-2] >= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
107
111
|
self.ema_close_signal = "SELL"
|
108
112
|
else:
|
109
113
|
self.ema_close_signal = "HOLD"
|
110
114
|
else:
|
111
115
|
if df is not None and len(df) >= 1:
|
112
|
-
if df['close'].iloc[-1] > df['ma_medium'].iloc[-1] and df['ma_medium'].iloc[-1] > df['ma_slow'].iloc[-1]:
|
116
|
+
if df['close'].iloc[-1] > df['ma_medium'].iloc[-1] and df['ma_medium'].iloc[-1] > df['ma_slow'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
113
117
|
self.ema_open_signal = "BUY"
|
114
118
|
self.ema_close_signal = "BUY"
|
115
|
-
elif df['close'].iloc[-1] < df['ma_medium'].iloc[-1] and df['ma_medium'].iloc[-1] < df['ma_slow'].iloc[-1]:
|
119
|
+
elif df['close'].iloc[-1] < df['ma_medium'].iloc[-1] and df['ma_medium'].iloc[-1] < df['ma_slow'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
116
120
|
self.ema_open_signal = "SELL"
|
117
121
|
self.ema_close_signal = "SELL"
|
118
122
|
else:
|
@@ -120,9 +124,9 @@ class Interval:
|
|
120
124
|
self.ema_close_signal = "HOLD"
|
121
125
|
|
122
126
|
if self.settings.EMA_CLOSE_ON_FAST_MEDIUM:
|
123
|
-
if df['close'].iloc[-1] > df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
|
127
|
+
if df['close'].iloc[-1] > df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
124
128
|
self.ema_close_signal = "BUY"
|
125
|
-
elif df['close'].iloc[-1] < df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1]:
|
129
|
+
elif df['close'].iloc[-1] < df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1] and df['ma_spread'].iloc[-1] > 0:
|
126
130
|
self.ema_close_signal = "SELL"
|
127
131
|
else:
|
128
132
|
self.ema_close_signal = "HOLD"
|
@@ -740,7 +744,6 @@ class Tickers:
|
|
740
744
|
f"{period}_cb": intervalObj.signal_strength,
|
741
745
|
f"{period}_barcolor": lastcandle['barcolor'],
|
742
746
|
f"{period}_ema_open": intervalObj.ema_open_signal,
|
743
|
-
f"{period}_ema_open": intervalObj.ema_open_signal,
|
744
747
|
f"{period}_ema_close": intervalObj.ema_close_signal,
|
745
748
|
f"{period}_macd":intervalObj.macd_signal,
|
746
749
|
f"{period}_bbm":intervalObj.bbm_signal,
|
@@ -9,6 +9,7 @@ import time
|
|
9
9
|
from datetime import datetime
|
10
10
|
import pytz
|
11
11
|
from pathlib import Path
|
12
|
+
import re
|
12
13
|
|
13
14
|
|
14
15
|
from ThreadManager import ThreadManager
|
@@ -63,14 +64,17 @@ HOST = os.getenv('HOST')
|
|
63
64
|
|
64
65
|
logger = Logger(__name__, LOG_FILE).get_logger()
|
65
66
|
|
66
|
-
|
67
|
-
|
67
|
+
def get_version():
|
68
|
+
version_file = os.path.abspath("bitunix_automated_crypto_trading/version.py")
|
69
|
+
with open(version_file) as f:
|
70
|
+
return re.search(r'__version__ = "(.*?)"', f.read()).group(1)
|
71
|
+
|
68
72
|
class bitunix():
|
69
73
|
def __init__(self, password, api_key, secret_key, settings, logger):
|
70
74
|
self.screen_refresh_interval =settings.SCREEN_REFRESH_INTERVAL
|
71
75
|
self.logger=logger
|
72
76
|
self.autoTrade=settings.AUTOTRADE
|
73
|
-
|
77
|
+
self.settings = settings
|
74
78
|
self.threadManager = ThreadManager()
|
75
79
|
self.notifications = NotificationManager(logger)
|
76
80
|
self.bitunixApi = BitunixApi(api_key, secret_key, settings, self.logger)
|
@@ -80,7 +84,7 @@ class bitunix():
|
|
80
84
|
self.DB = {"admin": {"password": password}}
|
81
85
|
|
82
86
|
#sqllite database connection
|
83
|
-
self.connection = sqlite3.connect(
|
87
|
+
self.connection = sqlite3.connect(self.settings.DATABASE)
|
84
88
|
#create table if not exist
|
85
89
|
self.cursor = self.connection.cursor()
|
86
90
|
#create benchmark table
|
@@ -88,6 +92,7 @@ class bitunix():
|
|
88
92
|
|
89
93
|
async def update_settings(self, settings):
|
90
94
|
self.settings = settings
|
95
|
+
self.settings.DATABASE = CONFIG_FILE.replace(".txt", ".db")
|
91
96
|
await self.bitunixSignal.update_settings(settings)
|
92
97
|
await self.bitunixApi.update_settings(settings)
|
93
98
|
|
@@ -210,8 +215,10 @@ async def read_root(request: Request):
|
|
210
215
|
|
211
216
|
#when main page requested
|
212
217
|
@app.get("/main", response_class=HTMLResponse)
|
213
|
-
async def main_page(request: Request,
|
214
|
-
|
218
|
+
async def main_page(request: Request, user=Depends(login_manager)):
|
219
|
+
version = get_version()
|
220
|
+
return templates.TemplateResponse("main.html", {"request": request, "user": user, "version": version})
|
221
|
+
|
215
222
|
|
216
223
|
#when main page opened
|
217
224
|
@app.websocket("/wsmain")
|
@@ -629,6 +636,7 @@ def main():
|
|
629
636
|
|
630
637
|
#load config variables using setting class in config.py validating using pydantic
|
631
638
|
settings = Settings()
|
639
|
+
settings.DATABASE = CONFIG_FILE.replace(".txt", ".db")
|
632
640
|
|
633
641
|
bitunix = bitunix(PASSWORD, API_KEY, SECRET_KEY, settings, logger)
|
634
642
|
bitunix.bitunixSignal.notifications.add_notification(f"Starting auto trade on port {port} using {env_file} and {config_file} ....................")
|
@@ -17,6 +17,8 @@ class Settings(BaseSettings):
|
|
17
17
|
LEVERAGE: int = Field(default=20, ge=1, le=100)
|
18
18
|
ORDER_AMOUNT_PERCENTAGE: float = Field(default=0.01, ge=0.0, le=100)
|
19
19
|
MAX_AUTO_TRADES: int = Field(default=10, ge=0)
|
20
|
+
PROFIT_PERCENTAGE: float = Field(default=25, ge=0.0)
|
21
|
+
LOSS_PERCENTAGE: float = Field(default=50, ge=0.0)
|
20
22
|
PROFIT_AMOUNT: float = Field(default=0.25, ge=0.0)
|
21
23
|
LOSS_AMOUNT: float = Field(default=5.0, ge=0.0)
|
22
24
|
OPTION_MOVING_AVERAGE: str = Field(default="1h")
|
@@ -106,6 +108,10 @@ class Settings(BaseSettings):
|
|
106
108
|
|
107
109
|
# Benchmark
|
108
110
|
BENCHMARK: bool = Field(default=False)
|
111
|
+
|
112
|
+
#DB
|
113
|
+
DATABASE: str = Field(default="bitunix.db")
|
114
|
+
|
109
115
|
|
110
116
|
class Config:
|
111
117
|
# Specify the file name for loading environment variables
|
@@ -0,0 +1 @@
|
|
1
|
+
__version__ = "3.2.1"
|
@@ -1,18 +1,19 @@
|
|
1
1
|
bitunix_automated_crypto_trading/AsyncThreadRunner.py,sha256=bNIM_1xRYQOFEsIn74EX6qVpC59-GMhhr2CeiPr_GWg,3253
|
2
2
|
bitunix_automated_crypto_trading/BitunixApi.py,sha256=udgBwbWowf7v46jVVyfs-VjeNh9ajnghTiJf70lvn5w,11269
|
3
|
-
bitunix_automated_crypto_trading/BitunixSignal.py,sha256=
|
3
|
+
bitunix_automated_crypto_trading/BitunixSignal.py,sha256=3b0uhMzvB30QM5WqqLAF0wRNC5d5GzYtqE35petfVs8,74081
|
4
4
|
bitunix_automated_crypto_trading/BitunixWebSocket.py,sha256=-_7wRAZxJXG63joBq2k3TUC4qd06v7Miki-LGVtNIDk,11234
|
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
|
7
7
|
bitunix_automated_crypto_trading/SupportResistance.py,sha256=x_to4M4OHg0h8o40DXDBa4E_5io-y2Lb5qo2VzFnu_8,5765
|
8
8
|
bitunix_automated_crypto_trading/ThreadManager.py,sha256=Lw5_1EIT0m3AFSv5CIMpnjtA0DnNw2qQ6JtSpT34LyM,2349
|
9
|
-
bitunix_automated_crypto_trading/TickerManager.py,sha256=
|
9
|
+
bitunix_automated_crypto_trading/TickerManager.py,sha256=xzFzH1qDxCGi2bNji1fO8t7WM971RtN-HsUTWxTn7Ic,42717
|
10
10
|
bitunix_automated_crypto_trading/__init__.py,sha256=1hzk6nX8NnUCr1tsq8oFq1qGCNhNwnwldWE75641Eew,78
|
11
|
-
bitunix_automated_crypto_trading/bitunix.py,sha256=
|
12
|
-
bitunix_automated_crypto_trading/config.py,sha256=
|
11
|
+
bitunix_automated_crypto_trading/bitunix.py,sha256=JGjPiFbk5HIuCFGyMhpqCIKKD2MXrpoxTXPvzLyBJ7A,27165
|
12
|
+
bitunix_automated_crypto_trading/config.py,sha256=H9iMKzibh295kQrf4RG66hv7_zF_x8Dvp7uCnFU7Voo,5478
|
13
13
|
bitunix_automated_crypto_trading/logger.py,sha256=NHnA5JZdUFkTAhB7i-1iCAwrdf1fxhDuRvJUkbKPi9Y,2923
|
14
|
-
bitunix_automated_crypto_trading
|
15
|
-
bitunix_automated_crypto_trading-3.1.
|
16
|
-
bitunix_automated_crypto_trading-3.1.
|
17
|
-
bitunix_automated_crypto_trading-3.1.
|
18
|
-
bitunix_automated_crypto_trading-3.1.
|
14
|
+
bitunix_automated_crypto_trading/version.py,sha256=J63pT2dn-L7FddRjqXZQu2HME4y81dMpl-G5zJhSIHY,21
|
15
|
+
bitunix_automated_crypto_trading-3.2.1.dist-info/METADATA,sha256=aYyn_BCMcYWCbjHvm3kSheeZVJK0G_o9I_Dvi8nx5QM,996
|
16
|
+
bitunix_automated_crypto_trading-3.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
17
|
+
bitunix_automated_crypto_trading-3.2.1.dist-info/entry_points.txt,sha256=UXREYHuSl2XYd_tOtLIq0zg3d1kX3lixX5SpN8yGBw4,82
|
18
|
+
bitunix_automated_crypto_trading-3.2.1.dist-info/top_level.txt,sha256=uyFzHUCOsp8elnG2Ovor6xXcf7dxRxY-C-Txiwix64Q,33
|
19
|
+
bitunix_automated_crypto_trading-3.2.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|