'code': -1102, 'symbol' was not sent, was empty/null, or malformed

Hi everyone, and thank you for helping me. I’m a student of coding, with a basic knowledge and trying to learn through doing different stuff. At this moment, I’m working on a simple automated trading bot (just as a hobby, I know this is far from being a real strategy). I have a similar version of the code working on the SPOT market, but with market orders.

The problem comes when I try to change the code to place only limit orders. I did some changes, and though it was going to buy and sell given the conditions, but I get this message from response.json: {‘code’: -1102, ‘msg’: “Mandatory parameter ‘symbol’ was not sent, was empty/null, or malformed.”}.

I checked the Binance API doc and several different sites, videos but I still don’t see the problem. Thank you again for helping a passionate begginer.

Here’s the code (api keys hidden):

API_KEY = "x"
API_SECRET = "x"

#Function of limited order
def limit_order(symbol, side, quantity, price):
    endpoint = "https://api.binance.com/api/v3/order"
    timestamp = int(time.time() * 1000)
    params = f'&symbol={symbol}&side={side}&type=LIMIT&timeInForce=GTC&quantity={quantity}&price={price}&timestamp={timestamp}'
    signature = hmac.new(API_SECRET.encode('utf-8'), params.encode('utf-8'), hashlib.sha256).hexdigest()
    headers = { "X-MBX-APIKEY": API_KEY, "X-MBX-SIGNATURE": signature }
    payload = {
        "symbol": symbol,
        "side": side,
        "type": "LIMIT",
        "timeInForce": "GTC",
        "quantity": quantity,
        "price": price,
        "timestamp": timestamp
    }
    try:
        response = requests.post(endpoint, json = payload, headers = headers)
        response_json = response.json()
        print(response_json)
    except Exception:
        print("Request Error")

# Live price function
async def live_price():
    previous_price = None
    start_time = None
    buy_price = None
    sell_price = None
    buy_time = None
    profit = 0.0
    pnl = 0.0
    
    async with websockets.connect('wss://stream.binance.com:9443/ws/btcusdt@ticker') as websocket:
        while True:
            response = json.loads(await websocket.recv())
            timestamp = datetime.fromtimestamp(response["E"] / 1000)
            close_price = float(response['c'])
            
            if not start_time:
                start_time = timestamp
            
            if previous_price:
                return_rate = (close_price - previous_price) / previous_price * 100
                cumulative_return = (((return_rate + 100) / 100) * (close_price / previous_price)) - 1
                print(f"{timestamp.strftime('%Y-%m-%d %H:%M:%S')} - Close price: {close_price} Cumulative Return: {cumulative_return * 100:.4f}%")
                
                if (timestamp - start_time).total_seconds() > 60:
                    start_time = None
                    cumulative_return = 0
                    print("Reset cumulative return")
                
                if cumulative_return < -0.0002 and not buy_price:
                    buy_price = close_price
                    # Here is a limited buy order placed for the BTC/USDT pair at 0.00045 BTC
                    limit_order("BTCUSDT", "BUY", 0.00045, buy_price)
                    print(f"Real Buy Price: {buy_price}")
                if cumulative_return >= 0.00015 and buy_price:
                    sell_price = close_price
                    # Here is a limited sell order placed for the BTC/USDT pair at 0.00045 BTC
                    limit_order("BTCUSDT", "SELL", 0.00045, sell_price)
                    profit = sell_price - buy_price
                    pnl += profit
                    print(f"Real Buy Price: {buy_price} Real Sell Price: {sell_price} Profit: {profit} P&L: {pnl}")
                    buy_price = None
                    sell_price = None
                    profit = 0.0
            else:
                print(f"{timestamp.strftime('%Y-%m-%d %H:%M:%S')} - Close price: {close_price}")
                
            previous_price = close_price

asyncio.get_event_loop().run_until_complete(live_price())

I’m a bit lost and I don’t know what to do next. As I said, the version of the code that places market orders is working fine, so I took that code and I’m unsuccesfully trying to implement the limit order version.
Thank you very much!

  1. Print the params before sending the request, it will reveal what’s the real value that was sent to the server. As the error indicating the problem coming from “symbol”, you should be able to find out the problem.
  2. You could send parameters in url, even it’s a POST. It can help you to debug, like printing out the whole url for investigation.
  3. binance-signature-examples/spot.py at master · binance/binance-signature-examples · GitHub
    has similar codes in python to place order. Hope it will be helpful.

Happy coding.