[Python] Authentication Failure on Crypto.com exchange API request Python

Discussão em 'Python' iniciado por Stack, Fevereiro 18, 2025.

  1. Stack

    Stack Membro Participativo

    I am trying to test a basic trading script on Crypto.com's exchange and I keep getting this message.

    API Response: {'code': 40101, 'message': 'Authentication failure'} Buy Order Response: {'code': 40101, 'message': 'Authentication failure'}

    I have tried creating a few new API Keys and ensuring I am copying them over exactly and I am still getting the same error. I think there's something wrong with my digital signature, but I am not sure what it is.

    I found this post where there was a somewhat similar issue, but I was not able to figure out my issue from reading it.

    www.crypto.com authenticating, python HMAC-SHA256

    Here is my code with my API Keys removed.

    import requests
    import hmac
    import hashlib
    import json
    from datetime import datetime, timedelta

    # Replace with your Crypto.com API credentials
    API_KEY = "MY_API_KEY"
    API_SECRET = "MY_API_SECRET"
    BASE_URL = "https://api.crypto.com/exchange/v1"
    SYMBOL = "BTC_USDT"
    BUY_AMOUNT = 0.00001 # Adjust according to your trading strategy, 0.00002 min order qty
    SELL_THRESHOLD = 1.005 # 0.5% increase
    last_buy_price = None # Store the last buy price


    def generate_signature(payload: dict) -> str:
    """Generates HMAC signature for authentication."""
    message = json.dumps(payload, separators=(',', ':'), sort_keys=True)
    return hmac.new(API_SECRET.encode(), message.encode(), hashlib.sha256).hexdigest()


    def get_ticker():
    """Fetches the latest ticker information."""
    endpoint = f"{BASE_URL}/public/get-tickers"
    params = {"instrument_name": SYMBOL}
    response = requests.get(endpoint, params=params)
    data = response.json()

    if "result" in data and "data" in data["result"]:
    ticker_data = data["result"]["data"]
    if isinstance(ticker_data, list):
    return ticker_data[0] # Extract the first item if it's a list
    return ticker_data
    else:
    raise ValueError("Unexpected API response structure: " + str(data))


    def place_buy_order():
    """Places a buy order for BTC."""
    global last_buy_price
    endpoint = f"{BASE_URL}/private/create-order"
    timestamp = int(time.time() * 1000)
    ticker_data = get_ticker()

    # Ensure price precision (Crypto.com may require specific decimal places)
    buy_price = str(round(float(ticker_data["a"]), 2)) # Convert price to string with 2 decimal places
    buy_amount = str(format(BUY_AMOUNT,'f')) # Ensure minimum order quantity and convert to type string

    params = {
    "instrument_name": SYMBOL,
    "price": buy_price,
    "quantity": buy_amount,
    "side": "BUY",
    "type": "LIMIT"
    }

    payload = {
    "api_key": API_KEY,
    "id": timestamp,
    "method": "private/create-order",
    "params": params,
    "nonce": timestamp
    }
    payload["sig"] = generate_signature(payload)
    headers = {"Content-Type": "application/json"}

    # Debugging: Print request payload
    print("Payload being sent:", json.dumps(payload, indent=2))

    response = requests.post(endpoint, json=payload, headers=headers)
    response_data = response.json()

    print("API Response:", response.json())

    if response.status_code == 200 and response_data.get("code") == 0:
    last_buy_price = float(buy_price) # Update last buy price

    return response_data


    def place_sell_order():
    """Places a sell order for BTC."""
    endpoint = f"{BASE_URL}/private/create-order"
    timestamp = int(time.time() * 1000)
    ticker_data = get_ticker()

    # Ensure price precision (Crypto.com may require specific decimal places)
    sell_price = str(round(float(ticker_data["a"]), 2)) # Adjust precision if needed
    sell_amount = str(format(BUY_AMOUNT,'f')) # Ensure minimum order quantity and convert to type string

    params = {
    "instrument_name": SYMBOL,
    "price": sell_price,
    "quantity": sell_amount,
    "side": "SELL",
    "type": "LIMIT"
    }

    payload = {
    "api_key": API_KEY,
    "id": timestamp,
    "method": "private/create-order",
    "params": params,
    "nonce": timestamp
    }
    payload["sig"] = generate_signature(payload)
    headers = {"Content-Type": "application/json"}

    # Debugging: Print request payload
    print("Payload being sent:", json.dumps(payload, indent=2))

    response = requests.post(endpoint, json=payload, headers=headers)
    response_data = response.json()

    print("API Response:", response.json())

    return response_data


    def check_price_drop():
    """Checks if BTC price dropped more than 0.25% in the last 24 hours."""
    price_data = get_ticker()

    if isinstance(price_data, list):
    price_data = price_data[0] # If it's a list, take the first element

    current_price = float(price_data["a"])
    high_price_24h = float(price_data["h"])
    drop_percentage = (high_price_24h - current_price) / high_price_24h * 100
    return drop_percentage >= 0.25


    def check_price_rise():
    """Checks if BTC price increased more than 0.5% above the last buy price."""
    global last_buy_price
    if last_buy_price is None:
    return False

    price_data = get_ticker()
    if isinstance(price_data, list):
    price_data = price_data[0]

    current_price = float(price_data["a"])
    return current_price >= last_buy_price * SELL_THRESHOLD


    if __name__ == "__main__":
    while True:
    try:
    if check_price_drop():
    print("Price dropped more than 0.25%! Placing buy order...")
    order_response = place_buy_order()
    print("Buy Order Response:", order_response)
    elif check_price_rise():
    print("Price increased 0.5% above last buy price! Placing sell order...")
    order_response = place_sell_order()
    print("Sell Order Response:", order_response)
    else:
    print("No significant price movement detected. Checking again in 5 minutes.")
    except Exception as e:
    print("Error:", e)

    time.sleep(300) # Check every 5 minutes

    Continue reading...

Compartilhe esta Página