binance
Version:
Professional Node.js & JavaScript SDK for Binance REST APIs & WebSockets, with TypeScript & end-to-end tests.
1,736 lines (1,657 loc) • 641 kB
Plain Text
This file is a merged representation of a subset of the codebase, containing files not matching ignore patterns, combined into a single document by Repomix.
The content has been processed where content has been compressed (code blocks are separated by ⋮---- delimiter), security check has been disabled.
================================================================
File Summary
================================================================
Purpose:
--------
This file contains a packed representation of a subset of the repository's contents that is considered the most important context.
It is designed to be easily consumable by AI systems for analysis, code review,
or other automated processes.
File Format:
------------
The content is organized as follows:
1. This summary section
2. Repository information
3. Directory structure
4. Repository files (if enabled)
5. Multiple file entries, each consisting of:
a. A separator line (================)
b. The file path (File: path/to/file)
c. Another separator line
d. The full contents of the file
e. A blank line
Usage Guidelines:
-----------------
- This file should be treated as read-only. Any changes should be made to the
original repository files, not this packed version.
- When processing this file, use the file path to distinguish
between different files in the repository.
- Be aware that this file may contain sensitive information. Handle it with
the same level of security as you would the original repository.
Notes:
------
- Some files may have been excluded based on .gitignore rules and Repomix's configuration
- Binary files are not included in this packed representation. Please refer to the Repository Structure section for a complete list of file paths, including binary files
- Files matching these patterns are excluded: .github/, examples/apidoc/, docs/images/, docs/endpointFunctionList.md, test/, src/util/
- Files matching patterns in .gitignore are excluded
- Files matching default ignore patterns are excluded
- Content has been compressed - code blocks are separated by ⋮---- delimiter
- Security check has been disabled - content may contain sensitive information
- Files are sorted by Git change count (files with more changes are at the bottom)
================================================================
Directory Structure
================================================================
.circleci/
config.yml
examples/
auth/
rest-private-ed25519.md
rest-private-ed25519.ts
rest-private-rsa.md
rest-private-rsa.ts
misc/
README.md
rest-spot-exchange-info.ts
tracking-candles.ts
REST/
rest-future-bracket-order.ts
rest-portfoliomargin-private.ts
rest-portfoliomargin-public.ts
rest-spot-private-autoinvest.ts
rest-spot-private-misc.ts
rest-spot-private-trade.ts
rest-spot-public.ts
rest-usdm-order-sl.ts
rest-usdm-order.ts
rest-usdm-private-get.ts
rest-usdm-public.ts
rest-usdm-testnet.ts
WebSockets/
deprecated-ws-public.ts
ws-api-client.ts
ws-api-raw-promises.ts
ws-close.ts
ws-proxy-socks.ts
ws-public-spot-orderbook.ts
ws-public-spot-trades.ts
ws-public-usdm-funding.ts
ws-public.ts
ws-unsubscribe.ts
ws-userdata-connection-safety.ts
ws-userdata-listenKey-testnet.ts
ws-userdata-listenkey.ts
ws-userdata-README.MD
ws-userdata-wsapi.ts
README.md
src/
types/
websockets/
ws-api-requests.ts
ws-api-responses.ts
ws-api.ts
ws-events-formatted.ts
ws-events-raw.ts
ws-general.ts
coin.ts
futures.ts
portfolio-margin.ts
shared.ts
spot.ts
coinm-client.ts
index.ts
main-client.ts
portfolio-client.ts
usdm-client.ts
websocket-api-client.ts
websocket-client-legacy.ts
websocket-client.ts
webpack/
webpack.config.js
.eslintrc.cjs
.gitignore
.jshintrc
.npmignore
.nvmrc
.prettierrc
CHANGELOG.md
index.js
jest.config.ts
jsconfig.json
LICENSE.md
package.json
README.md
tea.yaml
tsconfig.build.json
tsconfig.json
tsconfig.linting.json
================================================================
Files
================================================================
================
File: .circleci/config.yml
================
version: 2.1
jobs:
test:
docker:
- image: cimg/node:15.1
# resource_class: tiagosiebler/localcirunner
# The resource_class feature allows configuring CPU and RAM resources for each job. Different resource classes are available for different executors. https://circleci.com/docs/2.0/configuration-reference/#resourceclass
resource_class: large
steps:
- checkout
- restore_cache:
# See the configuration reference documentation for more details on using restore_cache and save_cache steps
# https://circleci.com/docs/2.0/configuration-reference/?section=reference#save_cache
keys:
- node-deps-v1-{{ .Branch }}-{{checksum "package-lock.json"}}
- run:
name: install packages
command: npm ci --ignore-scripts
- save_cache:
key: node-deps-v1-{{ .Branch }}-{{checksum "package-lock.json"}}
paths:
- ~/.npm
- run:
name: Run Build
command: npm run build
- run:
name: Run Tests
command: npm run test
workflows:
integrationtests:
jobs:
- test
================
File: examples/auth/rest-private-ed25519.ts
================
import { MainClient } from '../../src/index';
⋮----
// or
// import { MainClient } from 'binance';
⋮----
// Received after creating a new API key with a self-generated RSA public key on binance
⋮----
// The self-generated RSA private key, this is never directly given to binance, but used to generate a signature
// Note: this MUST include the "BEGIN PRIVATE KEY" header so the SDK understands this is RSA auth
================
File: examples/auth/rest-private-rsa.md
================
# RSA Authentication with Binance APIs in Node.js
## Creating RSA Keys
Officially, binance recommends downloading and running a key generator from their repo. Guidance for this can be found on the binance website when trying to add a new RSA API key.
However, openssl can be used to create the public & private key files using the following steps:
```bash
# Generate a private key with either 2048 or 4096 bit length
openssl genrsa -out rsa-private-key.pem 4096
# Generate a corresponding public key
openssl rsa -in rsa-private-key.pem -pubout -out rsa-public-key.pem
```
## Using the RSA public key to get an API key from Binance
Once created, keep your **private key** completely secret! The **public** key needs to be provided to binance when creating new API credentials with the "Self-generated" option.
Your public key should look something like this:
```pem
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1uWxxOXZUaX6AeZszf4x
rBsU6axA5ipwxG7VPihVgssphDrrSOD0hZqnBmtF2bvT9ee1U0XOfMn+H+J5SH+1
jgUpfioqH0L+KXl6wmLoPsadgfJz0SiQlFnKTkDXvMmecr6cdMHi2qNEx4CMc68C
obvQ4Voz5qqpDwbohGtJh0p10PB//0Ejcoz0UwrTDq8BGeFmWa9pL/7h2vHtw+QU
UxlnGmt98M8KkKqqvVicMK+IVtng/QlDw9ofG2kQcbBkPRaTjNI+8ULtCDH0sOkZ
nT8PtGm4sEwmWH/dRWtUTWkMnUwCzuo/rWPb7WMprW2pKDTrLjUAr9M161t3Xa6W
JO03K3NOxupy7ilululLY8d/WKWYDOZMvS5bPiPRUoZqlJneC0CT/2q1W6GfWzsT
DCDTpgq/Ao7jTtnME9iadpwvFn0nMtNgJSrFDWPq8vKY9pRcEp/Na5qvIEOQIFnp
/kIDPuMf+LZwO8lGFO3jnndY+62835rm7t6ZNM3NLoNCarvUCEasobgDJHw7x7c1
fW/OxYtLrWGdMpsP0MewgGJZXcT7mvlBjQ+JWLoyIc5rYMIDw9RLWUPnrlRCxvPp
sD9kDX7eaipdoik5yLyMaRvd16Vt9Bck/9pbSHazm41m/nd4KCZeGdsvrAA2beww
zFWQQV9EX6/VLBgbnGTsMe0CAwEAAQ==
-----END PUBLIC KEY-----
```
Submit this in the "Upload public key" form, shown when creating a new API key on binance and choosing the "self-generated" option.
Note: the "-----BEGIN PUBLIC KEY-----" and "-----END PUBLIC KEY-----" header & footer can be included.
After using the public key to create a new API key, you will be given an API Key such as the following:
```
SIHqWcDeRoj6gkOjLjQh1dnV1CD7IgwQTfL4LVa8wu04zNTYVSmJBIHsjQjgwWqt
```
This is the first piece, used as the "apiKey" in the [rest-private-rsa.ts](./rest-private-rsa.ts) example.
## Using the RSA private key for RSA authentication with binance APIs in Node.js
Your private key, if generated with the above steps, should look something like this (but with much more text):
```pem
-----BEGIN RSA PRIVATE KEY-----
uayyi6wFTaNeG1/WCqhrowj2kCx8eB6NDZYl+OS9ZI9WC
q/44iFERNuP0TXvQx8tgvSZXyu4/G618QzKh0Ii1uAATt2upa8dp1uGl2U7EqBE8
p5y4pPzJuwvB3j6LQON20u2Wpbg8PQZACMfKym7lYDO+9MloK/gAQpyeYJzbw92C
YE/ymq4JVjCMCQKCAQEA4/X0I9TO8vT0D0l83o693QA3C09uSZ6j9Obx5UrtDnA9
sMkkRoe+R/vvIpVDzukMEEOmCuxbcdPoniVUKlTooK0Llo6JJ1l8CdFzQsOR97Pe
csB6pxkLLH2qHx05xPBy4PyoB
-----END RSA PRIVATE KEY-----
```
This is your secret, you should never share this with anyone, not even binance! Treat this like a password.
As part of this authentication process, your private key is used to generate a signature (using `RSA-SHA256`). This SDK handles this process automatically for you. RSA authentication is automatically detected if the "api_secret" parameter contains the words "PRIVATE KEY", such as the header shown in the example above.
Note: Binance also supports Ed25519 authentication. If your "secret" matches the following condition, the SDK will revert to to Ed25519 authentication:
- Contains "PRIVATE KEY" as a header
- Does NOT contain "RSA PRIVATE KEY" as a header.
From here, simply use the key provided by binance as the `api_key` parameter and your private key (with the header) as the `api_secret` parameter.
Based on the above example, the following would prepare the main REST client using the above credentials:
```typescript
const api_key = `SIHqWcDeRoj6gkOjLjQh1dnV1CD7IgwQTfL4LVa8wu04zNTYVSmJBIHsjQjgwWqt`;
const rsaPrivateKey = `
-----BEGIN RSA PRIVATE KEY-----
uayyi6wFTaNeG1/WCqhrowj2kCx8eB6NDZYl+OS9ZI9WC
q/44iFERNuP0TXvQx8tgvSZXyu4/G618QzKh0Ii1uAATt2upa8dp1uGl2U7EqBE8
p5y4pPzJuwvB3j6LQON20u2Wpbg8PQZACMfKym7lYDO+9MloK/gAQpyeYJzbw92C
YE/ymq4JVjCMCQKCAQEA4/X0I9TO8vT0D0l83o693QA3C09uSZ6j9Obx5UrtDnA9
sMkkRoe+R/vvIpVDzukMEEOmCuxbcdPoniVUKlTooK0Llo6JJ1l8CdFzQsOR97Pe
csB6pxkLLH2qHx05xPBy4PyoB
-----END RSA PRIVATE KEY-----
`;
const client = new MainClient({
api_key: api_key,
api_secret: rsaPrivateKey,
beautifyResponses: true,
});
```
For a complete example, refer to the [rest-private-rsa.ts](./rest-private-rsa.ts) file on GitHub.
================
File: examples/misc/README.md
================
# Utilities
These are miscellaneous utilities used by some of the examples in this repo. These do not represent best practices and are merely for easier demonstrations.
================
File: examples/misc/rest-spot-exchange-info.ts
================
import {
ExchangeInfo,
MainClient,
numberInString,
roundToStepSize,
roundToTickSize,
} from '../../src'; // from 'binance';
⋮----
} from '../../src'; // from 'binance';
⋮----
// or
// import { MainClient } from 'binance';
⋮----
// Optional (default: false) - when true, response strings are parsed to floats (only for known keys).
// beautifyResponses: true,
⋮----
interface SymbolInfo {
tickSize: numberInString;
qtyStepSize: numberInString;
minOrderQty: numberInString;
maxOrderQty: numberInString;
maxMarketQty: numberInString;
maxNumOfOrders: number;
minNotional: numberInString;
maxNotional: numberInString;
maxBasePrecisionDecimals: number;
maxQuotePrecisionDecimals: number;
}
⋮----
// Get full exchange info so we can cache it and use it for other functions without making request every time
async function fetchExchangeInfo()
⋮----
async function getSymbolInfo(
exchangeInfo: ExchangeInfo,
symbol: string,
): Promise<SymbolInfo>
⋮----
// Find the symbol information once
⋮----
// console.log(symbolInfo);
⋮----
// Extract filters from the symbol info
⋮----
/**
* Validates and formats an order based on symbol constraints
*/
function formatOrderParams(
symbol: string,
price: number,
quantity: number,
symbolInfo: any,
):
⋮----
// Check if price is within allowed range
⋮----
// Check if quantity is within allowed range
⋮----
// Check notional value (price * quantity)
⋮----
// Format price and quantity according to exchange requirements
⋮----
// Example usage
async function testSymbolUtils()
⋮----
// Test price formatting
⋮----
// Test quantity formatting
⋮----
// Test full order formatting
⋮----
// example how to use the order params
================
File: examples/misc/tracking-candles.ts
================
import { EventEmitter } from 'events';
⋮----
import {
DefaultLogger,
isWsFormattedKline,
KlineInterval,
USDMClient,
WebsocketClient,
} from '../../src';
⋮----
// or, with the npm package
/*
import {
WebsocketClient,
isWsFormattedKline,
USDMClient,
KlineInterval,
} from 'binance';
*/
⋮----
/**
* This elaborate example serves the following key functions:
* - Connect to various candle websockets to receive realtime candle events (update open candle & append closed candle)
* - Backfill some candles using the REST API
* - Once backfilled, start processing candle events (update & append in-memory, depending if candle closed or not)
* - Keep the candle stores trimmed, so we never store more than `maxStoredCandles` candles per symbol
* - When a connection opens or reconnects, the backfill is executed again to ensure there are no gaps
*
* The "onCandleClosed()" function is where you would run custom logic with a dataset of candles (e.g. run some indicator calculations)
*/
⋮----
/**
* Configuration logic
*/
⋮----
/**
* Data stores
*/
⋮----
interface EngineCandle {
open: number;
close: number;
high: number;
low: number;
volume: number;
openTime: number;
openDt: Date;
closeTime: number;
closeDt: Date;
}
⋮----
/**
* The shape of the events produced by the candle store.
* All the info needed to query the candle store for all candles, after receiving a candle closed event
*/
interface CandleStoreEvent {
symbol: string;
interval: string;
}
⋮----
/** These are the events produced by the candle store, which can be used to implement this abstraction layer */
export declare interface CandleEmitter extends EventEmitter {
on(event: 'candleClose', listener: (event: CandleStoreEvent) => void): this;
on(event: 'candleUpdate', listener: (event: CandleStoreEvent) => void): this;
}
⋮----
on(event: 'candleClose', listener: (event: CandleStoreEvent)
on(event: 'candleUpdate', listener: (event: CandleStoreEvent)
⋮----
/** Some options to configure the behaviour of the candle store */
interface CandleStoreOptions {
/** Keep a ceiling on how many candles are stored, before old ones are discarded (prevent the store from growing forever into infinity) */
maxStoredCandles?: number;
eventEmitter: EventEmitter;
}
⋮----
/** Keep a ceiling on how many candles are stored, before old ones are discarded (prevent the store from growing forever into infinity) */
⋮----
/**
/**
* A general store for symbol/interval candles, including handling the currently open candle, with some utility methods
*/
export class CandleStore
⋮----
// Closed candles are stored as an array of candles per interval in this store.
// This is essentially an object acting as a key/value store (key: interval, value: candle array)
⋮----
// Open candles are kept separate from the closed candles, also in a key/value store (key: interval, value: current open candle)
⋮----
constructor(symbol: string, options: CandleStoreOptions)
⋮----
// super();
⋮----
/**
* Overwrite the current candle store, e.g. after backfilling. Candles are sorted automatically before overwriting the store
*/
public setCandles(candles: EngineCandle[], interval: string): void
⋮----
public setOpenCandle(candle: EngineCandle | null, interval: string): void
⋮----
/**
* Provide a candle event to the store for processing (e.g candle closed vs open candle updated).
* - Closed candles are appended to the array.
* - Open candles are tracked separately and only (optionally) used during the getCandles(true) query.
*/
public processCandleEvent(
candle: EngineCandle,
interval: string,
isCandleClosed: boolean,
): void
⋮----
// console.log(this.symbol, `Open candle update`);
⋮----
// console.log(`Emit candle closed evt`, evt);
⋮----
private initCandleStores(interval: string)
⋮----
/**
* Execute a store-trim. This is called automatically during candle-closed events, but
* can be called manually (e.g. after backfilling) to ensure the store only keeps the most recent `maxStoredCandles`.
*/
public trimExcessCandles(interval: string): void
⋮----
// This mutates the closed candle store to remove the first x elements
⋮----
/**
* Query all candles in the store for an interval.
* Optionally append the currently open candle to the end of the array.
*/
public getCandles(
interval: string,
includeOpenCandle?: boolean,
): EngineCandle[]
⋮----
// check last candle has same open time as open candle, just in case
⋮----
// Include open candle at end of array
⋮----
/**
* A key value store for all symbols & intervals
*
* // All CandleStores for that symbol (one per symbol, supports many intervals in one store)
* const symbolCandles = allCandleStores[symbol];
*
*/
⋮----
/**
* Get a candle store for a symbol.
* Since a missing candle store is automatically initialised, you can assume this will always return a candle store.
*/
function getCandleStore(symbol: string): CandleStore
⋮----
// Hook up event consumers on the shared event emitter
⋮----
// eventEmitter.on('candleUpdate', (e) => {
// console.log('candle updated', {
// dt: new Date(),
// symbol: e.symbol,
// interval: e.interval,
// });
// });
⋮----
/** Ensure a candle store exists for this symbol & attach consumers to the store */
function initCandleStoreIfMissing(symbol: string): void
⋮----
// Inject your own event emitter and initialise one candle store per symbol (it supports multiple intervals)
⋮----
/**
* Websocket Listeners
*/
⋮----
// console.log('kline received ', { candle, isCandleClosed });
⋮----
// const candleStore: CandleStore = allIntervalCandleStores[symbol][interval];
⋮----
// response to command sent via WS stream (e.g. subscription confirmation)
// this will automatically trigger a backfill for that symbol.
⋮----
// empty response result === success
⋮----
// btcusdt@kline_1m -> btcusdt, kline_1m
⋮----
// kline_1m -> kline, 1m
// eslint-disable-next-line @typescript-eslint/no-unused-vars
⋮----
/**
* Execute a 1-page backfill (1000 candles). Called automatically when a connection opens OR reconnects.
*/
async function backfillCandles(
symbol: string,
interval: KlineInterval,
): Promise<void>
⋮----
// Map to a standard candle structure
⋮----
// Last candle might not be closed, so filter that out (ignore any candles with close time in the future)
⋮----
// const candleStore: CandleStore = allIntervalCandleStores[symbol][interval];
⋮----
// Overwrite the current candles in the store and remove excess candles
⋮----
/**
* Bootstrap a connection per symbol & timeframe. Backfill will automatically trigger when the connection opens successfully.
* Note: this will spawn one websocket connection per symbol per timeframe. For complex cases, this may create too many connections.
*/
⋮----
// Open a websocket to start consuming candle events
⋮----
function onCandleClosed(symbol: string, interval: string): void
⋮----
// When a candle closes, fetch all closed candles from the store for that symbol, e.g. to calculate some indicators
================
File: examples/REST/rest-future-bracket-order.ts
================
import { NewFuturesOrderParams, USDMClient } from '../../src/index';
⋮----
// submit a 1:1 bracket market buy order with market entry order
⋮----
// TODO: check balance and do other validations
⋮----
// create three orders
// 1. entry order (GTC),
// 2. take profit order (GTE_GTC),
// 3. stop loss order (GTE_GTC)
================
File: examples/REST/rest-portfoliomargin-private.ts
================
import { PortfolioClient } from '../../src/index';
⋮----
// or
// import { PortfolioClient } from 'binance';
⋮----
// const newOrderRes = await client.submitNewUMOrder({
// symbol: 'BTCUSDT',
// side: 'BUY',
// type: 'MARKET',
// quantity: '10',
// });
⋮----
// console.log('new order res: ', newOrderRes);
================
File: examples/REST/rest-portfoliomargin-public.ts
================
import { PortfolioClient } from '../../src/index';
⋮----
// or
// import { PortfolioClient } from 'binance';
⋮----
// const serverTime = await client.getServerTime();
// console.log('serverTime: ', serverTime);
================
File: examples/REST/rest-spot-private-autoinvest.ts
================
import { MainClient } from '../../src/index';
⋮----
// or
// import { MainClient } from 'binance';
================
File: examples/REST/rest-spot-private-misc.ts
================
import { MainClient } from '../../src/index';
⋮----
// or
// import { MainClient } from 'binance';
================
File: examples/REST/rest-spot-private-trade.ts
================
import {
MainClient,
NewSpotOrderParams,
OrderResponseFull,
SymbolPrice,
} from '../../src/index';
⋮----
// or
// import { MainClient } from 'binance';
⋮----
const entryAmountPercent = 50; // trigger trade with 50%
⋮----
const assetDecimalPlaces = 4; // get this from exchange info, it varies per asset
⋮----
// method to trim down to decimal.
function trimToDecimalPlaces(number: number, precision: number): number
⋮----
/**
* This is a very silly demonstration on placing market orders using various parts of the module.
* By default it will use 50% of your available USDT balance to buy BTC and sell it again.
*/
⋮----
/**
* Get available balance
*/
⋮----
// console.log('USDT balance object: ', usdtBal);
⋮----
/**
* Get last asset price
*/
⋮----
/**
* Calculate and submit buy amount
*/
⋮----
/**
* ACK = confirmation of order acceptance (no placement/fill information) -> OrderResponseACK
* RESULT = fill state -> OrderResponseResult
* FULL = fill state + detail on fills and other detail -> OrderResponseFull
*/
⋮----
/**
* Process bought fills and submit sell amount
*/
================
File: examples/REST/rest-spot-public.ts
================
import { MainClient } from '../../src/index';
⋮----
// or
// import { MainClient } from 'binance';
⋮----
// Optional (default: false) - when true, response strings are parsed to floats (only for known keys).
// beautifyResponses: true,
⋮----
// console.log(
// 'getAvgPrice: ',
// await client.getAvgPrice({ symbol: 'BTCUSDT' }),
// );
// console.log(
// 'getExchangeInfo: ',
// JSON.stringify(await client.getExchangeInfo(), null, 2),
// );
================
File: examples/REST/rest-usdm-order-sl.ts
================
/* eslint-disable @typescript-eslint/no-unused-vars */
import { USDMClient } from '../../src/index';
⋮----
// or
// import { USDMClient } from 'binance';
⋮----
async function start()
⋮----
// ### This is for Hedge Mode Only ###
// assuming you currently have a open position, and you want to modify the SL order.
⋮----
/**
* first we get all long and short positions status
* the result of this method in hedge mode is array of two objects
* first index for LONG and second index for SHORT
*/
⋮----
// if longAmount is bigger than 0 means we have open long position and if shortAmount is below 0 means we have open short position
⋮----
// if we have any open position then we continue
⋮----
// we get ourstop loss here
⋮----
// we want to modify our long position SL here
⋮----
// we get the StopLoss order which is realted to long
⋮----
// if it exists, cancel it.
⋮----
// creating SL order
⋮----
side: 'SELL', // the action of order, means this order will sell which is sl for long position
positionSide: 'LONG', // based on the headge mode we either LONG or SHORT, here we are doing it for our long pos
⋮----
closePosition: 'true', // this is here because we don't have the position quantity value, and it means closee all quantity
stopPrice: parseFloat((markPrice * 0.99).toFixed(3)), // set sl price 1% below current price
================
File: examples/REST/rest-usdm-order.ts
================
import { USDMClient } from '../../src/index';
⋮----
// or
// import { USDMClient } from 'binance';
⋮----
async function start()
⋮----
// To open a short position - if you don't have a position yet, and your account is set to one-way mode, just place a sell order to open a short position
⋮----
// newOrderRespType: 'FULL',
================
File: examples/REST/rest-usdm-private-get.ts
================
import { USDMClient } from '../../src/index';
// import axios from 'axios';
⋮----
// or
// import { USDMClient } from 'binance';
================
File: examples/REST/rest-usdm-public.ts
================
import { USDMClient } from '../../src';
⋮----
// keepAlive: true,
// ... any other params,
================
File: examples/REST/rest-usdm-testnet.ts
================
import { USDMClient } from '../../src/index';
⋮----
// or
// import { USDMClient } from 'binance';
⋮----
/**
* Note: testnet is NOT a good place to test strategy performance.
*
* For more information and guidance, refer to:
* https://github.com/tiagosiebler/awesome-crypto-examples/wiki/CEX-Testnets
*/
⋮----
async function start()
⋮----
// To open a short position - if you don't have a position yet, and your account is set to one-way mode, just place a sell order to open a short position
⋮----
// newOrderRespType: 'FULL',
================
File: examples/WebSockets/deprecated-ws-public.ts
================
/* eslint-disable @typescript-eslint/no-unused-vars */
import {
DefaultLogger,
isWsFormatted24hrTicker,
isWsFormatted24hrTickerArray,
isWsFormattedKline,
isWsFormattedRollingWindowTickerArray,
WebsocketClientV1,
} from '../../src/index';
⋮----
// or, with the npm package
/*
import {
WebsocketClientV1,
DefaultLogger,
isWsFormatted24hrTicker,
isWsFormattedKline,
} from 'binance';
*/
⋮----
/**
*
* This example demonstrates basic usage of the previous WebsocketClientV1, which should be considered deprecated.
*
*/
⋮----
// api_key: key,
// api_secret: secret,
⋮----
// manually handle events and narrow down to desired types
⋮----
// or use a supplied type guard (if available - not all type guards have been written yet)
⋮----
// console.log('log formattedMessage: ', JSON.stringify(data[0], null, 2));
⋮----
// response to command sent via WS stream (e.g LIST_SUBSCRIPTIONS)
⋮----
// wsClient.subscribeCoinIndexPrice(coinMSymbol);
// wsClient.subscribeSpotAllBookTickers();
⋮----
// wsClient.subscribeSpotKline(market, '1m');
// wsClient.subscribeKlines(market, '1m', 'usdm');
// wsClient.subscribeMarkPrice(market, 'usdm');
// wsClient.subscribeMarkPrice(coinMSymbol, 'coinm');
// wsClient.subscribeAllMarketMarkPrice('usdm');
// wsClient.subscribeAllMarketMarkPrice('coinm');
// wsClient.subscribeKlines(market, '1m', 'usdm');
// wsClient.subscribeContinuousContractKlines(market, 'perpetual', '1m', 'usdm');
// wsClient.subscribeIndexKlines(coinMSymbol, '1m');
// wsClient.subscribeMarkPriceKlines(coinMSymbol, '1m');
// wsClient.subscribeSymbolMini24hrTicker(market, 'usdm');
// wsClient.subscribeSymbolMini24hrTicker(coinMSymbol, 'coinm');
// wsClient.subscribeSymbolMini24hrTicker(market, 'spot');
// wsClient.subscribeSymbol24hrTicker(market, 'usdm');
// wsClient.subscribeSymbol24hrTicker(market, 'coinm');
// wsClient.subscribeSymbol24hrTicker(coinMSymbol, 'spot');
// wsClient.subscribeAllMini24hrTickers('usdm');
// wsClient.subscribeAllMini24hrTickers('coinm');
// wsClient.subscribeAllMini24hrTickers('spot');
// wsClient.subscribeAll24hrTickers('usdm');
// wsClient.subscribeAll24hrTickers('coinm');
// wsClient.subscribeAll24hrTickers('spot');
// wsClient.subscribeAllLiquidationOrders('usdm');
// wsClient.subscribeAllLiquidationOrders('coinm');
// wsClient.subscribeSpotSymbol24hrTicker(market);
// wsClient.subscribeAggregateTrades(market, 'usdm');
// wsClient.subscribeSpotPartialBookDepth('ETHBTC', 5, 1000);
⋮----
// wsClient.subscribeAllRollingWindowTickers('spot', '1d');
================
File: examples/WebSockets/ws-proxy-socks.ts
================
/**
* Minimal example for using a socks proxy with the ws client, extracted from https://github.com/tiagosiebler/binance/pull/319
*/
import { WebsocketClient } from '../../src/index';
⋮----
// or
// import { WebsocketClient } from 'binance';
================
File: examples/WebSockets/ws-public-spot-orderbook.ts
================
/* eslint-disable @typescript-eslint/no-unused-vars */
/* eslint-disable no-unused-vars */
import {
DefaultLogger,
isWsPartialBookDepthEventFormatted,
WebsocketClient,
WsMessagePartialBookDepthEventFormatted,
} from '../../src/index';
⋮----
// or, with the npm package
/*
import {
WebsocketClient,
DefaultLogger,
isWsFormattedTrade,
} from 'binance';
*/
⋮----
// trace: () => {},
⋮----
/**
* Simple example for receiving depth snapshots from spot orderbooks
*/
⋮----
// Request subscription to the following symbol events:
⋮----
// const symbols = ['BTCUSDT', 'ETHUSDT', 'BNBUSDT'];
⋮----
// Loop through symbols
⋮----
// The old way, convenient but unnecessary:
// wsClient.subscribePartialBookDepths(symbol, levels, 1000, 'spot');
⋮----
// Manually build a topic matching the structure expected by binance:
// btcusdt@depth20@1000ms
⋮----
// Request subscribe for these topics in the main product group (spot markets are under "main")
================
File: examples/WebSockets/ws-public-spot-trades.ts
================
import {
DefaultLogger,
isWsFormattedTrade,
WebsocketClient,
} from '../../src/index';
⋮----
// or, with the npm package
/*
import {
WebsocketClient,
DefaultLogger,
isWsFormattedTrade,
} from 'binance';
*/
⋮----
// trace: () => {},
⋮----
// Request subscription to the following symbol trade events:
⋮----
// Loop through symbols
================
File: examples/WebSockets/ws-public-usdm-funding.ts
================
import {
DefaultLogger,
isWsFormattedMarkPriceUpdateArray,
WebsocketClient,
} from '../../src/index';
⋮----
// or, with the npm package
/*
import {
WebsocketClient,
DefaultLogger,
isWsFormattedMarkPriceUpdateArray,
} from 'binance';
*/
⋮----
// trace: () => {},
⋮----
// api_key: key,
// api_secret: secret,
⋮----
// value is in decimal, multiply by 100 to get percent value
⋮----
// log table sorted alphabetically by symbol
⋮----
// response to command sent via WS stream (e.g LIST_SUBSCRIPTIONS)
================
File: examples/WebSockets/ws-unsubscribe.ts
================
/* eslint-disable @typescript-eslint/no-unused-vars */
import { WebsocketClient } from '../../src/index';
⋮----
// or, with the npm package
/*
import {
WebsocketClient,
DefaultLogger,
isWsFormatted24hrTicker,
isWsFormattedKline,
} from 'binance';
*/
⋮----
/**
*
* A simple demonstration on how to unsubscribe from one or more topics.
*
*/
⋮----
// Raw unprocessed incoming data, e.g. if you have the beautifier disabled
⋮----
/**
* The Websocket Client will automatically manage connectivity and active topics/subscriptions for you.
*
* Simply call wsClient.subscribe(topic, wsKey) as many times as you want, with or without an array.
*/
⋮----
// Aggregate Trade Streams
// https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#aggregate-trade-streams
⋮----
// Kline/Candlestick Streams for UTC
// https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#klinecandlestick-streams-for-utc
⋮----
// Individual Symbol Mini Ticker Stream
// https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-mini-ticker-stream
⋮----
// Individual Symbol Ticker Streams
// https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-ticker-streams
⋮----
// Individual Symbol Rolling Window Statistics Streams
// https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#individual-symbol-rolling-window-statistics-streams
⋮----
// Average Price
// https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams#average-price
⋮----
/**
* Subscribe to each available type of spot market topic, the new way
*/
⋮----
// 5 seconds later, unsubscribe from almost all topics except avg price
================
File: examples/WebSockets/ws-userdata-connection-safety.ts
================
import {
DefaultLogger,
isWsFormattedFuturesUserDataEvent,
isWsFormattedSpotUserDataEvent,
isWsFormattedSpotUserDataExecutionReport,
isWsFormattedUserDataEvent,
WebsocketClient,
WsUserDataEvents,
} from '../../src/index';
⋮----
// or
// import { DefaultLogger, WebsocketClient } from 'binance';
⋮----
/**
* This extended example for using the user data stream demonstrates one way to handle failures in the first connection attempt of the user data stream.
* In most cases this is overkill!
*/
⋮----
// optionally block some silly logs from showing in the logger
⋮----
// Optional, hook and customise logging behavior
⋮----
// wsClient.on('message', (data) => {
// console.log('raw message received ', JSON.stringify(data, null, 2));
// });
⋮----
function onUserDataEvent(data: WsUserDataEvents)
⋮----
// the market denotes which API category it came from
// if (data.wsMarket.includes('spot')) {
⋮----
// or use a type guard, if one exists (PRs welcome)
⋮----
// The wsKey can be parsed to determine the type of message (what websocket it came from)
// if (!Array.isArray(data) && data.wsKey.includes('userData')) {
// return onUserDataEvent(data);
// }
⋮----
// or use a type guard if available
⋮----
// response to command sent via WS stream (e.g LIST_SUBSCRIPTIONS)
⋮----
// Note: manually re-subscribing like this may only be needed if the FIRST user data connection attempt failed
// Capture exceptions using the error event, and handle this.
⋮----
// wsClient.subscribeMarginUserDataStream();
// wsClient.subscribeIsolatedMarginUserDataStream('BTCUSDT');
================
File: src/types/websockets/ws-general.ts
================
import { AxiosRequestConfig } from 'axios';
import WebSocket from 'isomorphic-ws';
⋮----
import { RestClientOptions } from '../../util/requestUtils';
import { WsKey } from '../../util/websockets/websocket-util';
⋮----
export interface MessageEventLike {
target: WebSocket;
type: 'message';
data: string;
}
⋮----
export function isMessageEvent(msg: unknown): msg is MessageEventLike
⋮----
export type WsMarket =
| 'spot'
| 'spotTestnet'
| 'crossMargin'
| 'isolatedMargin'
| 'riskDataMargin'
| 'usdm'
| 'usdmTestnet'
| 'coinm'
| 'coinmTestnet'
| 'options'
| 'optionsTestnet'
| 'portfoliom';
⋮----
export interface WsSharedBase {
wsMarket: WsMarket;
wsKey: WsKey;
streamName: string;
}
⋮----
export interface WsResponse {
type: 'message';
data: {
result: boolean | string[] | null;
id: number;
isWSAPIResponse: boolean;
wsKey: WsKey;
};
}
⋮----
// Same as inverse futures
export type WsPublicInverseTopic =
| 'orderBookL2_25'
| 'orderBookL2_200'
| 'trade'
| 'insurance'
| 'instrument_info'
| 'klineV2';
⋮----
export type WsPublicUSDTPerpTopic =
| 'orderBookL2_25'
| 'orderBookL2_200'
| 'trade'
| 'insurance'
| 'instrument_info'
| 'kline';
⋮----
export type WsPublicSpotV1Topic =
| 'trade'
| 'realtimes'
| 'kline'
| 'depth'
| 'mergedDepth'
| 'diffDepth';
⋮----
export type WsPublicSpotV2Topic =
| 'depth'
| 'kline'
| 'trade'
| 'bookTicker'
| 'realtimes';
⋮----
export type WsPublicTopics =
| WsPublicInverseTopic
| WsPublicUSDTPerpTopic
| WsPublicSpotV1Topic
| WsPublicSpotV2Topic
| string;
⋮----
// Same as inverse futures
export type WsPrivateInverseTopic =
| 'position'
| 'execution'
| 'order'
| 'stop_order';
⋮----
export type WsPrivateUSDTPerpTopic =
| 'position'
| 'execution'
| 'order'
| 'stop_order'
| 'wallet';
⋮----
export type WsPrivateSpotTopic =
| 'outboundAccountInfo'
| 'executionReport'
| 'ticketInfo';
⋮----
export type WsPrivateTopic =
| WsPrivateInverseTopic
| WsPrivateUSDTPerpTopic
| WsPrivateSpotTopic
| string;
⋮----
export type WsTopic = WsPublicTopics | WsPrivateTopic;
⋮----
export interface WSClientConfigurableOptions {
/** Your API key */
api_key?: string;
/** Your API secret */
api_secret?: string;
beautify?: boolean;
/**
* If true, log a warning if the beautifier is missing anything for an event
*/
beautifyWarnIfMissing?: boolean;
/**
* Set to `true` to connect to Binance's testnet environment.
*
* Notes:
* - Not all WebSocket categories support testnet.
* - If testing a strategy, this is not recommended. Testnet market data is very different from real market conditions. More guidance here: https://github.com/tiagosiebler/awesome-crypto-examples/wiki/CEX-Testnets
*/
testnet?: boolean;
/** Define a recv window when preparing a private websocket signature. This is in milliseconds, so 5000 == 5 seconds */
recvWindow?: number;
// Disable ping/pong ws heartbeat mechanism (not recommended)
disableHeartbeat?: boolean;
/** How often to check if the connection is alive */
pingInterval?: number;
/** How long to wait for a pong (heartbeat reply) before assuming the connection is dead */
pongTimeout?: number;
/** Delay in milliseconds before respawning the connection */
reconnectTimeout?: number;
restOptions?: RestClientOptions;
requestOptions?: AxiosRequestConfig;
wsOptions?: {
protocols?: string[];
agent?: any;
};
wsUrl?: string;
/**
* Allows you to provide a custom "signMessage" function, e.g. to use node's much faster createHmac method
*
* Look in the examples folder for a demonstration on using node's createHmac instead.
*/
customSignMessageFn?: (message: string, secret: string) => Promise<string>;
}
⋮----
/** Your API key */
⋮----
/** Your API secret */
⋮----
/**
* If true, log a warning if the beautifier is missing anything for an event
*/
⋮----
/**
* Set to `true` to connect to Binance's testnet environment.
*
* Notes:
* - Not all WebSocket categories support testnet.
* - If testing a strategy, this is not recommended. Testnet market data is very different from real market conditions. More guidance here: https://github.com/tiagosiebler/awesome-crypto-examples/wiki/CEX-Testnets
*/
⋮----
/** Define a recv window when preparing a private websocket signature. This is in milliseconds, so 5000 == 5 seconds */
⋮----
// Disable ping/pong ws heartbeat mechanism (not recommended)
⋮----
/** How often to check if the connection is alive */
⋮----
/** How long to wait for a pong (heartbeat reply) before assuming the connection is dead */
⋮----
/** Delay in milliseconds before respawning the connection */
⋮----
/**
* Allows you to provide a custom "signMessage" function, e.g. to use node's much faster createHmac method
*
* Look in the examples folder for a demonstration on using node's createHmac instead.
*/
⋮----
/**
* WS configuration that's always defined, regardless of user configuration
* (usually comes from defaults if there's no user-provided values)
*/
export interface WebsocketClientOptions extends WSClientConfigurableOptions {
pongTimeout: number;
pingInterval: number;
reconnectTimeout: number;
recvWindow: number;
authPrivateConnectionsOnConnect: boolean;
authPrivateRequests: boolean;
}
================
File: src/types/coin.ts
================
import { FuturesContractType, PositionSide } from './futures';
import { numberInString, OrderSide } from './shared';
⋮----
export interface PositionRisk {
symbol: string;
positionAmt: numberInString;
entryPrice: numberInString;
markPrice: numberInString;
unRealizedProfit: numberInString;
liquidationPrice: numberInString;
leverage: numberInString;
maxQty: numberInString;
marginType: string;
isolatedMargin: numberInString;
isAutoAddMargin: boolean;
positionSide: PositionSide;
updateTime: number;
}
⋮----
export interface CoinMOpenInterest {
symbol: string;
pair: string;
openInterest: numberInString;
contractType: FuturesContractType;
time: number;
}
export type SymbolOrPair =
| { pair: string; symbol?: never }
| { pair?: never; symbol: string };
⋮----
export interface CoinMSymbolOrderBookTicker {
symbol: string;
pair: string;
bidPrice: numberInString;
bidQty: numberInString;
askPrice: numberInString;
askQty: numberInString;
time: number;
}
⋮----
export interface CoinMPaginatedRequest {
fromId?: number;
startTime?: number;
endTime?: number;
limit?: number;
}
⋮----
export interface CoinMAccountTradeParamsWithPair extends CoinMPaginatedRequest {
pair: string;
symbol?: never;
fromId?: never;
}
⋮----
export interface CoinMAccountTradeParamsWithSymbol
extends CoinMPaginatedRequest {
symbol: string;
pair?: never;
}
⋮----
export interface CoinMAccountTradeParamsWithFromId
extends CoinMPaginatedRequest {
fromId: number;
startTime?: never;
endTime?: never;
}
⋮----
export type CoinMAccountTradeParams =
| CoinMAccountTradeParamsWithSymbol
| CoinMAccountTradeParamsWithPair
| CoinMAccountTradeParamsWithFromId;
⋮----
export interface CoinMPositionTrade {
symbol: string;
id: number;
orderId: number;
pair: string;
side: OrderSide;
price: numberInString;
qty: numberInString;
realizedPnl: numberInString;
marginAsset: string;
baseQty: numberInString;
commission: numberInString;
commissionAsset: string;
time: number;
positionSide: PositionSide;
buyer: boolean;
maker: boolean;
}
⋮----
export interface FundingRate {
symbol: string;
adjustedFundingRateCap: string;
adjustedFundingRateFloor: string;
fundingIntervalHours: number;
disclaimer: boolean;
}
⋮----
export interface GetClassicPortfolioMarginNotionalLimitParams {
symbol?: string;
pair?: string;
}
⋮----
export interface ClassicPortfolioMarginNotionalLimit {
symbol: string;
pair: string;
notionalLimit: string;
}
⋮----
export interface ClassicPortfolioMarginAccount {
maxWithdrawAmountUSD: string;
asset: string;
maxWithdrawAmount: string;
}
⋮----
export interface FuturesTransactionHistoryDownloadLink {
downloadId: string;
status: string;
url: string;
notified: boolean;
expirationTimestamp: number;
isExpired: boolean | null;
}
================
File: src/types/portfolio-margin.ts
================
// Enums
export type PMStrategyType =
| 'STOP'
| 'STOP_MARKET'
| 'TAKE_PROFIT'
| 'TAKE_PROFIT_MARKET'
| 'TRAILING_STOP_MARKET';
⋮----
export type PMWorkingType = 'MARK_PRICE' | 'CONTRACT_PRICE';
⋮----
export type PMPriceMatch =
| 'NONE'
| 'OPPONENT'
| 'OPPONENT_5'
| 'OPPONENT_10'
| 'OPPONENT_20'
| 'QUEUE'
| 'QUEUE_5'
| 'QUEUE_10'
| 'QUEUE_20';
⋮----
export type PMSelfTradePreventionMode =
| 'NONE'
| 'EXPIRE_TAKER'
| 'EXPIRE_MAKER'
| 'EXPIRE_BOTH';
⋮----
export type PMMarginOrderType =
| 'LIMIT'
| 'MARKET'
| 'STOP_LOSS'
| 'STOP_LOSS_LIMIT'
| 'TAKE_PROFIT'
| 'TAKE_PROFIT_LIMIT';
⋮----
export type PMMarginSideEffectType =
| 'NO_SIDE_EFFECT'
| 'MARGIN_BUY'
| 'AUTO_REPAY'
| 'AUTO_BORROW_REPAY';
⋮----
export type PMAutoCloseType = 'LIQUIDATION' | 'ADL';
⋮----
export interface NewPortfolioUMOrderReq {
symbol: string;
side: 'BUY' | 'SELL';
positionSide?: 'BOTH' | 'LONG' | 'SHORT'; // Default BOTH for One-way Mode
type: 'LIMIT' | 'MARKET';
timeInForce?: string;
quantity?: string;
reduceOnly?: boolean; // Cannot be sent in Hedge Mode
price?: string;
newClientOrderId?: string; // Must match: ^[\.A-Z\:/a-z0-9_-]{1,32}$
newOrderRespType?: 'ACK' | 'RESULT'; // Default: ACK
priceMatch?: PMPriceMatch; // Only for LIMIT/STOP/TAKE_PROFIT orders
selfTradePreventionMode?: PMSelfTradePreventionMode;
goodTillDate?: number; // Mandatory when timeInForce is GTD
}
⋮----
positionSide?: 'BOTH' | 'LONG' | 'SHORT'; // Default BOTH for One-way Mode
⋮----
reduceOnly?: boolean; // Cannot be sent in Hedge Mode
⋮----
newClientOrderId?: string; // Must match: ^[\.A-Z\:/a-z0-9_-]{1,32}$
newOrderRespType?: 'ACK' | 'RESULT'; // Default: ACK
priceMatch?: PMPriceMatch; // Only for LIMIT/STOP/TAKE_PROFIT orders
⋮----
goodTillDate?: number; // Mandatory when timeInForce is GTD
⋮----
export interface NewPortfolioUMOrderResponse {
clientOrderId: string;
cumQty: string;
cumQuote: string;
executedQty: string;
orderId: number;
avgPrice: string;
origQty: string;
price: string;
reduceOnly: boolean;
side: 'BUY' | 'SELL';
positionSide: 'BOTH' | 'LONG' | 'SHORT';
status: string;
symbol: string;
timeInForce: string;
type: 'LIMIT' | 'MARKET';
selfTradePreventionMode: PMSelfTradePreventionMode;
goodTillDate?: number;
updateTime: number;
priceMatch: PMPriceMatch;
}
⋮----
export interface NewPortfolioUMConditionalOrderReq {
symbol: string;
side: 'BUY' | 'SELL';
positionSide?: 'BOTH' | 'LONG' | 'SHORT';
strategyType: PMStrategyType;
timeInForce?: string;
quantity?: string;
reduceOnly?: boolean;
price?: string;
workingType?: PMWorkingType;
priceProtect?: boolean;
newClientStrategyId?: string;
stopPrice?: string;
activationPrice?: string;
callbackRate?: string;
priceMatch?: PMPriceMatch;
selfTradePreventionMode?: PMSelfTradePreventionMode;
goodTillDate?: number;
}
⋮----
export interface NewPortfolioConditionalOrderResponse {
newClientStrategyId: string;
strategyId: number;
strategyStatus: string;
strategyType: PMStrategyType;
origQty: string;
price: string;
reduceOnly: boolean;
side: 'BUY' | 'SELL';
positionSide: 'BOTH' | 'LONG' | 'SHORT';
stopPrice?: string;
symbol: string;
timeInForce: string;
activatePrice?: string;
priceRate?: string;
bookTime: number;
updateTime: number;
workingType: PMWorkingType;
priceProtect: boolean;
selfTradePreventionMode: PMSelfTradePreventionMode;
goodTillDate?: number;
priceMatch: PMPriceMatch;
}
⋮----
export interface NewPortfolioCMOrderReq {
symbol: string;
side: 'BUY' | 'SELL';
positionSide?: 'BOTH' | 'LONG' | 'SHORT';
type: 'LIMIT' | 'MARKET';
timeInForce?: string;
quantity?: string;
reduceOnly?: boolean;
price?: string;
newClientOrderId?: string;
newOrderRespType?: 'ACK' | 'RESULT';
}
⋮----
export interface NewPortfolioCMOrderResponse {
clientOrderId: string;
cumQty: string;
cumBase: string;
executedQty: string;
orderId: number;
avgPrice: string;
origQty: string;
price: string;
reduceOnly: boolean;
side: 'BUY' | 'SELL';
positionSide: 'BOTH' | 'LONG' | 'SHORT';
status: string;
symbol: string;
pair: string;
timeInForce: string;
type: 'LIMIT' | 'MARKET';
updateTime: number;
}
⋮----
export interface NewPortfolioCMConditionalOrderReq {
symbol: string;
side: 'BUY' | 'SELL';
positionSide?: 'BOTH' | 'LONG' | 'SHORT';
strategyType: PMStrategyType;
timeInForce?: string;
quantity?: string;
reduceOnly?: boolean;
price?: string;
workingType?: PMWorkingType;
priceProtect?: boolean;
newClientStrategyId?: string;
stopPrice?: string;
activationPrice?: string;
callbackRate?: string;
}
⋮----
export interface NewPortfolioCMConditionalOrderResponse {
newClientStrategyId: string;
strategyId: number;
strategyStatus: string;
strategyType: PMStrategyType;
origQty: string;
price: string;
reduceOnly: boolean;
side: 'BUY' | 'SELL';
positionSide: 'BOTH' | 'LONG' | 'SHORT';
stopPrice?: string;
symbol: string;
pair: string;
timeInForce: string;
activatePrice?: string;
priceRate?: string;
bookTime: number;
updateTime: number;
workingType: PMWorkingType;
priceProtect: boolean;
}
⋮----
export interface MarginOrderFill {
price: string;
qty: string;
commission: string;
commissionAsset: string;
}
⋮----
export interface NewPortfolioMarginOrderReq {
symbol: string;
side: 'BUY' | 'SELL';
type: PMMarginOrderType;
quantity?: string;
quoteOrderQty?: string;
price?: string;
stopPrice?: string;
newClientOrderId?: string;
newOrderRespType?: 'ACK' | 'RESULT' | 'FULL';
icebergQty?: string;
sideEffectType?: PMMarginSideEffectType;
timeInForce?: string;
selfTradePreventionMode?: PMSelfTradePreventionMode;
autoRepayAtCancel?: boolean;
}
⋮----
export interface NewPortfolioMarginOrderResponse {
symbol: string;
orderId: number;
clientOrderId: string;
transactTime: number;
price: string;
origQty: string;
executedQty: string;
cummulativeQuoteQty: string;
status: string;
timeInForce: string;
type: PMMarginOrderType;
side: 'BUY' | 'SELL';
marginBuyBorrowAmount?: string;
marginBuyBorrowAsset?: string;
fills: MarginOrderFill[];
}
⋮----
export interface PortfolioMarginOCOOrder {
symbol: string;
orderId: number;
clientOrderId: string;
}
⋮----
export interface PortfolioMarginOCOOrderReport {
symbol: string;
orderId: number;
orderListId: number;
clientOrderId: string;
transactTime: number;
price: string;
origQty: string;
executedQty: string;
cummulativeQuoteQty: string;
status: string;
timeInForce: string;
type: string;
side: 'BUY' | 'SELL';
stopPrice?: string;
}
⋮----
export interface NewPortfolioMarginOCOReq {
symbol: string;
listClientOrderId?: string;
side: 'BUY' | 'SELL';
quantity: string;
limitClientOrderId?: string;
price: string;
limitIcebergQty?: string;
stopClientOrderId?: string;
stopPrice: string;
stopLimitPrice?: string;
stopIcebergQty?: string;
stopLimitTimeInForce?: 'GTC' | 'FOK' | 'IOC';
newOrderRespType?: 'ACK' | 'RESULT' | 'FULL';
sideEffectType?: PMMarginSideEffectType;
}
⋮----
export interface NewPortfolioMarginOCOResponse {
orderListId: number;
contingencyType: 'OCO';
listStatusType: string;
listOrderStatus: string;
listClientOrderId: string;
transactionTime: number;
symbol: string;
marginBuyB