使用Bybit API进行BTC/USDT衍生品交易时遇qty invalid错误求助
Bybit API 下单提示「qty invalid」但已满足最小下单量的解决办法
问题描述
我尝试通过Bybit API购买最小量BTC,已输入平台要求的最小下单量(0.001 BTC),且账户USDT余额充足(当前余额99.97 USDT),但下单时持续返回错误:params error: qty invalid。
运行日志
Starting USDT balance: 99.97 No BTC in the account. Buying 0.001 BTC... Placing market buy order for 0.00100000 BTC at 28254.80 USDT/BTC Order response: {'ret_code': 10001, 'ret_msg': 'params error: qty invalid', 'result': {}, 'ext_code': '', 'ext_info': '', 'time_now': '1680641484.301085', 'rate_limit_status': 99, 'rate_limit': 100, 'rate_limit_reset_ms': 1680641484300}
我的Python代码
import requests import time import hmac import hashlib from urllib.parse import urlencode # API keys API_KEY = 'API KEY' API_SECRET = 'API SECRET' # Base URLs BYBIT_BASE_URL = 'https://api.bybit.com' # Constants SYMBOL = 'BTCUSDT' ORDER_TYPE = 'Market' FIXED_ORDER_QTY_BTC = 0.001 QUANTITY_STEP_SIZE = 0.001 def generate_signature(secret, params): query_string = urlencode(sorted(params.items())) hmac_sha256 = hmac.new(secret.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256) return hmac_sha256.hexdigest() def get_balance(coin): timestamp = int(time.time() * 1000) params = { 'api_key': API_KEY, 'timestamp': timestamp, 'coin': coin } params['sign'] = generate_signature(API_SECRET, params) url = f"{BYBIT_BASE_URL}/v2/private/wallet/balance" response = requests.get(url, params=params) return response.json() def place_order(side, qty, order_type): timestamp = int(time.time() * 1000) params = { 'api_key': API_KEY, 'timestamp': timestamp, 'symbol': SYMBOL, 'side': side, 'order_type': order_type, 'qty': qty, 'time_in_force': 'GoodTillCancel', 'reduce_only': False } params['sign'] = generate_signature(API_SECRET, params) url = f"{BYBIT_BASE_URL}/v2/private/order/create" response = requests.post(url, data=params) return response.json() def get_ticker_price(symbol): url = f"{BYBIT_BASE_URL}/v2/public/tickers?symbol={symbol}" response = requests.get(url) return response.json() def main(): # Get current USDT balance usdt_balance = float(get_balance('USDT')['result']['USDT']['available_balance']) print(f"Starting USDT balance: {usdt_balance:.2f}") # Check if BTC balance is zero btc_balance = float(get_balance('BTC')['result']['BTC']['available_balance']) if btc_balance == 0: print(f"No BTC in the account. Buying {FIXED_ORDER_QTY_BTC} BTC...") ticker_price = float(get_ticker_price(SYMBOL)['result'][0]['last_price']) order_qty = round(FIXED_ORDER_QTY_BTC / QUANTITY_STEP_SIZE) * QUANTITY_STEP_SIZE print(f"Placing market buy order for {order_qty:.8f} BTC at {ticker_price:.2f} USDT/BTC") response = place_order('Buy', order_qty, ORDER_TYPE) print(f"Order response: {response}") while True: # Get current BTC balance btc_balance = float(get_balance('BTC')['result']['BTC']['available_balance']) if btc_balance >= order_qty: print(f"Bought {order_qty:.8f} BTC") break else: print("Waiting for BTC to be bought...") time.sleep(10) # Get updated USDT balance usdt_balance = float(get_balance('USDT')['result']['USDT']['available_balance']) print(f"Updated USDT balance: {usdt_balance:.2f}") if __name__ == '__main__': main()
问题原因
你使用的/v2/private/order/create是合约交易接口,该接口中qty参数的单位不是BTC,而是「合约张数」(BTCUSDT合约每张对应0.001 BTC)。你直接传入0.001作为qty,会被识别为0.001张,不符合合约最小下单张数(通常为1张)的要求,因此触发参数错误。
如果你的需求是现货交易,则需要使用现货专用API接口,而非合约接口。
解决方案
方案1:进行合约交易(USDT永续)
将qty改为整数1(对应0.001 BTC),因为合约以「张数」为单位:
def place_order(side, qty, order_type): timestamp = int(time.time() * 1000) params = { 'api_key': API_KEY, 'timestamp': timestamp, 'symbol': SYMBOL, 'side': side, 'order_type': order_type, 'qty': 1, # 修改为1张,对应0.001 BTC 'time_in_force': 'GoodTillCancel', 'reduce_only': False } params['sign'] = generate_signature(API_SECRET, params) url = f"{BYBIT_BASE_URL}/v2/private/order/create" response = requests.post(url, data=params) return response.json()
方案2:进行现货交易
替换为现货专用接口/spot/v1/order,并调整参数格式:
def place_order(side, qty, order_type): timestamp = int(time.time() * 1000) params = { 'api_key': API_KEY, 'timestamp': timestamp, 'symbol': SYMBOL, 'side': side.upper(), 'type': order_type.upper(), 'qty': str(qty), # 现货接口要求qty为字符串格式 'timeInForce': 'GTC' # 现货接口参数名为timeInForce,而非time_in_force } params['sign'] = generate_signature(API_SECRET, params) url = f"{BYBIT_BASE_URL}/spot/v1/order" response = requests.post(url, data=params) return response.json()
现货交易的最小下单量确实是0.001 BTC,你的FIXED_ORDER_QTY_BTC = 0.001符合要求。
额外检查点
- 确认API密钥权限:现货交易需开启现货权限,合约交易需开启合约权限;
- 检查参数大小写:Bybit部分API参数区分大小写,比如现货接口的
timeInForce不能写成time_in_force。
内容的提问来源于stack exchange,提问作者Daan
相关产品推荐
相关产品推荐

