Skip to content

Commit 102cc87

Browse files
authored
Merge pull request freqtrade#12059 from freqtrade/feat/bitget
Add bitget base support
2 parents c93c97c + f2fb1b7 commit 102cc87

File tree

5 files changed

+108
-0
lines changed

5 files changed

+108
-0
lines changed

docs/exchanges.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,22 @@ It's therefore required to pass the UID as well.
328328
!!! Warning "Necessary Verification"
329329
Bitmart requires Verification Lvl2 to successfully trade on the spot market through the API - even though trading via UI works just fine with just Lvl1 verification.
330330

331+
## Bitget
332+
333+
Bitget requires a passphrase for each api key, you will therefore need to add this key into the configuration so your exchange section looks as follows:
334+
335+
```json
336+
"exchange": {
337+
"name": "bitget",
338+
"key": "your_exchange_key",
339+
"secret": "your_exchange_secret",
340+
"password": "your_exchange_api_key_password",
341+
// ...
342+
}
343+
```
344+
345+
Bitget supports [time_in_force](configuration.md#understand-order_time_in_force).
346+
331347
## Hyperliquid
332348

333349
!!! Tip "Stoploss on Exchange"

freqtrade/exchange/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
# isort: on
77
from freqtrade.exchange.binance import Binance
88
from freqtrade.exchange.bingx import Bingx
9+
from freqtrade.exchange.bitget import Bitget
910
from freqtrade.exchange.bitmart import Bitmart
1011
from freqtrade.exchange.bitpanda import Bitpanda
1112
from freqtrade.exchange.bitvavo import Bitvavo

freqtrade/exchange/bitget.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import logging
2+
from datetime import timedelta
3+
4+
from freqtrade.enums import CandleType
5+
from freqtrade.exchange import Exchange
6+
from freqtrade.exchange.exchange_types import FtHas
7+
from freqtrade.util.datetime_helpers import dt_now, dt_ts
8+
9+
10+
logger = logging.getLogger(__name__)
11+
12+
13+
class Bitget(Exchange):
14+
"""
15+
Bitget exchange class. Contains adjustments needed for Freqtrade to work
16+
with this exchange.
17+
18+
Please note that this exchange is not included in the list of exchanges
19+
officially supported by the Freqtrade development team. So some features
20+
may still not work as expected.
21+
"""
22+
23+
_ft_has: FtHas = {
24+
"ohlcv_candle_limit": 200, # 200 for historical candles, 1000 for recent ones.
25+
"order_time_in_force": ["GTC", "FOK", "IOC", "PO"],
26+
}
27+
_ft_has_futures: FtHas = {
28+
"mark_ohlcv_timeframe": "4h",
29+
}
30+
31+
def ohlcv_candle_limit(
32+
self, timeframe: str, candle_type: CandleType, since_ms: int | None = None
33+
) -> int:
34+
"""
35+
Exchange ohlcv candle limit
36+
bitget has the following behaviour:
37+
* 1000 candles for up-to-date data
38+
* 200 candles for historic data (prior to a certain date)
39+
:param timeframe: Timeframe to check
40+
:param candle_type: Candle-type
41+
:param since_ms: Starting timestamp
42+
:return: Candle limit as integer
43+
"""
44+
timeframe_map = self._api.options["fetchOHLCV"]["maxRecentDaysPerTimeframe"]
45+
days = timeframe_map.get(timeframe, 30)
46+
47+
if candle_type in (CandleType.FUTURES, CandleType.SPOT) and (
48+
not since_ms or dt_ts(dt_now() - timedelta(days=days)) < since_ms
49+
):
50+
return 1000
51+
52+
return super().ohlcv_candle_limit(timeframe, candle_type, since_ms)

tests/exchange_online/conftest.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,13 @@
408408
"candle_count": 200,
409409
"orderbook_max_entries": 50,
410410
},
411+
"bitget": {
412+
"pair": "BTC/USDT",
413+
"stake_currency": "USDT",
414+
"hasQuoteVolume": True,
415+
"timeframe": "1h",
416+
"candle_count": 1000,
417+
},
411418
"htx": {
412419
"pair": "ETH/BTC",
413420
"stake_currency": "BTC",

tests/exchange_online/test_ccxt_compat.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,3 +521,35 @@ def test_private_method_presence(self, exchange: EXCHANGE_FIXTURE_TYPE):
521521
exch, exchangename = exchange
522522
for method in EXCHANGES[exchangename].get("private_methods", []):
523523
assert hasattr(exch._api, method)
524+
525+
def test_ccxt_bitget_ohlcv_candle_limit(self, exchange: EXCHANGE_FIXTURE_TYPE):
526+
exch, exchangename = exchange
527+
if exchangename != "bitget":
528+
pytest.skip("This test is only for the Bitget exchange")
529+
530+
timeframes = ("1m", "5m", "1h")
531+
532+
for timeframe in timeframes:
533+
assert exch.ohlcv_candle_limit(timeframe, CandleType.SPOT) == 1000
534+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUTURES) == 1000
535+
assert exch.ohlcv_candle_limit(timeframe, CandleType.MARK) == 200
536+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUNDING_RATE) == 200
537+
538+
start_time = dt_ts(dt_now() - timedelta(days=17))
539+
assert exch.ohlcv_candle_limit(timeframe, CandleType.SPOT, start_time) == 1000
540+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUTURES, start_time) == 1000
541+
assert exch.ohlcv_candle_limit(timeframe, CandleType.MARK, start_time) == 200
542+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUNDING_RATE, start_time) == 200
543+
start_time = dt_ts(dt_now() - timedelta(days=48))
544+
length = 200 if timeframe in ("1m", "5m") else 1000
545+
assert exch.ohlcv_candle_limit(timeframe, CandleType.SPOT, start_time) == length
546+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUTURES, start_time) == length
547+
assert exch.ohlcv_candle_limit(timeframe, CandleType.MARK, start_time) == 200
548+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUNDING_RATE, start_time) == 200
549+
550+
start_time = dt_ts(dt_now() - timedelta(days=61))
551+
length = 200
552+
assert exch.ohlcv_candle_limit(timeframe, CandleType.SPOT, start_time) == length
553+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUTURES, start_time) == length
554+
assert exch.ohlcv_candle_limit(timeframe, CandleType.MARK, start_time) == 200
555+
assert exch.ohlcv_candle_limit(timeframe, CandleType.FUNDING_RATE, start_time) == 200

0 commit comments

Comments
 (0)