Daan
Daan

Reputation: 1

Use the Bybit API to do a derivatives trade on BTC/USDT

While running my code I keep getting the same error, qty invalid but I'm giving it the minimum required value and got enough balance on the account as you can see.

Already checked out a lot of issues on google but couldn't find this specific error.

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 Code:

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()

Trying to buy the minimum amount of BTC through the API.

Upvotes: -1

Views: 3536

Answers (1)

777Eternal 777
777Eternal 777

Reputation: 1

Here you can just use this code from official bybit api testing, just remove test from endpoint and put your api info

import requests
import time
import hashlib
import hmac
import uuid

api_key='XXXXXXXXX'
secret_key='XXXXXXXXX'
httpClient=requests.Session()
recv_window=str(5000)
url="https://api-testnet.bybit.com" # Testnet endpoint

def HTTP_Request(endPoint,method,payload,Info):
    global time_stamp
    time_stamp=str(int(time.time() * 10 ** 3))
    signature=genSignature(payload)
    headers = {
        'X-BAPI-API-KEY': api_key,
        'X-BAPI-SIGN': signature,
        'X-BAPI-SIGN-TYPE': '2',
        'X-BAPI-TIMESTAMP': time_stamp,
        'X-BAPI-RECV-WINDOW': recv_window,
        'Content-Type': 'application/json'
    }
    if(method=="POST"):
        response = httpClient.request(method, url+endPoint, headers=headers, data=payload)
    else:
        response = httpClient.request(method, url+endPoint+"?"+payload, headers=headers)
    print(response.text)
    print(Info + " Elapsed Time : " + str(response.elapsed))

def genSignature(payload):
    param_str= str(time_stamp) + api_key + recv_window + payload
    hash = hmac.new(bytes(secret_key, "utf-8"), param_str.encode("utf-8"),hashlib.sha256)
    signature = hash.hexdigest()
    return signature

#Create Order
endpoint="/contract/v3/private/order/create"
method="POST"
orderLinkId=uuid.uuid4().hex
params='{"symbol": "BTCUSDT","side": "Buy","positionIdx": 1,"orderType": "Limit","qty": "0.001","price": "10000","timeInForce": "GoodTillCancel","orderLinkId": "' + orderLinkId + '"}'
HTTP_Request(endpoint,method,params,"Create")

#Get unfilled Orders
endpoint="/contract/v3/private/order/unfilled-orders"
method="GET"
params='settleCoin=USDT'
HTTP_Request(endpoint,method,params,"UnFilled")

#Get Order List
endpoint="/contract/v3/private/order/list"
method="GET"
params="symbol=BTCUSDT&orderStatus=New&orderLinkId="+orderLinkId
HTTP_Request(endpoint,method,params,"List")

#Cancel Order
endpoint="/contract/v3/private/order/cancel"
method="POST"
params='{"symbol": "BTCUSDT","orderLinkId": "'+orderLinkId+'"}'
HTTP_Request(endpoint,method,params,"Cancel")

Upvotes: -2

Related Questions