3

I tried to do API trading in Kucoin. I developed a bot that is finding the trading opportunities well, while I encountered problems in making new orders. Pls check the code and help me to make it functional.

The code was edited in accordance with the comment of Lev Levitsky is as follows:

import json
import urllib
import requests

import base64
import hmac
import hashlib

api_key        = 'api_key'
api_secret     = 'api_secret'
api_passphrase = 'api_passphrase'
base_uri       = 'https://api-futures.kucoin.com'
endpoint       = '/api/v1/orders?symbol=MATICUSDTM'
method         = 'POST'

x= {}
x["symbol"]         = "MATICUSDTM"
x["signal_type"]    = "SHORT"
x["leverage"]       = 5
x["exchange"]       = "Kucoin"
x["entrance_price"] = 2.1000
x["trading_size"]   = 150
x["tp1"]            = 2.08
x["sl1"]            = 2.12

all_futures_signals = list()
all_futures_signals.append(x)

def get_headers(method, endpoint, api_key, api_passphrase,body):
    api_secret     = ''
    now = int(time.time() * 1000)
    str_to_sign = str(now) + method + endpoint + str(body)

    signature  = base64.b64encode(hmac.new(api_secret.encode('utf-8'), str_to_sign.encode('utf-8'), hashlib.sha256).digest())
    passphrase = base64.b64encode(hmac.new(api_secret.encode('utf-8'), api_passphrase.encode('utf-8'), hashlib.sha256).digest())

    return {'KC-API-KEY': api_key,
            'KC-API-KEY-VERSION': '2',
            'KC-API-PASSPHRASE': passphrase,
            'KC-API-SIGN': signature,
            'KC-API-TIMESTAMP': str(now)}


body = {
    "clientOid"    : "",
    "reduceOnly"   : False,   # A mark to reduce the position size only
    "closeOrder"   : False,   # If closeOrder is set to TRUE, the system will close the position and the position size will become 0. Side, Size and Leverage fields can be left empty and the system will determine the side and size automatically.
    "forceHold"    : False,   # The system will forcely freeze certain amount of funds for this order, including orders whose direction is opposite to the current positions. This feature is to ensure that the order won’t be canceled by the matching engine in such a circumstance that not enough funds are frozen for the order.
    "hidden"       : False,   # A hidden order will enter but not display on the orderbook.
    "iceberg"      : False,   # When placing an iceberg order, you need to set the visible size. The minimum visible size is 1/20 of the order size. The minimum visible size shall be greater than the minimum order size, or an error will occur.
    "visibleSize"  : 0,       # When placing an iceberg order, you need to set the visible size. The minimum visible size is 1/20 of the order size. The minimum visible size shall be greater than the minimum order size, or an error will occur.
    "leverage"     : x["leverage"],
    "postOnly"     : False,   # The post-only flag ensures that the trader always pays the maker fee and provides liquidity to the order book.
    "price"        : 2.1000, # The price specified must be a multiple number of the contract tickSize,
    "remark"       : "remark",
    "side"         : "buy",# sell/buy
    "size"         : x["trading_size"],      # The size must be no less than the lotSize for the contract and no larger than the maxOrderQty.
    "stop"         : "",      # down/up
    "stopPrice"    : "",
    "stopPriceType": "",      # TP/MP/IP: TP for trade price, MP for mark price, and IP for index price
    "symbol"       : x["symbol"],
    "timeInForce"  : "",      # GTC/IOC: Good Till Canceled GTC and Immediate Or Cancel IOC.
    "type"         : "limit", # limit/market
}

headers = get_headers(method, endpoint, api_key, api_passphrase, body)
x["opening_response"] = requests.post( base_uri + endpoint, body, headers=headers).json()
print(x["opening_response"])

I receive this error: {'code': '400005', 'msg': 'Invalid KC-API-SIGN'}

All inputs are correct. I think there is a problem with the code.

Best Regards Javad

Javad
  • 47
  • 1
  • 5
  • Hi Javad, I think your question can be improved. First of all, you need to show the full traceback. Second, try to make the shortest possible example that illustrates the error. You don't need to shows us all the functions you have, you can try directly calling the API that's causing you trouble, just for a clear and brief demo of the problem. – Lev Levitsky Jan 15 '22 at 12:18
  • Dear Lev Levitsky, I thank you for your comment. I summarized the code. Pls review it. – Javad Jan 16 '22 at 11:50
  • This is definitely much better! (Still, it's better to copy the full traceback you get for this code.) Sorry I can't help you with solving this, upvoted your question for better visibility. Good luck! – Lev Levitsky Jan 16 '22 at 20:19

3 Answers3

0

I think the problem is your endpoint variable. I believe you should not add the symbol to endpoint, when you are trying to add a new order. Remove it from endpoint and pass the symbol in body object. The other thing is that I think you do not need to pass empty strings to optional fields in body object. I am not sure about this but I think you should remove them from body object. It is a signing problem, therefore you have to check 4 variables: timestamp, method, endpoint and body. I hope this works.

  • Hi Javad, that means your passphrase does not get signed correctly. I made the mistake and gave this passphrase the value of trading password. But you should give your account password to this filed. So make sure your passphrase is equal to your account password. – Edelweiss Jan 19 '22 at 11:12
  • Hi [Edelweiss](https://stackoverflow.com/users/11564661/edelweiss), Thank you for your answer. I tried it without success. It doesn't work. – Javad Jan 19 '22 at 11:41
  • The former problem on SIGNATURE persists. {'code': '400005', 'msg': 'Invalid KC-API-SIGN'} – Javad Jan 19 '22 at 11:43
  • Just another question: When you created your API in your account, which type of API did you choose? Maybe the problem is that you created a read-only API? Check this also. I am sorry I wasn't able to help you. I do trades with Node.js App without any problems. – Edelweiss Jan 19 '22 at 11:46
  • I think the last two lines of the code are not correct. May I have your Node.js code for sending the order like last two lines of my code? It may be helpful. I appreciate your contribution. – Javad Jan 19 '22 at 11:52
  • I checked my api again. It is a trade_api. – Javad Jan 19 '22 at 12:15
  • I guess you should use their Client Library for python. You can find it on Github or read it on their API documentation. Good luck! – Edelweiss Jan 19 '22 at 12:22
0

have you considered using ccxt? It makes dealing with lower level API stuff like this somewhat easier.

Given that it's singling out the signature as being invalid, but not saying any headers are missing, it could mean that the signature for str_to_sign variable is wrong?

Let's look at it:

api_secret     = ''
now = int(time.time() * 1000)
str_to_sign = str(now) + method + endpoint + str(body)

From the looks of it, your api_secret is just an empty string, so the resulting signature won't be correct.

so, a couple of lines down when you make the signature:

    signature  = base64.b64encode(hmac.new(api_secret.encode('utf-8'), str_to_sign.encode('utf-8'), hashlib.sha256).digest())

Even though api_secret is given a value in the higher scope, it's overridden by this local variable which is an empty string. If your api_secret were actually an empty string, then your code would produce the correct signature, but it's not so it isn't

So, If you give it as a param to your get_headers function ie.

def get_headers(method, endpoint, api_key, api_passphrase, api_secret, body):

And delete the first line api_secret = ''

Then maybe it will work?

If it doesn't work, then it's a different problem. (eg. if you had actually put your API key in there and just redacted it before posting). I don't know since I haven't tried running your code.

PS: To Edelweiss: Grüzi aus Berner Oberland!

Jonathon Quick
  • 125
  • 1
  • 1
  • 6
-1

According to a comment of edelweiss, an easier way is using the client of Kucoin API. It is here.

First, I installed the client using this code.

!pip install kucoin-futures-python

Then, I opened a position by this code:

from kucoin_futures.client import Trade

client = Trade(key='api_key', secret='api_secret', passphrase='api_passphrase', is_sandbox=False, url='')
order_id = client.create_limit_order(symbol, side, lever, size, price, clientOid='', **kwargs)
Javad
  • 47
  • 1
  • 5