bitunix-automated-crypto-trading 3.0.1__tar.gz → 3.0.4__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 (22) hide show
  1. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/PKG-INFO +1 -1
  2. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/README.md +3 -32
  3. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/BitunixApi.py +1 -1
  4. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/BitunixSignal.py +14 -10
  5. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/TickerManager.py +62 -34
  6. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/config.py +3 -2
  7. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading.egg-info/PKG-INFO +1 -1
  8. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/setup.py +1 -1
  9. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/AsyncThreadRunner.py +0 -0
  10. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/BitunixWebSocket.py +0 -0
  11. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/DataFrameHtmlRenderer.py +0 -0
  12. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/NotificationManager.py +0 -0
  13. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/ThreadManager.py +0 -0
  14. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/__init__.py +0 -0
  15. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/bitunix.py +0 -0
  16. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading/logger.py +0 -0
  17. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading.egg-info/SOURCES.txt +0 -0
  18. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading.egg-info/dependency_links.txt +0 -0
  19. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading.egg-info/entry_points.txt +0 -0
  20. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading.egg-info/requires.txt +0 -0
  21. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/bitunix_automated_crypto_trading.egg-info/top_level.txt +0 -0
  22. {bitunix_automated_crypto_trading-3.0.1 → bitunix_automated_crypto_trading-3.0.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitunix_automated_crypto_trading
3
- Version: 3.0.1
3
+ Version: 3.0.4
4
4
  Summary: Bitunix Futures Auto Trading Platform
5
5
  Home-page: https://github.com/tcj2001/bitunix-automated-crypto-trading
6
6
  Author: tcj2001
@@ -73,9 +73,10 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
73
73
 
74
74
  - `Study Parameters`:
75
75
  - `EMA_STUDY`: Enable EMA study
76
- - `EMA_CROSSING`: Check EMA crossing or crossed, COMPARING FAST AND MEDIUM MOVING AVERAGE
76
+ - `EMA_CROSSING`: Check EMA crossing or crossed, COMPARING MEDIUM AND SLOW MOVING AVERAGE
77
77
  - `EMA_CHECK_ON_OPEN`: Check EMA on open
78
78
  - `EMA_CHECK_ON_CLOSE`: Check EMA on close
79
+ - `EMA_CLOSE_ON_FAST_MEDIUM`: Check EMA close comparing fast and medium
79
80
 
80
81
  - `MACD_STUDY`: Enable MACD study
81
82
  - `MACD_CROSSING`: Check MACD crossing or crossed, comparing MACD line and signal line
@@ -156,37 +157,7 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
156
157
  - AutoTradeProcess function inside BitunixSignal.py, you can setup your opening and closing trading strategy
157
158
  - User interface will list the stocks in the signal window with BUY or SELL signal based on the descending value of signal_strength
158
159
  - All study can be controlled thru environment variables
159
- - Auto trade process open the trade based on following conditions:
160
- - If the current candle is bullish
161
- and moving average is above the medium moving average
162
- and MACD_line > Signal_line
163
- and RSI is above the long RSI
164
- and current close is above bollinger band middle line
165
- and ADX is above 25 (STRONG)
166
- it will open long position
167
- - If the current candle is bearish
168
- and moving average is below the medium moving average
169
- and MACD_line < Signal_line
170
- and RSI is below the long RSI
171
- and current close is belowe bollinger band middle line
172
- and ADX is above 25 (STRONG)
173
- it will open short position
174
- - Auto trade process closes the trade based on following conditions:
175
- - If the current candle is bearish, it will close the trade
176
- - If the trade is in profit and greater than the profit_amount , it will close the trade
177
- - If the trade is in profit and greater than the profit_amount , it will close the trade
178
- - If the trade is in loss and greater than the loss_amount , it will close the trade
179
- - If the order is open for more than 1 minute, it will close the open orders
180
- - It will close long or short postions:
181
- - If the trade is long and the fast moving average is above the medium moving average, it will close the trade
182
- - If the trade is short and the fast moving average is below the medium moving average, it will close the trade
183
- - If the trade is long and the MACD_line < Signal_line, it will close the trade
184
- - If the trade is short and the MACD_line > Signal_line, it will close the trade
185
- - If the trade is long and the short RSI < long RSI, it will close the trade
186
- - If the trade is short and the short RSI > long RSI, it will close the trade
187
- - if the trade is long and current close is less bollinger band middle line , it will close the trade
188
- - if the trade is short and the current close is above bollinger band middle line , it will close the trade
189
- - if the trade is long or short and the ADX is below 25 (WEAK), it will close the trade
160
+ - Auto trade process for opening the trade and closing the trade is configurable using the config file
190
161
 
191
162
 
192
163
  ## Installation
@@ -91,7 +91,7 @@ class BitunixApi:
91
91
  "nonce": nonce,
92
92
  }
93
93
 
94
- query_string = urlencode(sorted(params.items())).replace('=','') if params else ""
94
+ query_string = urlencode(sorted(params.items())).replace('=','').replace('&','') if params else ""
95
95
  signature = await self.sign_request(nonce, timestamp, query_params=query_string)
96
96
  headers["sign"] = signature
97
97
 
@@ -496,8 +496,9 @@ class BitunixSignal:
496
496
  try:
497
497
  self.positionHistoryData = await self.bitunixApi.GetPositionHistoryData()
498
498
  if self.positionHistoryData and 'positionList' in self.positionHistoryData:
499
- self.positionHistorydf = pd.DataFrame(self.positionHistoryData['positionList'], columns=["symbol", "side","realizedPNL", "ctime", "maxQty", "closePrice","fee", "funding"])
499
+ self.positionHistorydf = pd.DataFrame(self.positionHistoryData['positionList'], columns=["symbol", "side","realizedPNL", "ctime", "mtime","maxQty", "closePrice","fee", "funding"])
500
500
  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')
501
+ 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')
501
502
  self.positionHistorydf['charts'] = self.positionHistorydf.apply(self.add_charts_button, axis=1)
502
503
  self.positionHistorydf['bitunix'] = self.positionHistorydf.apply(self.add_bitunix_button, axis=1)
503
504
 
@@ -560,12 +561,12 @@ class BitunixSignal:
560
561
  self.signaldf_filtered = self.tickerObjects.signaldf_filtered
561
562
 
562
563
  if not self.positiondf.empty and not self.signaldf_full.empty:
563
- columns=['symbol', f"{period}_trend", f"{period}_cb", f"{period}_barcolor", f"{period}_ema", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", f"{period}_candle_trend", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low"]
564
+ columns=['symbol', f"{period}_trend", f"{period}_cb", f"{period}_barcolor", f"{period}_ema_open", f"{period}_ema_close", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", f"{period}_candle_trend", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low"]
564
565
  columns2=["qty", "side", "unrealizedPNL", "realizedPNL", "ctime", "avgOpenPrice", "bid", "bidcolor", "last", "lastcolor", "ask", "askcolor", "charts", "bitunix", "action", "add", "reduce"]
565
566
  if set(columns).issubset(self.signaldf_full.columns) and set(columns2).issubset(self.positiondf.columns):
566
- columnOrder= ['symbol', "side", "unrealizedPNL", "realizedPNL", f"{period}_trend", f"{period}_cb", f"{period}_barcolor", f"{period}_ema", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", 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"]
567
+ columnOrder= ['symbol', "side", "unrealizedPNL", "realizedPNL", f"{period}_trend", f"{period}_cb", f"{period}_barcolor", f"{period}_ema_open", f"{period}_ema_close", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", 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"]
567
568
  self.positiondf2 = pd.merge(self.positiondf, self.signaldf_full[["symbol", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low",
568
- f"{period}_ema", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", f"{period}_adx", f"{period}_candle_trend",
569
+ f"{period}_ema_open", f"{period}_ema_close", f"{period}_macd", f"{period}_bbm", f"{period}_rsi", f"{period}_adx", f"{period}_candle_trend",
569
570
  f"{period}_trend",f"{period}_cb", f"{period}_barcolor"]], left_on="symbol", right_index=True, how="left")[columnOrder]
570
571
  self.positiondfStyle= self.positiondfrenderer.render_html(self.positiondf2)
571
572
  else:
@@ -579,7 +580,7 @@ class BitunixSignal:
579
580
  # Assign to self.signaldf for HTML rendering
580
581
  self.signaldf = self.signaldf_filtered[[
581
582
  "symbol", f"{period}_trend",f"{period}_cb", f"{period}_barcolor",
582
- f"{period}_ema", f"{period}_macd", f"{period}_bbm", f"{period}_rsi",f"{period}_adx",f"{period}_candle_trend",
583
+ f"{period}_ema_open", f"{period}_ema_close", f"{period}_macd", f"{period}_bbm", f"{period}_rsi",f"{period}_adx",f"{period}_candle_trend",
583
584
  'lastcolor', 'bidcolor', 'askcolor', 'bid', 'ask', 'last',
584
585
  f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low",
585
586
  ]].sort_values(by=[f'{period}_cb'], ascending=[False])
@@ -690,7 +691,7 @@ class BitunixSignal:
690
691
  total_pnl = unrealized_pnl + realized_pnl
691
692
  side=row['side']
692
693
 
693
- requiredCols=[f'{period}_open', f'{period}_close', f'{period}_high', f'{period}_low', f'{period}_ema', f'{period}_macd', f'{period}_bbm', f'{period}_rsi', f'{period}_candle_trend', f'{period}_trend', f'{period}_cb', f'{period}_barcolor']
694
+ requiredCols=[f'{period}_open', f'{period}_close', f'{period}_high', f'{period}_low', f'{period}_ema_open', f"{period}_ema_close", f'{period}_macd', f'{period}_bbm', f'{period}_rsi', f'{period}_candle_trend', f'{period}_trend', f'{period}_cb', f'{period}_barcolor']
694
695
  required_cols = set(requiredCols)
695
696
 
696
697
  # Close position that fall the below criteria
@@ -739,9 +740,9 @@ class BitunixSignal:
739
740
  )
740
741
  continue
741
742
 
742
- # Moving average comparison between fast and medium
743
+ # Moving average comparison between fast and medium or medium and slow
743
744
  if self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_CLOSE:
744
- if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_ema'] == "SELL":
745
+ if row.side == 'BUY' and self.signaldf_full.at[row.symbol, f'{period}_ema_close'] == "SELL":
745
746
  last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
746
747
  price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
747
748
 
@@ -758,7 +759,7 @@ class BitunixSignal:
758
759
  )
759
760
  continue
760
761
 
761
- if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_ema'] == "BUY":
762
+ if row.side == 'SELL' and self.signaldf_full.at[row.symbol, f'{period}_ema_close'] == "BUY":
762
763
  last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
763
764
  price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
764
765
  self.notifications.add_notification(
@@ -1027,7 +1028,10 @@ class BitunixSignal:
1027
1028
  side = data['side']
1028
1029
  positionId = data['positionId']
1029
1030
  event = data['event']
1030
- entryValue = float(data['entryValue'])
1031
+ if 'entryValue' in data:
1032
+ entryValue = float(data['entryValue'])
1033
+ else:
1034
+ entryValue = 0
1031
1035
  price = entryValue / qty if entryValue != 0 and qty != 0 else 0
1032
1036
 
1033
1037
  if event == "OPEN":
@@ -19,7 +19,8 @@ class Interval:
19
19
 
20
20
  #these signals are used to list stocks in the signals sections on the main page
21
21
  self.current_signal="HOLD"
22
- self.ema_signal="HOLD"
22
+ self.ema_open_signal="HOLD"
23
+ self.ema_close_signal="HOLD"
23
24
  self.macd_signal="HOLD"
24
25
  self.bbm_signal="HOLD"
25
26
  self.rsi_signal="HOLD"
@@ -54,34 +55,55 @@ class Interval:
54
55
  df['ma_fast'] = talib.EMA(df['close'], timeperiod=self.settings.MA_FAST)
55
56
  df['ma_fast'] = df['ma_fast'].bfill()
56
57
  df.fillna({'ma_fast':0}, inplace=True)
58
+ df['ma_fast_slope'] = df['ma_fast'].diff()
59
+ df['ma_fast_angle'] = np.degrees(np.arctan(df['ma_fast_slope']))
60
+ df.fillna({'ma_fast_slope':0}, inplace=True)
61
+ df.fillna({'ma_fast_angle':0}, inplace=True)
57
62
 
58
- df['ma_slow'] = talib.EMA(df['close'], timeperiod=self.settings.MA_SLOW)
59
- df['ma_slow'] = df['ma_slow'].bfill()
60
- df.fillna({'ma_slow':0}, inplace=True)
61
-
62
63
  df['ma_medium'] = talib.EMA(df['close'], timeperiod=self.settings.MA_MEDIUM)
63
64
  df['ma_medium'] = df['ma_medium'].bfill()
64
65
  df.fillna({'ma_medium':0}, inplace=True)
65
-
66
- df['ma_slope'] = df['ma_medium'].diff()
67
- df['ma_angle'] = np.degrees(np.arctan(df['ma_slope']))
68
- df.fillna({'ma_slope':0}, inplace=True)
69
- df.fillna({'ma_angle':0}, inplace=True)
66
+ df['ma_medium_slope'] = df['ma_medium'].diff()
67
+ df['ma_medium_angle'] = np.degrees(np.arctan(df['ma_medium_slope']))
68
+ df.fillna({'ma_medium_slope':0}, inplace=True)
69
+ df.fillna({'ma_medium_angle':0}, inplace=True)
70
70
 
71
+ df['ma_slow'] = talib.EMA(df['close'], timeperiod=self.settings.MA_SLOW)
72
+ df['ma_slow'] = df['ma_slow'].bfill()
73
+ df.fillna({'ma_slow':0}, inplace=True)
74
+ df['ma_slow_slope'] = df['ma_slow'].diff()
75
+ df['ma_slow_angle'] = np.degrees(np.arctan(df['ma_slow_slope']))
76
+ df.fillna({'ma_slow_slope':0}, inplace=True)
77
+ df.fillna({'ma_slow_angle':0}, inplace=True)
78
+
71
79
  if self.settings.EMA_CROSSING:
72
- if df['ma_fast'].iloc[-2] <= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
73
- self.ema_signal = "BUY"
74
- elif df['ma_fast'].iloc[-2] >= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] <= df['ma_medium'].iloc[-1]:
75
- self.ema_signal = "SELL"
80
+ if df['ma_medium'].iloc[-2] <= df['ma_slow'].iloc[-2] and df['ma_medium'].iloc[-1] > df['ma_slow'].iloc[-1]:
81
+ self.ema_open_signal = "BUY"
82
+ self.ema_close_signal = "BUY"
83
+ elif df['ma_medium'].iloc[-2] >= df['ma_slow'].iloc[-2] and df['ma_medium'].iloc[-1] < df['ma_slow'].iloc[-1]:
84
+ self.ema_open_signal = "SELL"
85
+ self.ema_close_signal = "SELL"
76
86
  else:
77
- self.ema_signal = "HOLD"
87
+ self.ema_open_signal = "HOLD"
88
+ self.ema_close_signal = "HOLD"
89
+
90
+ if self.settings.EMA_CLOSE_ON_FAST_MEDIUM:
91
+ if df['ma_fast'].iloc[-2] <= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
92
+ self.ema_close_signal = "BUY"
93
+ elif df['ma_fast'].iloc[-2] >= df['ma_medium'].iloc[-2] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1]:
94
+ self.ema_close_signal = "SELL"
95
+ else:
96
+ self.ema_close_signal = "HOLD"
78
97
  else:
79
- if df['close'].iloc[-1] > df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
80
- self.ema_signal = "BUY"
81
- elif df['close'].iloc[-1] < df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1]:
82
- self.ema_signal = "SELL"
98
+ if df['close'].iloc[-1] > df['ma_medium'].iloc[-1] and df['ma_medium'].iloc[-1] > df['ma_slow'].iloc[-1]:
99
+ self.ema_open_signal = "BUY"
100
+ self.ema_close_signal = "BUY"
101
+ elif df['close'].iloc[-1] < df['ma_medium'].iloc[-1] and df['ma_medium'].iloc[-1] < df['ma_slow'].iloc[-1]:
102
+ self.ema_open_signal = "SELL"
103
+ self.ema_close_signal = "SELL"
83
104
  else:
84
- self.ema_signal = "HOLD"
105
+ self.ema_open_signal = "HOLD"
106
+ self.ema_close_signal = "HOLD"
85
107
  else:
86
108
  # Drop EMA columns if not used
87
109
  df.drop(['ma_fast', 'ma_medium', 'ma_slow', 'ma_slope', 'ma_angle'], axis=1, inplace=True, errors='ignore')
@@ -96,10 +118,10 @@ class Interval:
96
118
  df.fillna({'MACD_Signal':0}, inplace=True)
97
119
  df.fillna({'MACD_Histogram':0}, inplace=True)
98
120
 
99
- df['MACD_slope'] = df['MACD_Signal'].diff()
100
- df['MACD_angle'] = np.degrees(np.arctan(df['MACD_slope']))
101
- df.fillna({'MACD_slope':0}, inplace=True)
102
- df.fillna({'MACD_angle':0}, inplace=True)
121
+ df['MACD_Line_slope'] = df['MACD_Line'].diff()
122
+ df['MACD_Line_angle'] = np.degrees(np.arctan(df['MACD_Line_slope']))
123
+ df.fillna({'MACD_Line_slope':0}, inplace=True)
124
+ df.fillna({'MACD_Line_angle':0}, inplace=True)
103
125
 
104
126
  if self.settings.MACD_CROSSING:
105
127
  if df['MACD_Line'].iloc[-2] <= df['MACD_Signal'].iloc[-2] and df['MACD_Line'].iloc[-1] > df['MACD_Signal'].iloc[-1]:
@@ -156,14 +178,18 @@ class Interval:
156
178
  if self.settings.RSI_STUDY:
157
179
  df['rsi_fast'] = talib.RSI(df['close'],timeperiod=self.settings.RSI_FAST)
158
180
  df.fillna({'rsi_fast':0}, inplace=True)
181
+ df['rsi_fast_slope'] = df['rsi_fast'].diff()
182
+ df['rsi_fast_angle'] = np.degrees(np.arctan(df['rsi_fast_slope']))
183
+ df.fillna({'rsi_fast_slope':0}, inplace=True)
184
+ df.fillna({'rsi_fast_angle':0}, inplace=True)
159
185
 
160
186
  df['rsi_slow'] = talib.RSI(df['close'],timeperiod=self.settings.RSI_SLOW)
161
187
  df.fillna({'rsi_slow':0}, inplace=True)
188
+ df['rsi_slow_slope'] = df['rsi_slow'].diff()
189
+ df['rsi_slow_angle'] = np.degrees(np.arctan(df['rsi_slow_slope']))
190
+ df.fillna({'rsi_slow_slope':0}, inplace=True)
191
+ df.fillna({'rsi_slow_angle':0}, inplace=True)
162
192
 
163
- df['rsi_slope'] = df['rsi_fast'].diff()
164
- df['rsi_angle'] = np.degrees(np.arctan(df['rsi_slope']))
165
- df.fillna({'rsi_slope':0}, inplace=True)
166
- df.fillna({'rsi_angle':0}, inplace=True)
167
193
 
168
194
  if self.settings.RSI_CROSSING:
169
195
  if df['rsi_fast'].iloc[-2] <= df['rsi_slow'].iloc[-2] and df['rsi_fast'].iloc[-1] > df['rsi_slow'].iloc[-1]:
@@ -225,7 +251,7 @@ class Interval:
225
251
 
226
252
  # Check for BUY signal
227
253
  buy_conditions = (
228
- (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_signal == "BUY") or
254
+ (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "BUY") or
229
255
  (self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "BUY") or
230
256
  (self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "BUY") or
231
257
  (self.settings.RSI_STUDY and self.settings.RSI_CHECK_ON_OPEN and self.rsi_signal == "BUY")
@@ -237,7 +263,7 @@ class Interval:
237
263
 
238
264
  # Check for SELL signal
239
265
  sell_conditions = (
240
- (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_signal == "SELL") or
266
+ (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "SELL") or
241
267
  (self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "SELL") or
242
268
  (self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "SELL") or
243
269
  (self.settings.RSI_STUDY and self.settings.RSI_CHECK_ON_OPEN and self.rsi_signal == "SELL")
@@ -260,7 +286,7 @@ class Interval:
260
286
  # ADX is enabled and strong and candle trend is enabled and bullish
261
287
  # then BUY or SELL
262
288
  buy_conditions = (
263
- (not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN or self.ema_signal == "BUY") and
289
+ (not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN or self.ema_open_signal == "BUY") and
264
290
  (not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN or self.macd_signal == "BUY") and
265
291
  (not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN or self.bbm_signal == "BUY") and
266
292
  (not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN or self.rsi_signal == "BUY")
@@ -272,7 +298,7 @@ class Interval:
272
298
 
273
299
  # Check for SELL signal
274
300
  sell_conditions = (
275
- (not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN or self.ema_signal == "SELL") and
301
+ (not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN or self.ema_open_signal == "SELL") and
276
302
  (not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN or self.macd_signal == "SELL") and
277
303
  (not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN or self.bbm_signal == "SELL") and
278
304
  (not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN or self.rsi_signal == "SELL")
@@ -548,7 +574,8 @@ class Tickers:
548
574
  if not interval._data is None:
549
575
  args[0].get_interval_ticks(intervalId)._data = interval._data
550
576
  args[0].get_interval_ticks(intervalId).current_signal = interval.current_signal
551
- args[0].get_interval_ticks(intervalId).ema_signal = interval.ema_signal
577
+ args[0].get_interval_ticks(intervalId).ema_open_signal = interval.ema_open_signal
578
+ args[0].get_interval_ticks(intervalId).ema_close_signal = interval.ema_close_signal
552
579
  args[0].get_interval_ticks(intervalId).macd_signal = interval.macd_signal
553
580
  args[0].get_interval_ticks(intervalId).bbm_signal = interval.bbm_signal
554
581
  args[0].get_interval_ticks(intervalId).rsi_signal = interval.rsi_signal
@@ -584,7 +611,8 @@ class Tickers:
584
611
  f"{period}_trend": intervalObj.current_signal,
585
612
  f"{period}_cb": intervalObj.signal_strength,
586
613
  f"{period}_barcolor": lastcandle['barcolor'],
587
- f"{period}_ema": intervalObj.ema_signal,
614
+ f"{period}_ema_open": intervalObj.ema_open_signal,
615
+ f"{period}_ema_close": intervalObj.ema_close_signal,
588
616
  f"{period}_macd":intervalObj.macd_signal,
589
617
  f"{period}_bbm":intervalObj.bbm_signal,
590
618
  f"{period}_rsi":intervalObj.rsi_signal,
@@ -18,8 +18,8 @@ class Settings(BaseSettings):
18
18
  BARS: int = Field(default=100, ge=1)
19
19
 
20
20
  # Technical Indicators Parameters
21
- MA_FAST: int = Field(default=12, ge=1)
22
- MA_MEDIUM: int = Field(default=26, ge=1)
21
+ MA_FAST: int = Field(default=10, ge=1)
22
+ MA_MEDIUM: int = Field(default=20, ge=1)
23
23
  MA_SLOW: int = Field(default=50, ge=1)
24
24
  RSI_FAST: int = Field(default=6, ge=1)
25
25
  RSI_SLOW: int = Field(default=24, ge=1)
@@ -38,6 +38,7 @@ class Settings(BaseSettings):
38
38
  EMA_CROSSING: bool = Field(default=False)
39
39
  EMA_CHECK_ON_OPEN: bool = Field(default=True)
40
40
  EMA_CHECK_ON_CLOSE: bool = Field(default=True)
41
+ EMA_CLOSE_ON_FAST_MEDIUM: bool = Field(default=True)
41
42
 
42
43
  MACD_CHART: bool = Field(default=False)
43
44
  MACD_STUDY: bool = Field(default=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitunix_automated_crypto_trading
3
- Version: 3.0.1
3
+ Version: 3.0.4
4
4
  Summary: Bitunix Futures Auto Trading Platform
5
5
  Home-page: https://github.com/tcj2001/bitunix-automated-crypto-trading
6
6
  Author: tcj2001
@@ -66,7 +66,7 @@ class CustomInstall(install):
66
66
 
67
67
  setup(
68
68
  name="bitunix_automated_crypto_trading",
69
- version="3.0.1",
69
+ version="3.0.4",
70
70
  license="MIT",
71
71
  author="tcj2001",
72
72
  author_email="thomsonmathews@hotmail.com",