Merge pull request #32 from tiagosiebler/#29

Breaking Change: fix #29 & process recent api deprecations
This commit is contained in:
Tiago
2020-11-11 21:23:22 +00:00
committed by GitHub
4 changed files with 105 additions and 40 deletions

View File

@@ -5,20 +5,27 @@
[1]: https://www.npmjs.com/package/bybit-api [1]: https://www.npmjs.com/package/bybit-api
An light node.js wrapper for the Bybit Cryptocurrency Derivative exchange API. Forked & adapted from [@pxtrn/bybit-api](https://github.com/pixtron/bybit-api). A production-ready Node.js connector for the Bybit APIs and WebSockets.
## Installation ## Installation
`npm install --save bybit-api` `npm install --save bybit-api`
## Usage ## Usage
Create API credentials at bybit (obviously you need to be logged in): Create API credentials at Bybit
- [Livenet](https://bybit.com/app/user/api-management?affiliate_id=9410&language=en-US&group_id=0&group_type=1) - [Livenet](https://bybit.com/app/user/api-management?affiliate_id=9410&language=en-US&group_id=0&group_type=1)
- [Testnet](https://testnet.bybit.com/app/user/api-management) - [Testnet](https://testnet.bybit.com/app/user/api-management)
## Documentation ## Issues & Discussion
Most of the documentation is in [Bybit's official API docs](https://bybit-exchange.github.io/docs/inverse/#t-introduction). Most of this library's methods accept objects that directly correspond to expectations from Bybit's API docs. - Issues? Check the [issues tab](https://github.com/tiagosiebler/bybit-api/issues).
- Discuss & collaborate with other node devs? Join our [Node.js Algo Traders](https://t.me/nodetraders) engineering community on telegram.
### Rest client ## Documentation
Most methods accept JS objects. These can be populated using parameters specified by Bybit's API documentation.
- [Bybit API Inverse Documentation](https://bybit-exchange.github.io/docs/inverse/#t-introduction).
- [Bybit API Linear Documentation (not supported yet)](https://bybit-exchange.github.io/docs/linear/#t-introduction)
### Inverse Contracts
#### Rest client
```javascript ```javascript
const {RestClient} = require('bybit-api'); const {RestClient} = require('bybit-api');
@@ -32,13 +39,13 @@ client.changeUserLeverage({leverage: 4, symbol: 'ETHUSD'})
console.log(result); console.log(result);
}) })
.catch(err => { .catch(err => {
console.error(error); console.error(err);
}); });
``` ```
See rest client [api docs](./doc/rest-client.md) for further information. See inverse [rest-client.js](./master/lib/rest-client.js) for further information.
### Websocket client #### Websocket client
```javascript ```javascript
const {WebsocketClient} = require('bybit-api'); const {WebsocketClient} = require('bybit-api');
@@ -50,28 +57,27 @@ const ws = new WebsocketClient({key: API_KEY, secret: PRIVATE_KEY});
ws.subscribe(['position', 'execution', 'trade']); ws.subscribe(['position', 'execution', 'trade']);
ws.subscribe('kline.BTCUSD.1m'); ws.subscribe('kline.BTCUSD.1m');
ws.on('open', function() { ws.on('open', () => {
console.log('connection open'); console.log('connection open');
}); });
ws.on('update', function(message) { ws.on('update', message => {
console.log('update', message); console.log('update', message);
}); });
ws.on('response', function(response) { ws.on('response', response => {
console.log('response', response); console.log('response', response);
}); });
ws.on('close', function() { ws.on('close', () => {
console.log('connection closed'); console.log('connection closed');
}); });
ws.on('error', function(err) { ws.on('error', err => {
console.error('ERR', err); console.error('ERR', err);
}); });
``` ```
See inverse [websocket-client.js](./master/lib/websocket-client.js) & [ws api docs](./doc/websocket-client.md) for further information.
See websocket client [api docs](./doc/websocket-client.md) for further information.
### Customise Logging ### Customise Logging
Pass a custom logger which supports the log methods `silly`, `debug`, `notice`, `info`, `warning` and `error`, or override methods from the default logger as desired: Pass a custom logger which supports the log methods `silly`, `debug`, `notice`, `info`, `warning` and `error`, or override methods from the default logger as desired:
@@ -82,20 +88,11 @@ const { RestClient, WebsocketClient, DefaultLogger } = require('bybit-api');
// Disable all logging on the silly level // Disable all logging on the silly level
DefaultLogger.silly = () => {}; DefaultLogger.silly = () => {};
const API_KEY = 'xxx'; const ws = new WebsocketClient({key: 'xxx', secret: 'yyy'}, DefaultLogger);
const PRIVATE_KEY = 'yyy';
const ws = new WebsocketClient({key: API_KEY, secret: PRIVATE_KEY}, DefaultLogger);
``` ```
## Contributions & Thanks ## Contributions & Thanks
### Donations ### Donations
#### pixtron
This library was started by @pixtron. If this library helps you to trade better on bybit, feel free to donate a coffee to @pixtron:
- BTC `1Fh1158pXXudfM6ZrPJJMR7Y5SgZUz4EdF`
- ETH `0x21aEdeC53ab7593b77C9558942f0c9E78131e8d7`
- LTC `LNdHSVtG6UWsriMYLJR3qLdfVNKwJ6GSLF`
#### tiagosiebler #### tiagosiebler
If you found this project interesting or useful, create accounts with my referral links: If you found this project interesting or useful, create accounts with my referral links:
- [Bybit](https://www.bybit.com/en-US/register?affiliate_id=9410&language=en-US&group_id=0&group_type=1) - [Bybit](https://www.bybit.com/en-US/register?affiliate_id=9410&language=en-US&group_id=0&group_type=1)
@@ -105,5 +102,11 @@ Or buy me a coffee using any of these:
- BTC: `1C6GWZL1XW3jrjpPTS863XtZiXL1aTK7Jk` - BTC: `1C6GWZL1XW3jrjpPTS863XtZiXL1aTK7Jk`
- ETH (ERC20): `0xd773d8e6a50758e1ada699bb6c4f98bb4abf82da` - ETH (ERC20): `0xd773d8e6a50758e1ada699bb6c4f98bb4abf82da`
#### pixtron
The original library was started by @pixtron. If this library helps you to trade better on bybit, feel free to donate a coffee to @pixtron:
- BTC `1Fh1158pXXudfM6ZrPJJMR7Y5SgZUz4EdF`
- ETH `0x21aEdeC53ab7593b77C9558942f0c9E78131e8d7`
- LTC `LNdHSVtG6UWsriMYLJR3qLdfVNKwJ6GSLF`
### Contributions & Pull Requests ### Contributions & Pull Requests
Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items. Contributions are encouraged, I will review any incoming pull requests. See the issues tab for todo items.

View File

@@ -6,6 +6,7 @@
"exclude": [ "exclude": [
"node_modules", "node_modules",
"**/node_modules/*", "**/node_modules/*",
"coverage" "coverage",
"doc"
] ]
} }

View File

@@ -1,6 +1,4 @@
const assert = require('assert'); const assert = require('assert');
const RequestWrapper = require('./util/requestWrapper'); const RequestWrapper = require('./util/requestWrapper');
module.exports = class RestClient { module.exports = class RestClient {
@@ -54,6 +52,17 @@ module.exports = class RestClient {
assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required'); assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required');
assert(params.symbol, 'Parameter symbol is required'); assert(params.symbol, 'Parameter symbol is required');
return await this.request.post('v2/private/order/replace', params);
}
/**
* @deprecated use replaceActiveOrder()
*/
async replaceActiveOrderOld(params) {
assert(params, 'No params passed');
assert(params.order_id || params.order_link_id, 'Parameter order_id OR order_link_id is required');
assert(params.symbol, 'Parameter symbol is required');
return await this.request.post('open-api/order/replace', params); return await this.request.post('open-api/order/replace', params);
} }
@@ -66,6 +75,24 @@ module.exports = class RestClient {
} }
async placeConditionalOrder(params) { async placeConditionalOrder(params) {
assert(params, 'No params passed');
assert(params.side, 'Parameter side is required');
assert(params.symbol, 'Parameter symbol is required');
assert(params.order_type, 'Parameter order_type is required');
assert(params.qty, 'Parameter qty is required');
assert(params.base_price, 'Parameter base_price is required');
assert(params.stop_px, 'Parameter stop_px is required');
assert(params.time_in_force, 'Parameter time_in_force is required');
if (params.order_type === 'Limit') assert(params.price, 'Parameter price is required for limit orders');
return await this.request.post('v2/private/stop-order/create', params);
}
/**
* @deprecated use placeConditionalOrder
*/
async placeConditionalOrderOld(params) {
assert(params, 'No params passed'); assert(params, 'No params passed');
assert(params.side, 'Parameter side is required'); assert(params.side, 'Parameter side is required');
assert(params.symbol, 'Parameter symbol is required'); assert(params.symbol, 'Parameter symbol is required');
@@ -81,10 +108,28 @@ module.exports = class RestClient {
} }
async getConditionalOrder(params) { async getConditionalOrder(params) {
assert(params.symbol, 'Parameter symbol is required');
return await this.request.get('v2/private/stop-order/list', params);
}
/**
* @deprecated use placeConditionalOrder
*/
async getConditionalOrderOld(params) {
return await this.request.get('open-api/stop-order/list', params); return await this.request.get('open-api/stop-order/list', params);
} }
async cancelConditionalOrder(params) { async cancelConditionalOrder(params) {
assert(params, 'No params passed');
assert(params.stop_order_id || params.order_link_id, 'Parameter stop_order_id OR order_link_id is required');
return await this.request.post('v2/private/stop-order/cancel', params);
}
/**
* @deprecated use cancelConditionalOrder
*/
async cancelConditionalOrderOld(params) {
assert(params, 'No params passed'); assert(params, 'No params passed');
assert(params.stop_order_id, 'Parameter stop_order_id is required'); assert(params.stop_order_id, 'Parameter stop_order_id is required');
@@ -99,6 +144,17 @@ module.exports = class RestClient {
} }
async replaceConditionalOrder(params) { async replaceConditionalOrder(params) {
assert(params, 'No params passed');
assert(params.stop_order_id || params.order_link_id, 'Parameter stop_order_id OR order_link_id is required');
assert(params.symbol, 'Parameter symbol is required');
return await this.request.post('v2/private/stop-order/replace', params);
}
/**
* @deprecated use replaceConditionalOrder
*/
async replaceConditionalOrderOld(params) {
assert(params, 'No params passed'); assert(params, 'No params passed');
assert(params.stop_order_id, 'Parameter stop_order_id is required'); assert(params.stop_order_id, 'Parameter stop_order_id is required');
assert(params.symbol, 'Parameter symbol is required'); assert(params.symbol, 'Parameter symbol is required');
@@ -114,10 +170,17 @@ module.exports = class RestClient {
return await this.request.get('v2/private/stop-order', params); return await this.request.get('v2/private/stop-order', params);
} }
/**
* @deprecated use getPosition() instead
*/
async getUserLeverage() { async getUserLeverage() {
return await this.request.get('user/leverage'); return await this.request.get('user/leverage');
} }
async getPosition(params) {
return await this.request.get('v2/private/position/list', params);
}
async changeUserLeverage(params) { async changeUserLeverage(params) {
assert(params, 'No params passed'); assert(params, 'No params passed');
assert(params.leverage, 'Parameter leverage is required'); assert(params.leverage, 'Parameter leverage is required');
@@ -126,13 +189,9 @@ module.exports = class RestClient {
return await this.request.post('user/leverage/save', params); return await this.request.post('user/leverage/save', params);
} }
async getPosition(params) { /**
assert(params, 'No params passed'); * @deprecated use getPosition() instead
assert(params.symbol, 'Parameter symbol is required'); */
return await this.request.get('v2/private/position/list', params);
}
async getPositions() { async getPositions() {
return await this.request.get('position/list'); return await this.request.get('position/list');
} }

View File

@@ -1,7 +1,7 @@
{ {
"name": "bybit-api", "name": "bybit-api",
"version": "1.2.1", "version": "1.2.2",
"description": "A node.js wrapper for the Bybit Cryptocurrency Derivative exchange APIs", "description": "A production-ready Node.js connector for the Bybit APIs and WebSockets",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "echo \"Error: no test specified\" && exit 1"
@@ -18,13 +18,15 @@
"rest api", "rest api",
"inverse", "inverse",
"nodejs", "nodejs",
"node",
"trading", "trading",
"cryptocurrency", "cryptocurrency",
"bitcoin" "bitcoin",
"best"
], ],
"author": "Stefan Aebischer <os@pixtron.ch> (https://pixtron.ch)", "author": "Tiago Siebler (https://github.com/tiagosiebler)",
"contributors": [ "contributors": [
"Tiago Siebler (https://github.com/tiagosiebler)" "Stefan Aebischer <os@pixtron.ch> (https://pixtron.ch)"
], ],
"license": "MIT", "license": "MIT",
"bugs": { "bugs": {