You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 02:57:56