Giter Club home page Giter Club logo

kucoin-node-api's Introduction

kucoin-node-api

This is an open source project created to utilize the Kucoin v2 API to support automated, algorithmic trading. The project was made and tested for Node 8.0+.

There are no guarentees towards the stability or effectiveness of this project. Comments, contributions, stars and donations are, however, all welcome.

Installation

npm install kucoin-node-api

Alternatively, you can clone/download the repository and import into your project by file path.

Getting Started

To begin using the API wrapper, require it, create a config object that contains your API key, Secret key and Passphrase provided by Kucoin. Then run the custom init() function with your config object as a parameter. If you are only using Public endpoints, the config object only requires the environment key/value pair.

Example code is as follows:

const api = require('kucoin-node-api')

const config = {
  apiKey: 'xXXXXXXXXXXXXXXXXXXXXxxxxxxxxxxxxxxxxxxxxxXXX',
  secretKey: 'xxxxxxxxXXXXXXXXXXXXXxxXXXXXXXXXXXXXxxxXXX',
  passphrase: 'xxxxxx',
  environment: 'live'
}

api.init(config)

Using the API Wrapper

Once the API wrapper object is created, you can call any of the associated functions. They will return a Promise which can be utlized with .then/.catch or async/await. Note that the Promise based approach will return directly whereas the async/await approach requires calling the function.

Simple example:

// Promise based approach for getting account information (private & signed)
api.getAccounts().then((r) => {
  console.log(r.data)
}).catch((e) => {
  console.log(e)
})

// Async/Await get account info example (private & signed)
async function getAccounts() {
  try {
    let r = await api.getAccounts()
    console.log(r.data)
  } catch(err) {
    console.log(err)
  } 
}

This approach allows for more complex multi-call asynchronous functionality, especially useful for automated trading.

Market Endpoint (Public)

Public endpoints do not require an API Key, Secret Key or API Passphrase.

/* 
  Get Symbols List
  GET /api/v1/symbols
  market = string [optional]
*/
api.getSymbols(market)
/*  
  Get Ticker
  GET /api/v1/market/orderbook/level1?symbol=<symbol>
  symbol = string
*/
api.getTicker(symbol)
/* 
  Get All Tickers
  GET /api/v1/market/allTickers
*/
api.getAllTickers()
/* 
  Get 24hr Stats
  GET /api/v1/market/stats?symbol=<symbol>
  symbol = string
*/
api.get24hrStats(symbol)
/* 
  Get Market List
  GET /api/v1/markets
*/
api.getMarketList(symbol)
/* 
  Get Part Order Book (aggregated) 
  GET /api/v1/market/orderbook/level2_20?symbol=<symbol>
  GET /api/v1/market/orderbook/level2_100?symbol=<symbol>
  params = {
    amount: integer (20 || 100) 
    symbol: string
  }
*/
api.getPartOrderBook(params)
/* 
  Get Full Order Book (aggregated)
  GET /api/v2/market/orderbook/level2?symbol=<symbol> 
  symbol = string
*/
api.getFullOrderBook(symbol)
/* 
  Get Full Order Book (atomic) 
  GET /api/v1/market/orderbook/level3?symbol=<symbol>
  symbol = string
*/
api.getFullOrderBookAtomic(symbol)
/* 
  Get Trade Histories
  GET /api/v1/market/histories?symbol=<symbol>
  symbol = string
*/
api.getTradeHistories(symbol)
/* 
  Get Klines
  GET /api/v1/market/candles?symbol=<symbol>
  params = {
    symbol: string
    startAt: long (unix time)
    endAt: long (unix time)
    type: enum [1min, 3min, 5min, 15min, 30min, 1hour, 2hour, 4hour, 6hour, 8hour, 12hour 1day, 1week]
  }
*/
api.getKlines(params)
/* 
  Get currencies
  GET /api/v1/currencies
*/
api.getCurrencies()
/* 
  Get currency detail
  GET /api/v1/currencies/{currency}
  currency = string
*/
api.getCurrency(currency)
/* 
  Get Fiat Price
  GET /api/v1/prices
  params = {
    base: string (e.g. 'USD') [optional]
    currencies: array
  }
*/
api.getFiatPrices(params)
/* 
  Server Time
  GET /api/v1/timestamp
*/
api.getServerTime()

User Endpoints (Private)

/* 
  List Accounts
  GET /api/v1/accounts
  params = {
    currency: string [optional]
    type: string [optional]
  }
*/
api.getAccounts()
/* 
  Get Account
  GET /api/v1/accounts/<accountId>
  params = {
    id: accountId
  }
*/
api.getAccountById(params)
/* 
  Create Account
  POST /api/v1/accounts
  params = {
    type: string ['main' || 'trade']
    currency: string
  }
*/
api.createAccount(params)
/*  
  Get Account Ledgers
  GET /api/v1/accounts/<accountId>/ledgers
  params = {
    id: string
    startAt: long (unix time)
    endAt: long (unix time)
  }
*/
api.getAccountLedgers(params)
/* 
  Get Holds
  GET /api/v1/accounts/<accountId>/holds
  params = {
    id: string
  }
*/
api.getHolds(params)
/*  
  Inner Transfer
  POST /api/accounts/inner-transfer
  params = {
    clientOid: string
    currency: string,
    from: string
    to: string
    amount: string
  }
*/
api.innerTransfer(params)
/*  
  Create Deposit Address
  POST /api/v1/deposit-addresses
  params = {
    currency: string
  }
*/
api.createDepositAddress(params)
/* 
  Get Deposit Address
  GET /api/v1/deposit-addresses?currency=<currency>
  params = {
    currency: string
  }
*/
api.getDepositAddress(params)
/* 
  Get Deposit List
  GET /api/v1/deposits
  params = {
    currency: string [optional]
    startAt: long (unix time)
    endAt: long (unix time)
    status: string [optional]
  }
*/
api.getDepositList(params)
/* 
  Get Margin Account
  GET /api/v1/margin/account
*/
api.getMarginAccount()
/*  
  Get Withdrawals List
  GET /api/v1/withdrawals
  params = {
    currency: string [optional]
    startAt: long (unix time)
    endAt: long (unix time)
    status: string [optional]
  }
*/
api.getWithdrawalsList(params)
/* 
  Get Repay Record
  GET /api/v1/margin/borrow/outstanding
  params = {
    currency: string [optional]
    currentPage: string [optional (default 1)]
    pageSize: string [optional (default 50)]
  }
*/
api.getRepayRecord(params)
/* 
  Get Withdrawal Quotas
  GET /api/v1/withdrawals/quotas
  params = {
    currency: string
  }
*/
api.getWithdrawalQuotas(params)
/* 
  Apply Withdrawal
  POST /api/v1/withdrawals
  params = {
    currency: string
    address: string
    amount: number
    memo: string [optional]
    isInner: boolean [optional]
    remark: string [optional]
  }
*/
api.applyForWithdrawal(params)
/* 
  Cancel Withdrawal
  DELETE /api/v1/withdrawls/<withdrawlId>
  params = {
    withdrawalId: string
  }
*/
api.cancelWithdrawal(params)
/* 
  Get V1 Historical Withdrawals List
  GET /api/v1/hist-withdrawals
  params = {
    currentPage: integer [optional]
    pageSize: integer [optional]
    currency: string [optional - currency code]
    startAt: long (unix time) [optional]
    endAt: long (unix time) [optional]
    status: string [optional] Available value: PROCESSING, SUCCESS, and FAILURE
  }
*/
api.getV1HistoricalWithdrawls(params)
/* 
  Get V1 Historical Deposits List
  GET /api/v1/hist-deposits
  params = {
    currentPage: integer [optional]
    pageSize: integer [optional]
    currency: string [optional - currency code]
    startAt: long (unix time) [optional]
    endAt: long (unix time) [optional]
    status: string [optional] Available value: PROCESSING, SUCCESS, and FAILURE
  }
*/
api.getV1HistoricalDeposits(params)

Trade Endpoints (Private)

/* 
  Place a new order
  POST /api/v1/orders
  Details for market order vs. limit order and params see https://docs.kucoin.com/#place-a-new-order
  General params
  params = {
    clientOid: string
    side: string ['buy' || 'sell]
    symbol: string
    type: string [optional, default: limit]
    remark: string [optional]
    stop: string [optional] - either loss or entry and needs stopPrice
    stopPrice: string [optional] - needed for stop 
    stp: string [optional] (self trade prevention)
    price: string,
    size: string,
    timeInForce: string [optional, default is GTC]
    cancelAfter: long (unix time) [optional]
    hidden: boolean [optional]
    Iceberg: boolean [optional]
    visibleSize: string [optional]
  }
*/
api.placeOrder(params)
/* 
  Cancel an order
  DELETE /api/v1/orders/<order-id>
  params = {
    id: order-id
  }
*/
api.cancelOrder(params)
/* 
  Cancel all orders
  DELETE /api/v1/orders
  params = {
    symbol: string [optional]
  }
*/
api.cancelAllOrders(params)
/* 
  List orders
  GET /api/v1/orders
  params = {
    status: string [optional, default: dealt, alt: active]
    symbol: string [optional]
    side: string [optional, 'buy' || 'sell]
    type: string [optional, limit || limit_stop || market_stop]
    startAt: long (unix time) [optional]
    endAt: long (unix time) [optional]
  }
*/
api.getOrders(params)
/* 
  Get an order
  GET /api/v1/orders/<order-id>
  params = {
    id: order-id
  }
*/
api.getOrderById(params)
/* 
  List Fills
  GET /api/v1/fills
  params: {
    orderId: string [optional]
    symbol: string [optional]
    side: string [optional, 'buy' || 'sell]
    type: string [optional]
    startAt: long (unix time) [optional]
    endAt: long (unix time) [optional]
  }
*/
api.listFills(params)
/* 
  Get V1 Historical Orders List
  GET /api/v1/hist-orders
  params: {
    currentPage: integer [optional]
    pageSize: integer [optional]
    symbol: string [optional]
    startAt: long (unix time) [optional]
    endAt: long (unix time) [optional]
    side: string (buy || sell) [optional]
  }
*/
api.getV1HistoricalOrders(params)
/* 
  Get Position Details
  GET /api/v1/position?symbol=${symbol}
  Get Position List
  GET /api/v1/positions
  params: {
    symbol: string [optional]
  }
*/
api.getPosition()       // Get Position List
api.getPosition(params) // Get Position Details

Websockets

The websocket component of the API wrapper is utilized by initializing websockets based on topics that match Kucoin endpoints. These include:

  • 'ticker'
  • 'allTicker'
  • 'symbolSnapshot'
  • 'marketSnapshot'
  • 'orderbook'
  • 'match'
  • 'fullMatch' (optional - private)
  • 'orders' (private)
  • 'balances' (private)

To initialize a websocket, provide the paramaters and an event handler. A simple example is as follows:

// Parameters 
params = {
  topic: enum (see above)
  symbols: array (ignored if not required by the endpoint, single array element if single, multiple if desired)
}

// Public streaming websocket for the orderbook of the provide symbol(s)
api.initSocket({topic: "orderbook", symbols: ['KCS-BTC']}, (msg) => {
  let data = JSON.parse(msg)
  console.log(data)
})

// Private streaming websocket for account balances
api.initSocket({topic: "balances"}, (msg) => {
  let data = JSON.parse(msg)
  console.log(data)
})

The event handler can be programmed to manipulate/store the returned websocket stream data as desired.

Donation Addresses

BTC: 3KvTuAnv7o2VAf4LGgg1MiDURd2DgjFGaa

ETH: 0x7713a223e0e86355ac02b1e0de77695e822071cf

NEO: AWngpjmoXPHiJH6rtf81brPiyPomYAqe8j

Contact me for any other specific cryptocurrencies you'd prefer to use.

License

This project is open source and uses the ISC license. Feel free to utilize it in whatever way you see fit.

kucoin-node-api's People

Contributors

darkgl avatar dependabot[bot] avatar escwdev avatar fahadalbukhari avatar hishamudeen avatar jaggedsoft avatar mohaiminuleraj avatar pradyumnad avatar reiniervanderhoeven avatar rhinodavid avatar shadowstep33 avatar transakliquidity avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

kucoin-node-api's Issues

July 13, 2020 KuCoin Update

image
kucoin pushes the whole entire orderbook to you over websocket now
no other exchange does that as far as i know

normally you've gotta do a whole bunch of BS first

  1. connect to websocket
  2. put all messages from websocket into a queue
  3. download the full orderbook snapshot (uses a lot of weight, can only do one market per 3 seconds or so)
  4. process the queue backlog, but only items with a higher sequence id than what you just downloaded
  5. process realtime websockets as they come

now you could get ALL orders from all markets at once if your machine can handle it

I'm gonna push an update that allows people to specify their own websocket endpoints, and add a shortcut for the 50 best bid/ask depth

if anyone else wants to tackle the rest of the list be my guest otherwise i'll probably get around to it eventually

  1. Add Private Channel Messages
    2. Full MatchEngine Data (revision) (Level 3)
    3. Level2 - 5 best ask/bid orders
    4. Level2 - 50 best ask/bid orders
  2. Add Get Full Order Book(atomic)(revision)

Want to join a cool crypto discord? there are some really talented folks in here and you would probably feel right at home
https://discord.gg/a8m7pCQ

0 dealFunds/dealSize after successful trade

image

On occasion after performing a trade, I sometimes log the output of the trade data. Sometimes I am seeing that the keys dealFunds and dealSize are 0, when they should not be. This is important if I want to do a trade in sequence to know those values; in other words, the base currency I receive can also be repurposed as the quote currency.

What am I doing wrong? (spot limit order)

Hi,

Fairly new to this and it seems i'm doing something wrong...
I try to set a Limit order in BTC-USDT as a test but I get a "undefined" back as response.

This is the code i'm using:
api.placeOrder({clientOid: "test", side: "buy", symbol: "BTC-USDT", type: "limit", price: "49500", size: "60"}).then((r) => { console.log(r.data) }).catch((e) => { console.log(e) })

The only response I get is:
undefined

Can you give me a clue what i'm doing wrong?
Thanks!

Websocket enotfound

Hi, i'm getting this error when I try to init a websocket:

{ Error: getaddrinfo ENOTFOUND push1-v2.kucoin.com push1-v2.kucoin.com:80
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
  errno: 'ENOTFOUND',
  code: 'ENOTFOUND',
  syscall: 'getaddrinfo',
  hostname: 'push1-v2.kucoin.com',
  host: 'push1-v2.kucoin.com',
  port: 80 }

code

hello good day where did you code this program? in what editor? thank you i hope u can help me

getSymbols API not working with market parameter

The query parameter is missing in the query string.

market.js line number 11 replace

From:

let endpoint = '/api/v1/symbols'

To:

let endpoint = `/api/v1/symbols?market=${market}`

I hope this will help.

borrowing & lending data?

Hi, is there any plans to add the borrowing and lending information from kucoin API into this wrapper? thanks!

New REST and Websocket Endpoints

There are a bunch of new endpoints related to Kucoin margin trading that need to be added. Putting here for visibility. I may get around to it but will also review and accept any contributions that are solid.

Websocket 'orders'

Hey I think I found a bug,

when using the ws topic 'orders' I get an invalid topic error.
I could fix it by replacing '/market/level3:' with '/spotMarket/tradeOrders' in line 140 of the lib/websockets.js file.

Hope this helps.

having issue with Margin Trading

i never done crypto bot projects before so i may have some glitches here...
public methods are working just fine...
in private methods, placeOrder methods to be specific there is 2 error:

  1. the end point in trade.js file should change from '/api/v1/orders' to '/api/v1/margin/order'
  2. im getting 'You must enable Margin Trading.' with status 100000 and i know its about permissions. the point is i already gave this permission to api from kucoin dashboard api managment.

and i need help for sending a request with this details

  1. margin mode enabled with type 'market' so i give it the amount of USDT and api buy the coin (in my case XRP) with bestBid price that i'm getting from 'getTicker' method
  2. set the stopLoss and takeProfit by percent (price is ok. i will calculate it my self)
  3. defining SHORT or LONG for the order (i didn't figure it out. is it the side param? (BUY or SELL) )
    thanks in advance...
placeOrder(side) {
        return new Promise(async (resolve, reject) => {
            let latestData = {}
            await api.getTicker(process.env.CRYPTO_PAIR + '-USDT').then(r => latestData = r.data).then(r => console.log(r)).catch(err => reject(err))
            let fund = 3
            let params = {
                clientOid: latestData.time,
                side: side,
                symbol: process.env.CRYPTO_PAIR + '-USDT',
                tradeType: 'MARGIN_TRADE',
                type: 'market',
                stop: 'loss',
                stopPrice: latestData.bestBid - (latestData.bestBid / 100 * process.env.STOP_LOSS_PERCENT),
                timestamp: latestData.time,
                fund,
                size: fund / latestData.bestBid
            }
            await api.placeOrder(params).then(r => resolve(r)).catch(err => reject(err))
        })
    }

Typescript Interfaces

Would it be possible to add typescript interfaces to your package? I'm using it and love it. If you don't have the time or bandwidth, I have a fork and may do it, too, but if you can, that would make my life so much easier.

I really appreciate it!
-JI

example bots?

I'm looking to create a bot that buys at 5% dip and sells at 10% gain. Just do this over and over.

Before I started I wanted to know if anyone knows of any example bots before I recreate the wheel.

Websockets for Public topics not providing sign fails.

This should be fixable by doing this.

--- a/lib/websockets.js
+++ b/lib/websockets.js
@@ -53,7 +53,10 @@ Sockets.initSocket = async function(params, eventHandler) {
     if ( !params.sign ) params.sign = false;
     if ( !params.endpoint ) params.endpoint = false;
     let [topic, endpoint, type] = Sockets.topics( params.topic, params.symbols, params.endpoint, params.sign )
-    let sign = this.sign('/api/v1/bullet-private', {}, 'POST')
+    var sign = null;
+    if (params.sign) {
+      sign = this.sign('/api/v1/bullet-private', {}, 'POST')
+    }
     let websocket = await getSocketEndpoint(type, this.baseURL, this.environment, sign)
     let ws = new WebSocket(websocket)
     Sockets.ws[topic] = ws

Closing ws stream

Hello, I already commented this in another issue but figured it'd be appropriate to create an issue of my own.

I'm opening a websocket with:

const ws = api.initSocket( { topic: 'ticker', symbols: [BTC-USDT] }, (msg) => { let data = JSON.parse(msg); console.log(data); }

Then calling:

ws();

to close the stream I receive the error

TypeError: ws is not a function

Any idea why I'm getting this? Is this the correct way to close the ws?

[WS] Invalid URL: undefined on sandbox

Hi. Thanks for awesome library !

I experienced a bug when trying to api.initSocket (topic: orders) when connecting to sandbox.
Error:
TypeError [ERR_INVALID_URL]: Invalid URL: undefined at new NodeError (node:internal/errors:329:5) at onParseError (node:internal/url:282:9) at new URL (node:internal/url:358:5) at initAsClient (/xxx/node_modules/kucoin-node-api/node_modules/ws/lib/websocket.js:484:27) at new WebSocket (/xxx/node_modules/kucoin-node-api/node_modules/ws/lib/websocket.js:70:7) at Object.Sockets.initSocket (/xxx/node_modules/kucoin-node-api/lib/websockets.js:58:14) at processTicksAndRejections (node:internal/process/task_queues:94:5) { input: 'undefined', code: 'ERR_INVALID_URL' }

Error 400005

Getting this error when trying api.placeOrder, not sure where it comes from, all the other endpoints work just fine (can get accounts, balances etc)

data: { code: '400005', msg: 'Invalid KC-API-SIGN' }

Anyone having the same problem? any solution?

Problem with "PRIVATE" endpoint

Hello !
I just created an API Key on my sub account in order to do some test with their API.
The problem is when I want to do :

await api.getAccounts()

I have this error :

TypeError [ERR_INVALID_ARG_TYPE]: The "data" argument must be of type string or an instance of Buffer, TypedArray, or DataView. Received undefined

I checked all parameters, my connection, API credentials... Nothing work.

Thanks in advance !

Add "Place Bulk Orders"

Add support for "Place Bulk Orders"
https://docs.kucoin.com/#place-bulk-orders

Like that:

/* 
  Place Bulk Orders
  POST /api/v1/orders/multi
  Details for params see https://docs.kucoin.com/#place-bulk-orders
  General params
  params = {
    symbol: string,
    orderList: [
      {
          clientOid: string
          side: string ['buy' || 'sell]
          type: string [optional, default: limit] - limit or market
          remark: string [optional]
          stop: string [optional] - either loss or entry and needs stopPrice
          stopPrice: string [optional] - needed for stop 
          stp: string [optional] (self trade prevention)
          tradeType: string [optional, default: TRADE] - TRADE (Spot Trade), MARGIN_TRADE (Margin Trade)
          price: string,
          size: string,
          timeInForce: string [optional, default is GTC]
          cancelAfter: long (unix time) [optional]
          postOnly: boolean [optional] - Post only flag, invalid when timeInForce is IOC or FOK
          hidden: boolean [optional]
          Iceberg: boolean [optional]
          visibleSize: string [optional]
      }
    ]
  }
*/
api.placeBulkOrders(params)

How to configure proxy?

I'm trying to start websocket with a proxy. But its not working as expected. Is there any config changes we have to do to enable proxy?

In axios http adaptor, I found a set proxy config but not sure how to use it.

^ TypeError: Cannot read properties of undefined (reading 'init')

i get the error after to init
api.init(initConfig) ^ TypeError: Cannot read properties of undefined (reading 'init')
cannot read api after import.

import api  from 'kucoin-node-api';

  const config = {
      apiKey: kucoinApiKey,
      secretKey: kucoinApiSecret,
      passphrase: kucoinApiPassphrase,
      environment: productionEnv() ? "live" : 'sandbox'
    };
 api.init(config )

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.