cleaning, fix and add spot post tests
This commit is contained in:
@@ -9,3 +9,34 @@ export const positionTpSlModeEnum = {
|
|||||||
/** Partial take profit/stop loss mode (multiple TP and SL orders can be placed, covering portions of the position) */
|
/** Partial take profit/stop loss mode (multiple TP and SL orders can be placed, covering portions of the position) */
|
||||||
Partial: 'Partial',
|
Partial: 'Partial',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const API_ERROR_CODE = {
|
||||||
|
BALANCE_INSUFFICIENT_SPOT: -1131,
|
||||||
|
ORDER_NOT_FOUND_OR_TOO_LATE_SPOT: -2013,
|
||||||
|
/** This could mean bad request, incorrect value types or even incorrect/missing values */
|
||||||
|
PARAMS_MISSING_OR_WRONG: 10001,
|
||||||
|
ORDER_NOT_FOUND_OR_TOO_LATE: 20001,
|
||||||
|
POSITION_STATUS_NOT_NORMAL: 30013,
|
||||||
|
CANNOT_SET_TRADING_STOP_FOR_ZERO_POS: 30024,
|
||||||
|
/** Seen when placing an order */
|
||||||
|
INSUFFICIENT_BALANCE_FOR_ORDER_COST: 30031,
|
||||||
|
POSITION_IDX_NOT_MATCH_POSITION_MODE: 30041,
|
||||||
|
/** Seen if a conditional order is too large */
|
||||||
|
INSUFFICIENT_BALANCE: 30042,
|
||||||
|
/** E.g. trying to change position margin while on cross */
|
||||||
|
POSITION_IS_CROSS_MARGIN: 30056,
|
||||||
|
POSITION_MODE_NOT_MODIFIED: 30083,
|
||||||
|
ISOLATED_NOT_MODIFIED: 30084,
|
||||||
|
RISK_LIMIT_NOT_EXISTS: 30090,
|
||||||
|
LEVERAGE_NOT_MODIFIED: 34036,
|
||||||
|
SAME_SLTP_MODE: 37002,
|
||||||
|
ORDER_NOT_FOUND_OR_TOO_LATE_LINEAR: 130010,
|
||||||
|
ORDER_COST_NOT_AVAILABLE: 130021,
|
||||||
|
CANNOT_SET_LINEAR_TRADING_STOP_FOR_ZERO_POS: 130024,
|
||||||
|
ISOLATED_NOT_MODIFIED_LINEAR: 130056,
|
||||||
|
POSITION_SIZE_IS_ZERO: 130057,
|
||||||
|
AUTO_ADD_MARGIN_NOT_MODIFIED: 130060,
|
||||||
|
INSUFFICIENT_BALANCE_FOR_ORDER_COST_LINEAR: 130080,
|
||||||
|
SAME_SLTP_MODE_LINEAR: 130150,
|
||||||
|
RISK_ID_NOT_MODIFIED: 134026,
|
||||||
|
} as const;
|
||||||
|
|||||||
@@ -7,5 +7,4 @@ export * from './logger';
|
|||||||
export * from './types/shared';
|
export * from './types/shared';
|
||||||
export * from './types/spot';
|
export * from './types/spot';
|
||||||
export * from './util/WsStore';
|
export * from './util/WsStore';
|
||||||
export * from './util/enum';
|
|
||||||
export * from './constants/enum';
|
export * from './constants/enum';
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import {
|
|||||||
} from './types/spot';
|
} from './types/spot';
|
||||||
import BaseRestClient from './util/BaseRestClient';
|
import BaseRestClient from './util/BaseRestClient';
|
||||||
import {
|
import {
|
||||||
|
agentSource,
|
||||||
getRestBaseUrl,
|
getRestBaseUrl,
|
||||||
RestClientOptions,
|
RestClientOptions,
|
||||||
REST_CLIENT_TYPE_ENUM,
|
REST_CLIENT_TYPE_ENUM,
|
||||||
@@ -121,7 +122,10 @@ export class SpotClient extends BaseRestClient {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
submitOrder(params: NewSpotOrder): Promise<APIResponse<any>> {
|
submitOrder(params: NewSpotOrder): Promise<APIResponse<any>> {
|
||||||
return this.postPrivate('/spot/v1/order', params);
|
return this.postPrivate('/spot/v1/order', {
|
||||||
|
...params,
|
||||||
|
agentSource,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getOrder(params: SpotOrderQueryById): Promise<APIResponse<any>> {
|
getOrder(params: SpotOrderQueryById): Promise<APIResponse<any>> {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
serializeParams,
|
serializeParams,
|
||||||
RestClientType,
|
RestClientType,
|
||||||
REST_CLIENT_TYPE_ENUM,
|
REST_CLIENT_TYPE_ENUM,
|
||||||
|
agentSource,
|
||||||
} from './requestUtils';
|
} from './requestUtils';
|
||||||
|
|
||||||
// axios.interceptors.request.use((request) => {
|
// axios.interceptors.request.use((request) => {
|
||||||
@@ -162,8 +163,13 @@ export default abstract class BaseRestClient {
|
|||||||
|
|
||||||
const signResult = await this.prepareSignParams(params, isPublicApi);
|
const signResult = await this.prepareSignParams(params, isPublicApi);
|
||||||
|
|
||||||
if (method === 'GET') {
|
if (method === 'GET' || this.isSpotClient()) {
|
||||||
options.params = signResult.paramsWithSign;
|
options.params = signResult.paramsWithSign;
|
||||||
|
if (options.params?.agentSource) {
|
||||||
|
options.data = {
|
||||||
|
agentSource: agentSource,
|
||||||
|
};
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
options.data = signResult.paramsWithSign;
|
options.data = signResult.paramsWithSign;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
export const API_ERROR_CODE = {
|
|
||||||
PARAMS_MISSING_OR_WRONG: 10001,
|
|
||||||
ORDER_NOT_FOUND_OR_TOO_LATE: 20001,
|
|
||||||
POSITION_STATUS_NOT_NORMAL: 30013,
|
|
||||||
CANNOT_SET_TRADING_STOP_FOR_ZERO_POS: 30024,
|
|
||||||
/** Seen when placing an order */
|
|
||||||
INSUFFICIENT_BALANCE_FOR_ORDER_COST: 30031,
|
|
||||||
POSITION_IDX_NOT_MATCH_POSITION_MODE: 30041,
|
|
||||||
/** Seen if a conditional order is too large */
|
|
||||||
INSUFFICIENT_BALANCE: 30042,
|
|
||||||
/** E.g. trying to change position margin while on cross */
|
|
||||||
POSITION_IS_CROSS_MARGIN: 30056,
|
|
||||||
POSITION_MODE_NOT_MODIFIED: 30083,
|
|
||||||
ISOLATED_NOT_MODIFIED: 30084,
|
|
||||||
RISK_LIMIT_NOT_EXISTS: 30090,
|
|
||||||
LEVERAGE_NOT_MODIFIED: 34036,
|
|
||||||
SAME_SLTP_MODE: 37002,
|
|
||||||
ORDER_NOT_FOUND_OR_TOO_LATE_LINEAR: 130010,
|
|
||||||
ORDER_COST_NOT_AVAILABLE: 130021,
|
|
||||||
CANNOT_SET_LINEAR_TRADING_STOP_FOR_ZERO_POS: 130024,
|
|
||||||
ISOLATED_NOT_MODIFIED_LINEAR: 130056,
|
|
||||||
POSITION_SIZE_IS_ZERO: 130057,
|
|
||||||
AUTO_ADD_MARGIN_NOT_MODIFIED: 130060,
|
|
||||||
INSUFFICIENT_BALANCE_FOR_ORDER_COST_LINEAR: 130080,
|
|
||||||
SAME_SLTP_MODE_LINEAR: 130150,
|
|
||||||
RISK_ID_NOT_MODIFIED: 134026,
|
|
||||||
} as const;
|
|
||||||
@@ -85,6 +85,8 @@ export function isWsPong(response: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const agentSource = 'bybitapinode';
|
||||||
|
|
||||||
export const REST_CLIENT_TYPE_ENUM = {
|
export const REST_CLIENT_TYPE_ENUM = {
|
||||||
inverse: 'inverse',
|
inverse: 'inverse',
|
||||||
inverseFutures: 'inverseFutures',
|
inverseFutures: 'inverseFutures',
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { InverseFuturesClient } from '../../src';
|
import { API_ERROR_CODE, InverseFuturesClient } from '../../src';
|
||||||
import { API_ERROR_CODE } from '../../src/util/enum';
|
|
||||||
import { successResponseObject } from '../response.util';
|
import { successResponseObject } from '../response.util';
|
||||||
|
|
||||||
describe('Private Inverse-Futures REST API POST Endpoints', () => {
|
describe('Private Inverse-Futures REST API POST Endpoints', () => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
import { API_ERROR_CODE } from '../../src';
|
||||||
import { InverseClient } from '../../src/inverse-client';
|
import { InverseClient } from '../../src/inverse-client';
|
||||||
import { API_ERROR_CODE } from '../../src/util/enum';
|
import { successResponseObject } from '../response.util';
|
||||||
import { successResponseList, successResponseObject } from '../response.util';
|
|
||||||
|
|
||||||
describe('Private Inverse REST API Endpoints', () => {
|
describe('Private Inverse REST API Endpoints', () => {
|
||||||
const useLivenet = true;
|
const useLivenet = true;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { LinearClient } from '../../src';
|
import { API_ERROR_CODE, LinearClient } from '../../src';
|
||||||
import { API_ERROR_CODE } from '../../src/util/enum';
|
|
||||||
import { successResponseObject } from '../response.util';
|
import { successResponseObject } from '../response.util';
|
||||||
|
|
||||||
describe('Private Inverse-Futures REST API POST Endpoints', () => {
|
describe('Private Inverse-Futures REST API POST Endpoints', () => {
|
||||||
|
|||||||
56
test/spot/private.write.test.ts
Normal file
56
test/spot/private.write.test.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { API_ERROR_CODE, SpotClient } from '../../src';
|
||||||
|
import { successResponseObject } from '../response.util';
|
||||||
|
|
||||||
|
describe('Private Inverse-Futures REST API POST 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 SpotClient(API_KEY, API_SECRET, useLivenet, {
|
||||||
|
disable_time_sync: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Warning: if some of these start to fail with 10001 params error, it's probably that this future expired and a newer one exists with a different symbol!
|
||||||
|
const symbol = 'BTCUSDT';
|
||||||
|
|
||||||
|
// These tests are primarily check auth is working by expecting balance or order not found style errors
|
||||||
|
|
||||||
|
it('submitOrder()', async () => {
|
||||||
|
expect(
|
||||||
|
await api.submitOrder({
|
||||||
|
side: 'Buy',
|
||||||
|
symbol,
|
||||||
|
qty: 10000,
|
||||||
|
type: 'MARKET',
|
||||||
|
})
|
||||||
|
).toMatchObject({
|
||||||
|
ret_code: API_ERROR_CODE.BALANCE_INSUFFICIENT_SPOT,
|
||||||
|
ret_msg: 'Balance insufficient ',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancelOrder()', async () => {
|
||||||
|
expect(
|
||||||
|
await api.cancelOrder({
|
||||||
|
orderId: '1231231',
|
||||||
|
})
|
||||||
|
).toMatchObject({
|
||||||
|
ret_code: API_ERROR_CODE.ORDER_NOT_FOUND_OR_TOO_LATE_SPOT,
|
||||||
|
ret_msg: 'Order does not exist.',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cancelOrderBatch()', async () => {
|
||||||
|
expect(
|
||||||
|
await api.cancelOrderBatch({
|
||||||
|
symbol,
|
||||||
|
orderTypes: ['LIMIT', 'LIMIT_MAKER'],
|
||||||
|
})
|
||||||
|
).toMatchObject(successResponseObject(''));
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user