Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
crazalchemist opened this issue Dec 8, 2021 · 10 comments

Comments

@crazalchemist
Copy link

crazalchemist commented Dec 8, 2021

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
Copy link

I have exacty the same issue.

@Koosel
Copy link

Koosel commented Apr 3, 2022

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
Copy link

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

@Karlheinzniebuhr
Copy link

futures_place_batch_order() worked for me

@oscnet
Copy link

oscnet commented Jun 6, 2022

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
Copy link

I got the same error on AsyncClient with futures_place_batch_order

@luk0y
Copy link
Contributor

luk0y commented Mar 1, 2024

Facing the same issue. Has anyone found a workaround?

The issue comes when using AsyncClient

@luk0y
Copy link
Contributor

luk0y commented Mar 2, 2024

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
Copy link
Contributor

luk0y commented Mar 2, 2024

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.

master...luk0y:python-binance:patch-1#diff-7c2526962b0f482567b059ee588b65c2aa2e3a3903174a42205e5dfbb0f8a95e

@TSoer
Copy link

TSoer commented Oct 5, 2024

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.

master...luk0y:python-binance:patch-1#diff-7c2526962b0f482567b059ee588b65c2aa2e3a3903174a42205e5dfbb0f8a95e

Can you show a working example. I think this error is due to double encoding happening, first in the futures_place_batch_order function and then in aiohttp when the request request because of this '%' sign is replaced with '%25'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants