copy trading API
This commit is contained in:
12
.github/workflows/npmpublish.yml
vendored
12
.github/workflows/npmpublish.yml
vendored
@@ -9,16 +9,6 @@ on:
|
|||||||
- master
|
- master
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-node@v1
|
|
||||||
with:
|
|
||||||
node-version: 12
|
|
||||||
#- run: npm ci
|
|
||||||
#- run: npm test
|
|
||||||
|
|
||||||
publish-npm:
|
publish-npm:
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -37,7 +27,7 @@ jobs:
|
|||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
if: steps.version-updated.outputs.has-updated
|
if: steps.version-updated.outputs.has-updated
|
||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 16
|
||||||
registry-url: https://registry.npmjs.org/
|
registry-url: https://registry.npmjs.org/
|
||||||
|
|
||||||
- run: npm ci --ignore-scripts
|
- run: npm ci --ignore-scripts
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ export const API_ERROR_CODE = {
|
|||||||
SUCCESS: 0,
|
SUCCESS: 0,
|
||||||
/** This could mean bad request, incorrect value types or even incorrect/missing values */
|
/** This could mean bad request, incorrect value types or even incorrect/missing values */
|
||||||
PARAMS_MISSING_OR_WRONG: 10001,
|
PARAMS_MISSING_OR_WRONG: 10001,
|
||||||
|
INCORRECT_API_KEY_PERMISSIONS: 10005,
|
||||||
ORDER_NOT_FOUND_OR_TOO_LATE: 20001,
|
ORDER_NOT_FOUND_OR_TOO_LATE: 20001,
|
||||||
POSITION_STATUS_NOT_NORMAL: 30013,
|
POSITION_STATUS_NOT_NORMAL: 30013,
|
||||||
CANNOT_SET_TRADING_STOP_FOR_ZERO_POS: 30024,
|
CANNOT_SET_TRADING_STOP_FOR_ZERO_POS: 30024,
|
||||||
|
|||||||
157
src/copy-trading-client.ts
Normal file
157
src/copy-trading-client.ts
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
import {
|
||||||
|
APIResponseWithTime,
|
||||||
|
CopyTradingCancelOrderRequest,
|
||||||
|
CopyTradingCloseOrderRequest,
|
||||||
|
CopyTradingOrderListRequest,
|
||||||
|
CopyTradingOrderRequest,
|
||||||
|
CopyTradingTradingStopRequest,
|
||||||
|
CopyTradingTransferRequest,
|
||||||
|
USDCAPIResponse,
|
||||||
|
} from './types';
|
||||||
|
import { REST_CLIENT_TYPE_ENUM } from './util';
|
||||||
|
import BaseRestClient from './util/BaseRestClient';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* REST API client for USDC Perpetual APIs
|
||||||
|
*/
|
||||||
|
export class CopyTradingClient extends BaseRestClient {
|
||||||
|
getClientType() {
|
||||||
|
// Follows the same authentication mechanism as USDC APIs
|
||||||
|
return REST_CLIENT_TYPE_ENUM.usdc;
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchServerTime(): Promise<number> {
|
||||||
|
const res = await this.getServerTime();
|
||||||
|
return Number(res.time_now);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Market Data Endpoints
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
getSymbolList(): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.get('/contract/v3/public/copytrading/symbol/list');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Account Data Endpoints
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** -> Order API */
|
||||||
|
|
||||||
|
/** Create order */
|
||||||
|
submitOrder(params: CopyTradingOrderRequest): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate(
|
||||||
|
'/contract/v3/private/copytrading/order/create',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Set Trading Stop */
|
||||||
|
setTradingStop(
|
||||||
|
params: CopyTradingTradingStopRequest
|
||||||
|
): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate(
|
||||||
|
'/contract/v3/private/copytrading/order/trading-stop',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Query Order List */
|
||||||
|
getActiveOrders(
|
||||||
|
params?: CopyTradingOrderListRequest
|
||||||
|
): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.getPrivate(
|
||||||
|
'/contract/v3/private/copytrading/order/list',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Cancel order */
|
||||||
|
cancelOrder(
|
||||||
|
params: CopyTradingCancelOrderRequest
|
||||||
|
): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate(
|
||||||
|
'/contract/v3/private/copytrading/order/cancel',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Close Order. This endpoint's rate_limit will decrease by 10 per request; ie, one request to this endpoint consumes 10 from the limit allowed per minute. */
|
||||||
|
closeOrder(
|
||||||
|
params: CopyTradingCloseOrderRequest
|
||||||
|
): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate('/contract/v3/private/copytrading/order/close', {
|
||||||
|
params,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** -> Positions API */
|
||||||
|
|
||||||
|
/** Position List */
|
||||||
|
getPositions(symbol?: string): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.getPrivate('/contract/v3/private/copytrading/position/list', {
|
||||||
|
symbol,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Close Position */
|
||||||
|
closePosition(
|
||||||
|
symbol: string,
|
||||||
|
positionIdx: string
|
||||||
|
): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate('/contract/v3/private/copytrading/position/close', {
|
||||||
|
symbol,
|
||||||
|
positionIdx,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Only integers can be set to set the leverage */
|
||||||
|
setLeverage(
|
||||||
|
symbol: string,
|
||||||
|
buyLeverage: string,
|
||||||
|
sellLeverage: string
|
||||||
|
): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate(
|
||||||
|
'/contract/v3/private/copytrading/position/set-leverage',
|
||||||
|
{ symbol, buyLeverage, sellLeverage }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Wallet Data Endpoints
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Get Wallet Balance */
|
||||||
|
getBalance(): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.getPrivate('/contract/v3/private/copytrading/wallet/balance');
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Transfer */
|
||||||
|
transfer(params: CopyTradingTransferRequest): Promise<USDCAPIResponse<any>> {
|
||||||
|
return this.postPrivate(
|
||||||
|
'/contract/v3/private/copytrading/wallet/transfer',
|
||||||
|
params
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* API Data Endpoints
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
getServerTime(): Promise<APIResponseWithTime> {
|
||||||
|
return this.get('/v2/public/time');
|
||||||
|
}
|
||||||
|
|
||||||
|
getAnnouncements(): Promise<APIResponseWithTime<any[]>> {
|
||||||
|
return this.get('/v2/public/announcement');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './account-asset-client';
|
export * from './account-asset-client';
|
||||||
|
export * from './copy-trading-client';
|
||||||
export * from './inverse-client';
|
export * from './inverse-client';
|
||||||
export * from './inverse-futures-client';
|
export * from './inverse-futures-client';
|
||||||
export * from './linear-client';
|
export * from './linear-client';
|
||||||
@@ -6,7 +7,7 @@ export * from './spot-client';
|
|||||||
export * from './usdc-option-client';
|
export * from './usdc-option-client';
|
||||||
export * from './usdc-perpetual-client';
|
export * from './usdc-perpetual-client';
|
||||||
export * from './websocket-client';
|
export * from './websocket-client';
|
||||||
export * from './logger';
|
export * from './util/logger';
|
||||||
export * from './types';
|
export * from './types';
|
||||||
export * from './util/WsStore';
|
export * from './util/WsStore';
|
||||||
export * from './constants/enum';
|
export * from './constants/enum';
|
||||||
|
|||||||
53
src/types/request/copy-trading.ts
Normal file
53
src/types/request/copy-trading.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { OrderSide } from '../shared';
|
||||||
|
import { USDCOrderType } from './usdc-shared';
|
||||||
|
|
||||||
|
export interface CopyTradingOrderRequest {
|
||||||
|
side: OrderSide;
|
||||||
|
symbol: string;
|
||||||
|
orderType: USDCOrderType;
|
||||||
|
price: string;
|
||||||
|
qty: string;
|
||||||
|
takeProfit?: string;
|
||||||
|
stopLoss?: string;
|
||||||
|
tpTriggerBy?: string;
|
||||||
|
slTriggerBy?: string;
|
||||||
|
orderLinkId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CopyTradingTradingStopRequest {
|
||||||
|
symbol: string;
|
||||||
|
parentOrderId: string;
|
||||||
|
takeProfit?: string;
|
||||||
|
stopLoss?: string;
|
||||||
|
tpTriggerBy?: string;
|
||||||
|
slTriggerBy?: string;
|
||||||
|
parentOrderLinkId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CopyTradingOrderListRequest {
|
||||||
|
symbol?: string;
|
||||||
|
orderId?: string;
|
||||||
|
orderLinkId?: string;
|
||||||
|
copyTradeOrderType?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CopyTradingCancelOrderRequest {
|
||||||
|
symbol: string;
|
||||||
|
orderId?: string;
|
||||||
|
orderLinkId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CopyTradingCloseOrderRequest {
|
||||||
|
symbol: string;
|
||||||
|
orderLinkId?: string;
|
||||||
|
parentOrderId?: string;
|
||||||
|
parentOrderLinkId?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CopyTradingTransferRequest {
|
||||||
|
transferId: string;
|
||||||
|
coin: string;
|
||||||
|
amount: string;
|
||||||
|
fromAccountType: string;
|
||||||
|
toAccountType: string;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './account-asset';
|
export * from './account-asset';
|
||||||
|
export * from './copy-trading';
|
||||||
export * from './usdt-perp';
|
export * from './usdt-perp';
|
||||||
export * from './usdc-perp';
|
export * from './usdc-perp';
|
||||||
export * from './usdc-options';
|
export * from './usdc-options';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { WsConnectionState } from '../websocket-client';
|
|
||||||
import { DefaultLogger } from '../logger';
|
|
||||||
|
|
||||||
import WebSocket from 'isomorphic-ws';
|
import WebSocket from 'isomorphic-ws';
|
||||||
|
|
||||||
|
import { WsConnectionState } from '../websocket-client';
|
||||||
|
import { DefaultLogger } from './logger';
|
||||||
|
|
||||||
type WsTopic = string;
|
type WsTopic = string;
|
||||||
type WsTopicList = Set<WsTopic>;
|
type WsTopicList = Set<WsTopic>;
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
export * from './BaseRestClient';
|
export * from './BaseRestClient';
|
||||||
export * from './requestUtils';
|
export * from './requestUtils';
|
||||||
export * from './WsStore';
|
export * from './WsStore';
|
||||||
|
export * from './logger';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import WebSocket from 'isomorphic-ws';
|
|||||||
|
|
||||||
import { InverseClient } from './inverse-client';
|
import { InverseClient } from './inverse-client';
|
||||||
import { LinearClient } from './linear-client';
|
import { LinearClient } from './linear-client';
|
||||||
import { DefaultLogger } from './logger';
|
import { DefaultLogger } from './util/logger';
|
||||||
import { SpotClient } from './spot-client';
|
import { SpotClient } from './spot-client';
|
||||||
import { KlineInterval } from './types/shared';
|
import { KlineInterval } from './types/shared';
|
||||||
import { signMessage } from './util/node-support';
|
import { signMessage } from './util/node-support';
|
||||||
|
|||||||
36
test/copy-trading/private.read.test.ts
Normal file
36
test/copy-trading/private.read.test.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { API_ERROR_CODE, CopyTradingClient } from '../../src';
|
||||||
|
import { successResponseObject } from '../response.util';
|
||||||
|
|
||||||
|
describe('Private Copy Trading REST API Endpoints', () => {
|
||||||
|
const useLivenet = true;
|
||||||
|
const API_KEY = process.env.API_KEY_COM;
|
||||||
|
const API_SECRET = process.env.API_SECRET_COM;
|
||||||
|
|
||||||
|
it('should have api credentials to test with', () => {
|
||||||
|
expect(API_KEY).toStrictEqual(expect.any(String));
|
||||||
|
expect(API_SECRET).toStrictEqual(expect.any(String));
|
||||||
|
});
|
||||||
|
|
||||||
|
const api = new CopyTradingClient(API_KEY, API_SECRET, useLivenet);
|
||||||
|
|
||||||
|
// Don't have copy trading properly enabled on the test account, so testing is very light
|
||||||
|
// (just make sure auth works and endpoint doesn't throw)
|
||||||
|
|
||||||
|
it('getActiveOrders()', async () => {
|
||||||
|
expect(await api.getActiveOrders()).toMatchObject({
|
||||||
|
retCode: API_ERROR_CODE.INCORRECT_API_KEY_PERMISSIONS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getPositions()', async () => {
|
||||||
|
expect(await api.getPositions()).toMatchObject({
|
||||||
|
retCode: API_ERROR_CODE.INCORRECT_API_KEY_PERMISSIONS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getBalance()', async () => {
|
||||||
|
expect(await api.getBalance()).toMatchObject({
|
||||||
|
retCode: API_ERROR_CODE.INCORRECT_API_KEY_PERMISSIONS,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
26
test/copy-trading/public.read.test.ts
Normal file
26
test/copy-trading/public.read.test.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { CopyTradingClient } from '../../src';
|
||||||
|
import { successResponseObject } from '../response.util';
|
||||||
|
|
||||||
|
describe('Public Copy Trading REST API Endpoints', () => {
|
||||||
|
const useLivenet = true;
|
||||||
|
const API_KEY = undefined;
|
||||||
|
const API_SECRET = undefined;
|
||||||
|
|
||||||
|
const api = new CopyTradingClient(API_KEY, API_SECRET, useLivenet);
|
||||||
|
|
||||||
|
it('getSymbolList()', async () => {
|
||||||
|
expect(await api.getSymbolList()).toMatchObject({
|
||||||
|
result: {
|
||||||
|
list: expect.any(Array),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getServerTime()', async () => {
|
||||||
|
expect(await api.getServerTime()).toMatchObject(successResponseObject());
|
||||||
|
});
|
||||||
|
|
||||||
|
it('getAnnouncements()', async () => {
|
||||||
|
expect(await api.getAnnouncements()).toMatchObject(successResponseObject());
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user