Merge pull request #10249 from freqtrade/bingx

Add Support for Bingx
This commit is contained in:
Matthias
2024-05-26 19:36:51 +02:00
committed by GitHub
10 changed files with 67 additions and 5 deletions

View File

@@ -29,6 +29,7 @@ Please read the [exchange specific notes](docs/exchanges.md) to learn about even
- [X] [Binance](https://www.binance.com/) - [X] [Binance](https://www.binance.com/)
- [X] [Bitmart](https://bitmart.com/) - [X] [Bitmart](https://bitmart.com/)
- [X] [BingX](https://bingx.com/invite/0EM9RX)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [HTX](https://www.htx.com/) (Former Huobi) - [X] [HTX](https://www.htx.com/) (Former Huobi)
- [X] [Kraken](https://kraken.com/) - [X] [Kraken](https://kraken.com/)

View File

@@ -127,6 +127,13 @@ These settings will be checked on startup, and freqtrade will show an error if t
Freqtrade will not attempt to change these settings. Freqtrade will not attempt to change these settings.
## Bingx
BingX supports [time_in_force](configuration.md#understand-order_time_in_force) with settings "GTC" (good till cancelled), "IOC" (immediate-or-cancel) and "PO" (Post only) settings.
!!! Tip "Stoploss on Exchange"
Bingx supports `stoploss_on_exchange` and can use both stop-limit and stop-market orders. It provides great advantages, so we recommend to benefit from it by enabling stoploss on exchange.
## Kraken ## Kraken
Kraken supports [time_in_force](configuration.md#understand-order_time_in_force) with settings "GTC" (good till cancelled), "IOC" (immediate-or-cancel) and "PO" (Post only) settings. Kraken supports [time_in_force](configuration.md#understand-order_time_in_force) with settings "GTC" (good till cancelled), "IOC" (immediate-or-cancel) and "PO" (Post only) settings.

View File

@@ -41,6 +41,7 @@ Please read the [exchange specific notes](exchanges.md) to learn about eventual,
- [X] [Binance](https://www.binance.com/) - [X] [Binance](https://www.binance.com/)
- [X] [Bitmart](https://bitmart.com/) - [X] [Bitmart](https://bitmart.com/)
- [X] [BingX](https://bingx.com/invite/0EM9RX)
- [X] [Gate.io](https://www.gate.io/ref/6266643) - [X] [Gate.io](https://www.gate.io/ref/6266643)
- [X] [HTX](https://www.htx.com/) (Former Huobi) - [X] [HTX](https://www.htx.com/) (Former Huobi)
- [X] [Kraken](https://kraken.com/) - [X] [Kraken](https://kraken.com/)

View File

@@ -30,6 +30,7 @@ The Order-type will be ignored if only one mode is available.
|----------|-------------| |----------|-------------|
| Binance | limit | | Binance | limit |
| Binance Futures | market, limit | | Binance Futures | market, limit |
| Bingx | market, limit |
| HTX (former Huobi) | limit | | HTX (former Huobi) | limit |
| kraken | market, limit | | kraken | market, limit |
| Gate | limit | | Gate | limit |

View File

@@ -113,6 +113,7 @@ def ask_user_config() -> Dict[str, Any]:
"choices": [ "choices": [
"binance", "binance",
"binanceus", "binanceus",
"bingx",
"gate", "gate",
"htx", "htx",
"kraken", "kraken",
@@ -128,7 +129,7 @@ def ask_user_config() -> Dict[str, Any]:
"message": "Do you want to trade Perpetual Swaps (perpetual futures)?", "message": "Do you want to trade Perpetual Swaps (perpetual futures)?",
"default": False, "default": False,
"filter": lambda val: "futures" if val else "spot", "filter": lambda val: "futures" if val else "spot",
"when": lambda x: x["exchange_name"] in ["binance", "gate", "okx"], "when": lambda x: x["exchange_name"] in ["binance", "gate", "okx", "bybit"],
}, },
{ {
"type": "autocomplete", "type": "autocomplete",

View File

@@ -17,6 +17,7 @@ class Bingx(Exchange):
_ft_has: Dict = { _ft_has: Dict = {
"ohlcv_candle_limit": 1000, "ohlcv_candle_limit": 1000,
"stoploss_on_exchange": False, "stoploss_on_exchange": True,
"stoploss_order_types": {"limit": "limit", "market": "market"}, "stoploss_order_types": {"limit": "limit", "market": "market"},
"order_time_in_force": ["GTC", "IOC", "PO"],
} }

View File

@@ -53,6 +53,7 @@ MAP_EXCHANGE_CHILDCLASS = {
SUPPORTED_EXCHANGES = [ SUPPORTED_EXCHANGES = [
"binance", "binance",
"bingx",
"bitmart", "bitmart",
"gate", "gate",
"htx", "htx",

View File

@@ -2,7 +2,7 @@ numpy==1.26.4
pandas==2.2.2 pandas==2.2.2
pandas-ta==0.3.14b pandas-ta==0.3.14b
ccxt==4.3.27 ccxt==4.3.30
cryptography==42.0.7 cryptography==42.0.7
aiohttp==3.9.5 aiohttp==3.9.5
SQLAlchemy==2.0.30 SQLAlchemy==2.0.30

View File

@@ -45,7 +45,25 @@ EXCHANGES = {
"workingTime": 1674493798550, "workingTime": 1674493798550,
"fills": [], "fills": [],
"selfTradePreventionMode": "NONE", "selfTradePreventionMode": "NONE",
} },
{
"symbol": "SOLUSDT",
"orderId": 3551312894,
"orderListId": -1,
"clientOrderId": "x-R4DD3S8297c73a11ccb9dc8f2811ba",
"transactTime": 1674493798550,
"price": "15.50000000",
"origQty": "1.10000000",
"executedQty": "1.10000000",
"cummulativeQuoteQty": "17.05",
"status": "FILLED",
"timeInForce": "GTC",
"type": "LIMIT",
"side": "BUY",
"workingTime": 1674493798550,
"fills": [],
"selfTradePreventionMode": "NONE",
},
], ],
}, },
"binanceus": { "binanceus": {
@@ -288,6 +306,36 @@ EXCHANGES = {
"hasQuoteVolume": True, "hasQuoteVolume": True,
"timeframe": "1h", "timeframe": "1h",
"futures": False, "futures": False,
"sample_order": [
{
"symbol": "SOL-USDT",
"orderId": "1762393630149869568",
"transactTime": "1674493798550",
"price": "15.5",
"stopPrice": "0",
"origQty": "1.1",
"executedQty": "1.1",
"cummulativeQuoteQty": "17.05",
"status": "FILLED",
"type": "LIMIT",
"side": "BUY",
"clientOrderID": "",
},
{
"symbol": "SOL-USDT",
"orderId": "1762393630149869568",
"transactTime": "1674493798550",
"price": "15.5",
"stopPrice": "0",
"origQty": "1.1",
"executedQty": "1.1",
"cummulativeQuoteQty": "17.05",
"status": "FILLED",
"type": "MARKET",
"side": "BUY",
"clientOrderID": "",
},
],
}, },
} }

View File

@@ -76,7 +76,8 @@ class TestCCXTExchange:
assert isinstance(po["timestamp"], int) assert isinstance(po["timestamp"], int)
assert isinstance(po["price"], float) assert isinstance(po["price"], float)
assert po["price"] == 15.5 assert po["price"] == 15.5
if po["average"] is not None: if po["status"] == "closed":
# Filled orders should have average assigned.
assert isinstance(po["average"], float) assert isinstance(po["average"], float)
assert po["average"] == 15.5 assert po["average"] == 15.5
assert po["symbol"] == pair assert po["symbol"] == pair