bitunix-automated-crypto-trading 3.1.5__tar.gz → 3.1.7__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 (23) hide show
  1. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/PKG-INFO +1 -1
  2. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/README.md +7 -0
  3. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/BitunixSignal.py +30 -20
  4. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/TickerManager.py +98 -25
  5. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/config.py +11 -5
  6. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading.egg-info/PKG-INFO +1 -1
  7. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/setup.py +1 -1
  8. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/AsyncThreadRunner.py +0 -0
  9. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/BitunixApi.py +0 -0
  10. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/BitunixWebSocket.py +0 -0
  11. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/DataFrameHtmlRenderer.py +0 -0
  12. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/NotificationManager.py +0 -0
  13. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/SupportResistance.py +0 -0
  14. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/ThreadManager.py +0 -0
  15. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/__init__.py +0 -0
  16. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/bitunix.py +0 -0
  17. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading/logger.py +0 -0
  18. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading.egg-info/SOURCES.txt +0 -0
  19. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading.egg-info/dependency_links.txt +0 -0
  20. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading.egg-info/entry_points.txt +0 -0
  21. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading.egg-info/requires.txt +0 -0
  22. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/bitunix_automated_crypto_trading.egg-info/top_level.txt +0 -0
  23. {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.7}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitunix_automated_crypto_trading
3
- Version: 3.1.5
3
+ Version: 3.1.7
4
4
  Summary: Bitunix Futures Auto Trading Platform
5
5
  Home-page: https://github.com/tcj2001/bitunix-automated-crypto-trading
6
6
  Author: tcj2001
@@ -26,6 +26,7 @@ A real-time cryptocurrency trading platform built with FastAPI and WebSocket tec
26
26
  - MACD
27
27
  - Bollinger Bands
28
28
  - RSI
29
+ - Support and Resistance levels
29
30
  - Brearish or bullish candle based on the close near high or low of the current candle
30
31
  - strength based on consecutive colored candles count
31
32
  - ADX
@@ -48,6 +49,7 @@ A real-time cryptocurrency trading platform built with FastAPI and WebSocket tec
48
49
  The platform can be configured through the `config.py` file or `config.txt`. Key configuration parameters include:
49
50
  - Trading Parameters:
50
51
  - `AUTOTRADE` : True or False
52
+ - `TICKERS`: supply a list of tickers seperated by comma to trade, e.g., "BTCUSDT,ETHUSDT" or "" to auto select based on MIN_VOLUME and THRESHOLD
51
53
  - `LEVERAGE`: Trading leverage (1-100)
52
54
  - `THRESHOLD`: Ticker selection based close near high or low of the day
53
55
  - `MIN_VOLUME`: Ticker selection based on Minimum trading volume
@@ -59,6 +61,7 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
59
61
  - `BARS`: Number of bars to use for study and charting
60
62
 
61
63
  - `Technical Indicators Parameters`:
64
+ - `BOS_PERIOD`: Break of structure period, number of bars to look back to determine the previous high or low
62
65
  - `MA_FAST`: Fast moving average period
63
66
  - `MA_MEDIUM`: Medium moving average period
64
67
  - `MA_SLOW`: Slow moving average period
@@ -72,6 +75,7 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
72
75
  - `ADX_PERIOD`: ADX period
73
76
 
74
77
  - `Study Parameters`:
78
+ - `BOS_STUDY`: Enable Break Of Structure study
75
79
  - `EMA_STUDY`: Enable EMA study
76
80
  - `EMA_CHART`: Display EMA chart
77
81
  - `EMA_STUDY`: Enable EMA study
@@ -98,9 +102,11 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
98
102
  - `RSI_CHECK_ON_OPEN`: Check RSI on open
99
103
  - `RSI_CHECK_ON_CLOSE`: Check RSI on close
100
104
 
105
+ - `TRENDLINE_PEAK_DISTANCE` : distance between peaks or troughs
101
106
  - `TRENDLINE_STUDY`: Enable Trendline support and resistance study
102
107
  - `TRENDLINE_CHART`: Display Trendline chart
103
108
  - `TRENDLINE_LOOKBACK`: Lookback period for trendline study
109
+ - `TRENDLINE_BREAKOUT`: Check if breakout from support or resistance line
104
110
  - `TRENDLINE_CHECK_ON_OPEN`: Check Trendline support and resistance on open
105
111
  - `TRENDLINE_CHECK_ON_CLOSE`: Check Trendline support and resistance on close
106
112
 
@@ -155,6 +161,7 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
155
161
  - Max auto trades
156
162
  - Take Profit amount
157
163
  - Accept Loss amount
164
+ - BOS study is basically when the price breakout from the previous high or low
158
165
  - You can control the study like Moving Average, MACD, Bollinger Band, RSI or close proximity to high or low of the candle using the env file
159
166
  - You can control the trading strategy using the CalculateStudy function in TickerManager.py and AutoTradeProcess function in BitunixSignal.py
160
167
  - Changes are activated by unchecking and checking the AutoTrade checkbox
@@ -99,19 +99,23 @@ class BitunixSignal:
99
99
  self.tickerObjects.update_settings(settings)
100
100
 
101
101
  async def load_tickers(self):
102
- symbols = await self.bitunixApi.GetTickerList(float(self.settings.THRESHOLD), float(self.settings.MIN_VOLUME))
103
- self.pendingPositions= await self.bitunixApi.GetPendingPositionData()
104
- self.pendingOrders= await self.bitunixApi.GetPendingOrderData()
105
- olist=[]
106
- plist=[]
107
- if self.pendingPositions:
108
- plist = [entry['symbol'] for entry in self.pendingPositions]
109
- if self.pendingOrders['orderList']:
110
- olist = [entry['symbol'] for entry in self.pendingOrders['orderList']]
111
- newlist=olist+plist+list(set(symbols))
112
- self.tickerList=newlist[:300]
113
- self.tickerList.remove("STMXUSDT")
114
- #self.tickerList=['POLUSDT']
102
+ if self.settings.TICKERS=="":
103
+ symbols = await self.bitunixApi.GetTickerList(float(self.settings.THRESHOLD), float(self.settings.MIN_VOLUME))
104
+ self.pendingPositions= await self.bitunixApi.GetPendingPositionData()
105
+ self.pendingOrders= await self.bitunixApi.GetPendingOrderData()
106
+ olist=[]
107
+ plist=[]
108
+ if self.pendingPositions:
109
+ plist = [entry['symbol'] for entry in self.pendingPositions]
110
+ if self.pendingOrders['orderList']:
111
+ olist = [entry['symbol'] for entry in self.pendingOrders['orderList']]
112
+ newlist=olist+plist+list(set(symbols))
113
+ self.tickerList=newlist[:300]
114
+ self.tickerList.remove("STMXUSDT")
115
+ #self.tickerList=['POLUSDT']
116
+ else:
117
+ self.tickerList = self.settings.TICKERS.split(",")
118
+ self.tickerList = [sym.strip().upper() for sym in self.tickerList if sym.strip()]
115
119
 
116
120
  [await self.add_ticker_to_tickerObjects(sym) for sym in self.tickerList]
117
121
  self.notifications.add_notification(f"{len(self.tickerList)} ticker list loaded")
@@ -559,11 +563,16 @@ class BitunixSignal:
559
563
  self.signaldf_filtered = self.tickerObjects.signaldf_filtered
560
564
 
561
565
  if not self.positiondf.empty and not self.signaldf_full.empty:
562
- 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}_trendline", f"{period}_candle_trend", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low"]
566
+ columns=['symbol', f"{period}_trend", f"{period}_cb", f"{period}_barcolor",
567
+ f"{period}_bos",
568
+ 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"]
563
569
  columns2=["qty", "side", "unrealizedPNL", "realizedPNL", "ctime", "avgOpenPrice", "bid", "bidcolor", "last", "lastcolor", "ask", "askcolor", "charts", "bitunix", "action", "add", "reduce"]
564
570
  if set(columns).issubset(self.signaldf_full.columns) and set(columns2).issubset(self.positiondf.columns):
565
- 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}_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"]
571
+ columnOrder= ['symbol', "side", "unrealizedPNL", "realizedPNL", f"{period}_trend", f"{period}_cb", f"{period}_barcolor",
572
+ f"{period}_bos",
573
+ 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"]
566
574
  self.positiondf2 = pd.merge(self.positiondf, self.signaldf_full[["symbol", f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low",
575
+ f"{period}_bos",
567
576
  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",
568
577
  f"{period}_trend",f"{period}_cb", f"{period}_barcolor"]], left_on="symbol", right_index=True, how="left")[columnOrder]
569
578
  self.positiondfStyle= self.positiondfrenderer.render_html(self.positiondf2)
@@ -578,6 +587,7 @@ class BitunixSignal:
578
587
  # Assign to self.signaldf for HTML rendering
579
588
  self.signaldf = self.signaldf_filtered[[
580
589
  "symbol", f"{period}_trend",f"{period}_cb", f"{period}_barcolor",
590
+ f"{period}_bos",
581
591
  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",
582
592
  'lastcolor', 'bidcolor', 'askcolor', 'bid', 'last', 'ask',
583
593
  f"{period}_open", f"{period}_close", f"{period}_high", f"{period}_low",
@@ -640,7 +650,7 @@ class BitunixSignal:
640
650
  #open position upto a max of max_auto_trades from the signal list
641
651
  df=self.signaldf.copy(deep=False)
642
652
  for index, row in df.iterrows():
643
- side = "BUY" if row[f'{period}_barcolor'] == self.green else "SELL" if row[f'{period}_barcolor'] == self.red else ""
653
+ 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 ""
644
654
  if side != "":
645
655
  select = True
646
656
  self.pendingPositions = await self.bitunixApi.GetPendingPositionData({'symbol': row.symbol})
@@ -945,8 +955,8 @@ class BitunixSignal:
945
955
  continue
946
956
 
947
957
  # candle reversed
948
- if self.settings.CANDLE_TREND_STUDY and self.settings.CANDLE_TREND_CHECK_ON_CLOSE:
949
- 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}_candle_trend'] == "BEARISH":
958
+ if self.settings.CANDLE_TREND_STUDY and self.settings.CANDLE_TREND_REVERSAL_CHECK_ON_CLOSE:
959
+ 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":
950
960
  last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
951
961
  price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
952
962
 
@@ -963,7 +973,7 @@ class BitunixSignal:
963
973
  )
964
974
  continue
965
975
 
966
- 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}_candle_trend'] == "BULLISH":
976
+ 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":
967
977
  last, bid, ask, mtv = await self.GetTickerBidLastAsk(row.symbol)
968
978
  price = (ask if row['side'] == "BUY" else bid if row['side'] == "SELL" else last) if bid<=last<=ask else last
969
979
 
@@ -982,7 +992,7 @@ class BitunixSignal:
982
992
 
983
993
  await asyncio.sleep(0)
984
994
 
985
- self.lastAutoTradeTime = time.time()
995
+ self.lastAutoTradeTime = time.time()
986
996
  except Exception as e:
987
997
  stack = traceback.extract_stack()
988
998
  function_name = stack[-1].name
@@ -63,6 +63,23 @@ class Interval:
63
63
  # Get the last color and its consecutive count
64
64
  self.signal_strength = df['Consecutive'].iloc[-1]
65
65
 
66
+ # Break of Strcuture
67
+ if self.settings.BOS_STUDY:
68
+ if df['high'].size > 1 and df['low'].size > 1 and df['close'].size > 1:
69
+ high = talib.MAX(df.iloc[:-1]['high'].values, timeperiod=self.settings.BOS_PERIOD)[-1]
70
+ low = talib.MIN(df.iloc[:-1]['low'].values, timeperiod=self.settings.BOS_PERIOD)[-1]
71
+ close = df['close'].iloc[-1]
72
+ if close > high:
73
+ self.bos_signal = "BUY"
74
+ elif close < low:
75
+ self.bos_signal = "SELL"
76
+ else:
77
+ self.bos_signal = "HOLD"
78
+ else:
79
+ self.bos_signal = "HOLD"
80
+ else:
81
+ self.bos_signal = "HOLD"
82
+
66
83
  # Calculate the Moving Averages
67
84
  if self.settings.EMA_STUDY:
68
85
  df['ma_fast'] = talib.EMA(df['close'], timeperiod=self.settings.MA_FAST)
@@ -116,6 +133,14 @@ class Interval:
116
133
  else:
117
134
  self.ema_open_signal = "HOLD"
118
135
  self.ema_close_signal = "HOLD"
136
+
137
+ if self.settings.EMA_CLOSE_ON_FAST_MEDIUM:
138
+ if df['close'].iloc[-1] > df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
139
+ self.ema_close_signal = "BUY"
140
+ elif df['close'].iloc[-1] < df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1]:
141
+ self.ema_close_signal = "SELL"
142
+ else:
143
+ self.ema_close_signal = "HOLD"
119
144
  else:
120
145
  # Drop EMA columns if not used
121
146
  df.drop(['ma_fast', 'ma_medium', 'ma_slow', 'ma_slope', 'ma_angle'], axis=1, inplace=True, errors='ignore')
@@ -233,16 +258,20 @@ class Interval:
233
258
  df.fillna({'support_line':0}, inplace=True)
234
259
  df.fillna({'resistance_line':0}, inplace=True)
235
260
  if df is not None and len(df) >= 2:
236
- if df['high'].iloc[-3] >= df['support_line'].iloc[-3] and df['close'].iloc[-2] < df['support_line'].iloc[-2] and df['close'].iloc[-1] < df['open'].iloc[-1]:
237
- self.trendline_signal = "SELL"
238
- elif df['low'].iloc[-3] <= df['resistance_line'].iloc[-3] and df['close'].iloc[-2] > df['resistance_line'].iloc[-2] and df['close'].iloc[-1] > df['open'].iloc[-1]:
239
- self.trendline_signal = "BUY"
240
- elif df['close'].iloc[-3] > df['support_line'].iloc[-3] and df['close'].iloc[-2] > df['support_line'].iloc[-2] and df['close'].iloc[-1] > df['open'].iloc[-1]:
241
- self.trendline_signal = "BUY"
242
- elif df['close'].iloc[-3] < df['resistance_line'].iloc[-3] and df['close'].iloc[-2] < df['resistance_line'].iloc[-2] and df['close'].iloc[-1] < df['open'].iloc[-1]:
243
- self.trendline_signal = "SELL"
261
+ if self.settings.TRENDLINE_BREAKOUT:
262
+ if df['close'].iloc[-2] > df['support_line'].iloc[-2] and df['open'].iloc[-1] > df['support_line'].iloc[-1] and df['close'].iloc[-1] > df['open'].iloc[-1]:
263
+ self.trendline_signal = "BUY"
264
+ elif df['close'].iloc[-2] < df['resistance_line'].iloc[-2] and df['open'].iloc[-1] < df['resistance_line'].iloc[-1] and df['close'].iloc[-1] < df['open'].iloc[-1]:
265
+ self.trendline_signal = "SELL"
266
+ else:
267
+ self.trendline_signal = "HOLD"
244
268
  else:
245
- self.trendline_signal = "HOLD"
269
+ if df['high'].iloc[-3] >= df['support_line'].iloc[-3] and df['close'].iloc[-2] < df['support_line'].iloc[-2] and df['close'].iloc[-1] < df['open'].iloc[-1]:
270
+ self.trendline_signal = "SELL"
271
+ elif df['low'].iloc[-3] <= df['resistance_line'].iloc[-3] and df['close'].iloc[-2] > df['resistance_line'].iloc[-2] and df['close'].iloc[-1] > df['open'].iloc[-1]:
272
+ self.trendline_signal = "BUY"
273
+ else:
274
+ self.trendline_signal = "HOLD"
246
275
 
247
276
  # Calculate the ADX
248
277
  if self.settings.ADX_STUDY:
@@ -288,6 +317,7 @@ class Interval:
288
317
 
289
318
  # Check for BUY signal
290
319
  buy_conditions = (
320
+ (self.settings.BOS_STUDY and self.bos_signal == "BUY") or
291
321
  (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "BUY") or
292
322
  (self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "BUY") or
293
323
  (self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "BUY") or
@@ -301,6 +331,7 @@ class Interval:
301
331
 
302
332
  # Check for SELL signal
303
333
  sell_conditions = (
334
+ (self.settings.BOS_STUDY and self.bos_signal == "SELL") or
304
335
  (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "SELL") or
305
336
  (self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "SELL") or
306
337
  (self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "SELL") or
@@ -320,17 +351,34 @@ class Interval:
320
351
  else:
321
352
  self.current_signal = "HOLD"
322
353
  else:
323
- # If EMA is enabled and crossing and MACD is enabled and crossing and BBM is enabled and crossing and RSI is enbabled and crossing
324
- # and
325
- # ADX is enabled and strong and candle trend is enabled and bullish
326
- # then BUY or SELL
327
354
  buy_conditions = (
328
- (not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN or self.ema_open_signal == "BUY") and
329
- (not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN or self.macd_signal == "BUY") and
330
- (not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN or self.bbm_signal == "BUY") and
331
- (not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN or self.rsi_signal == "BUY") and
332
- (not self.settings.TRENDLINE_STUDY or not self.settings.TRENDLINE_CHECK_ON_OPEN or self.trendline_signal == "BUY")
355
+ (self.settings.BOS_STUDY and self.bos_signal == "BUY")
356
+ or not self.settings.BOS_STUDY
357
+ ) and (
358
+ (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "BUY")
359
+ or not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN
360
+ ) and (
361
+ (self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "BUY")
362
+ or not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN
363
+ ) and (
364
+ (self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "BUY")
365
+ or not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN
366
+ ) and (
367
+ (self.settings.RSI_STUDY and self.settings.RSI_CHECK_ON_OPEN and self.rsi_signal == "BUY")
368
+ or not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN
369
+ ) and (
370
+ (self.settings.TRENDLINE_STUDY and self.settings.TRENDLINE_CHECK_ON_OPEN and self.trendline_signal == "BUY")
371
+ or not self.settings.TRENDLINE_STUDY or not self.settings.TRENDLINE_CHECK_ON_OPEN
333
372
  )
373
+ if not any([
374
+ self.settings.EMA_STUDY, self.settings.MACD_STUDY, self.settings.BBM_STUDY,
375
+ self.settings.RSI_STUDY, self.settings.TRENDLINE_STUDY
376
+ ]) and not any([
377
+ self.settings.EMA_CHECK_ON_OPEN, self.settings.MACD_CHECK_ON_OPEN, self.settings.BBM_CHECK_ON_OPEN,
378
+ self.settings.RSI_CHECK_ON_OPEN, self.settings.TRENDLINE_CHECK_ON_OPEN
379
+ ]):
380
+ buy_conditions = False
381
+
334
382
  additional_buy_conditions = (
335
383
  (not self.settings.ADX_STUDY or not self.settings.ADX_CHECK_ON_OPEN or self.adx_signal == "STRONG") and
336
384
  (not self.settings.CANDLE_TREND_STUDY or not self.settings.CANDLE_TREND_CHECK_ON_OPEN or self.candle_trend == "BULLISH")
@@ -338,15 +386,36 @@ class Interval:
338
386
 
339
387
  # Check for SELL signal
340
388
  sell_conditions = (
341
- (not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN or self.ema_open_signal == "SELL") and
342
- (not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN or self.macd_signal == "SELL") and
343
- (not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN or self.bbm_signal == "SELL") and
344
- (not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN or self.rsi_signal == "SELL") and
345
- (not self.settings.TRENDLINE_STUDY or not self.settings.TRENDLINE_CHECK_ON_OPEN or self.trendline_signal == "SELL")
389
+ (self.settings.BOS_STUDY and self.bos_signal == "SELL")
390
+ or not self.settings.BOS_STUDY
391
+ ) and (
392
+ (self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "SELL")
393
+ or not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN
394
+ ) and (
395
+ (self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "SELL")
396
+ or not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN
397
+ ) and (
398
+ (self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "SELL")
399
+ or not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN
400
+ ) and (
401
+ (self.settings.RSI_STUDY and self.settings.RSI_CHECK_ON_OPEN and self.rsi_signal == "SELL")
402
+ or not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN
403
+ ) and (
404
+ (self.settings.TRENDLINE_STUDY and self.settings.TRENDLINE_CHECK_ON_OPEN and self.trendline_signal == "SELL")
405
+ or not self.settings.TRENDLINE_STUDY or not self.settings.TRENDLINE_CHECK_ON_OPEN
346
406
  )
407
+ if not any([
408
+ self.settings.EMA_STUDY, self.settings.MACD_STUDY, self.settings.BBM_STUDY,
409
+ self.settings.RSI_STUDY, self.settings.TRENDLINE_STUDY
410
+ ]) and not any([
411
+ self.settings.EMA_CHECK_ON_OPEN, self.settings.MACD_CHECK_ON_OPEN, self.settings.BBM_CHECK_ON_OPEN,
412
+ self.settings.RSI_CHECK_ON_OPEN, self.settings.TRENDLINE_CHECK_ON_OPEN
413
+ ]):
414
+ sell_conditions = False
415
+
347
416
  additional_sell_conditions = (
348
- (not self.settings.ADX_STUDY or not self.settings.ADX_CHECK_ON_OPEN or self.adx_signal == "STRONG") and
349
- (not self.settings.CANDLE_TREND_STUDY or not self.settings.CANDLE_TREND_CHECK_ON_OPEN or self.candle_trend == "BEARISH")
417
+ (self.settings.ADX_STUDY and self.settings.ADX_CHECK_ON_OPEN and self.adx_signal == "STRONG") or
418
+ (self.settings.CANDLE_TREND_STUDY and self.settings.CANDLE_TREND_CHECK_ON_OPEN or self.candle_trend == "BEARISH")
350
419
  )
351
420
 
352
421
  # Determine current signal
@@ -623,6 +692,7 @@ class Tickers:
623
692
  if not interval._data is None and len(interval._data) >= self.settings.BARS:
624
693
  args[0].get_interval_ticks(intervalId)._data = interval._data
625
694
  args[0].get_interval_ticks(intervalId).current_signal = interval.current_signal
695
+ args[0].get_interval_ticks(intervalId).bos_signal = interval.bos_signal
626
696
  args[0].get_interval_ticks(intervalId).ema_open_signal = interval.ema_open_signal
627
697
  args[0].get_interval_ticks(intervalId).ema_close_signal = interval.ema_close_signal
628
698
  args[0].get_interval_ticks(intervalId).macd_signal = interval.macd_signal
@@ -660,6 +730,8 @@ class Tickers:
660
730
  f"{period}_trend": intervalObj.current_signal,
661
731
  f"{period}_cb": intervalObj.signal_strength,
662
732
  f"{period}_barcolor": lastcandle['barcolor'],
733
+ f"{period}_bos": intervalObj.bos_signal,
734
+ f"{period}_ema_open": intervalObj.ema_open_signal,
663
735
  f"{period}_ema_open": intervalObj.ema_open_signal,
664
736
  f"{period}_ema_close": intervalObj.ema_close_signal,
665
737
  f"{period}_macd":intervalObj.macd_signal,
@@ -687,6 +759,7 @@ class Tickers:
687
759
  'lastcolor': "", 'bidcolor': "", 'askcolor': "", 'bid': 0.0, 'ask': 0.0, 'last': 0.0,
688
760
  f"{period}_cb":0, f"{period}_barcolor": "", f"{period}_trend": "",
689
761
  f"{period}_open": 0.0, f"{period}_close": 0.0, f"{period}_high": 0.0, f"{period}_low": 0.0,
762
+ f"{period}_bos": "",
690
763
  f"{period}_ema": "", f"{period}_macd": "", f"{period}_bbm": "", f"{period}_rsi": "", f"{period}_trendline": "", f"{period}_candle_trend": "", f"{period}_adx": ""
691
764
  }
692
765
  df.fillna(fill_values, inplace=True)
@@ -6,11 +6,14 @@ import sqlite3
6
6
  class Settings(BaseSettings):
7
7
  # Start autotrading on start
8
8
  AUTOTRADE: bool = Field(default=False)
9
+
10
+ #Ticker list
11
+ TICKERS:str = Field(default="")
12
+ THRESHOLD: float = Field(default=5.0, ge=0.0)
13
+ MIN_VOLUME: int = Field(default=10_000_000, ge=0)
9
14
 
10
15
  # Trading Parameters
11
16
  LEVERAGE: int = Field(default=20, ge=1, le=100)
12
- THRESHOLD: float = Field(default=5.0, ge=0.0)
13
- MIN_VOLUME: int = Field(default=10_000_000, ge=0)
14
17
  ORDER_AMOUNT_PERCENTAGE: float = Field(default=0.01, ge=0.0, le=100)
15
18
  MAX_AUTO_TRADES: int = Field(default=10, ge=0)
16
19
  PROFIT_AMOUNT: float = Field(default=0.25, ge=0.0)
@@ -19,6 +22,7 @@ class Settings(BaseSettings):
19
22
  BARS: int = Field(default=100, ge=1)
20
23
 
21
24
  # Technical Indicators Parameters
25
+ BOS_PERIOD: int = Field(default=20, ge=1)
22
26
  MA_FAST: int = Field(default=10, ge=1)
23
27
  MA_MEDIUM: int = Field(default=20, ge=1)
24
28
  MA_SLOW: int = Field(default=50, ge=1)
@@ -34,6 +38,7 @@ class Settings(BaseSettings):
34
38
  # Technical Indicators
35
39
  OPEN_ON_ANY_SIGNAL: bool = Field(default=True)
36
40
 
41
+ BOS_STUDY: bool = Field(default=True)
37
42
  EMA_CHART: bool = Field(default=True)
38
43
  EMA_STUDY: bool = Field(default=True)
39
44
  EMA_CROSSING: bool = Field(default=False)
@@ -59,10 +64,10 @@ class Settings(BaseSettings):
59
64
  RSI_CHECK_ON_OPEN: bool = Field(default=False)
60
65
  RSI_CHECK_ON_CLOSE: bool = Field(default=False)
61
66
 
67
+ TRENDLINE_PEAK_DISTANCE: int = Field(default=1, ge=0, le=30)
62
68
  TRENDLINE_CHART: bool = Field(default=True)
63
69
  TRENDLINE_STUDY: bool = Field(default=True)
64
- TRENDLINE_PEAK_DISTANCE: int = Field(default=1, ge=0, le=30)
65
- TRENDLINE_LOOKBACK: int = Field(default=20, ge=10, le=200)
70
+ TRENDLINE_BREAKOUT: bool = Field(default=False)
66
71
  TRENDLINE_CHECK_ON_OPEN: bool = Field(default=False)
67
72
  TRENDLINE_CHECK_ON_CLOSE: bool = Field(default=False)
68
73
 
@@ -72,7 +77,7 @@ class Settings(BaseSettings):
72
77
 
73
78
  CANDLE_TREND_STUDY: bool = Field(default=True)
74
79
  CANDLE_TREND_CHECK_ON_OPEN: bool = Field(default=False)
75
- CANDLE_TREND_CHECK_ON_CLOSE: bool = Field(default=False)
80
+ CANDLE_TREND_REVERSAL_CHECK_ON_CLOSE: bool = Field(default=False)
76
81
 
77
82
  # Time Intervals
78
83
  SCREEN_REFRESH_INTERVAL: int = Field(default=1, ge=1)
@@ -101,6 +106,7 @@ class Settings(BaseSettings):
101
106
  # Specify the file name for loading environment variables
102
107
  env_file = os.path.dirname(os.path.abspath(__file__))+"/config.txt"
103
108
 
109
+
104
110
  @classmethod
105
111
  def load_from_db(cls, db_path: str, table_name: str = "settings"):
106
112
  # Connect to SQLite database
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: bitunix_automated_crypto_trading
3
- Version: 3.1.5
3
+ Version: 3.1.7
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.1.5",
69
+ version="3.1.7",
70
70
  license="MIT",
71
71
  author="tcj2001",
72
72
  author_email="thomsonmathews@hotmail.com",