bitunix-automated-crypto-trading 3.1.5__tar.gz → 3.1.6__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.
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/PKG-INFO +1 -1
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/README.md +6 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/BitunixSignal.py +30 -20
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/TickerManager.py +95 -25
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/config.py +10 -5
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading.egg-info/PKG-INFO +1 -1
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/setup.py +1 -1
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/AsyncThreadRunner.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/BitunixApi.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/BitunixWebSocket.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/DataFrameHtmlRenderer.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/NotificationManager.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/SupportResistance.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/ThreadManager.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/__init__.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/bitunix.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading/logger.py +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading.egg-info/SOURCES.txt +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading.egg-info/dependency_links.txt +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading.egg-info/entry_points.txt +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading.egg-info/requires.txt +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/bitunix_automated_crypto_trading.egg-info/top_level.txt +0 -0
- {bitunix_automated_crypto_trading-3.1.5 → bitunix_automated_crypto_trading-3.1.6}/setup.cfg +0 -0
@@ -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
|
@@ -72,6 +74,7 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
|
|
72
74
|
- `ADX_PERIOD`: ADX period
|
73
75
|
|
74
76
|
- `Study Parameters`:
|
77
|
+
- `BOS_STUDY`: Enable Break Of Structure study
|
75
78
|
- `EMA_STUDY`: Enable EMA study
|
76
79
|
- `EMA_CHART`: Display EMA chart
|
77
80
|
- `EMA_STUDY`: Enable EMA study
|
@@ -98,9 +101,11 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
|
|
98
101
|
- `RSI_CHECK_ON_OPEN`: Check RSI on open
|
99
102
|
- `RSI_CHECK_ON_CLOSE`: Check RSI on close
|
100
103
|
|
104
|
+
- `TRENDLINE_PEAK_DISTANCE` : distance between peaks or troughs
|
101
105
|
- `TRENDLINE_STUDY`: Enable Trendline support and resistance study
|
102
106
|
- `TRENDLINE_CHART`: Display Trendline chart
|
103
107
|
- `TRENDLINE_LOOKBACK`: Lookback period for trendline study
|
108
|
+
- `TRENDLINE_BREAKOUT`: Check if breakout from support or resistance line
|
104
109
|
- `TRENDLINE_CHECK_ON_OPEN`: Check Trendline support and resistance on open
|
105
110
|
- `TRENDLINE_CHECK_ON_CLOSE`: Check Trendline support and resistance on close
|
106
111
|
|
@@ -155,6 +160,7 @@ The platform can be configured through the `config.py` file or `config.txt`. Key
|
|
155
160
|
- Max auto trades
|
156
161
|
- Take Profit amount
|
157
162
|
- Accept Loss amount
|
163
|
+
- BOS study is basically when the price breakout from the previous high or low
|
158
164
|
- 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
165
|
- You can control the trading strategy using the CalculateStudy function in TickerManager.py and AutoTradeProcess function in BitunixSignal.py
|
160
166
|
- 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
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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",
|
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",
|
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.
|
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'] == "
|
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
|
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
|
-
|
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,20 @@ 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
|
+
high = df.iloc[:-1]['high'].max()
|
69
|
+
low = df.iloc[:-1]['low'].min()
|
70
|
+
close = df['close'].iloc[-1]
|
71
|
+
if close > high:
|
72
|
+
self.bos_signal = "BUY"
|
73
|
+
elif close < low:
|
74
|
+
self.bos_signal = "SELL"
|
75
|
+
else:
|
76
|
+
self.bos_signal = "HOLD"
|
77
|
+
else:
|
78
|
+
self.bos_signal = "HOLD"
|
79
|
+
|
66
80
|
# Calculate the Moving Averages
|
67
81
|
if self.settings.EMA_STUDY:
|
68
82
|
df['ma_fast'] = talib.EMA(df['close'], timeperiod=self.settings.MA_FAST)
|
@@ -116,6 +130,14 @@ class Interval:
|
|
116
130
|
else:
|
117
131
|
self.ema_open_signal = "HOLD"
|
118
132
|
self.ema_close_signal = "HOLD"
|
133
|
+
|
134
|
+
if self.settings.EMA_CLOSE_ON_FAST_MEDIUM:
|
135
|
+
if df['close'].iloc[-1] > df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] > df['ma_medium'].iloc[-1]:
|
136
|
+
self.ema_close_signal = "BUY"
|
137
|
+
elif df['close'].iloc[-1] < df['ma_fast'].iloc[-1] and df['ma_fast'].iloc[-1] < df['ma_medium'].iloc[-1]:
|
138
|
+
self.ema_close_signal = "SELL"
|
139
|
+
else:
|
140
|
+
self.ema_close_signal = "HOLD"
|
119
141
|
else:
|
120
142
|
# Drop EMA columns if not used
|
121
143
|
df.drop(['ma_fast', 'ma_medium', 'ma_slow', 'ma_slope', 'ma_angle'], axis=1, inplace=True, errors='ignore')
|
@@ -233,16 +255,20 @@ class Interval:
|
|
233
255
|
df.fillna({'support_line':0}, inplace=True)
|
234
256
|
df.fillna({'resistance_line':0}, inplace=True)
|
235
257
|
if df is not None and len(df) >= 2:
|
236
|
-
if
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
self.trendline_signal = "SELL"
|
258
|
+
if self.settings.TRENDLINE_BREAKOUT:
|
259
|
+
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]:
|
260
|
+
self.trendline_signal = "BUY"
|
261
|
+
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]:
|
262
|
+
self.trendline_signal = "SELL"
|
263
|
+
else:
|
264
|
+
self.trendline_signal = "HOLD"
|
244
265
|
else:
|
245
|
-
|
266
|
+
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]:
|
267
|
+
self.trendline_signal = "SELL"
|
268
|
+
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]:
|
269
|
+
self.trendline_signal = "BUY"
|
270
|
+
else:
|
271
|
+
self.trendline_signal = "HOLD"
|
246
272
|
|
247
273
|
# Calculate the ADX
|
248
274
|
if self.settings.ADX_STUDY:
|
@@ -288,6 +314,7 @@ class Interval:
|
|
288
314
|
|
289
315
|
# Check for BUY signal
|
290
316
|
buy_conditions = (
|
317
|
+
(self.settings.BOS_STUDY and self.bos_signal == "BUY") or
|
291
318
|
(self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "BUY") or
|
292
319
|
(self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "BUY") or
|
293
320
|
(self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "BUY") or
|
@@ -301,6 +328,7 @@ class Interval:
|
|
301
328
|
|
302
329
|
# Check for SELL signal
|
303
330
|
sell_conditions = (
|
331
|
+
(self.settings.BOS_STUDY and self.bos_signal == "SELL") or
|
304
332
|
(self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "SELL") or
|
305
333
|
(self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "SELL") or
|
306
334
|
(self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "SELL") or
|
@@ -320,17 +348,34 @@ class Interval:
|
|
320
348
|
else:
|
321
349
|
self.current_signal = "HOLD"
|
322
350
|
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
351
|
buy_conditions = (
|
328
|
-
(
|
329
|
-
|
330
|
-
|
331
|
-
(
|
332
|
-
|
352
|
+
(self.settings.BOS_STUDY and self.bos_signal == "BUY")
|
353
|
+
or not self.settings.BOS_STUDY
|
354
|
+
) and (
|
355
|
+
(self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "BUY")
|
356
|
+
or not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN
|
357
|
+
) and (
|
358
|
+
(self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "BUY")
|
359
|
+
or not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN
|
360
|
+
) and (
|
361
|
+
(self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "BUY")
|
362
|
+
or not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN
|
363
|
+
) and (
|
364
|
+
(self.settings.RSI_STUDY and self.settings.RSI_CHECK_ON_OPEN and self.rsi_signal == "BUY")
|
365
|
+
or not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN
|
366
|
+
) and (
|
367
|
+
(self.settings.TRENDLINE_STUDY and self.settings.TRENDLINE_CHECK_ON_OPEN and self.trendline_signal == "BUY")
|
368
|
+
or not self.settings.TRENDLINE_STUDY or not self.settings.TRENDLINE_CHECK_ON_OPEN
|
333
369
|
)
|
370
|
+
if not any([
|
371
|
+
self.settings.EMA_STUDY, self.settings.MACD_STUDY, self.settings.BBM_STUDY,
|
372
|
+
self.settings.RSI_STUDY, self.settings.TRENDLINE_STUDY
|
373
|
+
]) and not any([
|
374
|
+
self.settings.EMA_CHECK_ON_OPEN, self.settings.MACD_CHECK_ON_OPEN, self.settings.BBM_CHECK_ON_OPEN,
|
375
|
+
self.settings.RSI_CHECK_ON_OPEN, self.settings.TRENDLINE_CHECK_ON_OPEN
|
376
|
+
]):
|
377
|
+
buy_conditions = False
|
378
|
+
|
334
379
|
additional_buy_conditions = (
|
335
380
|
(not self.settings.ADX_STUDY or not self.settings.ADX_CHECK_ON_OPEN or self.adx_signal == "STRONG") and
|
336
381
|
(not self.settings.CANDLE_TREND_STUDY or not self.settings.CANDLE_TREND_CHECK_ON_OPEN or self.candle_trend == "BULLISH")
|
@@ -338,15 +383,36 @@ class Interval:
|
|
338
383
|
|
339
384
|
# Check for SELL signal
|
340
385
|
sell_conditions = (
|
341
|
-
(
|
342
|
-
|
343
|
-
|
344
|
-
(
|
345
|
-
|
386
|
+
(self.settings.BOS_STUDY and self.bos_signal == "SELL")
|
387
|
+
or not self.settings.BOS_STUDY
|
388
|
+
) and (
|
389
|
+
(self.settings.EMA_STUDY and self.settings.EMA_CHECK_ON_OPEN and self.ema_open_signal == "SELL")
|
390
|
+
or not self.settings.EMA_STUDY or not self.settings.EMA_CHECK_ON_OPEN
|
391
|
+
) and (
|
392
|
+
(self.settings.MACD_STUDY and self.settings.MACD_CHECK_ON_OPEN and self.macd_signal == "SELL")
|
393
|
+
or not self.settings.MACD_STUDY or not self.settings.MACD_CHECK_ON_OPEN
|
394
|
+
) and (
|
395
|
+
(self.settings.BBM_STUDY and self.settings.BBM_CHECK_ON_OPEN and self.bbm_signal == "SELL")
|
396
|
+
or not self.settings.BBM_STUDY or not self.settings.BBM_CHECK_ON_OPEN
|
397
|
+
) and (
|
398
|
+
(self.settings.RSI_STUDY and self.settings.RSI_CHECK_ON_OPEN and self.rsi_signal == "SELL")
|
399
|
+
or not self.settings.RSI_STUDY or not self.settings.RSI_CHECK_ON_OPEN
|
400
|
+
) and (
|
401
|
+
(self.settings.TRENDLINE_STUDY and self.settings.TRENDLINE_CHECK_ON_OPEN and self.trendline_signal == "SELL")
|
402
|
+
or not self.settings.TRENDLINE_STUDY or not self.settings.TRENDLINE_CHECK_ON_OPEN
|
346
403
|
)
|
404
|
+
if not any([
|
405
|
+
self.settings.EMA_STUDY, self.settings.MACD_STUDY, self.settings.BBM_STUDY,
|
406
|
+
self.settings.RSI_STUDY, self.settings.TRENDLINE_STUDY
|
407
|
+
]) and not any([
|
408
|
+
self.settings.EMA_CHECK_ON_OPEN, self.settings.MACD_CHECK_ON_OPEN, self.settings.BBM_CHECK_ON_OPEN,
|
409
|
+
self.settings.RSI_CHECK_ON_OPEN, self.settings.TRENDLINE_CHECK_ON_OPEN
|
410
|
+
]):
|
411
|
+
sell_conditions = False
|
412
|
+
|
347
413
|
additional_sell_conditions = (
|
348
|
-
(
|
349
|
-
(
|
414
|
+
(self.settings.ADX_STUDY and self.settings.ADX_CHECK_ON_OPEN and self.adx_signal == "STRONG") or
|
415
|
+
(self.settings.CANDLE_TREND_STUDY and self.settings.CANDLE_TREND_CHECK_ON_OPEN or self.candle_trend == "BEARISH")
|
350
416
|
)
|
351
417
|
|
352
418
|
# Determine current signal
|
@@ -623,6 +689,7 @@ class Tickers:
|
|
623
689
|
if not interval._data is None and len(interval._data) >= self.settings.BARS:
|
624
690
|
args[0].get_interval_ticks(intervalId)._data = interval._data
|
625
691
|
args[0].get_interval_ticks(intervalId).current_signal = interval.current_signal
|
692
|
+
args[0].get_interval_ticks(intervalId).bos_signal = interval.bos_signal
|
626
693
|
args[0].get_interval_ticks(intervalId).ema_open_signal = interval.ema_open_signal
|
627
694
|
args[0].get_interval_ticks(intervalId).ema_close_signal = interval.ema_close_signal
|
628
695
|
args[0].get_interval_ticks(intervalId).macd_signal = interval.macd_signal
|
@@ -660,6 +727,8 @@ class Tickers:
|
|
660
727
|
f"{period}_trend": intervalObj.current_signal,
|
661
728
|
f"{period}_cb": intervalObj.signal_strength,
|
662
729
|
f"{period}_barcolor": lastcandle['barcolor'],
|
730
|
+
f"{period}_bos": intervalObj.bos_signal,
|
731
|
+
f"{period}_ema_open": intervalObj.ema_open_signal,
|
663
732
|
f"{period}_ema_open": intervalObj.ema_open_signal,
|
664
733
|
f"{period}_ema_close": intervalObj.ema_close_signal,
|
665
734
|
f"{period}_macd":intervalObj.macd_signal,
|
@@ -687,6 +756,7 @@ class Tickers:
|
|
687
756
|
'lastcolor': "", 'bidcolor': "", 'askcolor': "", 'bid': 0.0, 'ask': 0.0, 'last': 0.0,
|
688
757
|
f"{period}_cb":0, f"{period}_barcolor": "", f"{period}_trend": "",
|
689
758
|
f"{period}_open": 0.0, f"{period}_close": 0.0, f"{period}_high": 0.0, f"{period}_low": 0.0,
|
759
|
+
f"{period}_bos": "",
|
690
760
|
f"{period}_ema": "", f"{period}_macd": "", f"{period}_bbm": "", f"{period}_rsi": "", f"{period}_trendline": "", f"{period}_candle_trend": "", f"{period}_adx": ""
|
691
761
|
}
|
692
762
|
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)
|
@@ -34,6 +37,7 @@ class Settings(BaseSettings):
|
|
34
37
|
# Technical Indicators
|
35
38
|
OPEN_ON_ANY_SIGNAL: bool = Field(default=True)
|
36
39
|
|
40
|
+
BOS_STUDY: bool = Field(default=True)
|
37
41
|
EMA_CHART: bool = Field(default=True)
|
38
42
|
EMA_STUDY: bool = Field(default=True)
|
39
43
|
EMA_CROSSING: bool = Field(default=False)
|
@@ -59,10 +63,10 @@ class Settings(BaseSettings):
|
|
59
63
|
RSI_CHECK_ON_OPEN: bool = Field(default=False)
|
60
64
|
RSI_CHECK_ON_CLOSE: bool = Field(default=False)
|
61
65
|
|
66
|
+
TRENDLINE_PEAK_DISTANCE: int = Field(default=1, ge=0, le=30)
|
62
67
|
TRENDLINE_CHART: bool = Field(default=True)
|
63
68
|
TRENDLINE_STUDY: bool = Field(default=True)
|
64
|
-
|
65
|
-
TRENDLINE_LOOKBACK: int = Field(default=20, ge=10, le=200)
|
69
|
+
TRENDLINE_BREAKOUT: bool = Field(default=False)
|
66
70
|
TRENDLINE_CHECK_ON_OPEN: bool = Field(default=False)
|
67
71
|
TRENDLINE_CHECK_ON_CLOSE: bool = Field(default=False)
|
68
72
|
|
@@ -72,7 +76,7 @@ class Settings(BaseSettings):
|
|
72
76
|
|
73
77
|
CANDLE_TREND_STUDY: bool = Field(default=True)
|
74
78
|
CANDLE_TREND_CHECK_ON_OPEN: bool = Field(default=False)
|
75
|
-
|
79
|
+
CANDLE_TREND_REVERSAL_CHECK_ON_CLOSE: bool = Field(default=False)
|
76
80
|
|
77
81
|
# Time Intervals
|
78
82
|
SCREEN_REFRESH_INTERVAL: int = Field(default=1, ge=1)
|
@@ -101,6 +105,7 @@ class Settings(BaseSettings):
|
|
101
105
|
# Specify the file name for loading environment variables
|
102
106
|
env_file = os.path.dirname(os.path.abspath(__file__))+"/config.txt"
|
103
107
|
|
108
|
+
|
104
109
|
@classmethod
|
105
110
|
def load_from_db(cls, db_path: str, table_name: str = "settings"):
|
106
111
|
# Connect to SQLite database
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|