ccxt / ccxt

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading API with support for more than 100 bitcoin/altcoin exchanges
https://docs.ccxt.com
MIT License
32.44k stars 7.46k forks source link

Can't create any order on binance futures #9472

Closed Salz0 closed 3 years ago

Salz0 commented 3 years ago

I just can't get futures orders running

response = await self.account.exchange.fapiPrivate_post_order({  # noqa: unresolved
                        'symbol': self.formattedSymbol,
                        'side': self.account.side,
                        'positionSide': _positionSide,
                        'quantity': _amount,
                        'type': 1
                        })

Getting "Invalid order type"

response = await self.account.exchange.fapiPrivate_post_positionmargin({  # noqa: unresolved
                         'symbol': self.account.futureMarketAsset['id'],
                         'amount': _amount,
                         'positionSide': _positionSide,  # BOTH for One-way positions, LONG/SHORT for Hedge Mode # noqa
                         'type': _side,  # 1 = add position margin, 2 = reduce position margin # noqa
                     })

Getting "Cannot add position margin: position is 0."


if futures:
    self.amount = self.account.exchange.amount_to_precision(self.formattedSymbol, self.futureAmount)
await self.account.exchange.create_order(amount=self.amount, side=self.account.side,
                                         symbol=self.formattedSymbol, type=self.account.orderType,
                                         params=params)

Getting binance {"code":-4061,"msg":"Order's position side does not match user's setting."}

It becomes somewhat tiring, is there any documentation on this, couldn't find it in the manual. Also can't find any documentation on the specific fapi methods, the code is unreachable, and couldn't find it in the manual.

Salz0 commented 3 years ago

In the third one 'self.account'.side is "BUY", params are empty, self.account.orderType = 'MARKET'

kroitor commented 3 years ago

@Salz0 what's your CCXT version number?

Salz0 commented 3 years ago

@Salz0 what's your CCXT version number?

1.51.82

frosty00 commented 3 years ago

@Salz0 have you tried doing

binanceFutures = binanceusdm (keys)
await binanceFutures.createOrder ('BTC/USDT', 'limit', 'buy', 0.01, 40000)
wesleywilian commented 3 years ago

Also you can use the testnet with:

exchange.set_sandbox_mode(True)

https://testnet.binancefuture.com/en/futures/BTCUSDT

Salz0 commented 3 years ago

Also you can use the testnet with:

exchange.set_sandbox_mode(True)

https://testnet.binancefuture.com/en/futures/BTCUSDT

I am using the testnet, same things

Salz0 commented 3 years ago

@Salz0 have you tried doing

binanceFutures = binanceusdm (keys)
await binanceFutures.createOrder ('BTC/USDT', 'limit', 'buy', 0.01, 40000)

what is binanceusdm?

kroitor commented 3 years ago

@Salz0 it's a shorthand that we added recently for more convenient initialization of binance futures, without having to specify the defaultType.

Salz0 commented 3 years ago

@Salz0 have you tried doing

binanceFutures = binanceusdm (keys)
await binanceFutures.createOrder ('BTC/USDT', 'limit', 'buy', 0.01, 40000)
ccxt.base.errors.ExchangeError: binanceusdm {"code":-4061,"msg":"Order's position side does not match user's setting."}

I also tried

keys = {
    "apiKey": os.environ[f"API_KEY{self.account.accountId}"],
    "secret": os.environ[f"API_SECRET{self.account.accountId}"]
}
binanceFutures = binancecoinm(keys)
response = await binanceFutures.create_order(amount=self.amount, side=self.account.side,
                                                                           symbol=self.formattedSymbol,
                                                                           type=self.account.orderType)

getting --> ccxt.base.errors.BadSymbol: binancecoinm does not have market symbol BTC/USDT

kroitor commented 3 years ago

@Salz0 what do you see from this short snippet ↓ ?

import ccxt
from pprint import pprint
print('CCXT Version:', ccxt.__version__)
exchange = ccxt.binanceusdm({
     'apiKey': 'YOUR_API_KEY',
     'secret': 'YOUR_SECRET',
})

markets = exchange.load_markets()
market = exchange.market('BTC/USDT')
pprint(market)
Salz0 commented 3 years ago

@Salz0 what do you see from this short snippet ↓ ?

import ccxt
from pprint import pprint
print('CCXT Version:', ccxt.__version__)
exchange = ccxt.binanceusdm({
     'apiKey': 'YOUR_API_KEY',
     'secret': 'YOUR_SECRET',
})

markets = exchange.load_markets()
market = exchange.market('BTC/USDT')
pprint(market)
CCXT Version: 1.51.82
{'active': True,
 'base': 'BTC',
 'baseId': 'BTC',
 'contractSize': '1',
 'delivery': False,
 'expiry': None,
 'expiryDatetime': None,
 'feeSide': 'get',
 'future': True,
 'id': 'BTCUSDT',
 'info': {'baseAsset': 'BTC',
          'baseAssetPrecision': '8',
          'contractType': 'PERPETUAL',
          'deliveryDate': '4133404800000',
          'filters': [{'filterType': 'PRICE_FILTER',
                       'maxPrice': '1000000',
                       'minPrice': '556.72',
                       'tickSize': '0.01'},
                      {'filterType': 'LOT_SIZE',
                       'maxQty': '1000',
                       'minQty': '0.001',
                       'stepSize': '0.001'},
                      {'filterType': 'MARKET_LOT_SIZE',
                       'maxQty': '1000',
                       'minQty': '0.001',
                       'stepSize': '0.001'},
                      {'filterType': 'MAX_NUM_ORDERS', 'limit': '200'},
                      {'filterType': 'MAX_NUM_ALGO_ORDERS', 'limit': '10'},
                      {'filterType': 'MIN_NOTIONAL', 'notional': '5'},
                      {'filterType': 'PERCENT_PRICE',
                       'multiplierDecimal': '4',
                       'multiplierDown': '0.8500',
                       'multiplierUp': '1.1500'}],
          'maintMarginPercent': '2.5000',
          'marginAsset': 'USDT',
          'onboardDate': '1569398400000',
          'orderTypes': ['LIMIT',
                         'MARKET',
                         'STOP',
                         'STOP_MARKET',
                         'TAKE_PROFIT',
                         'TAKE_PROFIT_MARKET',
                         'TRAILING_STOP_MARKET'],
          'pair': 'BTCUSDT',
          'pricePrecision': '2',
          'quantityPrecision': '3',
          'quoteAsset': 'USDT',
          'quotePrecision': '8',
          'requiredMarginPercent': '5.0000',
          'settlePlan': '0',
          'status': 'TRADING',
          'symbol': 'BTCUSDT',
          'timeInForce': ['GTC', 'IOC', 'FOK', 'GTX'],
          'triggerProtect': '0.0500',
          'underlyingSubType': [],
          'underlyingType': 'COIN'},
 'inverse': False,
 'limits': {'amount': {'max': 1000.0, 'min': 0.001},
            'cost': {'max': None, 'min': 5.0},
            'market': {'max': 1000.0, 'min': 0.001},
            'price': {'max': 1000000.0, 'min': 556.72}},
 'linear': True,
 'lowercaseId': 'btcusdt',
 'maker': 0.001,
 'margin': False,
 'percentage': True,
 'precision': {'amount': 3, 'base': 8, 'price': 2, 'quote': 8},
 'quote': 'USDT',
 'quoteId': 'USDT',
 'spot': False,
 'symbol': 'BTC/USDT',
 'taker': 0.001,
 'tierBased': False,
 'type': 'future'}
frosty00 commented 3 years ago

i think it is because you are in hedge mode, you need to change it to one direction mode in the binance futures settings

Salz0 commented 3 years ago

i think it is because you are in hedge mode, you need to change it to one direction mode in the binance futures settings

Ok, got one-way, now after getting Insufficient margin-error I am trying to do a transfer to the coin, (because am doing it all in isolated mode)

out = await self.account.exchange.futures_transfer(code="USDT", amount=20, type=1)
logger.info(f"{out=}")

And am getting

binanceusdm {"code":-5013,"msg":"Asset transfer failed: insufficient balance"}

While having {'BNB': 0.0, 'USDT': 43.4006899, 'BUSD': 0.0} on the wallet

Is there any guide for this? I am trying to set up my bot for futures ( enabling isolated/crossed trades ) and It is difficult to get a grasp of how it is all done. Maybe there is some solution out there?

frosty00 commented 3 years ago

you can try binanceusdm.transferIn ('USDT', 20) if you have 20USDT in your spot wallet

Salz0 commented 3 years ago

you can try binanceusdm.transferIn ('USDT', 20) if you have 20USDT in your spot wallet

Does this transfer from the spot wallet? Because I already have everything on the future wallet

Salz0 commented 3 years ago

Right now, when trying to execute a order I get binanceusdm {"code":-2019,"msg":"Margin is insufficient."}

On libraries like python-binance you just need to set up the type and mode -> then execute the order. I have don't the identical thing here and I can't grasp what I am missing

frosty00 commented 3 years ago

@Salz0 what is the leverage of the contract, also note that the default amount is in BTC not USDT, so if you want to make a small long to test you could do

await binanceusdm.createOrder ('BTC/USDT', 'limit', 'buy', 0.01, 40000)
Salz0 commented 3 years ago
await self.account.exchange.create_order('BTC/USDT', 'limit', 'buy', 0.01, 39254.73)

Returns ccxt.base.errors.InsufficientFunds: binanceusdm {"code":-2019,"msg":"Margin is insufficient."}

When I tried doing something that corresponds to the wallet (0.00069 BTC) It said ccxt.base.errors.ExchangeError: binanceusdm {"code":-4003,"msg":"Quantity less than zero."}

Salz0 commented 3 years ago
await self.account.exchange.create_order('BTC/USDT', 'limit', 'buy', 0.01, 39254.73)

Returns ccxt.base.errors.InsufficientFunds: binanceusdm {"code":-2019,"msg":"Margin is insufficient."}

When I tried doing something that corresponds to the wallet (0.00069 BTC) It said ccxt.base.errors.ExchangeError: binanceusdm {"code":-4003,"msg":"Quantity less than zero."}

0.00069 BTC is 24USD

kroitor commented 3 years ago

@Salz0 your call to create_order('BTC/USDT', 'limit', 'buy', 0.01, 39254.73) will try to place an order for 0.01 BTC * 39254.73 USDT = 392.5473 USDT total cost. Do you have sufficient funds on your futures account to place that order?

Salz0 commented 3 years ago

@Salz0 your call to create_order('BTC/USDT', 'limit', 'buy', 0.01, 39254.73) will try to place an order for 0.01 BTC * 39254.73 USDT = 392.5473 USDT total cost. Do you have sufficient funds on your futures account to place that order?

I have 40USD, I have executed with 0.00069 BTC amount parameter

kroitor commented 3 years ago

@Salz0 please, paste your verbose output:

import ccxt
from pprint import pprint
print('CCXT Version:', ccxt.__version__)
exchange = ccxt.binanceusdm({
     'apiKey': 'YOUR_API_KEY',
     'secret': 'YOUR_SECRET',
})

markets = exchange.load_markets()
market = exchange.market('BTC/USDT')
print('-------------------------------------------------------------------------------------')
print('Market limits:')
pprint(market['limits'])
balance = exchange.fetch_balance()
print('-------------------------------------------------------------------------------------')
print('Total balances:')
pprint(balance['total'])
print('-------------------------------------------------------------------------------------')
exchange.verbose = True  # add this
order = exchange.create_order('BTC/USDT', 'limit', 'buy', 0.000069, 39254.73)
print('Order:')
pprint(order)

Make sure that your balance is sufficient and your order is above limits.

Those are documented here:

~/ccxt $ node examples/js/cli binanceusdm market BTC/USDT
Node.js: v14.15.4
CCXT v1.52.26
binanceusdm.market (BTC/USDT)
{         limits: { amount: { min: 0.001, max: 1000 },
                     price: { min: 556.72, max: 1000000 },
                      cost: { min: 5, max: undefined },
                    market: { min: 0.001, max: 1000 }      },
       precision: { base: 8, quote: 8, amount: 3, price: 2 },

As you can see above, the minimal order amount is 0.001 BTC, and the minimal cost (amount * price) must be 5 USDT. Moreover, the amount precision for BTC/USDT is just 3 decimals, so you cannot order 0.000069, cause that violates the exchange rules as explained in the Manual above. The amount of 0.000069 contradicts the Binance limits and precision.

Hope that answers your question, let us know if not.

Salz0 commented 3 years ago

CCXT Version: 1.51.82
-------------------------------------------------------------------------------------
Market limits:
{'amount': {'max': 1000.0, 'min': 0.001},
 'cost': {'max': None, 'min': 5.0},
 'market': {'max': 1000.0, 'min': 0.001},
 'price': {'max': 1000000.0, 'min': 556.72}}
-------------------------------------------------------------------------------------
Total balances:
{'BNB': 0.0, 'BUSD': 0.0, 'USDT': 43.4006899}
-------------------------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\korol\AppData\Roaming\JetBrains\PyCharm2021.1\scratches\scratch_9.py", line 23, in <module>
    order = exchange.create_order('BTC/USDT', 'limit', 'buy', 0.000069, 39254.73)
  File "C:\Users\korol\AppData\Local\pypoetry\Cache\virtualenvs\ts-bot-4iVuk_MM-py3.9\lib\site-packages\ccxt\binance.py", line 2084, in create_order
    response = getattr(self, method)(self.extend(request, params))
  File "C:\Users\korol\AppData\Local\pypoetry\Cache\virtualenvs\ts-bot-4iVuk_MM-py3.9\lib\site-packages\ccxt\base\exchange.py", line 461, in inner
    return entry(_self, **inner_kwargs)
  File "C:\Users\korol\AppData\Local\pypoetry\Cache\virtualenvs\ts-bot-4iVuk_MM-py3.9\lib\site-packages\ccxt\binance.py", line 3780, in request
    response = self.fetch2(path, api, method, params, headers, body)
  File "C:\Users\korol\AppData\Local\pypoetry\Cache\virtualenvs\ts-bot-4iVuk_MM-py3.9\lib\site-packages\ccxt\base\exchange.py", line 482, in fetch2
    return self.fetch(request['url'], request['method'], request['headers'], request['body'])
  File "C:\Users\korol\AppData\Local\pypoetry\Cache\virtualenvs\ts-bot-4iVuk_MM-py3.9\lib\site-packages\ccxt\base\exchange.py", line 609, in fetch
    self.handle_errors(http_status_code, http_status_text, url, method, headers, http_response, json_response, request_headers, request_body)
  File "C:\Users\korol\AppData\Local\pypoetry\Cache\virtualenvs\ts-bot-4iVuk_MM-py3.9\lib\site-packages\ccxt\binance.py", line 3775, in handle_errors
    raise ExchangeError(feedback)
ccxt.base.errors.ExchangeError: binanceusdm {"code":-4003,"msg":"Quantity less than zero."}

So, my leverage is set to 1

Do I understand correctly that I need to set a leverage such that my order in total exceeds 0.001??

By the way, did I just execute?

{'amount': 0.001,
 'average': 33199.37,
 'clientOrderId': '',
 'cost': 33.19937,
 'datetime': None,
 'fee': None,
 'fees': [],
 'filled': 0.001,
 'id': '24678626189',
 'info': {'avgPrice': '33199.37000',
          'clientOrderId': '',
          'closePosition': False,
          'cumQty': '0.001',
          'cumQuote': '33.19937',
          'executedQty': '0.001',
          'orderId': '',
          'origQty': '0.001',
          'origType': 'LIMIT',
          'positionSide': 'BOTH',
          'price': '38152.76',
          'priceProtect': False,
          'reduceOnly': False,
          'side': 'BUY',
          'status': 'FILLED',
          'stopPrice': '0',
          'symbol': 'BTCUSDT',
          'timeInForce': 'GTC',
          'type': 'LIMIT',
          'updateTime': '1625132821297',
          'workingType': 'CONTRACT_PRICE'},
 'lastTradeTimestamp': None,
 'postOnly': False,
 'price': 38152.76,
 'remaining': 0.0,
 'side': 'buy',
 'status': 'closed',
 'stopPrice': None,
 'symbol': 'BTC/USDT',
 'timeInForce': 'GTC',
 'timestamp': None,
 'trades': [],
 'type': 'limit'}
kroitor commented 3 years ago

By the way, did I just execute?

Yes.

kroitor commented 3 years ago

@Salz0

Do I understand correctly that I need to set a leverage such that my order in total exceeds 0.001??

You have to be very precise with terms. There's no order total. There's order amount (in BTC), the order price (in USDT) and the order cost (amount * price, in USDT). These terms are explained here: https://github.com/ccxt/ccxt/wiki/Manual#placing-orders. All three (amount, price, cost) values must conform to the exchanges' rules as explained in this section: https://github.com/ccxt/ccxt/wiki/Manual#precision-and-limits

We highly recommend reading the entire Manual from top to bottom, it has the answers to most starting questions and it will really save your time:

On the leverage – that is not specified explicitly, but you must have at least some maintenance margin to be able to keep your position open. Otherwise the exchanges will liquidate it. You can also test whether Binance allows you to place limit orders within your margin on their website. You can also use the testnet to trade virtual funds for testing purposes.

One the executed limit order – if your price is higher than the current market price, the exchange will give you the market price in your favor, so you don't overpay, which is effectively the same as placing a market order. You can see that in the output above – the average filling price for your order was much lower than you ordered: 'average': 33199.37.