@cubexch/client
Advanced tools
Comparing version 1.2.0 to 1.4.0
"use strict"; | ||
/* eslint-disable */ | ||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT. | ||
// versions: | ||
// protoc-gen-ts_proto v1.181.1 | ||
// protoc v4.25.3 | ||
// source: codes.proto | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CloseCode = exports.protobufPackage = void 0; | ||
/* eslint-disable */ | ||
exports.protobufPackage = "codes"; | ||
@@ -6,0 +11,0 @@ /** |
@@ -14,5 +14,9 @@ export declare const protobufPackage = "market_data"; | ||
* Market by Order (MBO). In addition, clients can subscribe to the trade stream | ||
* and price candlesticks. Clients should submit a [`Config`](#config) and then | ||
* process [`MdMessage`](#mdmessage)'s. | ||
* and price candlesticks. | ||
* | ||
* Upon connection, clients should submit a [`Config`](#config) and then | ||
* process a stream of [`MdMessages`](#mdmessages). | ||
* Note that this message type is distinct from the [`MdMessage`](#mdmessage), | ||
* where the former is a wrapper containing one or more of the latter. | ||
* | ||
* ### Aggregate Book Tops Data | ||
@@ -331,2 +335,6 @@ * | ||
} | ||
/** | ||
* A wrapper containing one or more Market Data messages, | ||
* each of which will be an [`MdMessage`](#mdmessage). | ||
*/ | ||
export interface MdMessages { | ||
@@ -352,7 +360,7 @@ messages: MdMessage[]; | ||
transactTime: bigint; | ||
/** The best bid price. */ | ||
/** The best bid price of the direct or implied book, whichever is better. */ | ||
bidPrice?: bigint | undefined; | ||
/** The total bid quantity at the best bid price. */ | ||
bidQuantity?: bigint | undefined; | ||
/** The best ask price. */ | ||
/** The best ask price of the direct or implied book, whichever is better. */ | ||
askPrice?: bigint | undefined; | ||
@@ -365,6 +373,3 @@ /** The total ask quantity at the best ask price. */ | ||
rolling24hPrice?: bigint | undefined; | ||
impliedBidPrice?: bigint | undefined; | ||
impliedBidQuantity?: bigint | undefined; | ||
impliedAskPrice?: bigint | undefined; | ||
impliedAskQuantity?: bigint | undefined; | ||
/** Which trading operations are currently allowed on this market. */ | ||
marketState: MarketState; | ||
@@ -371,0 +376,0 @@ } |
"use strict"; | ||
/* eslint-disable */ | ||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT. | ||
// versions: | ||
// protoc-gen-ts_proto v1.181.1 | ||
// protoc v4.25.3 | ||
// source: market_data.proto | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MarketByOrderDiff_DiffOp = exports.MarketByPriceDiff_DiffOp = exports.RateUpdateSide = exports.AggressingSide = exports.MarketState = exports.KlineInterval = exports.Side = exports.protobufPackage = void 0; | ||
/* eslint-disable */ | ||
exports.protobufPackage = "market_data"; | ||
@@ -18,5 +23,9 @@ /** | ||
* Market by Order (MBO). In addition, clients can subscribe to the trade stream | ||
* and price candlesticks. Clients should submit a [`Config`](#config) and then | ||
* process [`MdMessage`](#mdmessage)'s. | ||
* and price candlesticks. | ||
* | ||
* Upon connection, clients should submit a [`Config`](#config) and then | ||
* process a stream of [`MdMessages`](#mdmessages). | ||
* Note that this message type is distinct from the [`MdMessage`](#mdmessage), | ||
* where the former is a wrapper containing one or more of the latter. | ||
* | ||
* ### Aggregate Book Tops Data | ||
@@ -23,0 +32,0 @@ * |
@@ -29,3 +29,3 @@ "use strict"; | ||
default: | ||
throw new tsProtoGlobalThis.Error("Unrecognized enum value " + object + " for enum CloseCode"); | ||
throw new globalThis.Error("Unrecognized enum value " + object + " for enum CloseCode"); | ||
} | ||
@@ -51,20 +51,5 @@ } | ||
default: | ||
throw new tsProtoGlobalThis.Error("Unrecognized enum value " + object + " for enum CloseCode"); | ||
throw new globalThis.Error("Unrecognized enum value " + object + " for enum CloseCode"); | ||
} | ||
} | ||
exports.closeCodeToJSON = closeCodeToJSON; | ||
var tsProtoGlobalThis = (() => { | ||
if (typeof globalThis !== "undefined") { | ||
return globalThis; | ||
} | ||
if (typeof self !== "undefined") { | ||
return self; | ||
} | ||
if (typeof window !== "undefined") { | ||
return window; | ||
} | ||
if (typeof global !== "undefined") { | ||
return global; | ||
} | ||
throw "Unable to locate global object"; | ||
})(); |
@@ -1,2 +0,2 @@ | ||
import { Side, TimeInForce, OrderType, SelfTradePrevention, PostOnly, ConnectionStatus, Credentials, OrderRequest, NewOrder, CancelOrder, ModifyOrder, MassCancel, Heartbeat, OrderResponse, NewOrderAck, CancelOrderAck, CancelOrderAck_Reason, ModifyOrderAck, MassCancelAck, MassCancelAck_Reason, NewOrderReject, NewOrderReject_Reason, CancelOrderReject, CancelOrderReject_Reason, ModifyOrderReject, ModifyOrderReject_Reason, Fill, FixedPointDecimal, AssetPosition, RawUnits, Bootstrap, RestingOrders, AssetPositions, Done, TradingStatus, RestingOrder } from '../trade'; | ||
import { Side, TimeInForce, OrderType, SelfTradePrevention, PostOnly, ConnectionStatus, Credentials, OrderRequest, NewOrder, CancelOrder, ModifyOrder, MassCancel, Heartbeat, OrderResponse, NewOrderAck, CancelOrderAck, CancelOrderAck_Reason, ModifyOrderAck, MassCancelAck, MassCancelAck_Reason, NewOrderReject, NewOrderReject_Reason, CancelOrderReject, CancelOrderReject_Reason, ModifyOrderReject, ModifyOrderReject_Reason, Fill, ImpliedMatchFee, FixedPointDecimal, AssetPosition, RawUnits, Bootstrap, RestingOrders, AssetPositions, Done, TradingStatus, RestingOrder } from '../trade'; | ||
import * as _m0 from "protobufjs/minimal"; | ||
@@ -121,2 +121,8 @@ export declare function sideFromJSON(object: any): Side; | ||
}; | ||
export declare const ImpliedMatchFeeMethods: { | ||
encode(message: ImpliedMatchFee, writer?: _m0.Writer): _m0.Writer; | ||
decode(input: _m0.Reader | Uint8Array, length?: number): ImpliedMatchFee; | ||
fromJSON(object: any): ImpliedMatchFee; | ||
toJSON(message: ImpliedMatchFee): unknown; | ||
}; | ||
export declare const FixedPointDecimalMethods: { | ||
@@ -123,0 +129,0 @@ encode(message: FixedPointDecimal, writer?: _m0.Writer): _m0.Writer; |
export declare const protobufPackage = "trade"; | ||
/** | ||
* This schema defines the Protobuf messages used for communication with the | ||
* Cube Order Service (Osmium, OS). The base URL for channels described in this | ||
* page is `wss://api.cube.exchange/os`. The `proto` definition file can be found | ||
* [here](https://github.com/cubexch/ws-api/blob/main/schema/trade.proto). | ||
* Cube Order Service (OS, or "Osmium"). | ||
* | ||
* - The connection URL for this Websocket API is `wss://api.cube.exchange/os`. | ||
* | ||
* - See also: | ||
* - The [Protobuf definition file for the Websocket connection](https://github.com/cubexch/ws-api/blob/main/schema/trade.proto) | ||
* - [General documentation pertaining to the Trade API](https://cubexch.gitbook.io/cube-api/trade-api) | ||
* | ||
* ### Connection | ||
@@ -21,85 +25,2 @@ * | ||
* interval is missed, the order service will disconnect the websocket. | ||
* | ||
* ### Price, Quantity, and Lots | ||
* | ||
* All orders are placed on a single market, specified by the market-id. The | ||
* market definition specifies the base and quote assets and their respective | ||
* lot sizes for the particular market. Prices and quantities in this API are in | ||
* units of base and quote _lots_. That is, a quantity of 1 equals 1 base lot, | ||
* and a price of 10 equals 10 quote lots / base lot (read as quote lots per | ||
* base lot). | ||
* | ||
* For example, consider an ETHBTC market. ETH is the base asset and BTC is the | ||
* quote asset. ETH has 18 decimal places (`1 ETH = 10^18 WEI`) and BTC has 8 | ||
* decimal places (`1 BTC = 10^8 SAT`). Suppose that in this example, the ETHBTC | ||
* market has a base lot size of `10^15` and a quote lot size of `10^0` (`1`). | ||
* Then an order placed with `quantity = 230` and `price = 6300` in | ||
* market-agnostic terms is an order for `0.23 ETH` at a price of `0.06300 BTC / | ||
* ETH`. In more detail, we have: | ||
* | ||
* ```text | ||
* 230 base lots | ||
* * (10^15 WEI / base lot) | ||
* / (10^18 WEI / ETH) | ||
* = 0.230 ETH | ||
* | ||
* 6300 quote lots / base lot | ||
* * (1 SAT / quote lot) | ||
* / (10^15 WEI / base lot) | ||
* * (10^18 WEI / ETH) | ||
* / (10^8 SAT / BTC) | ||
* = 0.06300 BTC / ETH | ||
* ``` | ||
* | ||
* ### Trading Fees | ||
* | ||
* Trading Fees are calculated on each individual trade as a ratio of the filled quantity, | ||
* and are always charged as a deduction from the asset received in that trade. | ||
* | ||
* Fee ratios may vary from trade to trade based on the user's VIP level. | ||
* For fee discounts based on Trading Volume, ratios are adjusted continuously | ||
* at the time of each trade based on the user's trailing 30-day volume. | ||
* | ||
* To ensure that the client has enough information to determine the exact fee charged, | ||
* the fee ratio is expressed as a fixed-point decimal number consisting of a mantissa and an exponent. | ||
* Generally, the exponent will be "-4", indicating that the mantissa is equivalent to pips, | ||
* Though some fees may be expressed with greater granularity. | ||
* | ||
* For example, consider the case of a trade where: | ||
* - Asset received is BTC | ||
* - `quantity` = 5 | ||
* - `fee_ratio.mantissa` = 11 | ||
* - `fee_ratio.exponent` = -4 | ||
* | ||
* ...in which case: | ||
* - The fee ratio would be 0.0011, or 11 pips. | ||
* - The fee would be equal to 0.0055 BTC. | ||
* - The total amount credited at settlement would be 4.9945 BTC. | ||
* | ||
* If you need exact granularity at time of trade, you can replicate the fee calculation performed by the exchange. | ||
* To avoid rounding errors, this entire process is performed in integer math using the exponent as a devisor. | ||
* In the example above, the full fee amount in indivisible [RawUnits](#rawunits) would be calculated as: | ||
* ```text | ||
* 5 * 100_000_000 * 11 / 10_000 = 550_000 RawUnits | ||
* | ||
* (in the BTC case, that would be 550,000 Satoshi) | ||
* ``` | ||
* | ||
* Since the fee is expressed with a decimal exponent, it's highly likely that this calculation results in a whole number. | ||
* In the unlikely case that the final division results in a non-whole number, the result should be truncated, | ||
* hence the division at the end: i.e. the fee is rounded down to the nearest `RawUnit`. | ||
* | ||
* ### Exchange Order ID | ||
* | ||
* Each order is assigned a unique ID by the exchange. This order ID is | ||
* consistent across modifies (including cancel-replace), and other operations. | ||
* The exchange order ID can be used to find a particular order in the | ||
* market-by-order market data feed, which allows the determination of FIFO | ||
* queue priority, etc. | ||
* | ||
* ### Transact Time | ||
* | ||
* The transact time is the matching engine timestamp for when an event is | ||
* processed. Events that occur with the same transact time occur atomically | ||
* from the perspective of the matching engine. | ||
*/ | ||
@@ -141,2 +62,10 @@ /** | ||
* | ||
* Limit orders refer to orders of type: | ||
* - LIMIT | ||
* | ||
* Market orders refer to orders of type: | ||
* - MARKET_LIMIT | ||
* - MARKET_WITH_PROTECTION | ||
* | ||
* Pre-flight quantity checks: | ||
* - Note that for LIMIT orders, there is a pre-flight check that there is | ||
@@ -146,6 +75,32 @@ * sufficient available balance to place this order at the price and quantity | ||
* EXCEEDED_SPOT_POSITION reason. | ||
* - For MARKET_LIMIT and MARKET_WITH_PROTECTION orders, there is no such | ||
* pre-flight check and a submitted order will be partially filled up until | ||
* the subaccount's position limit. The remaining quantity will be canceled | ||
* with the POSITION_LIMIT reason. | ||
* - For Market orders, there is no quantity-based pre-flight check and a | ||
* submitted order will be partially filled up until the subaccount's position | ||
* limit. The remaining quantity will be canceled with the POSITION_LIMIT | ||
* reason. | ||
* | ||
* For the following section, let | ||
* | ||
* ``` | ||
* P_r = reference price | ||
* L = protection levels | ||
* P_ap = default protection ask price = P_r + L | ||
* P_bp = default protection bid price = P_r - L | ||
* ``` | ||
* | ||
* Market order protections: | ||
* - Before execution, the following pre-flight slippage check is always | ||
* performed: | ||
* | ||
* ``` | ||
* P_a = best book ask price | ||
* P_b = best book bid price | ||
* if side == BID: | ||
* ensure P_a <= P_ap | ||
* if side == ASK: | ||
* ensure P_b >= P_bp | ||
* ``` | ||
* | ||
* Note that this calculation is irrespective of the order parameters. | ||
* - During execution, the match stops depending on the exit condition specified | ||
* by the order type. | ||
*/ | ||
@@ -170,3 +125,3 @@ export declare enum OrderType { | ||
* MARKET_WITH_PROTECTION - A market with protection order crosses the bid-ask spread and continues to | ||
* cross until the order is fully filled or the protection price is reached. | ||
* cross until the order is fully filled or the protection level is reached. | ||
* - The protection price is defined as: | ||
@@ -251,6 +206,6 @@ * - If the price is provided, this price is used as the protection price. | ||
* When calculated for: | ||
* secret key: "cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe" | ||
* timestamp: 1706546268 | ||
* - secret key: "cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe" | ||
* - timestamp: 1706546268 | ||
* ...the resulting signature should be: | ||
* "tmtSP4NIzTLXyVUHIOfinotGnPWyfM8JefxivBdSjc8=" | ||
* - "tmtSP4NIzTLXyVUHIOfinotGnPWyfM8JefxivBdSjc8=" | ||
* | ||
@@ -274,9 +229,13 @@ * #### Rust | ||
* mac.update(×tamp.to_le_bytes()); | ||
* | ||
* let signature_bytes = <[u8; 32]>::from(mac.finalize().into_bytes()); | ||
* let signature = base64::general_purpose::STANDARD.encode(signature_bytes); | ||
* | ||
* println!("{}", signature); | ||
* ``` | ||
* | ||
* #### Typescript | ||
* ``` | ||
* ```typescript | ||
* import { createHmac } from 'crypto'; | ||
* | ||
* const secretKey = "cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe"; | ||
@@ -291,3 +250,25 @@ * const timestampSecs = Math.floor(Date.now() / 1000); | ||
* .digest('base64'); | ||
* | ||
* console.log(signature) | ||
* ``` | ||
* | ||
* #### Python | ||
* ```python | ||
* import base64 | ||
* import hmac | ||
* | ||
* # Calculates "signature" field for "Credentials" message | ||
* def calculate_signature(secret_key: bytes, timestamp_seconds: int) -> str: | ||
* h = hmac.new(secret_key, digestmod=hashlib.sha256) | ||
* h.update("cube.xyz".encode('utf-8')) | ||
* h.update(timestamp_seconds.to_bytes(8, byteorder="little", signed=False)) | ||
* signature_bytes = h.digest() | ||
* return base64.standard_b64encode(signature_bytes).decode('utf-8') | ||
* | ||
* secret_key = bytes.fromhex("cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe") | ||
* timestamp = int(time.time()) | ||
* signature = calculate_signature(secret_key, timestamp) | ||
* | ||
* print(signature) | ||
* ```` | ||
*/ | ||
@@ -313,3 +294,17 @@ export interface Credentials { | ||
} | ||
/** Place a new order. */ | ||
/** | ||
* Place a new order. | ||
* | ||
* Execution details: | ||
* - For market orders, exactly one of `quantity` or `quote_quantity` must be | ||
* specified. | ||
* - For MARKET_WITH_PROTECTION, if `price` is specified, it will override the | ||
* default protection price. | ||
* - Matching will stop upon reaching the protection price, or `quantity` (or | ||
* `quote_quantity`) filled. | ||
* - When specifying `quote_quantity`, the order is considered 'fully filled' | ||
* when there is insufficient remaining quote quantity to fill 1 lot at the | ||
* next trade price. In that case, there will _not_ be a `CancelOrderAck` | ||
* published. | ||
*/ | ||
export interface NewOrder { | ||
@@ -325,3 +320,4 @@ /** | ||
price?: bigint | undefined; | ||
quantity: bigint; | ||
/** Required for LIMIT orders. */ | ||
quantity?: bigint | undefined; | ||
side: Side; | ||
@@ -349,2 +345,12 @@ timeInForce: TimeInForce; | ||
cancelOnDisconnect: boolean; | ||
/** | ||
* The quantity of the quote asset that the user wants to spend (for a BID) or | ||
* receive (for an ASK). For limit orders, this is immediately converted to a | ||
* base quantity using the provided price. For market orders, this is the | ||
* maximum quantity that will be executed. | ||
* | ||
* Note that lot size rules will be respected, and the actual quantity | ||
* executed will be expressed in base quantity units. | ||
*/ | ||
quoteQuantity?: bigint | undefined; | ||
} | ||
@@ -452,2 +458,3 @@ /** | ||
tradingStatus?: TradingStatus | undefined; | ||
impliedMatchFee?: ImpliedMatchFee | undefined; | ||
} | ||
@@ -464,11 +471,15 @@ /** | ||
requestId: bigint; | ||
/** [Exchange order ID](#exchange-order-id) */ | ||
/** [Exchange order ID](trade-api.md#exchange-order-id) */ | ||
exchangeOrderId: bigint; | ||
marketId: bigint; | ||
/** | ||
* If the order ultimately rests, the `price` field will include the resting | ||
* price. | ||
* The price that matching completed at. For limit orders, this will be the | ||
* limit price. For market orders, this will be the protection price. | ||
*/ | ||
price?: bigint | undefined; | ||
/** The quantity submitted in the new-order request. */ | ||
price: bigint; | ||
/** | ||
* If `quote_quantity` was not specified, the quantity submitted in the | ||
* new-order request. Otherwise, the quantity of the base asset that was | ||
* executed. | ||
*/ | ||
quantity: bigint; | ||
@@ -478,6 +489,7 @@ side: Side; | ||
orderType: OrderType; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
subaccountId: bigint; | ||
cancelOnDisconnect: boolean; | ||
quoteQuantity?: bigint | undefined; | ||
} | ||
@@ -498,3 +510,3 @@ /** | ||
requestId: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -504,3 +516,3 @@ subaccountId: bigint; | ||
marketId: bigint; | ||
/** [Exchange order ID](#exchange-order-id) */ | ||
/** [Exchange order ID](trade-api.md#exchange-order-id) */ | ||
exchangeOrderId: bigint; | ||
@@ -537,3 +549,3 @@ } | ||
requestId: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -549,3 +561,3 @@ /** The quantity remaining on the book after applying the modify request. */ | ||
cumulativeQuantity: bigint; | ||
/** [Exchange order ID](#exchange-order-id) */ | ||
/** [Exchange order ID](trade-api.md#exchange-order-id) */ | ||
exchangeOrderId: bigint; | ||
@@ -563,3 +575,3 @@ } | ||
requestId: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -582,3 +594,3 @@ reason?: MassCancelAck_Reason | undefined; | ||
requestId: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -589,6 +601,7 @@ subaccountId: bigint; | ||
price?: bigint | undefined; | ||
quantity: bigint; | ||
quantity?: bigint | undefined; | ||
side: Side; | ||
timeInForce: TimeInForce; | ||
orderType: OrderType; | ||
quoteQuantity?: bigint | undefined; | ||
} | ||
@@ -658,3 +671,8 @@ /** | ||
*/ | ||
OUTSIDE_PRICE_BAND = 21 | ||
OUTSIDE_PRICE_BAND = 21, | ||
LIMIT_ORDER_WITHOUT_PRICE = 22, | ||
/** CONFLICTING_QUANTITY_TYPE - Both `quantity` and `quote_quantity` were specified. */ | ||
CONFLICTING_QUANTITY_TYPE = 23, | ||
/** NO_QUANTITY_TYPE - Neither `quantity` nor `quote_quantity` was specified. */ | ||
NO_QUANTITY_TYPE = 24 | ||
} | ||
@@ -668,3 +686,3 @@ /** Cancel-order-reject indicates that a cancel-order request was not applied. */ | ||
requestId: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -692,3 +710,3 @@ subaccountId: bigint; | ||
requestId: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -746,3 +764,3 @@ subaccountId: bigint; | ||
clientOrderId: bigint; | ||
/** [Exchange order ID](#exchange-order-id) */ | ||
/** [Exchange order ID](trade-api.md#exchange-order-id) */ | ||
exchangeOrderId: bigint; | ||
@@ -754,3 +772,3 @@ /** | ||
* To determine the exact amount of the assets exchanged in the fill, | ||
* use the fill_quantity and quote_quantity fields. | ||
* use the fill_quantity and fill_quote_quantity fields. | ||
*/ | ||
@@ -772,3 +790,3 @@ fillPrice: bigint; | ||
fillQuoteQuantity: bigint; | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
@@ -782,3 +800,3 @@ subaccountId: bigint; | ||
* Indicates the fee charged on this trade. | ||
* See [Fees](#fees) for details. | ||
* See [Trading Fees](cube-fees.md#trading-fees) for details. | ||
*/ | ||
@@ -793,2 +811,33 @@ feeRatio: FixedPointDecimal | undefined; | ||
/** | ||
* Indicates the implied match fee for a trade. | ||
* This message will be delivered once for each aggressing NewOrder (taker order) | ||
* that results in one or more implied fills. | ||
* If an implied match occurs but the implied match fee is zero, | ||
* this message will still be delivered and the fee_amount will be zero. | ||
*/ | ||
export interface ImpliedMatchFee { | ||
msgSeqNum: bigint; | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
transactTime: bigint; | ||
/** The ID of the market in which the order was placed */ | ||
marketId: bigint; | ||
/** The ID of the subaccount which placed the aggressing order that resulted in the implied match. */ | ||
subaccountId: bigint; | ||
/** The ID assigned by the client that placed the aggressing order that resulted in the implied match. */ | ||
clientOrderId: bigint; | ||
/** The ID assigned by the exchange to the agressing order that resulted in the implied match. */ | ||
exchangeOrderId: bigint; | ||
/** The ID of the asset demoninating the fee_amount. */ | ||
feeAssetId: bigint; | ||
/** | ||
* The amount of the implied match fee in indivisible RawUnits. | ||
* For details on how this is calculated, reference the documentation related to Implied Matching. | ||
* Note that, unlike trading fees, this value is already accounted for | ||
* in the quantities reported by the fill_quantity and fill_quote_quantity fields | ||
* and does not need to be subtracted from the total | ||
* when reconciling the associated trade against on-chain settlement. | ||
*/ | ||
feeAmount: RawUnits | undefined; | ||
} | ||
/** | ||
* A fixed-point decimal number. | ||
@@ -854,3 +903,3 @@ * Matches the representation preferred by the FIX protocol, | ||
export interface Done { | ||
/** [Transact time](#transact-time) */ | ||
/** [Transact time](trade-api.md#transact-time) */ | ||
latestTransactTime: bigint; | ||
@@ -876,3 +925,3 @@ /** | ||
clientOrderId: bigint; | ||
/** [Exchange order ID](#exchange-order-id) */ | ||
/** [Exchange order ID](trade-api.md#exchange-order-id) */ | ||
exchangeOrderId: bigint; | ||
@@ -893,3 +942,3 @@ marketId: bigint; | ||
remainingQuantity: bigint; | ||
/** [Transact time](#transact-time) of the NewOrderAck */ | ||
/** [Transact time](trade-api.md#transact-time) of the NewOrderAck */ | ||
restTime: bigint; | ||
@@ -896,0 +945,0 @@ subaccountId: bigint; |
149
lib/trade.js
"use strict"; | ||
/* eslint-disable */ | ||
// Code generated by protoc-gen-ts_proto. DO NOT EDIT. | ||
// versions: | ||
// protoc-gen-ts_proto v1.181.1 | ||
// protoc v4.25.3 | ||
// source: trade.proto | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ModifyOrderReject_Reason = exports.CancelOrderReject_Reason = exports.NewOrderReject_Reason = exports.MassCancelAck_Reason = exports.CancelOrderAck_Reason = exports.ConnectionStatus = exports.PostOnly = exports.SelfTradePrevention = exports.OrderType = exports.TimeInForce = exports.Side = exports.protobufPackage = void 0; | ||
/* eslint-disable */ | ||
exports.protobufPackage = "trade"; | ||
/** | ||
* This schema defines the Protobuf messages used for communication with the | ||
* Cube Order Service (Osmium, OS). The base URL for channels described in this | ||
* page is `wss://api.cube.exchange/os`. The `proto` definition file can be found | ||
* [here](https://github.com/cubexch/ws-api/blob/main/schema/trade.proto). | ||
* Cube Order Service (OS, or "Osmium"). | ||
* | ||
* - The connection URL for this Websocket API is `wss://api.cube.exchange/os`. | ||
* | ||
* - See also: | ||
* - The [Protobuf definition file for the Websocket connection](https://github.com/cubexch/ws-api/blob/main/schema/trade.proto) | ||
* - [General documentation pertaining to the Trade API](https://cubexch.gitbook.io/cube-api/trade-api) | ||
* | ||
* ### Connection | ||
@@ -25,85 +34,2 @@ * | ||
* interval is missed, the order service will disconnect the websocket. | ||
* | ||
* ### Price, Quantity, and Lots | ||
* | ||
* All orders are placed on a single market, specified by the market-id. The | ||
* market definition specifies the base and quote assets and their respective | ||
* lot sizes for the particular market. Prices and quantities in this API are in | ||
* units of base and quote _lots_. That is, a quantity of 1 equals 1 base lot, | ||
* and a price of 10 equals 10 quote lots / base lot (read as quote lots per | ||
* base lot). | ||
* | ||
* For example, consider an ETHBTC market. ETH is the base asset and BTC is the | ||
* quote asset. ETH has 18 decimal places (`1 ETH = 10^18 WEI`) and BTC has 8 | ||
* decimal places (`1 BTC = 10^8 SAT`). Suppose that in this example, the ETHBTC | ||
* market has a base lot size of `10^15` and a quote lot size of `10^0` (`1`). | ||
* Then an order placed with `quantity = 230` and `price = 6300` in | ||
* market-agnostic terms is an order for `0.23 ETH` at a price of `0.06300 BTC / | ||
* ETH`. In more detail, we have: | ||
* | ||
* ```text | ||
* 230 base lots | ||
* * (10^15 WEI / base lot) | ||
* / (10^18 WEI / ETH) | ||
* = 0.230 ETH | ||
* | ||
* 6300 quote lots / base lot | ||
* * (1 SAT / quote lot) | ||
* / (10^15 WEI / base lot) | ||
* * (10^18 WEI / ETH) | ||
* / (10^8 SAT / BTC) | ||
* = 0.06300 BTC / ETH | ||
* ``` | ||
* | ||
* ### Trading Fees | ||
* | ||
* Trading Fees are calculated on each individual trade as a ratio of the filled quantity, | ||
* and are always charged as a deduction from the asset received in that trade. | ||
* | ||
* Fee ratios may vary from trade to trade based on the user's VIP level. | ||
* For fee discounts based on Trading Volume, ratios are adjusted continuously | ||
* at the time of each trade based on the user's trailing 30-day volume. | ||
* | ||
* To ensure that the client has enough information to determine the exact fee charged, | ||
* the fee ratio is expressed as a fixed-point decimal number consisting of a mantissa and an exponent. | ||
* Generally, the exponent will be "-4", indicating that the mantissa is equivalent to pips, | ||
* Though some fees may be expressed with greater granularity. | ||
* | ||
* For example, consider the case of a trade where: | ||
* - Asset received is BTC | ||
* - `quantity` = 5 | ||
* - `fee_ratio.mantissa` = 11 | ||
* - `fee_ratio.exponent` = -4 | ||
* | ||
* ...in which case: | ||
* - The fee ratio would be 0.0011, or 11 pips. | ||
* - The fee would be equal to 0.0055 BTC. | ||
* - The total amount credited at settlement would be 4.9945 BTC. | ||
* | ||
* If you need exact granularity at time of trade, you can replicate the fee calculation performed by the exchange. | ||
* To avoid rounding errors, this entire process is performed in integer math using the exponent as a devisor. | ||
* In the example above, the full fee amount in indivisible [RawUnits](#rawunits) would be calculated as: | ||
* ```text | ||
* 5 * 100_000_000 * 11 / 10_000 = 550_000 RawUnits | ||
* | ||
* (in the BTC case, that would be 550,000 Satoshi) | ||
* ``` | ||
* | ||
* Since the fee is expressed with a decimal exponent, it's highly likely that this calculation results in a whole number. | ||
* In the unlikely case that the final division results in a non-whole number, the result should be truncated, | ||
* hence the division at the end: i.e. the fee is rounded down to the nearest `RawUnit`. | ||
* | ||
* ### Exchange Order ID | ||
* | ||
* Each order is assigned a unique ID by the exchange. This order ID is | ||
* consistent across modifies (including cancel-replace), and other operations. | ||
* The exchange order ID can be used to find a particular order in the | ||
* market-by-order market data feed, which allows the determination of FIFO | ||
* queue priority, etc. | ||
* | ||
* ### Transact Time | ||
* | ||
* The transact time is the matching engine timestamp for when an event is | ||
* processed. Events that occur with the same transact time occur atomically | ||
* from the perspective of the matching engine. | ||
*/ | ||
@@ -147,2 +73,10 @@ /** | ||
* | ||
* Limit orders refer to orders of type: | ||
* - LIMIT | ||
* | ||
* Market orders refer to orders of type: | ||
* - MARKET_LIMIT | ||
* - MARKET_WITH_PROTECTION | ||
* | ||
* Pre-flight quantity checks: | ||
* - Note that for LIMIT orders, there is a pre-flight check that there is | ||
@@ -152,6 +86,32 @@ * sufficient available balance to place this order at the price and quantity | ||
* EXCEEDED_SPOT_POSITION reason. | ||
* - For MARKET_LIMIT and MARKET_WITH_PROTECTION orders, there is no such | ||
* pre-flight check and a submitted order will be partially filled up until | ||
* the subaccount's position limit. The remaining quantity will be canceled | ||
* with the POSITION_LIMIT reason. | ||
* - For Market orders, there is no quantity-based pre-flight check and a | ||
* submitted order will be partially filled up until the subaccount's position | ||
* limit. The remaining quantity will be canceled with the POSITION_LIMIT | ||
* reason. | ||
* | ||
* For the following section, let | ||
* | ||
* ``` | ||
* P_r = reference price | ||
* L = protection levels | ||
* P_ap = default protection ask price = P_r + L | ||
* P_bp = default protection bid price = P_r - L | ||
* ``` | ||
* | ||
* Market order protections: | ||
* - Before execution, the following pre-flight slippage check is always | ||
* performed: | ||
* | ||
* ``` | ||
* P_a = best book ask price | ||
* P_b = best book bid price | ||
* if side == BID: | ||
* ensure P_a <= P_ap | ||
* if side == ASK: | ||
* ensure P_b >= P_bp | ||
* ``` | ||
* | ||
* Note that this calculation is irrespective of the order parameters. | ||
* - During execution, the match stops depending on the exit condition specified | ||
* by the order type. | ||
*/ | ||
@@ -177,3 +137,3 @@ var OrderType; | ||
* MARKET_WITH_PROTECTION - A market with protection order crosses the bid-ask spread and continues to | ||
* cross until the order is fully filled or the protection price is reached. | ||
* cross until the order is fully filled or the protection level is reached. | ||
* - The protection price is defined as: | ||
@@ -326,2 +286,7 @@ * - If the price is provided, this price is used as the protection price. | ||
NewOrderReject_Reason[NewOrderReject_Reason["OUTSIDE_PRICE_BAND"] = 21] = "OUTSIDE_PRICE_BAND"; | ||
NewOrderReject_Reason[NewOrderReject_Reason["LIMIT_ORDER_WITHOUT_PRICE"] = 22] = "LIMIT_ORDER_WITHOUT_PRICE"; | ||
/** CONFLICTING_QUANTITY_TYPE - Both `quantity` and `quote_quantity` were specified. */ | ||
NewOrderReject_Reason[NewOrderReject_Reason["CONFLICTING_QUANTITY_TYPE"] = 23] = "CONFLICTING_QUANTITY_TYPE"; | ||
/** NO_QUANTITY_TYPE - Neither `quantity` nor `quote_quantity` was specified. */ | ||
NewOrderReject_Reason[NewOrderReject_Reason["NO_QUANTITY_TYPE"] = 24] = "NO_QUANTITY_TYPE"; | ||
})(NewOrderReject_Reason = exports.NewOrderReject_Reason || (exports.NewOrderReject_Reason = {})); | ||
@@ -328,0 +293,0 @@ var CancelOrderReject_Reason; |
{ | ||
"name": "@cubexch/client", | ||
"version": "1.2.0", | ||
"version": "1.4.0", | ||
"scripts": { | ||
@@ -17,3 +17,3 @@ "build": "tsc" | ||
}, | ||
"packageManager": "yarn@3.6.1" | ||
"packageManager": "pnpm@8.15.6" | ||
} |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
457897
11311