sammchardy / python-binance

Binance Exchange API python implementation for automated trading
https://python-binance.readthedocs.io/en/latest/
MIT License
6.01k stars 2.2k forks source link

The AsyncClient.futures_place_batch_order provide an "1022 INVALID_SIGNATURE" error #1099

Open crazalchemist opened 2 years ago

crazalchemist commented 2 years ago

Describe the bug The AsyncClient.futures_place_batch_order provide an "1022 INVALID_SIGNATURE" error

To Reproduce


from binance.client import AsyncClient, Client
import asyncio

api_key = ''
api_secret = ''

async def main():
    client_1_a = AsyncClient(api_key, api_secret)
    client_1_s = Client(api_key, api_secret)

    params_in = {"batchOrders": []}
    params1 = {
            "symbol": "ADAUSDT",
            "side": "BUY",
            "positionSide": "LONG",
            "type": "LIMIT",
            "quantity": "20",
            "price": "1.40",
            "timeInForce": "GTC"
            }
    params2 = {
            "symbol": "CHRUSDT",
            "side": "BUY",
            "positionSide": "LONG",
            "type": "LIMIT",
            "quantity": "30",
            "price": "0.63",
            "timeInForce": "GTC"
            }
    params3 = {
            "symbol": "HOTUSDT",
            "side": "BUY",
            "positionSide": "LONG",
            "type": "LIMIT",
            "quantity": "2000",
            "price": "0.0095",
            "timeInForce": "GTC"
            }
    params_in["batchOrders"].append(params1)
    params_in["batchOrders"].append(params2)
    params_in["batchOrders"].append(params3)

    # Sequential future order and batch order working
    client_1_s.futures_create_order(**params1)
    client_1_s.futures_place_batch_order(**params_in)

    # Normal async future order working
    await client_1_a.futures_create_order(**params1)

    # async future batch order NOT working 
    await client_1_a.futures_place_batch_order(**params_in)
    # binance.exceptions.BinanceAPIException: APIError(code=-1022): Signature for this request is not valid.

    await client_1_a.session.close()

if __name__ == "__main__":
    asyncio.run(main())

Expected behavior A working order without signature error

Environment (please complete the following information): python3.7 / python3.9 debian 10 / Windows 10 python-binance tested on all major version from 1.0.0 New API keys with with spot and future enable just to be sure

Logs or Additional context Add any other context about the problem here.

myown-del commented 2 years ago

I have exacty the same issue.

Koosel commented 2 years ago

this way it doesn't give this error:

params_in = []

params0 = {
    'symbol':'BTCUSD_PERP',
    'side':'BUY',
    'type':'STOP_MARKET',
    'stopPrice':'48000',
    'quantity':'1'
}

params1 = {
    'symbol':'BTCUSD_PERP',
    'side':'BUY',
    'type':'STOP_MARKET',
    'stopPrice':'49000',
    'quantity':'1'
}

params2 = {
    'symbol':'BTCUSD_PERP',
    'side':'BUY',
    'type':'STOP_MARKET',
    'stopPrice':'50000',
    'quantity':'1'
}

params_in.append(params0)
params_in.append(params1)
params_in.append(params2)

client.futures_coin_place_batch_order(batchOrders=params_in)
Karlheinzniebuhr commented 2 years ago

I'm getting an error "Invalid symbol" with BTCBUSD_PERP

Karlheinzniebuhr commented 2 years ago

futures_place_batch_order() worked for me

oscnet commented 2 years ago
await client_1_a.futures_place_batch_order(**params_in)
binance.exceptions.BinanceAPIException: APIError(code=-1022): Signature for this request is not valid.

tested by 1.0.16

Maybe because the difference between request and aiohttp

xiandong79 commented 2 years ago

I got the same error on AsyncClient with futures_place_batch_order

luk0y commented 7 months ago

Facing the same issue. Has anyone found a workaround?

The issue comes when using AsyncClient

luk0y commented 7 months ago

Okay, because aiohttp is encoding the URL, and due to the changes in params because of the encoding, the signature is getting mismatched. To overcome this, I wrote a working code in Async by disabling the aiohttp encoding.

import aiohttp
import asyncio
import json
import hashlib
import hmac
import time
from urllib.parse import urlencode, quote
from yarl import URL

BASE_URL = 'https://fapi.binance.com'

apiKey = "Your_Api_Key"
secret = "Your_Secret_Key"

def get_signature(secret, query_string):
    return hmac.new(secret.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()

async def batch_order():
    PATH = '/fapi/v1/batchOrders'
    timestamp = int(time.time() * 1000)

    batch_orders = json.dumps([
        {
            "symbol": "BTCUSDT",
            "side": "BUY",
            "type": "LIMIT",
            "timeInForce": "GTC",
            "quantity": "0.01",
            "price": "25000",
        },
        {
            "symbol": "BTCUSDT",
            "side": "BUY",
            "type": "LIMIT",
            "timeInForce": "GTC",
            "quantity": "0.01",
            "price": "30000",
        }
    ])

    # Preparing the query string including batchOrders
    query_params = {
        'batchOrders': batch_orders,
        'timestamp': timestamp
    }
    query_string = urlencode(query_params, quote_via=quote)

    # Generating the signature
    signature = get_signature(secret, f"batchOrders={quote(batch_orders)}&timestamp={timestamp}")

    # Final URL with query params
    url = f"{BASE_URL}{PATH}?{query_string}&signature={signature}"

    headers = {
        'X-MBX-APIKEY': apiKey
    }
    async with aiohttp.ClientSession() as session:
        async with session.post(URL(url,encoded=True), headers=headers) as response:
            response_text = await response.text()
            print(response_text)

async def main():
    await batch_order()

if __name__ == "__main__":
    asyncio.run(main())
luk0y commented 7 months ago

This is working code but my interpretation towards this error is wrong. The reason we getting the signature error is because of params field. When I used data field the error got fixed.

https://github.com/sammchardy/python-binance/compare/master...luk0y:python-binance:patch-1#diff-7c2526962b0f482567b059ee588b65c2aa2e3a3903174a42205e5dfbb0f8a95e