diff --git a/README.md b/README.md index 4ed144f93..c00d2c999 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ hesitate to read the source code and understand the mechanism of this bot. Please read the [exchange specific notes](docs/exchanges.md) to learn about eventual, special configurations needed for each exchange. - [X] [Binance](https://www.binance.com/) +- [X] [Bitmart](https://bitmart.com/) - [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Huobi](http://huobi.com/) - [X] [Kraken](https://kraken.com/) diff --git a/docs/exchanges.md b/docs/exchanges.md index 237125e88..ac3957b07 100644 --- a/docs/exchanges.md +++ b/docs/exchanges.md @@ -302,6 +302,24 @@ We do strongly recommend to limit all API keys to the IP you're going to use it Bybit (futures only) supports `stoploss_on_exchange` and uses `stop-loss-limit` orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange. On futures, Bybit supports both `stop-limit` as well as `stop-market` orders. You can use either `"limit"` or `"market"` in the `order_types.stoploss` configuration setting to decide which type to use. +## Bitmart + +Bitmart requires the API key Memo (the name you give the API key) to go along with the exchange key and secret. +It's therefore required to pass the UID as well. + +```json +"exchange": { + "name": "bitmart", + "uid": "your_bitmart_api_key_memo", + "secret": "your_exchange_secret", + "password": "your_exchange_api_key_password", + // ... +} +``` + +!!! Warning "Necessary Verification" + 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. + ## All exchanges Should you experience constant errors with Nonce (like `InvalidNonce`), it is best to regenerate the API keys. Resetting Nonce is difficult and it's usually easier to regenerate the API keys. diff --git a/docs/index.md b/docs/index.md index dd80db958..1df5424de 100644 --- a/docs/index.md +++ b/docs/index.md @@ -40,6 +40,7 @@ Freqtrade is a free and open source crypto trading bot written in Python. It is Please read the [exchange specific notes](exchanges.md) to learn about eventual, special configurations needed for each exchange. - [X] [Binance](https://www.binance.com/) +- [X] [Bitmart](https://bitmart.com/) - [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Huobi](http://huobi.com/) - [X] [Kraken](https://kraken.com/) diff --git a/freqtrade/exchange/__init__.py b/freqtrade/exchange/__init__.py index 9ac31a0d8..8de9120dc 100644 --- a/freqtrade/exchange/__init__.py +++ b/freqtrade/exchange/__init__.py @@ -4,6 +4,7 @@ from freqtrade.exchange.common import remove_exchange_credentials, MAP_EXCHANGE_ from freqtrade.exchange.exchange import Exchange # isort: on from freqtrade.exchange.binance import Binance +from freqtrade.exchange.bitmart import Bitmart from freqtrade.exchange.bitpanda import Bitpanda from freqtrade.exchange.bittrex import Bittrex from freqtrade.exchange.bitvavo import Bitvavo diff --git a/freqtrade/exchange/bitmart.py b/freqtrade/exchange/bitmart.py new file mode 100644 index 000000000..5d792b153 --- /dev/null +++ b/freqtrade/exchange/bitmart.py @@ -0,0 +1,20 @@ +""" Bitmart exchange subclass """ +import logging +from typing import Dict + +from freqtrade.exchange import Exchange + + +logger = logging.getLogger(__name__) + + +class Bitmart(Exchange): + """ + Bitmart exchange class. Contains adjustments needed for Freqtrade to work + with this exchange. + """ + + _ft_has: Dict = { + "stoploss_on_exchange": False, # Bitmart API does not support stoploss orders + "ohlcv_candle_limit": 200, + } diff --git a/freqtrade/exchange/common.py b/freqtrade/exchange/common.py index 36bed9b20..ca986d2be 100644 --- a/freqtrade/exchange/common.py +++ b/freqtrade/exchange/common.py @@ -52,6 +52,7 @@ MAP_EXCHANGE_CHILDCLASS = { SUPPORTED_EXCHANGES = [ 'binance', + 'bitmart', 'gate', 'huobi', 'kraken', diff --git a/tests/exchange_online/conftest.py b/tests/exchange_online/conftest.py index c5f59ee0e..35c9a9d85 100644 --- a/tests/exchange_online/conftest.py +++ b/tests/exchange_online/conftest.py @@ -227,6 +227,7 @@ EXCHANGES = { 'timeframe': '1h', 'futures_pair': 'BTC/USDT:USDT', 'futures': True, + 'orderbook_max_entries': 50, 'leverage_tiers_public': True, 'leverage_in_spot_market': True, 'sample_order': [ @@ -247,6 +248,13 @@ EXCHANGES = { } ] }, + 'bitmart': { + 'pair': 'BTC/USDT', + 'stake_currency': 'USDT', + 'hasQuoteVolume': True, + 'timeframe': '1h', + 'orderbook_max_entries': 50, + }, 'huobi': { 'pair': 'ETH/BTC', 'stake_currency': 'BTC', diff --git a/tests/exchange_online/test_ccxt_compat.py b/tests/exchange_online/test_ccxt_compat.py index aa3dfdfae..b48d70de2 100644 --- a/tests/exchange_online/test_ccxt_compat.py +++ b/tests/exchange_online/test_ccxt_compat.py @@ -133,6 +133,7 @@ class TestCCXTExchange: exch, exchangename = exchange pair = EXCHANGES[exchangename]['pair'] l2 = exch.fetch_l2_order_book(pair) + orderbook_max_entries = EXCHANGES[exchangename].get('orderbook_max_entries') assert 'asks' in l2 assert 'bids' in l2 assert len(l2['asks']) >= 1 @@ -143,7 +144,7 @@ class TestCCXTExchange: # TODO: Gate is unstable here at the moment, ignoring the limit partially. return for val in [1, 2, 5, 25, 50, 100]: - if val > 50 and exchangename == 'bybit': + if orderbook_max_entries and val > orderbook_max_entries: continue l2 = exch.fetch_l2_order_book(pair, val) if not l2_limit_range or val in l2_limit_range: