@orderly.network/hooks 2.10.2 → 2.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +190 -59
- package/dist/index.d.ts +190 -59
- package/dist/index.js +1623 -926
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1618 -927
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -10
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import useSWR5__default, { mutate } from 'swr';
|
|
|
3
3
|
import * as useSWR5 from 'swr';
|
|
4
4
|
export { useSWR5 as swr };
|
|
5
5
|
export { unstable_serialize, default as useSWR, useSWRConfig } from 'swr';
|
|
6
|
-
import { TesnetTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderType, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, EMPTY_LIST, EMPTY_OBJECT, isNativeTokenChecker, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, ETHEREUM_MAINNET_CHAINID, LedgerWalletKey, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, SolanaChains, PositionType, DistributionType, TriggerPriceType } from '@orderly.network/types';
|
|
6
|
+
import { TesnetTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, MarginMode, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderType, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, EMPTY_LIST, EMPTY_OBJECT, isNativeTokenChecker, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, ETHEREUM_MAINNET_CHAINID, LedgerWalletKey, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, SolanaChains, PositionType, DistributionType, TriggerPriceType } from '@orderly.network/types';
|
|
7
7
|
import React, { createContext, useContext, useCallback, useState, useEffect, useMemo, useRef, useId, useLayoutEffect } from 'react';
|
|
8
8
|
import { zero, windowGuard, getTimestamp, getGlobalObject, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, getBBOType, camelCaseToUnderscoreCase, commify, todpIfNeed, getTPSLDirection } from '@orderly.network/utils';
|
|
9
9
|
import useSWRMutation from 'swr/mutation';
|
|
@@ -38,9 +38,9 @@ var __export = (target, all) => {
|
|
|
38
38
|
// src/version.ts
|
|
39
39
|
if (typeof window !== "undefined") {
|
|
40
40
|
window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
|
|
41
|
-
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.
|
|
41
|
+
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.11.0";
|
|
42
42
|
}
|
|
43
|
-
var version_default = "2.
|
|
43
|
+
var version_default = "2.11.0";
|
|
44
44
|
var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
|
|
45
45
|
var noCacheConfig = {
|
|
46
46
|
dedupingInterval: 0,
|
|
@@ -1084,12 +1084,12 @@ var findTPSLOrderPriceFromOrder = (order) => {
|
|
|
1084
1084
|
sl_order_price
|
|
1085
1085
|
};
|
|
1086
1086
|
};
|
|
1087
|
-
var findPositionTPSLFromOrders = (orders, symbol) => {
|
|
1087
|
+
var findPositionTPSLFromOrders = (orders, symbol, marginMode = MarginMode.CROSS) => {
|
|
1088
1088
|
const fullPositionOrder = orders?.find((order) => {
|
|
1089
|
-
return order.symbol === symbol && order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1089
|
+
return order.symbol === symbol && order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL && order.margin_mode === marginMode && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1090
1090
|
});
|
|
1091
1091
|
const partialPositionOrders = orders?.filter((order) => {
|
|
1092
|
-
return order.symbol === symbol && order.algo_type === AlgoOrderRootType.TP_SL && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1092
|
+
return order.symbol === symbol && order.margin_mode === marginMode && order.algo_type === AlgoOrderRootType.TP_SL && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1093
1093
|
}).sort((a, b) => {
|
|
1094
1094
|
return b.created_time - a.created_time;
|
|
1095
1095
|
});
|
|
@@ -2114,9 +2114,11 @@ var useAppStore = create()(
|
|
|
2114
2114
|
totalCollateral: zero,
|
|
2115
2115
|
totalValue: null,
|
|
2116
2116
|
freeCollateral: zero,
|
|
2117
|
+
freeCollateralUSDCOnly: zero,
|
|
2117
2118
|
availableBalance: 0,
|
|
2118
2119
|
unsettledPnL: 0,
|
|
2119
|
-
totalUnrealizedROI: 0
|
|
2120
|
+
totalUnrealizedROI: 0,
|
|
2121
|
+
usdcHolding: 0
|
|
2120
2122
|
},
|
|
2121
2123
|
appState: {
|
|
2122
2124
|
positionsLoading: false,
|
|
@@ -2137,9 +2139,11 @@ var useAppStore = create()(
|
|
|
2137
2139
|
totalCollateral: zero,
|
|
2138
2140
|
totalValue: null,
|
|
2139
2141
|
freeCollateral: zero,
|
|
2142
|
+
freeCollateralUSDCOnly: zero,
|
|
2140
2143
|
availableBalance: 0,
|
|
2141
2144
|
unsettledPnL: 0,
|
|
2142
|
-
totalUnrealizedROI: 0
|
|
2145
|
+
totalUnrealizedROI: 0,
|
|
2146
|
+
usdcHolding: 0
|
|
2143
2147
|
};
|
|
2144
2148
|
}, false);
|
|
2145
2149
|
},
|
|
@@ -3935,25 +3939,27 @@ var OrderbookService = class _OrderbookService {
|
|
|
3935
3939
|
};
|
|
3936
3940
|
var orderBookService = OrderbookService.getInstance();
|
|
3937
3941
|
var orderbook_service_default = orderBookService;
|
|
3942
|
+
var useMarkPriceStore = create((set, get3) => ({
|
|
3943
|
+
markPrices: {},
|
|
3944
|
+
// orderBook: {},
|
|
3945
|
+
// ask_bid: [],
|
|
3946
|
+
actions: {
|
|
3947
|
+
updateMarkPrice: (markPrice) => {
|
|
3948
|
+
set({
|
|
3949
|
+
markPrices: markPrice
|
|
3950
|
+
});
|
|
3951
|
+
},
|
|
3952
|
+
getMarkPriceBySymbol: (symbol) => {
|
|
3953
|
+
return get3().markPrices[symbol];
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
}));
|
|
3957
|
+
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
3958
|
+
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
3959
|
+
|
|
3960
|
+
// src/orderly/useMarkPrice.ts
|
|
3938
3961
|
var useMarkPrice = (symbol) => {
|
|
3939
|
-
const
|
|
3940
|
-
const [price, setPrice] = useState(0);
|
|
3941
|
-
const symbolRef = useRef(symbol);
|
|
3942
|
-
symbolRef.current = symbol;
|
|
3943
|
-
useEffect(() => {
|
|
3944
|
-
const unsubscribe = ws.subscribe(`${symbol}@markprice`, {
|
|
3945
|
-
onMessage: (message) => {
|
|
3946
|
-
if (message.symbol !== symbolRef.current) {
|
|
3947
|
-
unsubscribe?.();
|
|
3948
|
-
return;
|
|
3949
|
-
}
|
|
3950
|
-
setPrice(message.price);
|
|
3951
|
-
}
|
|
3952
|
-
});
|
|
3953
|
-
return () => {
|
|
3954
|
-
unsubscribe?.();
|
|
3955
|
-
};
|
|
3956
|
-
}, [symbol]);
|
|
3962
|
+
const price = useMarkPriceBySymbol(symbol);
|
|
3957
3963
|
return { data: price };
|
|
3958
3964
|
};
|
|
3959
3965
|
var useIndexPrice = (symbol) => {
|
|
@@ -3976,6 +3982,12 @@ var useIndexPrice = (symbol) => {
|
|
|
3976
3982
|
};
|
|
3977
3983
|
});
|
|
3978
3984
|
};
|
|
3985
|
+
|
|
3986
|
+
// src/orderly/useMarkPricesStream.ts
|
|
3987
|
+
var useMarkPricesStream = () => {
|
|
3988
|
+
const data = useMarkPriceStore((state) => state.markPrices);
|
|
3989
|
+
return { data };
|
|
3990
|
+
};
|
|
3979
3991
|
var useOpenInterest = (symbol) => {
|
|
3980
3992
|
const ws = useWS();
|
|
3981
3993
|
const symbolRef = useRef(symbol);
|
|
@@ -3995,29 +4007,6 @@ var useOpenInterest = (symbol) => {
|
|
|
3995
4007
|
};
|
|
3996
4008
|
});
|
|
3997
4009
|
};
|
|
3998
|
-
var useMarkPriceStore = create((set, get3) => ({
|
|
3999
|
-
markPrices: {},
|
|
4000
|
-
// orderBook: {},
|
|
4001
|
-
// ask_bid: [],
|
|
4002
|
-
actions: {
|
|
4003
|
-
updateMarkPrice: (markPrice) => {
|
|
4004
|
-
set({
|
|
4005
|
-
markPrices: markPrice
|
|
4006
|
-
});
|
|
4007
|
-
},
|
|
4008
|
-
getMarkPriceBySymbol: (symbol) => {
|
|
4009
|
-
return get3().markPrices[symbol];
|
|
4010
|
-
}
|
|
4011
|
-
}
|
|
4012
|
-
}));
|
|
4013
|
-
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
4014
|
-
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
4015
|
-
|
|
4016
|
-
// src/orderly/useMarkPricesStream.ts
|
|
4017
|
-
var useMarkPricesStream = () => {
|
|
4018
|
-
const data = useMarkPriceStore((state) => state.markPrices);
|
|
4019
|
-
return { data };
|
|
4020
|
-
};
|
|
4021
4010
|
|
|
4022
4011
|
// src/orderly/useTickerStream.ts
|
|
4023
4012
|
var useTickerStream = (symbol) => {
|
|
@@ -4710,6 +4699,94 @@ var useLeverage = () => {
|
|
|
4710
4699
|
maxLeverage: memoizedMaxLeverage
|
|
4711
4700
|
};
|
|
4712
4701
|
};
|
|
4702
|
+
var buildKey = (symbol, marginMode) => `${symbol}_${marginMode ?? MarginMode.CROSS}`;
|
|
4703
|
+
var useSymbolLeverageMap = () => {
|
|
4704
|
+
const { data, error, isLoading, mutate: mutate6 } = usePrivateQuery("/v1/client/leverages", {
|
|
4705
|
+
revalidateOnFocus: false,
|
|
4706
|
+
revalidateOnReconnect: false,
|
|
4707
|
+
errorRetryCount: 1
|
|
4708
|
+
});
|
|
4709
|
+
const leverages = useMemo(() => {
|
|
4710
|
+
if (!data || !Array.isArray(data)) return {};
|
|
4711
|
+
const map = {};
|
|
4712
|
+
for (const item of data) {
|
|
4713
|
+
const key = buildKey(item.symbol, item.margin_mode);
|
|
4714
|
+
map[key] = item.leverage;
|
|
4715
|
+
}
|
|
4716
|
+
return map;
|
|
4717
|
+
}, [data]);
|
|
4718
|
+
const getSymbolLeverage = (symbol, marginMode) => {
|
|
4719
|
+
if (!symbol) return void 0;
|
|
4720
|
+
const key = buildKey(symbol, marginMode);
|
|
4721
|
+
return leverages[key];
|
|
4722
|
+
};
|
|
4723
|
+
return {
|
|
4724
|
+
leverages,
|
|
4725
|
+
getSymbolLeverage,
|
|
4726
|
+
isLoading,
|
|
4727
|
+
error,
|
|
4728
|
+
refresh: mutate6
|
|
4729
|
+
};
|
|
4730
|
+
};
|
|
4731
|
+
var useMarginModes = () => {
|
|
4732
|
+
const { data, error, isLoading, mutate: mutate6 } = usePrivateQuery("/v1/client/margin_modes", {
|
|
4733
|
+
revalidateOnFocus: false,
|
|
4734
|
+
revalidateOnMount: true
|
|
4735
|
+
});
|
|
4736
|
+
const [setMarginModeInternal, { isMutating }] = useMutation(
|
|
4737
|
+
"/v1/client/margin_mode",
|
|
4738
|
+
"POST"
|
|
4739
|
+
);
|
|
4740
|
+
const marginModes = useMemo(() => {
|
|
4741
|
+
if (!data || !Array.isArray(data)) return {};
|
|
4742
|
+
const map = {};
|
|
4743
|
+
for (const item of data) {
|
|
4744
|
+
map[item.symbol] = item.default_margin_mode;
|
|
4745
|
+
}
|
|
4746
|
+
return map;
|
|
4747
|
+
}, [data]);
|
|
4748
|
+
const setMarginMode = (payload) => setMarginModeInternal(payload);
|
|
4749
|
+
const updateMarginMode = useCallback(
|
|
4750
|
+
async (payload) => {
|
|
4751
|
+
const result = await setMarginMode(payload);
|
|
4752
|
+
if (result.success) {
|
|
4753
|
+
await mutate6();
|
|
4754
|
+
return result;
|
|
4755
|
+
}
|
|
4756
|
+
throw new Error(result.message ?? "Failed to update margin mode");
|
|
4757
|
+
},
|
|
4758
|
+
[setMarginMode, mutate6]
|
|
4759
|
+
);
|
|
4760
|
+
return {
|
|
4761
|
+
marginModes,
|
|
4762
|
+
isLoading,
|
|
4763
|
+
error,
|
|
4764
|
+
refresh: mutate6,
|
|
4765
|
+
setMarginMode,
|
|
4766
|
+
updateMarginMode,
|
|
4767
|
+
isMutating
|
|
4768
|
+
};
|
|
4769
|
+
};
|
|
4770
|
+
var useMarginModeBySymbol = (symbol, fallback = MarginMode.CROSS) => {
|
|
4771
|
+
const { marginModes, isLoading, error, refresh, updateMarginMode } = useMarginModes();
|
|
4772
|
+
const marginMode = fallback === null ? marginModes[symbol] : marginModes[symbol] ?? fallback;
|
|
4773
|
+
const update = useCallback(
|
|
4774
|
+
async (mode) => {
|
|
4775
|
+
return updateMarginMode({
|
|
4776
|
+
symbol_list: [symbol],
|
|
4777
|
+
default_margin_mode: mode
|
|
4778
|
+
});
|
|
4779
|
+
},
|
|
4780
|
+
[symbol, updateMarginMode]
|
|
4781
|
+
);
|
|
4782
|
+
return {
|
|
4783
|
+
marginMode,
|
|
4784
|
+
isLoading,
|
|
4785
|
+
error,
|
|
4786
|
+
refresh,
|
|
4787
|
+
update
|
|
4788
|
+
};
|
|
4789
|
+
};
|
|
4713
4790
|
|
|
4714
4791
|
// src/orderly/useOdosQuote.ts
|
|
4715
4792
|
var useOdosQuote = () => {
|
|
@@ -5067,10 +5144,13 @@ var CalculatorService = class {
|
|
|
5067
5144
|
// this.pendingCalc = [];
|
|
5068
5145
|
// }
|
|
5069
5146
|
async handleCalcQueue(context) {
|
|
5070
|
-
const
|
|
5071
|
-
|
|
5147
|
+
const batchCollector = /* @__PURE__ */ new Map();
|
|
5148
|
+
let currentContext = context;
|
|
5149
|
+
while (this.calcQueue.length > 0) {
|
|
5150
|
+
const first = this.calcQueue.shift();
|
|
5151
|
+
if (!first) break;
|
|
5072
5152
|
const { scope, data, options } = first;
|
|
5073
|
-
const ctx =
|
|
5153
|
+
const ctx = currentContext || CalculatorContext.create(scope, data);
|
|
5074
5154
|
const calculators = this.calculators.get(scope);
|
|
5075
5155
|
if (Array.isArray(calculators) && calculators.length) {
|
|
5076
5156
|
try {
|
|
@@ -5078,13 +5158,46 @@ var CalculatorService = class {
|
|
|
5078
5158
|
} catch (e) {
|
|
5079
5159
|
}
|
|
5080
5160
|
if (!options?.skipUpdate) {
|
|
5081
|
-
this.
|
|
5161
|
+
this.collectUpdates(
|
|
5162
|
+
batchCollector,
|
|
5163
|
+
scope,
|
|
5164
|
+
calculators,
|
|
5165
|
+
ctx.outputToValue()
|
|
5166
|
+
);
|
|
5082
5167
|
}
|
|
5083
5168
|
}
|
|
5084
|
-
|
|
5085
|
-
|
|
5169
|
+
currentContext = ctx;
|
|
5170
|
+
}
|
|
5171
|
+
await this.commitBatchUpdates(batchCollector);
|
|
5172
|
+
this.ctx = currentContext;
|
|
5173
|
+
}
|
|
5174
|
+
collectUpdates(collector, scope, calculators, data) {
|
|
5175
|
+
if (!collector.has(scope)) {
|
|
5176
|
+
collector.set(scope, /* @__PURE__ */ new Map());
|
|
5177
|
+
}
|
|
5178
|
+
const scopeCollector = collector.get(scope);
|
|
5179
|
+
for (const calculator of calculators) {
|
|
5180
|
+
const item = data[calculator.name];
|
|
5181
|
+
if (item !== void 0 && item !== null) {
|
|
5182
|
+
scopeCollector.set(calculator.name, item);
|
|
5183
|
+
}
|
|
5184
|
+
}
|
|
5185
|
+
}
|
|
5186
|
+
async commitBatchUpdates(collector) {
|
|
5187
|
+
if (collector.size === 0) return;
|
|
5188
|
+
for (const [scope, updateMap] of collector.entries()) {
|
|
5189
|
+
const calculators = this.calculators.get(scope);
|
|
5190
|
+
if (!Array.isArray(calculators)) continue;
|
|
5191
|
+
const batchData = {};
|
|
5192
|
+
for (const [calculatorName, data] of updateMap.entries()) {
|
|
5193
|
+
batchData[calculatorName] = data;
|
|
5194
|
+
}
|
|
5195
|
+
try {
|
|
5196
|
+
this.scheduler.update(scope, calculators, batchData);
|
|
5197
|
+
} catch (e) {
|
|
5086
5198
|
}
|
|
5087
5199
|
}
|
|
5200
|
+
collector.clear();
|
|
5088
5201
|
}
|
|
5089
5202
|
stop() {
|
|
5090
5203
|
this.calcQueue = [];
|
|
@@ -5115,6 +5228,18 @@ var cancelIdleCallbackPolyfill = (id) => {
|
|
|
5115
5228
|
var safeRequestIdleCallback = typeof window !== "undefined" && window.requestIdleCallback ? window.requestIdleCallback.bind(window) : requestIdleCallbackPolyfill;
|
|
5116
5229
|
typeof window !== "undefined" && window.cancelIdleCallback ? window.cancelIdleCallback.bind(window) : cancelIdleCallbackPolyfill;
|
|
5117
5230
|
var ShardingScheduler = class {
|
|
5231
|
+
constructor() {
|
|
5232
|
+
/**
|
|
5233
|
+
* Maximum continuous execution time per frame (in milliseconds)
|
|
5234
|
+
* Prevents blocking the main thread for too long
|
|
5235
|
+
*/
|
|
5236
|
+
this.MAX_CONTINUOUS_MS = 5;
|
|
5237
|
+
/**
|
|
5238
|
+
* Minimum remaining idle time threshold (in milliseconds)
|
|
5239
|
+
* Ensures the browser has enough idle time for other tasks
|
|
5240
|
+
*/
|
|
5241
|
+
this.MIN_IDLE_REMAINING = 2;
|
|
5242
|
+
}
|
|
5118
5243
|
// run(calculators: Calculator[]) {}
|
|
5119
5244
|
calc(scope, calculators, data, ctx) {
|
|
5120
5245
|
return new Promise((resolve, reject) => {
|
|
@@ -5155,28 +5280,27 @@ var ShardingScheduler = class {
|
|
|
5155
5280
|
computation(data, processor, onComplete) {
|
|
5156
5281
|
let index = 0;
|
|
5157
5282
|
const results = [];
|
|
5158
|
-
const
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
const
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5283
|
+
const MAX_CONTINUOUS_MS = this.MAX_CONTINUOUS_MS;
|
|
5284
|
+
const MIN_IDLE_REMAINING = this.MIN_IDLE_REMAINING;
|
|
5285
|
+
const processNextShard = (deadline) => {
|
|
5286
|
+
const frameStart = performance.now();
|
|
5287
|
+
while (index < data.length) {
|
|
5288
|
+
const elapsed = performance.now() - frameStart;
|
|
5289
|
+
const remaining = deadline.timeRemaining();
|
|
5290
|
+
if (elapsed > MAX_CONTINUOUS_MS || remaining < MIN_IDLE_REMAINING) {
|
|
5291
|
+
safeRequestIdleCallback(processNextShard, {
|
|
5292
|
+
timeout: 1e3
|
|
5293
|
+
});
|
|
5294
|
+
return;
|
|
5170
5295
|
}
|
|
5296
|
+
const result = processor([data[index]]);
|
|
5297
|
+
if (result && result.length > 0) {
|
|
5298
|
+
results.push(...result);
|
|
5299
|
+
}
|
|
5300
|
+
index++;
|
|
5171
5301
|
}
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
timeout: 1e3
|
|
5175
|
-
});
|
|
5176
|
-
} else {
|
|
5177
|
-
onComplete(results.flat());
|
|
5178
|
-
}
|
|
5179
|
-
}
|
|
5302
|
+
onComplete(results);
|
|
5303
|
+
};
|
|
5180
5304
|
safeRequestIdleCallback(processNextShard, {
|
|
5181
5305
|
timeout: 1e3
|
|
5182
5306
|
});
|
|
@@ -5389,21 +5513,38 @@ var PositionCalculator = class extends BaseCalculator {
|
|
|
5389
5513
|
const unsettlementPnL = unsettlementPnL_total.toNumber();
|
|
5390
5514
|
let totalUnrealizedROI = 0, totalUnrealizedROI_index = 0;
|
|
5391
5515
|
if (portfolio) {
|
|
5392
|
-
const { totalValue, totalCollateral } = portfolio;
|
|
5516
|
+
const { totalValue, totalCollateral: crossMarginCollateral } = portfolio;
|
|
5393
5517
|
rows = rows.map((item) => {
|
|
5394
5518
|
const info = symbolsInfo[item.symbol];
|
|
5395
|
-
const
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5519
|
+
const totalCollateral = item.margin_mode === MarginMode.ISOLATED ? new Decimal(item.margin ?? 0).add(item.unsettlement_pnl ?? 0).toNumber() : crossMarginCollateral.toNumber();
|
|
5520
|
+
let est_liq_price;
|
|
5521
|
+
if (item.margin_mode === MarginMode.ISOLATED) {
|
|
5522
|
+
est_liq_price = positions.liquidationPriceIsolated({
|
|
5523
|
+
isolatedPositionMargin: item.margin ?? 0,
|
|
5524
|
+
costPosition: item.cost_position ?? 0,
|
|
5525
|
+
positionQty: item.position_qty ?? 0,
|
|
5526
|
+
sumUnitaryFunding: fundingRates?.[item.symbol]?.["sum_unitary_funding"] ?? 0,
|
|
5527
|
+
lastSumUnitaryFunding: item.last_sum_unitary_funding ?? 0,
|
|
5528
|
+
baseMMR: info?.["base_mmr"] ?? 0,
|
|
5529
|
+
baseIMR: info?.["base_imr"] ?? 0,
|
|
5530
|
+
IMRFactor: accountInfo.imr_factor[item.symbol],
|
|
5531
|
+
referencePrice: item.mark_price,
|
|
5532
|
+
leverage: item.leverage ?? 0
|
|
5533
|
+
});
|
|
5534
|
+
} else {
|
|
5535
|
+
est_liq_price = positions.liqPrice({
|
|
5536
|
+
symbol: item.symbol,
|
|
5537
|
+
markPrice: item.mark_price,
|
|
5538
|
+
totalCollateral,
|
|
5539
|
+
positionQty: item.position_qty,
|
|
5540
|
+
positions: rows,
|
|
5541
|
+
MMR: item.mmr,
|
|
5542
|
+
baseMMR: info?.["base_mmr"],
|
|
5543
|
+
baseIMR: info?.["base_imr"],
|
|
5544
|
+
IMRFactor: accountInfo.imr_factor[item.symbol],
|
|
5545
|
+
costPosition: item.cost_position
|
|
5546
|
+
});
|
|
5547
|
+
}
|
|
5407
5548
|
return {
|
|
5408
5549
|
...item,
|
|
5409
5550
|
est_liq_price
|
|
@@ -5554,7 +5695,9 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5554
5695
|
return {
|
|
5555
5696
|
...item,
|
|
5556
5697
|
holding: data.holding[item.token].holding,
|
|
5557
|
-
frozen: data.holding[item.token].frozen
|
|
5698
|
+
frozen: data.holding[item.token].frozen,
|
|
5699
|
+
isolatedMargin: data.holding[item.token].isolatedMargin,
|
|
5700
|
+
isolatedOrderFrozen: data.holding[item.token].isolatedOrderFrozen
|
|
5558
5701
|
};
|
|
5559
5702
|
}
|
|
5560
5703
|
return item;
|
|
@@ -5590,7 +5733,14 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5590
5733
|
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo) {
|
|
5591
5734
|
return null;
|
|
5592
5735
|
}
|
|
5593
|
-
const
|
|
5736
|
+
const totallCrossUnsettledPnL = positions3.rows.reduce(
|
|
5737
|
+
(sum, pos) => pos.margin_mode === MarginMode.ISOLATED ? sum : sum + (pos.unsettled_pnl ?? 0),
|
|
5738
|
+
0
|
|
5739
|
+
);
|
|
5740
|
+
const totalUnsettlementPnL = positions3.rows.reduce(
|
|
5741
|
+
(sum, pos) => sum + (pos.unsettled_pnl ?? 0),
|
|
5742
|
+
0
|
|
5743
|
+
);
|
|
5594
5744
|
const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
5595
5745
|
const [USDC_holding, nonUSDC] = parseHolding(
|
|
5596
5746
|
holding,
|
|
@@ -5601,28 +5751,51 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5601
5751
|
const totalCollateral = account.totalCollateral({
|
|
5602
5752
|
USDCHolding: USDC_holding,
|
|
5603
5753
|
nonUSDCHolding: nonUSDC,
|
|
5604
|
-
unsettlementPnL:
|
|
5754
|
+
unsettlementPnL: totallCrossUnsettledPnL,
|
|
5755
|
+
usdcBalancePendingShortQty: usdc?.pending_short ?? 0,
|
|
5756
|
+
usdcBalanceIsolatedOrderFrozen: usdc?.isolated_order_frozen ?? 0
|
|
5605
5757
|
});
|
|
5758
|
+
const sumIsolatedMargin = positions3.rows.reduce((acc, curr) => {
|
|
5759
|
+
if (curr.margin_mode !== MarginMode.ISOLATED) {
|
|
5760
|
+
return acc;
|
|
5761
|
+
}
|
|
5762
|
+
return acc.add(curr.margin ?? 0);
|
|
5763
|
+
}, zero);
|
|
5606
5764
|
const totalValue = account.totalValue({
|
|
5607
|
-
totalUnsettlementPnL
|
|
5765
|
+
totalUnsettlementPnL,
|
|
5608
5766
|
USDCHolding: USDC_holding,
|
|
5609
|
-
nonUSDCHolding: nonUSDC
|
|
5767
|
+
nonUSDCHolding: nonUSDC,
|
|
5768
|
+
totalIsolatedPositionMargin: sumIsolatedMargin.toNumber()
|
|
5610
5769
|
});
|
|
5611
5770
|
const totalUnrealizedROI = account.totalUnrealizedROI({
|
|
5612
5771
|
totalUnrealizedPnL: unrealizedPnL,
|
|
5613
5772
|
totalValue: totalValue.toNumber()
|
|
5614
5773
|
});
|
|
5774
|
+
const maxLeverageBySymbol = positions3.rows.reduce(
|
|
5775
|
+
(acc, position) => {
|
|
5776
|
+
if (position.margin_mode !== MarginMode.ISOLATED && position.leverage && !acc[position.symbol]) {
|
|
5777
|
+
acc[position.symbol] = position.leverage;
|
|
5778
|
+
}
|
|
5779
|
+
return acc;
|
|
5780
|
+
},
|
|
5781
|
+
{}
|
|
5782
|
+
);
|
|
5615
5783
|
const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
|
|
5616
5784
|
positions: positions3.rows,
|
|
5785
|
+
orders: [],
|
|
5617
5786
|
markPrices,
|
|
5618
5787
|
IMR_Factors: accountInfo.imr_factor,
|
|
5619
|
-
|
|
5788
|
+
maxLeverageBySymbol,
|
|
5620
5789
|
symbolInfo: createGetter({ ...symbolsInfo })
|
|
5621
5790
|
});
|
|
5622
5791
|
const freeCollateral = account.freeCollateral({
|
|
5623
5792
|
totalCollateral,
|
|
5624
5793
|
totalInitialMarginWithOrders
|
|
5625
5794
|
});
|
|
5795
|
+
const freeCollateralUSDCOnly = account.freeCollateralUSDCOnly({
|
|
5796
|
+
freeCollateral,
|
|
5797
|
+
nonUSDCHolding: nonUSDC
|
|
5798
|
+
});
|
|
5626
5799
|
const availableBalance = account.availableBalance({
|
|
5627
5800
|
USDCHolding: usdc?.holding ?? 0,
|
|
5628
5801
|
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
@@ -5633,8 +5806,10 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5633
5806
|
totalUnrealizedROI,
|
|
5634
5807
|
freeCollateral,
|
|
5635
5808
|
availableBalance,
|
|
5636
|
-
unsettledPnL,
|
|
5637
|
-
holding
|
|
5809
|
+
unsettledPnL: totalUnsettlementPnL,
|
|
5810
|
+
holding,
|
|
5811
|
+
usdcHolding: USDC_holding,
|
|
5812
|
+
freeCollateralUSDCOnly
|
|
5638
5813
|
};
|
|
5639
5814
|
}
|
|
5640
5815
|
update(data, scope) {
|
|
@@ -5643,10 +5818,12 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5643
5818
|
totalCollateral: data.totalCollateral,
|
|
5644
5819
|
totalValue: data.totalValue,
|
|
5645
5820
|
freeCollateral: data.freeCollateral,
|
|
5821
|
+
freeCollateralUSDCOnly: data.freeCollateralUSDCOnly,
|
|
5646
5822
|
availableBalance: data.availableBalance,
|
|
5647
5823
|
totalUnrealizedROI: data.totalUnrealizedROI,
|
|
5648
5824
|
unsettledPnL: data.unsettledPnL,
|
|
5649
|
-
holding: Array.isArray(data.holding) ? data.holding : []
|
|
5825
|
+
holding: Array.isArray(data.holding) ? data.holding : [],
|
|
5826
|
+
usdcHolding: typeof data.usdcHolding === "number" ? data.usdcHolding : data.usdcHolding.toNumber()
|
|
5650
5827
|
});
|
|
5651
5828
|
}
|
|
5652
5829
|
}
|
|
@@ -5777,7 +5954,7 @@ var usePositionStream = (symbol = "all", options) => {
|
|
|
5777
5954
|
}
|
|
5778
5955
|
if (Array.isArray(tpslOrders) && tpslOrders.length) {
|
|
5779
5956
|
rows = rows.map((item) => {
|
|
5780
|
-
const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol);
|
|
5957
|
+
const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol, item.margin_mode);
|
|
5781
5958
|
const full_tp_sl = fullPositionOrder ? findTPSLFromOrder(fullPositionOrder) : void 0;
|
|
5782
5959
|
const partialPossitionOrder = partialPositionOrders && partialPositionOrders.length ? partialPositionOrders[0] : void 0;
|
|
5783
5960
|
const partial_tp_sl = partialPossitionOrder ? findTPSLFromOrder(partialPossitionOrder) : void 0;
|
|
@@ -5909,15 +6086,21 @@ var useOrderStream = (params, options) => {
|
|
|
5909
6086
|
}
|
|
5910
6087
|
};
|
|
5911
6088
|
}, [normalOrderKeyFn, options?.keeplive]);
|
|
5912
|
-
const normalOrdersResponse = usePrivateInfiniteQuery(
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
6089
|
+
const normalOrdersResponse = usePrivateInfiniteQuery(
|
|
6090
|
+
normalOrderKeyFn,
|
|
6091
|
+
{
|
|
6092
|
+
initialSize: 1,
|
|
6093
|
+
formatter: (data) => data,
|
|
6094
|
+
revalidateOnFocus: false
|
|
6095
|
+
}
|
|
6096
|
+
);
|
|
6097
|
+
const algoOrdersResponse = usePrivateInfiniteQuery(
|
|
6098
|
+
algoOrderKeyFn,
|
|
6099
|
+
{
|
|
6100
|
+
formatter: (data) => data,
|
|
6101
|
+
revalidateOnFocus: false
|
|
6102
|
+
}
|
|
6103
|
+
);
|
|
5921
6104
|
const flattenOrders = useMemo(() => {
|
|
5922
6105
|
if (!normalOrdersResponse.data || !algoOrdersResponse.data && !sourceTypeAll) {
|
|
5923
6106
|
return null;
|
|
@@ -6035,7 +6218,9 @@ var useOrderStream = (params, options) => {
|
|
|
6035
6218
|
// trailing stop order fields
|
|
6036
6219
|
activated_price: order.activated_price,
|
|
6037
6220
|
callback_value: order.callback_value,
|
|
6038
|
-
callback_rate: order.callback_rate
|
|
6221
|
+
callback_rate: order.callback_rate,
|
|
6222
|
+
// Include margin_mode if present
|
|
6223
|
+
...order.margin_mode && { margin_mode: order.margin_mode }
|
|
6039
6224
|
});
|
|
6040
6225
|
default:
|
|
6041
6226
|
return doUpdateOrder({ ...order, order_id: orderId });
|
|
@@ -6230,7 +6415,14 @@ function formatPortfolio(inputs) {
|
|
|
6230
6415
|
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo || symbolsInfo?.isNil) {
|
|
6231
6416
|
return null;
|
|
6232
6417
|
}
|
|
6233
|
-
const
|
|
6418
|
+
const totallCrossUnsettledPnL = positions3.rows.reduce(
|
|
6419
|
+
(sum, pos) => pos.margin_mode === MarginMode.ISOLATED ? sum : sum + (pos.unsettled_pnl ?? 0),
|
|
6420
|
+
0
|
|
6421
|
+
);
|
|
6422
|
+
const totalUnsettlementPnL = positions3.rows.reduce(
|
|
6423
|
+
(sum, pos) => sum + (pos.unsettled_pnl ?? 0),
|
|
6424
|
+
0
|
|
6425
|
+
);
|
|
6234
6426
|
const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
6235
6427
|
const [USDC_holding, nonUSDC] = parseHolding(
|
|
6236
6428
|
holding,
|
|
@@ -6241,29 +6433,51 @@ function formatPortfolio(inputs) {
|
|
|
6241
6433
|
const totalCollateral = account.totalCollateral({
|
|
6242
6434
|
USDCHolding: USDC_holding,
|
|
6243
6435
|
nonUSDCHolding: nonUSDC,
|
|
6244
|
-
unsettlementPnL:
|
|
6436
|
+
unsettlementPnL: totallCrossUnsettledPnL,
|
|
6437
|
+
usdcBalancePendingShortQty: usdc?.pending_short ?? 0,
|
|
6438
|
+
usdcBalanceIsolatedOrderFrozen: usdc?.isolated_order_frozen ?? 0
|
|
6245
6439
|
});
|
|
6440
|
+
const sumIsolatedMargin = positions3.rows.reduce((acc, curr) => {
|
|
6441
|
+
if (curr.margin_mode !== MarginMode.ISOLATED) {
|
|
6442
|
+
return acc;
|
|
6443
|
+
}
|
|
6444
|
+
return acc.add(curr.margin ?? 0);
|
|
6445
|
+
}, zero);
|
|
6246
6446
|
const totalValue = account.totalValue({
|
|
6247
|
-
totalUnsettlementPnL
|
|
6447
|
+
totalUnsettlementPnL,
|
|
6248
6448
|
USDCHolding: USDC_holding,
|
|
6249
|
-
nonUSDCHolding: nonUSDC
|
|
6449
|
+
nonUSDCHolding: nonUSDC,
|
|
6450
|
+
totalIsolatedPositionMargin: sumIsolatedMargin.toNumber()
|
|
6250
6451
|
});
|
|
6251
6452
|
const totalUnrealizedROI = account.totalUnrealizedROI({
|
|
6252
6453
|
totalUnrealizedPnL: unrealizedPnL,
|
|
6253
6454
|
totalValue: totalValue.toNumber()
|
|
6254
6455
|
});
|
|
6456
|
+
const maxLeverageBySymbol = positions3.rows.reduce(
|
|
6457
|
+
(acc, position) => {
|
|
6458
|
+
if (position.margin_mode !== MarginMode.ISOLATED && position.leverage && !acc[position.symbol]) {
|
|
6459
|
+
acc[position.symbol] = position.leverage;
|
|
6460
|
+
}
|
|
6461
|
+
return acc;
|
|
6462
|
+
},
|
|
6463
|
+
{}
|
|
6464
|
+
);
|
|
6255
6465
|
const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
|
|
6256
6466
|
positions: positions3.rows,
|
|
6467
|
+
orders: [],
|
|
6257
6468
|
markPrices,
|
|
6258
6469
|
IMR_Factors: accountInfo.imr_factor,
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
symbolInfo: symbolsInfo
|
|
6470
|
+
maxLeverageBySymbol,
|
|
6471
|
+
symbolInfo: createGetter({ ...symbolsInfo })
|
|
6262
6472
|
});
|
|
6263
6473
|
const freeCollateral = account.freeCollateral({
|
|
6264
6474
|
totalCollateral,
|
|
6265
6475
|
totalInitialMarginWithOrders
|
|
6266
6476
|
});
|
|
6477
|
+
const freeCollateralUSDCOnly = account.freeCollateralUSDCOnly({
|
|
6478
|
+
freeCollateral,
|
|
6479
|
+
nonUSDCHolding: nonUSDC
|
|
6480
|
+
});
|
|
6267
6481
|
const availableBalance = account.availableBalance({
|
|
6268
6482
|
USDCHolding: usdc?.holding ?? 0,
|
|
6269
6483
|
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
@@ -6274,8 +6488,9 @@ function formatPortfolio(inputs) {
|
|
|
6274
6488
|
totalUnrealizedROI,
|
|
6275
6489
|
freeCollateral,
|
|
6276
6490
|
availableBalance,
|
|
6277
|
-
unsettledPnL,
|
|
6278
|
-
holding
|
|
6491
|
+
unsettledPnL: totalUnsettlementPnL,
|
|
6492
|
+
holding,
|
|
6493
|
+
freeCollateralUSDCOnly
|
|
6279
6494
|
};
|
|
6280
6495
|
}
|
|
6281
6496
|
function formatPositions(data, accountInfo, symbolsInfo, fundingRates) {
|
|
@@ -6795,7 +7010,9 @@ var useSubAccountAlgoOrderStream = (params, options) => {
|
|
|
6795
7010
|
// trailing stop order fields
|
|
6796
7011
|
activated_price: order.activated_price,
|
|
6797
7012
|
callback_value: order.callback_value,
|
|
6798
|
-
callback_rate: order.callback_rate
|
|
7013
|
+
callback_rate: order.callback_rate,
|
|
7014
|
+
// include margin_mode if present (align with useOrderStream)
|
|
7015
|
+
...order.margin_mode && { margin_mode: order.margin_mode }
|
|
6799
7016
|
});
|
|
6800
7017
|
default:
|
|
6801
7018
|
return doUpdateOrder({ ...order, order_id: orderId });
|
|
@@ -6982,120 +7199,122 @@ var useCollateral = (options = { dp: 6 }) => {
|
|
|
6982
7199
|
totalCollateral,
|
|
6983
7200
|
totalValue,
|
|
6984
7201
|
freeCollateral,
|
|
7202
|
+
freeCollateralUSDCOnly,
|
|
6985
7203
|
availableBalance,
|
|
6986
7204
|
unsettledPnL,
|
|
6987
|
-
holding
|
|
7205
|
+
holding,
|
|
7206
|
+
usdcHolding
|
|
6988
7207
|
} = useAppStore((state) => state.portfolio);
|
|
6989
7208
|
const accountInfo = useAppStore((state) => state.accountInfo);
|
|
6990
7209
|
return {
|
|
6991
7210
|
totalCollateral: totalCollateral.toDecimalPlaces(dp).toNumber(),
|
|
6992
7211
|
freeCollateral: freeCollateral.toDecimalPlaces(dp).toNumber(),
|
|
7212
|
+
freeCollateralUSDCOnly: freeCollateralUSDCOnly.toDecimalPlaces(dp).toNumber(),
|
|
6993
7213
|
totalValue: totalValue?.toDecimalPlaces(dp).toNumber() ?? null,
|
|
6994
7214
|
availableBalance,
|
|
6995
7215
|
unsettledPnL,
|
|
6996
7216
|
accountInfo,
|
|
6997
|
-
holding
|
|
7217
|
+
holding,
|
|
7218
|
+
usdcHolding
|
|
6998
7219
|
// @hidden
|
|
6999
7220
|
// positions: positionsPath(positions),
|
|
7000
7221
|
};
|
|
7001
7222
|
};
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
const {
|
|
7006
|
-
|
|
7007
|
-
{
|
|
7008
|
-
revalidateOnFocus: false
|
|
7009
|
-
}
|
|
7010
|
-
);
|
|
7011
|
-
useEffect(() => {
|
|
7012
|
-
if (!state.accountId || !symbol) return;
|
|
7013
|
-
const unsubscribe = ws.privateSubscribe("account", {
|
|
7014
|
-
onMessage: (data2) => {
|
|
7015
|
-
const res = data2?.accountDetail?.symbolLeverage || {};
|
|
7016
|
-
if (res.symbol === symbol) {
|
|
7017
|
-
const key = [`/v1/client/leverage?symbol=${symbol}`, state.accountId];
|
|
7018
|
-
mutate(
|
|
7019
|
-
key,
|
|
7020
|
-
(prevData) => {
|
|
7021
|
-
return {
|
|
7022
|
-
...prevData,
|
|
7023
|
-
leverage: res.leverage
|
|
7024
|
-
};
|
|
7025
|
-
},
|
|
7026
|
-
{
|
|
7027
|
-
revalidate: false
|
|
7028
|
-
}
|
|
7029
|
-
);
|
|
7030
|
-
}
|
|
7031
|
-
}
|
|
7032
|
-
});
|
|
7033
|
-
return () => unsubscribe?.();
|
|
7034
|
-
}, [symbol, state.accountId]);
|
|
7035
|
-
return data?.leverage;
|
|
7223
|
+
|
|
7224
|
+
// src/orderly/useLeverageBySymbol.ts
|
|
7225
|
+
var useLeverageBySymbol = (symbol, marginMode) => {
|
|
7226
|
+
const { getSymbolLeverage } = useSymbolLeverageMap();
|
|
7227
|
+
return getSymbolLeverage(symbol, marginMode);
|
|
7036
7228
|
};
|
|
7037
7229
|
|
|
7038
7230
|
// src/orderly/useMaxQty.ts
|
|
7039
|
-
|
|
7231
|
+
function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
|
|
7232
|
+
const reduceOnly = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.reduceOnly ?? false : reduceOnlyOrOptions ?? false;
|
|
7233
|
+
const finalMarginMode = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.marginMode ?? MarginMode.CROSS : marginMode ?? MarginMode.CROSS;
|
|
7040
7234
|
const positions3 = usePositions();
|
|
7041
7235
|
const accountInfo = useAccountInfo();
|
|
7042
7236
|
const symbolInfo = useSymbolsInfo();
|
|
7043
|
-
const { totalCollateral } = useCollateral();
|
|
7237
|
+
const { totalCollateral, freeCollateralUSDCOnly } = useCollateral();
|
|
7044
7238
|
const { data: markPrices } = useMarkPricesStream();
|
|
7045
|
-
const symbolLeverage = useLeverageBySymbol(symbol);
|
|
7239
|
+
const symbolLeverage = useLeverageBySymbol(symbol, finalMarginMode);
|
|
7046
7240
|
const maxQty = useMemo(() => {
|
|
7047
7241
|
if (!symbol) return 0;
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7242
|
+
if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3) {
|
|
7243
|
+
return 0;
|
|
7244
|
+
}
|
|
7245
|
+
const positionsArray = (positions3 === null ? [] : positions3).filter(
|
|
7246
|
+
(position) => position.margin_mode === finalMarginMode
|
|
7051
7247
|
);
|
|
7248
|
+
const positionQty = account.getQtyFromPositions(positionsArray, symbol);
|
|
7052
7249
|
if (reduceOnly) {
|
|
7053
|
-
if (positionQty
|
|
7054
|
-
|
|
7055
|
-
return 0;
|
|
7056
|
-
} else {
|
|
7057
|
-
return Math.abs(positionQty);
|
|
7058
|
-
}
|
|
7059
|
-
}
|
|
7060
|
-
if (positionQty < 0) {
|
|
7061
|
-
if (side === OrderSide.BUY) {
|
|
7062
|
-
return Math.abs(positionQty);
|
|
7063
|
-
} else {
|
|
7064
|
-
return 0;
|
|
7065
|
-
}
|
|
7066
|
-
}
|
|
7067
|
-
return 0;
|
|
7250
|
+
if (positionQty === 0) return 0;
|
|
7251
|
+
return side === OrderSide.BUY ? positionQty < 0 ? Math.abs(positionQty) : 0 : positionQty > 0 ? positionQty : 0;
|
|
7068
7252
|
}
|
|
7069
|
-
if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3)
|
|
7070
|
-
return 0;
|
|
7071
7253
|
const getSymbolInfo = symbolInfo[symbol];
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
)
|
|
7254
|
+
let currentSymbolPosition;
|
|
7255
|
+
const otherPositions = [];
|
|
7256
|
+
for (const position of positionsArray) {
|
|
7257
|
+
if (position.symbol === symbol) {
|
|
7258
|
+
currentSymbolPosition = position;
|
|
7259
|
+
} else {
|
|
7260
|
+
otherPositions.push(position);
|
|
7261
|
+
}
|
|
7262
|
+
}
|
|
7263
|
+
const markPrice = markPrices[symbol];
|
|
7264
|
+
const baseIMR = getSymbolInfo("base_imr") ?? 0;
|
|
7265
|
+
const IMR_Factor = accountInfo.imr_factor[symbol] ?? 0;
|
|
7266
|
+
const leverage = symbolLeverage || currentSymbolPosition?.leverage || 1;
|
|
7075
7267
|
const buyOrdersQty = currentSymbolPosition?.pending_long_qty ?? 0;
|
|
7076
7268
|
const sellOrdersQty = currentSymbolPosition?.pending_short_qty ?? 0;
|
|
7077
|
-
|
|
7269
|
+
if (finalMarginMode === MarginMode.ISOLATED) {
|
|
7270
|
+
const availableBalance = freeCollateralUSDCOnly;
|
|
7271
|
+
const pendingLongOrders = buyOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: buyOrdersQty }] : [];
|
|
7272
|
+
const pendingSellOrders = sellOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: sellOrdersQty }] : [];
|
|
7273
|
+
const markPriceDecimal = new Decimal(markPrice);
|
|
7274
|
+
const leverageDecimal = new Decimal(leverage);
|
|
7275
|
+
const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).div(leverageDecimal).toNumber() : 0;
|
|
7276
|
+
const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).div(leverageDecimal).toNumber() : 0;
|
|
7277
|
+
const symbolMaxNotional = accountInfo.max_notional?.[symbol] ?? positions.maxPositionNotional({
|
|
7278
|
+
leverage,
|
|
7279
|
+
IMRFactor: IMR_Factor
|
|
7280
|
+
});
|
|
7281
|
+
const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : markPrice;
|
|
7282
|
+
return account.maxQtyForIsolatedMargin({
|
|
7283
|
+
symbol,
|
|
7284
|
+
orderSide: side,
|
|
7285
|
+
currentOrderReferencePrice,
|
|
7286
|
+
availableBalance,
|
|
7287
|
+
leverage,
|
|
7288
|
+
baseIMR,
|
|
7289
|
+
IMR_Factor,
|
|
7290
|
+
markPrice,
|
|
7291
|
+
positionQty,
|
|
7292
|
+
pendingLongOrders,
|
|
7293
|
+
pendingSellOrders,
|
|
7294
|
+
isoOrderFrozenLong,
|
|
7295
|
+
isoOrderFrozenShort,
|
|
7296
|
+
symbolMaxNotional
|
|
7297
|
+
});
|
|
7298
|
+
}
|
|
7078
7299
|
const otherIMs = account.otherIMs({
|
|
7079
7300
|
positions: otherPositions,
|
|
7080
7301
|
symbolInfo,
|
|
7081
7302
|
markPrices,
|
|
7082
|
-
IMR_Factors: accountInfo.imr_factor
|
|
7083
|
-
// Not used
|
|
7084
|
-
maxLeverage: accountInfo.max_leverage
|
|
7303
|
+
IMR_Factors: accountInfo.imr_factor
|
|
7085
7304
|
});
|
|
7086
7305
|
return account.maxQty(side, {
|
|
7087
|
-
markPrice
|
|
7306
|
+
markPrice,
|
|
7088
7307
|
symbol,
|
|
7089
7308
|
baseMaxQty: getSymbolInfo("base_max"),
|
|
7090
7309
|
totalCollateral,
|
|
7091
|
-
maxLeverage:
|
|
7310
|
+
maxLeverage: leverage,
|
|
7092
7311
|
takerFeeRate: accountInfo.futures_taker_fee_rate,
|
|
7093
|
-
baseIMR
|
|
7312
|
+
baseIMR,
|
|
7094
7313
|
otherIMs,
|
|
7095
7314
|
positionQty,
|
|
7096
7315
|
buyOrdersQty,
|
|
7097
7316
|
sellOrdersQty,
|
|
7098
|
-
IMR_Factor
|
|
7317
|
+
IMR_Factor
|
|
7099
7318
|
});
|
|
7100
7319
|
}, [
|
|
7101
7320
|
symbol,
|
|
@@ -7105,10 +7324,12 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
|
|
|
7105
7324
|
accountInfo,
|
|
7106
7325
|
symbolInfo,
|
|
7107
7326
|
side,
|
|
7108
|
-
totalCollateral
|
|
7327
|
+
totalCollateral,
|
|
7328
|
+
finalMarginMode,
|
|
7329
|
+
symbolLeverage
|
|
7109
7330
|
]);
|
|
7110
7331
|
return Math.max(maxQty, 0);
|
|
7111
|
-
}
|
|
7332
|
+
}
|
|
7112
7333
|
var useMarginRatio = () => {
|
|
7113
7334
|
const positions3 = usePositionStore((state2) => state2.positions.all);
|
|
7114
7335
|
const { rows, notional } = positions3;
|
|
@@ -8414,29 +8635,67 @@ var usePrivateDataObserver = (options) => {
|
|
|
8414
8635
|
}, [state.accountId, subOrder]);
|
|
8415
8636
|
useEffect(() => {
|
|
8416
8637
|
if (!state.accountId) return;
|
|
8417
|
-
const
|
|
8638
|
+
const positionsKey = ["/v1/positions", state.accountId];
|
|
8639
|
+
const leveragesKey = ["/v1/client/leverages", state.accountId];
|
|
8418
8640
|
const unsubscribe = ws.privateSubscribe("account", {
|
|
8419
8641
|
onMessage: (data) => {
|
|
8420
|
-
const { symbol, leverage } = data?.accountDetail?.symbolLeverage || {};
|
|
8421
|
-
if (symbol
|
|
8422
|
-
|
|
8423
|
-
key,
|
|
8424
|
-
(prevPositions) => {
|
|
8425
|
-
if (prevPositions?.rows?.length) {
|
|
8426
|
-
return {
|
|
8427
|
-
...prevPositions,
|
|
8428
|
-
rows: prevPositions.rows.map((row) => {
|
|
8429
|
-
return row.symbol === symbol ? { ...row, leverage } : row;
|
|
8430
|
-
})
|
|
8431
|
-
};
|
|
8432
|
-
}
|
|
8433
|
-
return prevPositions;
|
|
8434
|
-
},
|
|
8435
|
-
{
|
|
8436
|
-
revalidate: false
|
|
8437
|
-
}
|
|
8438
|
-
);
|
|
8642
|
+
const { symbol, leverage, marginMode } = data?.accountDetail?.symbolLeverage || {};
|
|
8643
|
+
if (!symbol || leverage === void 0) {
|
|
8644
|
+
return;
|
|
8439
8645
|
}
|
|
8646
|
+
mutate(
|
|
8647
|
+
positionsKey,
|
|
8648
|
+
(prevPositions) => {
|
|
8649
|
+
if (prevPositions?.rows?.length) {
|
|
8650
|
+
return {
|
|
8651
|
+
...prevPositions,
|
|
8652
|
+
rows: prevPositions.rows.map((row) => {
|
|
8653
|
+
return row.symbol === symbol && row.margin_mode === marginMode ? { ...row, leverage } : row;
|
|
8654
|
+
})
|
|
8655
|
+
};
|
|
8656
|
+
}
|
|
8657
|
+
return prevPositions;
|
|
8658
|
+
},
|
|
8659
|
+
{
|
|
8660
|
+
revalidate: false
|
|
8661
|
+
}
|
|
8662
|
+
);
|
|
8663
|
+
mutate(
|
|
8664
|
+
leveragesKey,
|
|
8665
|
+
(prev) => {
|
|
8666
|
+
if (!prev) {
|
|
8667
|
+
return [
|
|
8668
|
+
{
|
|
8669
|
+
symbol,
|
|
8670
|
+
leverage,
|
|
8671
|
+
margin_mode: marginMode
|
|
8672
|
+
}
|
|
8673
|
+
];
|
|
8674
|
+
}
|
|
8675
|
+
const index = prev.findIndex(
|
|
8676
|
+
(item) => item.symbol === symbol && (item.margin_mode ?? MarginMode.CROSS) === (marginMode ?? MarginMode.CROSS)
|
|
8677
|
+
);
|
|
8678
|
+
if (index === -1) {
|
|
8679
|
+
return [
|
|
8680
|
+
...prev,
|
|
8681
|
+
{
|
|
8682
|
+
symbol,
|
|
8683
|
+
leverage,
|
|
8684
|
+
margin_mode: marginMode
|
|
8685
|
+
}
|
|
8686
|
+
];
|
|
8687
|
+
}
|
|
8688
|
+
const next = [...prev];
|
|
8689
|
+
next[index] = {
|
|
8690
|
+
...next[index],
|
|
8691
|
+
leverage
|
|
8692
|
+
};
|
|
8693
|
+
return next;
|
|
8694
|
+
},
|
|
8695
|
+
{
|
|
8696
|
+
revalidate: false
|
|
8697
|
+
}
|
|
8698
|
+
);
|
|
8440
8699
|
}
|
|
8441
8700
|
});
|
|
8442
8701
|
return () => unsubscribe?.();
|
|
@@ -8457,7 +8716,7 @@ var usePrivateDataObserver = (options) => {
|
|
|
8457
8716
|
...prevPositions,
|
|
8458
8717
|
rows: prevPositions.rows.map((row) => {
|
|
8459
8718
|
const itemIndex = nextPositions.findIndex(
|
|
8460
|
-
(item) => item.symbol === row.symbol
|
|
8719
|
+
(item) => item.symbol === row.symbol && item.marginMode === row.margin_mode
|
|
8461
8720
|
);
|
|
8462
8721
|
if (itemIndex >= 0) {
|
|
8463
8722
|
const itemArr = nextPositions.splice(itemIndex, 1);
|
|
@@ -8640,14 +8899,70 @@ var OrderValidation = class {
|
|
|
8640
8899
|
|
|
8641
8900
|
// src/services/orderCreator/baseCreator.ts
|
|
8642
8901
|
var BaseOrderCreator = class {
|
|
8643
|
-
|
|
8902
|
+
/**
|
|
8903
|
+
* Template method for order creation
|
|
8904
|
+
* Defines the algorithm structure with hooks for subclasses
|
|
8905
|
+
*/
|
|
8906
|
+
create(values, config) {
|
|
8907
|
+
this.beforeCreate(values, config);
|
|
8908
|
+
const order = this.buildOrder(values, config);
|
|
8909
|
+
return this.afterCreate(order, config);
|
|
8910
|
+
}
|
|
8911
|
+
/**
|
|
8912
|
+
* Template method for order validation
|
|
8913
|
+
* Defines the algorithm structure with hooks for subclasses
|
|
8914
|
+
*/
|
|
8915
|
+
validate(values, config) {
|
|
8916
|
+
this.beforeValidate(values, config);
|
|
8917
|
+
const errors = this.runValidations(values, config);
|
|
8918
|
+
return Promise.resolve(this.afterValidate(errors, values, config));
|
|
8919
|
+
}
|
|
8920
|
+
/**
|
|
8921
|
+
* Hook method called before order creation
|
|
8922
|
+
* Subclasses can override to perform pre-creation setup
|
|
8923
|
+
* @param values - Order values
|
|
8924
|
+
* @param config - Configuration
|
|
8925
|
+
*/
|
|
8926
|
+
beforeCreate(values, config) {
|
|
8927
|
+
}
|
|
8928
|
+
/**
|
|
8929
|
+
* Hook method called after order creation
|
|
8930
|
+
* Subclasses can override to perform post-creation processing
|
|
8931
|
+
* @param order - The created order
|
|
8932
|
+
* @param config - Configuration
|
|
8933
|
+
* @returns The final order (possibly modified)
|
|
8934
|
+
*/
|
|
8935
|
+
afterCreate(order, config) {
|
|
8936
|
+
return order;
|
|
8937
|
+
}
|
|
8938
|
+
/**
|
|
8939
|
+
* Hook method called before validation
|
|
8940
|
+
* Subclasses can override to perform pre-validation setup
|
|
8941
|
+
* @param values - Order values to validate
|
|
8942
|
+
* @param config - Configuration
|
|
8943
|
+
*/
|
|
8944
|
+
beforeValidate(values, config) {
|
|
8945
|
+
}
|
|
8946
|
+
/**
|
|
8947
|
+
* Hook method called after validation
|
|
8948
|
+
* Subclasses can override to perform post-validation processing
|
|
8949
|
+
* @param errors - Validation errors found
|
|
8950
|
+
* @param values - Original order values
|
|
8951
|
+
* @param config - Configuration
|
|
8952
|
+
* @returns Final validation result (possibly modified)
|
|
8953
|
+
*/
|
|
8954
|
+
afterValidate(errors, values, config) {
|
|
8955
|
+
return errors;
|
|
8956
|
+
}
|
|
8957
|
+
baseOrder(data) {
|
|
8644
8958
|
const order = {
|
|
8645
8959
|
symbol: data.symbol,
|
|
8646
8960
|
order_type: data.order_type === OrderType.LIMIT ? !!data.order_type_ext ? data.order_type_ext : data.order_type : data.order_type,
|
|
8647
8961
|
side: data.side,
|
|
8648
8962
|
reduce_only: data.reduce_only,
|
|
8649
8963
|
order_quantity: data.order_quantity,
|
|
8650
|
-
total: data.total
|
|
8964
|
+
total: data.total,
|
|
8965
|
+
margin_mode: data.margin_mode || MarginMode.CROSS
|
|
8651
8966
|
// slippage: data.slippage,
|
|
8652
8967
|
};
|
|
8653
8968
|
if (data.order_type === OrderType.MARKET && !!data.slippage) {
|
|
@@ -8666,10 +8981,21 @@ var BaseOrderCreator = class {
|
|
|
8666
8981
|
child_orders: [bracketOrder]
|
|
8667
8982
|
};
|
|
8668
8983
|
}
|
|
8984
|
+
/**
|
|
8985
|
+
* Base validation method that can be called by subclasses
|
|
8986
|
+
* Validates common order properties like quantity and min notional
|
|
8987
|
+
* @param values - Order values to validate
|
|
8988
|
+
* @param configs - Configuration
|
|
8989
|
+
* @returns Validation result (synchronous, not a Promise)
|
|
8990
|
+
*/
|
|
8669
8991
|
baseValidate(values, configs) {
|
|
8670
8992
|
const errors = {};
|
|
8671
8993
|
const { maxQty, symbol, markPrice } = configs;
|
|
8672
|
-
let
|
|
8994
|
+
let order_quantity = values.order_quantity;
|
|
8995
|
+
const total = values.total;
|
|
8996
|
+
const order_price = values.order_price;
|
|
8997
|
+
const reduce_only = values.reduce_only;
|
|
8998
|
+
const order_type = values.order_type;
|
|
8673
8999
|
const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
|
|
8674
9000
|
if (!order_quantity) {
|
|
8675
9001
|
if (total && order_price) {
|
|
@@ -8714,7 +9040,7 @@ var BaseOrderCreator = class {
|
|
|
8714
9040
|
};
|
|
8715
9041
|
}
|
|
8716
9042
|
this.validateBracketOrder(values, configs, errors);
|
|
8717
|
-
return
|
|
9043
|
+
return errors;
|
|
8718
9044
|
}
|
|
8719
9045
|
totalToQuantity(order, config) {
|
|
8720
9046
|
if (!order.order_quantity && order.total && order.order_price) {
|
|
@@ -8863,7 +9189,11 @@ var BBOOrderCreator = class extends BaseOrderCreator {
|
|
|
8863
9189
|
super(...arguments);
|
|
8864
9190
|
this.orderType = OrderType.LIMIT;
|
|
8865
9191
|
}
|
|
8866
|
-
|
|
9192
|
+
/**
|
|
9193
|
+
* Builds the BBO order
|
|
9194
|
+
* Implements template method hook
|
|
9195
|
+
*/
|
|
9196
|
+
buildOrder(values) {
|
|
8867
9197
|
const order = {
|
|
8868
9198
|
...this.baseOrder(values),
|
|
8869
9199
|
level: values.level
|
|
@@ -8876,15 +9206,18 @@ var BBOOrderCreator = class extends BaseOrderCreator {
|
|
|
8876
9206
|
"reduce_only",
|
|
8877
9207
|
"side",
|
|
8878
9208
|
"order_type",
|
|
9209
|
+
"margin_mode",
|
|
8879
9210
|
"level"
|
|
8880
9211
|
],
|
|
8881
9212
|
order
|
|
8882
9213
|
);
|
|
8883
9214
|
}
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
9215
|
+
/**
|
|
9216
|
+
* Runs base validations
|
|
9217
|
+
* Implements template method hook
|
|
9218
|
+
*/
|
|
9219
|
+
runValidations(values, configs) {
|
|
9220
|
+
return this.baseValidate(values, configs);
|
|
8888
9221
|
}
|
|
8889
9222
|
};
|
|
8890
9223
|
function getOrderPrice(order, askAndBid) {
|
|
@@ -8911,6 +9244,24 @@ function getOrderPrice(order, askAndBid) {
|
|
|
8911
9244
|
}
|
|
8912
9245
|
}
|
|
8913
9246
|
}
|
|
9247
|
+
order.getOrderReferencePrice;
|
|
9248
|
+
function getOrderReferencePriceFromOrder(order$1, askAndBid) {
|
|
9249
|
+
if (!askAndBid || askAndBid.length < 2) return null;
|
|
9250
|
+
if (!order$1.order_type || !order$1.side) {
|
|
9251
|
+
return null;
|
|
9252
|
+
}
|
|
9253
|
+
return order.getOrderReferencePrice(
|
|
9254
|
+
{
|
|
9255
|
+
orderType: order$1.order_type,
|
|
9256
|
+
orderTypeExt: order$1.order_type_ext,
|
|
9257
|
+
side: order$1.side,
|
|
9258
|
+
limitPrice: order$1.order_price ? Number(order$1.order_price) : void 0,
|
|
9259
|
+
triggerPrice: order$1.trigger_price ? Number(order$1.trigger_price) : void 0
|
|
9260
|
+
},
|
|
9261
|
+
askAndBid[0],
|
|
9262
|
+
askAndBid[1]
|
|
9263
|
+
);
|
|
9264
|
+
}
|
|
8914
9265
|
function getPriceRange(inputs) {
|
|
8915
9266
|
const { basePrice, side, symbolInfo } = inputs;
|
|
8916
9267
|
const { price_range, price_scope, quote_min, quote_max } = symbolInfo;
|
|
@@ -8924,97 +9275,170 @@ function getPriceRange(inputs) {
|
|
|
8924
9275
|
min: minPriceNumber,
|
|
8925
9276
|
max: scopePriceNumber
|
|
8926
9277
|
};
|
|
8927
|
-
const
|
|
8928
|
-
const
|
|
9278
|
+
const minPrice = Math.max(quote_min, priceRange?.min);
|
|
9279
|
+
const maxPrice = Math.min(quote_max, priceRange?.max);
|
|
8929
9280
|
return {
|
|
8930
|
-
minPrice
|
|
8931
|
-
maxPrice
|
|
9281
|
+
minPrice,
|
|
9282
|
+
maxPrice
|
|
8932
9283
|
};
|
|
8933
9284
|
}
|
|
8934
9285
|
|
|
8935
|
-
// src/services/orderCreator/
|
|
9286
|
+
// src/services/orderCreator/validators/TPSLValidationStrategy.ts
|
|
8936
9287
|
var formatPrice = (price, quote_dp) => {
|
|
8937
9288
|
return new Decimal(price).toDecimalPlaces(quote_dp).toNumber();
|
|
8938
9289
|
};
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
9290
|
+
var TPSLValidationStrategy = class {
|
|
9291
|
+
/**
|
|
9292
|
+
* Validates TP/SL order values
|
|
9293
|
+
* @param values - TP/SL order values including trigger prices, order prices, etc.
|
|
9294
|
+
* @param config - Configuration with symbol info and mark price
|
|
9295
|
+
* @returns Validation result object with any errors found
|
|
9296
|
+
*/
|
|
9297
|
+
validate(values, config) {
|
|
9298
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
9299
|
+
const {
|
|
9300
|
+
tp_trigger_price,
|
|
9301
|
+
tp_order_price,
|
|
9302
|
+
tp_order_type,
|
|
9303
|
+
sl_trigger_price,
|
|
9304
|
+
sl_order_price,
|
|
9305
|
+
sl_order_type,
|
|
9306
|
+
side,
|
|
9307
|
+
quantity,
|
|
9308
|
+
order_type,
|
|
9309
|
+
order_price
|
|
9310
|
+
} = values;
|
|
9311
|
+
const qty = Number(quantity);
|
|
9312
|
+
const maxQty = config.maxQty;
|
|
9313
|
+
const { quote_max, quote_min, quote_dp, base_min } = config.symbol ?? {};
|
|
9314
|
+
const mark_price = order_type === OrderType.MARKET || order_type == null ? config.markPrice : order_price ? Number(order_price) : void 0;
|
|
9315
|
+
const tpslSide = side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
|
|
9316
|
+
if (!isNaN(qty) && qty > maxQty) {
|
|
9317
|
+
result.quantity = OrderValidation.max("quantity", config.maxQty);
|
|
9318
|
+
}
|
|
9319
|
+
if (!isNaN(qty) && qty < (base_min ?? 0)) {
|
|
9320
|
+
result.quantity = OrderValidation.min("quantity", base_min ?? 0);
|
|
9321
|
+
}
|
|
9322
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null && Number(tp_trigger_price) < 0) {
|
|
9323
|
+
result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
|
|
9324
|
+
}
|
|
9325
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null && Number(sl_trigger_price) < 0) {
|
|
9326
|
+
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
9327
|
+
}
|
|
9328
|
+
if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
|
|
9329
|
+
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
9330
|
+
}
|
|
9331
|
+
if (sl_order_type === OrderType.LIMIT && !sl_order_price) {
|
|
9332
|
+
result.sl_order_price = OrderValidation.required("sl_order_price");
|
|
9333
|
+
}
|
|
9334
|
+
if (side === OrderSide.BUY && mark_price) {
|
|
9335
|
+
this.validateBuySide(
|
|
9336
|
+
{
|
|
9337
|
+
tp_trigger_price,
|
|
9338
|
+
tp_order_price,
|
|
9339
|
+
sl_trigger_price,
|
|
9340
|
+
sl_order_price
|
|
9341
|
+
},
|
|
9342
|
+
{
|
|
9343
|
+
mark_price,
|
|
9344
|
+
quote_min: quote_min ?? 0,
|
|
9345
|
+
quote_max: quote_max ?? 0,
|
|
9346
|
+
quote_dp: quote_dp ?? 0,
|
|
9347
|
+
tpslSide,
|
|
9348
|
+
symbol: config.symbol
|
|
9349
|
+
},
|
|
9350
|
+
result
|
|
8979
9351
|
);
|
|
8980
|
-
}
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
9352
|
+
} else if (side === OrderSide.SELL && mark_price) {
|
|
9353
|
+
this.validateSellSide(
|
|
9354
|
+
{
|
|
9355
|
+
tp_trigger_price,
|
|
9356
|
+
tp_order_price,
|
|
9357
|
+
sl_trigger_price,
|
|
9358
|
+
sl_order_price
|
|
9359
|
+
},
|
|
9360
|
+
{
|
|
9361
|
+
mark_price,
|
|
9362
|
+
quote_min: quote_min ?? 0,
|
|
9363
|
+
quote_max: quote_max ?? 0,
|
|
9364
|
+
quote_dp: quote_dp ?? 0,
|
|
9365
|
+
tpslSide,
|
|
9366
|
+
symbol: config.symbol
|
|
9367
|
+
},
|
|
9368
|
+
result
|
|
8985
9369
|
);
|
|
8986
9370
|
}
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
9371
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
9372
|
+
}
|
|
9373
|
+
/**
|
|
9374
|
+
* Validates TP/SL for BUY orders
|
|
9375
|
+
* For BUY orders:
|
|
9376
|
+
* - SL trigger price must be < mark price
|
|
9377
|
+
* - TP trigger price must be > mark price
|
|
9378
|
+
*/
|
|
9379
|
+
validateBuySide(prices, config, result) {
|
|
9380
|
+
const {
|
|
9381
|
+
tp_trigger_price,
|
|
9382
|
+
tp_order_price,
|
|
9383
|
+
sl_trigger_price,
|
|
9384
|
+
sl_order_price
|
|
9385
|
+
} = prices;
|
|
9386
|
+
const { mark_price, quote_min, quote_max, quote_dp, tpslSide, symbol } = config;
|
|
9387
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null) {
|
|
9388
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9389
|
+
if (!isNaN(slTrigger)) {
|
|
9390
|
+
if (quote_min > 0 && slTrigger < quote_min) {
|
|
9391
|
+
result.sl_trigger_price = OrderValidation.min(
|
|
9392
|
+
"sl_trigger_price",
|
|
9393
|
+
formatPrice(quote_min, quote_dp)
|
|
9394
|
+
);
|
|
9395
|
+
}
|
|
9396
|
+
if (slTrigger >= mark_price) {
|
|
9397
|
+
result.sl_trigger_price = OrderValidation.max(
|
|
9398
|
+
"sl_trigger_price",
|
|
9399
|
+
formatPrice(mark_price, quote_dp)
|
|
9400
|
+
);
|
|
9401
|
+
}
|
|
9402
|
+
}
|
|
8992
9403
|
}
|
|
8993
|
-
if (
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
9404
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null) {
|
|
9405
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9406
|
+
if (!isNaN(tpTrigger)) {
|
|
9407
|
+
if (tpTrigger <= mark_price) {
|
|
9408
|
+
result.tp_trigger_price = OrderValidation.min(
|
|
9409
|
+
"tp_trigger_price",
|
|
9410
|
+
formatPrice(mark_price, quote_dp)
|
|
9411
|
+
);
|
|
9412
|
+
}
|
|
9413
|
+
if (quote_max > 0 && tpTrigger > quote_max) {
|
|
9414
|
+
result.tp_trigger_price = OrderValidation.max(
|
|
9415
|
+
"tp_trigger_price",
|
|
9416
|
+
formatPrice(quote_max, quote_dp)
|
|
9417
|
+
);
|
|
9418
|
+
}
|
|
9419
|
+
}
|
|
8998
9420
|
}
|
|
8999
9421
|
if (sl_trigger_price && sl_order_price) {
|
|
9000
9422
|
const priceRange = getPriceRange({
|
|
9001
9423
|
side: tpslSide,
|
|
9002
9424
|
basePrice: Number(sl_trigger_price),
|
|
9003
|
-
symbolInfo:
|
|
9425
|
+
symbolInfo: symbol
|
|
9004
9426
|
});
|
|
9005
|
-
|
|
9427
|
+
const slOrderPrice = Number(sl_order_price);
|
|
9428
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9429
|
+
if (slOrderPrice < priceRange.minPrice) {
|
|
9006
9430
|
result.sl_order_price = OrderValidation.min(
|
|
9007
9431
|
"sl_order_price",
|
|
9008
9432
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9009
9433
|
);
|
|
9010
9434
|
}
|
|
9011
|
-
if (
|
|
9435
|
+
if (slOrderPrice > priceRange.maxPrice) {
|
|
9012
9436
|
result.sl_order_price = OrderValidation.max(
|
|
9013
9437
|
"sl_order_price",
|
|
9014
9438
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9015
9439
|
);
|
|
9016
9440
|
}
|
|
9017
|
-
if (
|
|
9441
|
+
if (slTrigger < slOrderPrice) {
|
|
9018
9442
|
result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
|
|
9019
9443
|
}
|
|
9020
9444
|
}
|
|
@@ -9022,69 +9446,96 @@ async function bracketOrderValidator(values, config) {
|
|
|
9022
9446
|
const priceRange = getPriceRange({
|
|
9023
9447
|
side: tpslSide,
|
|
9024
9448
|
basePrice: Number(tp_trigger_price),
|
|
9025
|
-
symbolInfo:
|
|
9449
|
+
symbolInfo: symbol
|
|
9026
9450
|
});
|
|
9027
|
-
|
|
9451
|
+
const tpOrderPrice = Number(tp_order_price);
|
|
9452
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9453
|
+
if (tpOrderPrice > priceRange.maxPrice) {
|
|
9028
9454
|
result.tp_order_price = OrderValidation.max(
|
|
9029
9455
|
"tp_order_price",
|
|
9030
9456
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9031
9457
|
);
|
|
9032
9458
|
}
|
|
9033
|
-
if (
|
|
9459
|
+
if (tpOrderPrice < priceRange.minPrice) {
|
|
9034
9460
|
result.tp_order_price = OrderValidation.min(
|
|
9035
9461
|
"tp_order_price",
|
|
9036
9462
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9037
9463
|
);
|
|
9038
9464
|
}
|
|
9039
|
-
if (
|
|
9465
|
+
if (tpTrigger > tpOrderPrice) {
|
|
9040
9466
|
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9041
9467
|
}
|
|
9042
9468
|
}
|
|
9043
9469
|
}
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
}
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9470
|
+
/**
|
|
9471
|
+
* Validates TP/SL for SELL orders
|
|
9472
|
+
* For SELL orders:
|
|
9473
|
+
* - SL trigger price must be > mark price
|
|
9474
|
+
* - TP trigger price must be < mark price
|
|
9475
|
+
*/
|
|
9476
|
+
validateSellSide(prices, config, result) {
|
|
9477
|
+
const {
|
|
9478
|
+
tp_trigger_price,
|
|
9479
|
+
tp_order_price,
|
|
9480
|
+
sl_trigger_price,
|
|
9481
|
+
sl_order_price
|
|
9482
|
+
} = prices;
|
|
9483
|
+
const { mark_price, quote_min, quote_max, quote_dp, tpslSide, symbol } = config;
|
|
9484
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null) {
|
|
9485
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9486
|
+
if (!isNaN(slTrigger)) {
|
|
9487
|
+
if (quote_max > 0 && slTrigger > quote_max) {
|
|
9488
|
+
result.sl_trigger_price = OrderValidation.max(
|
|
9489
|
+
"sl_trigger_price",
|
|
9490
|
+
formatPrice(quote_max, quote_dp)
|
|
9491
|
+
);
|
|
9492
|
+
}
|
|
9493
|
+
if (slTrigger <= mark_price) {
|
|
9494
|
+
result.sl_trigger_price = OrderValidation.min(
|
|
9495
|
+
"sl_trigger_price",
|
|
9496
|
+
formatPrice(mark_price, quote_dp)
|
|
9497
|
+
);
|
|
9498
|
+
}
|
|
9499
|
+
}
|
|
9062
9500
|
}
|
|
9063
|
-
if (
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9501
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null) {
|
|
9502
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9503
|
+
if (!isNaN(tpTrigger)) {
|
|
9504
|
+
if (tpTrigger >= mark_price) {
|
|
9505
|
+
result.tp_trigger_price = OrderValidation.max(
|
|
9506
|
+
"tp_trigger_price",
|
|
9507
|
+
formatPrice(mark_price, quote_dp)
|
|
9508
|
+
);
|
|
9509
|
+
}
|
|
9510
|
+
if (quote_min > 0 && tpTrigger < quote_min) {
|
|
9511
|
+
result.tp_trigger_price = OrderValidation.min(
|
|
9512
|
+
"tp_trigger_price",
|
|
9513
|
+
formatPrice(quote_min, quote_dp)
|
|
9514
|
+
);
|
|
9515
|
+
}
|
|
9516
|
+
}
|
|
9068
9517
|
}
|
|
9069
9518
|
if (sl_trigger_price && sl_order_price) {
|
|
9070
9519
|
const priceRange = getPriceRange({
|
|
9071
9520
|
side: tpslSide,
|
|
9072
9521
|
basePrice: Number(sl_trigger_price),
|
|
9073
|
-
symbolInfo:
|
|
9522
|
+
symbolInfo: symbol
|
|
9074
9523
|
});
|
|
9075
|
-
|
|
9524
|
+
const slOrderPrice = Number(sl_order_price);
|
|
9525
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9526
|
+
if (slOrderPrice < priceRange.minPrice) {
|
|
9076
9527
|
result.sl_order_price = OrderValidation.min(
|
|
9077
9528
|
"sl_order_price",
|
|
9078
9529
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9079
9530
|
);
|
|
9080
9531
|
}
|
|
9081
|
-
if (
|
|
9532
|
+
if (slOrderPrice > priceRange.maxPrice) {
|
|
9082
9533
|
result.sl_order_price = OrderValidation.max(
|
|
9083
9534
|
"sl_order_price",
|
|
9084
9535
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9085
9536
|
);
|
|
9086
9537
|
}
|
|
9087
|
-
if (
|
|
9538
|
+
if (slTrigger > slOrderPrice) {
|
|
9088
9539
|
result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
|
|
9089
9540
|
}
|
|
9090
9541
|
}
|
|
@@ -9092,37 +9543,294 @@ async function bracketOrderValidator(values, config) {
|
|
|
9092
9543
|
const priceRange = getPriceRange({
|
|
9093
9544
|
side: tpslSide,
|
|
9094
9545
|
basePrice: Number(tp_trigger_price),
|
|
9095
|
-
symbolInfo:
|
|
9546
|
+
symbolInfo: symbol
|
|
9096
9547
|
});
|
|
9097
|
-
|
|
9548
|
+
const tpOrderPrice = Number(tp_order_price);
|
|
9549
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9550
|
+
if (tpOrderPrice < priceRange.minPrice) {
|
|
9098
9551
|
result.tp_order_price = OrderValidation.min(
|
|
9099
9552
|
"tp_order_price",
|
|
9100
9553
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9101
9554
|
);
|
|
9102
9555
|
}
|
|
9103
|
-
if (
|
|
9556
|
+
if (tpOrderPrice > priceRange.maxPrice) {
|
|
9104
9557
|
result.tp_order_price = OrderValidation.max(
|
|
9105
9558
|
"tp_order_price",
|
|
9106
9559
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9107
9560
|
);
|
|
9108
9561
|
}
|
|
9109
|
-
if (
|
|
9562
|
+
if (tpTrigger < tpOrderPrice) {
|
|
9110
9563
|
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9111
9564
|
}
|
|
9112
9565
|
}
|
|
9113
9566
|
}
|
|
9114
|
-
|
|
9567
|
+
};
|
|
9568
|
+
|
|
9569
|
+
// src/services/orderCreator/baseBracketOrderCreator.ts
|
|
9570
|
+
async function bracketOrderValidator(values, config) {
|
|
9571
|
+
const strategy = new TPSLValidationStrategy();
|
|
9572
|
+
return strategy.validate(values, config);
|
|
9115
9573
|
}
|
|
9116
|
-
|
|
9574
|
+
|
|
9575
|
+
// src/services/orderCreator/validators/BaseValidator.ts
|
|
9576
|
+
var BaseValidator = class {
|
|
9577
|
+
/**
|
|
9578
|
+
* Sets the next validator in the chain
|
|
9579
|
+
* @param validator - The next validator to call
|
|
9580
|
+
* @returns The next validator for method chaining
|
|
9581
|
+
*/
|
|
9582
|
+
setNext(validator) {
|
|
9583
|
+
this.next = validator;
|
|
9584
|
+
return validator;
|
|
9585
|
+
}
|
|
9586
|
+
/**
|
|
9587
|
+
* Validates values and passes to next validator in chain
|
|
9588
|
+
* @param values - The values to validate
|
|
9589
|
+
* @param config - Configuration for validation
|
|
9590
|
+
* @param errors - Accumulated validation errors
|
|
9591
|
+
* @returns Updated validation result
|
|
9592
|
+
*/
|
|
9593
|
+
validate(values, config, errors) {
|
|
9594
|
+
const result = this.doValidate(values, config);
|
|
9595
|
+
if (result) {
|
|
9596
|
+
errors[this.getFieldName()] = result;
|
|
9597
|
+
}
|
|
9598
|
+
return this.next?.validate(values, config, errors) ?? errors;
|
|
9599
|
+
}
|
|
9600
|
+
};
|
|
9601
|
+
var PriceValidationStrategy = class {
|
|
9602
|
+
/**
|
|
9603
|
+
* Validates order price against symbol constraints and price range
|
|
9604
|
+
* @param values - Object containing order_price, side, and order_type
|
|
9605
|
+
* @param config - Configuration with symbol info and mark price
|
|
9606
|
+
* @returns Validation error if price is invalid, undefined otherwise
|
|
9607
|
+
*/
|
|
9608
|
+
validate(values, config) {
|
|
9609
|
+
const { order_price, side } = values;
|
|
9610
|
+
if (!order_price) {
|
|
9611
|
+
return OrderValidation.required("order_price");
|
|
9612
|
+
}
|
|
9613
|
+
const price = new Decimal(order_price);
|
|
9614
|
+
const { symbol } = config;
|
|
9615
|
+
const { quote_max, quote_min, quote_dp, price_range, price_scope } = symbol;
|
|
9616
|
+
const maxPriceNumber = order.maxPrice(config.markPrice, price_range);
|
|
9617
|
+
const minPriceNumber = order.minPrice(config.markPrice, price_range);
|
|
9618
|
+
const scopePriceNumber = order.scopePrice(
|
|
9619
|
+
config.markPrice,
|
|
9620
|
+
price_scope,
|
|
9621
|
+
side
|
|
9622
|
+
);
|
|
9623
|
+
const priceRange = side === OrderSide.BUY ? {
|
|
9624
|
+
min: scopePriceNumber,
|
|
9625
|
+
max: maxPriceNumber
|
|
9626
|
+
} : {
|
|
9627
|
+
min: minPriceNumber,
|
|
9628
|
+
max: scopePriceNumber
|
|
9629
|
+
};
|
|
9630
|
+
if (price.gt(quote_max)) {
|
|
9631
|
+
return OrderValidation.max("order_price", quote_max);
|
|
9632
|
+
}
|
|
9633
|
+
if (price.lt(quote_min)) {
|
|
9634
|
+
return OrderValidation.min("order_price", quote_min);
|
|
9635
|
+
}
|
|
9636
|
+
if (price.gt(priceRange.max)) {
|
|
9637
|
+
return OrderValidation.max(
|
|
9638
|
+
"order_price",
|
|
9639
|
+
new Decimal(priceRange.max).todp(quote_dp).toString()
|
|
9640
|
+
);
|
|
9641
|
+
}
|
|
9642
|
+
if (price.lt(priceRange.min)) {
|
|
9643
|
+
return OrderValidation.min(
|
|
9644
|
+
"order_price",
|
|
9645
|
+
new Decimal(priceRange.min).todp(quote_dp).toString()
|
|
9646
|
+
);
|
|
9647
|
+
}
|
|
9648
|
+
return void 0;
|
|
9649
|
+
}
|
|
9650
|
+
};
|
|
9651
|
+
var TriggerPriceValidationStrategy = class {
|
|
9652
|
+
/**
|
|
9653
|
+
* Validates trigger price against symbol constraints
|
|
9654
|
+
* @param values - Object containing trigger_price
|
|
9655
|
+
* @param config - Configuration with symbol info
|
|
9656
|
+
* @returns Validation error if trigger price is invalid, undefined otherwise
|
|
9657
|
+
*/
|
|
9658
|
+
validate(values, config) {
|
|
9659
|
+
const { trigger_price } = values;
|
|
9660
|
+
const { symbol } = config;
|
|
9661
|
+
const { quote_max, quote_min } = symbol;
|
|
9662
|
+
if (!trigger_price) {
|
|
9663
|
+
return OrderValidation.required("trigger_price");
|
|
9664
|
+
}
|
|
9665
|
+
const triggerPrice = Number(trigger_price);
|
|
9666
|
+
if (triggerPrice > quote_max) {
|
|
9667
|
+
return OrderValidation.max("trigger_price", quote_max);
|
|
9668
|
+
}
|
|
9669
|
+
if (triggerPrice < quote_min || triggerPrice === 0) {
|
|
9670
|
+
return OrderValidation.min("trigger_price", quote_min);
|
|
9671
|
+
}
|
|
9672
|
+
return void 0;
|
|
9673
|
+
}
|
|
9674
|
+
};
|
|
9675
|
+
|
|
9676
|
+
// src/services/orderCreator/validators/PriceValidator.ts
|
|
9677
|
+
var PriceValidator = class extends BaseValidator {
|
|
9678
|
+
constructor() {
|
|
9679
|
+
super();
|
|
9680
|
+
this.strategy = new PriceValidationStrategy();
|
|
9681
|
+
}
|
|
9682
|
+
doValidate(values, config) {
|
|
9683
|
+
return this.strategy.validate(
|
|
9684
|
+
{
|
|
9685
|
+
order_price: values.order_price,
|
|
9686
|
+
side: values.side,
|
|
9687
|
+
order_type: values.order_type
|
|
9688
|
+
},
|
|
9689
|
+
config
|
|
9690
|
+
);
|
|
9691
|
+
}
|
|
9692
|
+
getFieldName() {
|
|
9693
|
+
return "order_price";
|
|
9694
|
+
}
|
|
9695
|
+
};
|
|
9696
|
+
var QuantityValidationStrategy = class {
|
|
9697
|
+
/**
|
|
9698
|
+
* Validates order quantity against symbol constraints
|
|
9699
|
+
* Also handles conversion from total to quantity if needed
|
|
9700
|
+
* @param values - Object containing order_quantity, total, and order_price
|
|
9701
|
+
* @param config - Configuration with symbol info and max quantity
|
|
9702
|
+
* @returns Validation error if quantity is invalid, undefined otherwise
|
|
9703
|
+
*/
|
|
9704
|
+
validate(values, config) {
|
|
9705
|
+
let { order_quantity, total, order_price } = values;
|
|
9706
|
+
const { maxQty, symbol } = config;
|
|
9707
|
+
const { base_min, base_dp, quote_dp } = symbol;
|
|
9708
|
+
if (!order_quantity && total && order_price) {
|
|
9709
|
+
const totalNumber = new Decimal(total);
|
|
9710
|
+
const qty2 = totalNumber.dividedBy(order_price).toFixed(quote_dp);
|
|
9711
|
+
order_quantity = qty2;
|
|
9712
|
+
}
|
|
9713
|
+
if (!order_quantity) {
|
|
9714
|
+
return OrderValidation.required("order_quantity");
|
|
9715
|
+
}
|
|
9716
|
+
const qty = new Decimal(order_quantity);
|
|
9717
|
+
if (qty.lt(base_min)) {
|
|
9718
|
+
return OrderValidation.min(
|
|
9719
|
+
"order_quantity",
|
|
9720
|
+
new Decimal(base_min).todp(base_dp).toString()
|
|
9721
|
+
);
|
|
9722
|
+
}
|
|
9723
|
+
if (qty.gt(maxQty)) {
|
|
9724
|
+
return OrderValidation.max(
|
|
9725
|
+
"order_quantity",
|
|
9726
|
+
new Decimal(maxQty).todp(base_dp).toString()
|
|
9727
|
+
);
|
|
9728
|
+
}
|
|
9729
|
+
return void 0;
|
|
9730
|
+
}
|
|
9731
|
+
};
|
|
9732
|
+
|
|
9733
|
+
// src/services/orderCreator/validators/QuantityValidator.ts
|
|
9734
|
+
var QuantityValidator = class extends BaseValidator {
|
|
9735
|
+
constructor() {
|
|
9736
|
+
super();
|
|
9737
|
+
this.strategy = new QuantityValidationStrategy();
|
|
9738
|
+
}
|
|
9739
|
+
doValidate(values, config) {
|
|
9740
|
+
return this.strategy.validate(
|
|
9741
|
+
{
|
|
9742
|
+
order_quantity: values.order_quantity,
|
|
9743
|
+
total: values.total,
|
|
9744
|
+
order_price: values.order_price
|
|
9745
|
+
},
|
|
9746
|
+
config
|
|
9747
|
+
);
|
|
9748
|
+
}
|
|
9749
|
+
getFieldName() {
|
|
9750
|
+
return "order_quantity";
|
|
9751
|
+
}
|
|
9752
|
+
};
|
|
9753
|
+
|
|
9754
|
+
// src/services/orderCreator/validators/ValidationChain.ts
|
|
9755
|
+
var ValidationChain = class {
|
|
9756
|
+
constructor() {
|
|
9757
|
+
this.validators = [];
|
|
9758
|
+
}
|
|
9759
|
+
/**
|
|
9760
|
+
* Adds a validator to the chain
|
|
9761
|
+
* @param validator - The validator to add
|
|
9762
|
+
* @returns This chain instance for method chaining
|
|
9763
|
+
*/
|
|
9764
|
+
addValidator(validator) {
|
|
9765
|
+
this.validators.push(validator);
|
|
9766
|
+
if (!this.head) {
|
|
9767
|
+
this.head = validator;
|
|
9768
|
+
} else {
|
|
9769
|
+
let current = this.head;
|
|
9770
|
+
while (current && current.next) {
|
|
9771
|
+
current = current.next;
|
|
9772
|
+
}
|
|
9773
|
+
if (current) {
|
|
9774
|
+
current.setNext(validator);
|
|
9775
|
+
}
|
|
9776
|
+
}
|
|
9777
|
+
return this;
|
|
9778
|
+
}
|
|
9779
|
+
/**
|
|
9780
|
+
* Adds multiple validators to the chain
|
|
9781
|
+
* @param validators - Array of validators to add
|
|
9782
|
+
* @returns This chain instance for method chaining
|
|
9783
|
+
*/
|
|
9784
|
+
addValidators(validators) {
|
|
9785
|
+
validators.forEach((validator) => this.addValidator(validator));
|
|
9786
|
+
return this;
|
|
9787
|
+
}
|
|
9788
|
+
/**
|
|
9789
|
+
* Validates values using all validators in the chain
|
|
9790
|
+
* @param values - The values to validate
|
|
9791
|
+
* @param config - Configuration for validation
|
|
9792
|
+
* @returns Validation result with all errors found
|
|
9793
|
+
*/
|
|
9794
|
+
validate(values, config) {
|
|
9795
|
+
const errors = {};
|
|
9796
|
+
if (this.head) {
|
|
9797
|
+
return this.head.validate(values, config, errors);
|
|
9798
|
+
}
|
|
9799
|
+
return errors;
|
|
9800
|
+
}
|
|
9801
|
+
/**
|
|
9802
|
+
* Clears all validators from the chain
|
|
9803
|
+
*/
|
|
9804
|
+
clear() {
|
|
9805
|
+
this.validators = [];
|
|
9806
|
+
this.head = void 0;
|
|
9807
|
+
}
|
|
9808
|
+
/**
|
|
9809
|
+
* Gets the number of validators in the chain
|
|
9810
|
+
* @returns The number of validators
|
|
9811
|
+
*/
|
|
9812
|
+
get length() {
|
|
9813
|
+
return this.validators.length;
|
|
9814
|
+
}
|
|
9815
|
+
};
|
|
9816
|
+
|
|
9817
|
+
// src/services/orderCreator/limitOrderCreator.ts
|
|
9117
9818
|
var LimitOrderCreator = class extends BaseOrderCreator {
|
|
9118
9819
|
constructor() {
|
|
9119
9820
|
super(...arguments);
|
|
9821
|
+
// private priceValidationStrategy = new PriceValidationStrategy();
|
|
9822
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new PriceValidator());
|
|
9120
9823
|
this.orderType = OrderType.LIMIT;
|
|
9121
9824
|
}
|
|
9122
|
-
|
|
9825
|
+
/**
|
|
9826
|
+
* Builds the limit order
|
|
9827
|
+
* Implements template method hook
|
|
9828
|
+
*/
|
|
9829
|
+
buildOrder(values, config) {
|
|
9830
|
+
const orderlyValues = values;
|
|
9123
9831
|
const order = {
|
|
9124
|
-
...this.baseOrder(
|
|
9125
|
-
order_price:
|
|
9832
|
+
...this.baseOrder(orderlyValues),
|
|
9833
|
+
order_price: orderlyValues.order_price
|
|
9126
9834
|
};
|
|
9127
9835
|
this.totalToQuantity(order, config);
|
|
9128
9836
|
return pick(
|
|
@@ -9134,58 +9842,23 @@ var LimitOrderCreator = class extends BaseOrderCreator {
|
|
|
9134
9842
|
"reduce_only",
|
|
9135
9843
|
"side",
|
|
9136
9844
|
"order_type",
|
|
9845
|
+
"margin_mode",
|
|
9137
9846
|
"algo_type",
|
|
9138
9847
|
"child_orders"
|
|
9139
9848
|
],
|
|
9140
9849
|
order
|
|
9141
9850
|
);
|
|
9142
9851
|
}
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
const minPriceNumber = minPrice(config.markPrice, price_range);
|
|
9154
|
-
const scopePriceNumber = scopePrice(
|
|
9155
|
-
config.markPrice,
|
|
9156
|
-
price_scope,
|
|
9157
|
-
side
|
|
9158
|
-
);
|
|
9159
|
-
const priceRange = side === "BUY" ? {
|
|
9160
|
-
min: scopePriceNumber,
|
|
9161
|
-
max: maxPriceNumber
|
|
9162
|
-
} : {
|
|
9163
|
-
min: minPriceNumber,
|
|
9164
|
-
max: scopePriceNumber
|
|
9165
|
-
};
|
|
9166
|
-
if (price.gt(quote_max)) {
|
|
9167
|
-
errors.order_price = OrderValidation.max("order_price", quote_max);
|
|
9168
|
-
} else {
|
|
9169
|
-
if (price.gt(priceRange?.max)) {
|
|
9170
|
-
errors.order_price = OrderValidation.max(
|
|
9171
|
-
"order_price",
|
|
9172
|
-
new Decimal(priceRange.max).todp(symbol.quote_dp).toString()
|
|
9173
|
-
);
|
|
9174
|
-
}
|
|
9175
|
-
}
|
|
9176
|
-
if (price.lt(quote_min)) {
|
|
9177
|
-
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
9178
|
-
} else {
|
|
9179
|
-
if (price.lt(priceRange?.min)) {
|
|
9180
|
-
errors.order_price = OrderValidation.min(
|
|
9181
|
-
"order_price",
|
|
9182
|
-
new Decimal(priceRange.min).todp(symbol.quote_dp).toString()
|
|
9183
|
-
);
|
|
9184
|
-
}
|
|
9185
|
-
}
|
|
9186
|
-
}
|
|
9187
|
-
return errors;
|
|
9188
|
-
});
|
|
9852
|
+
/**
|
|
9853
|
+
* Runs validations using validation chain
|
|
9854
|
+
* Implements template method hook
|
|
9855
|
+
*/
|
|
9856
|
+
runValidations(values, config) {
|
|
9857
|
+
const orderlyValues = values;
|
|
9858
|
+
const errors = this.baseValidate(orderlyValues, config);
|
|
9859
|
+
const chainErrors = this.validationChain.validate(orderlyValues, config);
|
|
9860
|
+
Object.assign(errors, chainErrors);
|
|
9861
|
+
return errors;
|
|
9189
9862
|
}
|
|
9190
9863
|
};
|
|
9191
9864
|
|
|
@@ -9208,34 +9881,81 @@ var BracketLimitOrderCreator = class extends LimitOrderCreator {
|
|
|
9208
9881
|
}
|
|
9209
9882
|
};
|
|
9210
9883
|
|
|
9884
|
+
// src/services/orderCreator/validators/SlippageValidationStrategy.ts
|
|
9885
|
+
var SlippageValidationStrategy = class {
|
|
9886
|
+
/**
|
|
9887
|
+
* Validates slippage against estimated slippage
|
|
9888
|
+
* @param values - Object containing slippage value
|
|
9889
|
+
* @param config - Configuration with estimated slippage
|
|
9890
|
+
* @returns Validation error if slippage exceeds estimated, undefined otherwise
|
|
9891
|
+
*/
|
|
9892
|
+
validate(values, config) {
|
|
9893
|
+
const slippage = Number(values.slippage);
|
|
9894
|
+
const estSlippage = Number.isNaN(config.estSlippage) ? 0 : Number(config.estSlippage) * 100;
|
|
9895
|
+
if (!isNaN(slippage) && estSlippage > slippage) {
|
|
9896
|
+
return {
|
|
9897
|
+
type: "max",
|
|
9898
|
+
message: "Estimated slippage exceeds your maximum allowed slippage.",
|
|
9899
|
+
value: estSlippage
|
|
9900
|
+
};
|
|
9901
|
+
}
|
|
9902
|
+
return void 0;
|
|
9903
|
+
}
|
|
9904
|
+
};
|
|
9905
|
+
|
|
9906
|
+
// src/services/orderCreator/validators/SlippageValidator.ts
|
|
9907
|
+
var SlippageValidator = class extends BaseValidator {
|
|
9908
|
+
constructor() {
|
|
9909
|
+
super();
|
|
9910
|
+
this.strategy = new SlippageValidationStrategy();
|
|
9911
|
+
}
|
|
9912
|
+
doValidate(values, config) {
|
|
9913
|
+
return this.strategy.validate(
|
|
9914
|
+
{
|
|
9915
|
+
slippage: values.slippage
|
|
9916
|
+
},
|
|
9917
|
+
config
|
|
9918
|
+
);
|
|
9919
|
+
}
|
|
9920
|
+
getFieldName() {
|
|
9921
|
+
return "slippage";
|
|
9922
|
+
}
|
|
9923
|
+
};
|
|
9924
|
+
|
|
9211
9925
|
// src/services/orderCreator/marketOrderCreator.ts
|
|
9212
9926
|
var MarketOrderCreator = class extends BaseOrderCreator {
|
|
9213
|
-
|
|
9214
|
-
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
delete data["isStopOrder"];
|
|
9219
|
-
return {
|
|
9220
|
-
...data
|
|
9221
|
-
};
|
|
9927
|
+
constructor() {
|
|
9928
|
+
super(...arguments);
|
|
9929
|
+
this.slippageValidationStrategy = new SlippageValidationStrategy();
|
|
9930
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new SlippageValidator());
|
|
9931
|
+
this.orderType = OrderType.MARKET;
|
|
9222
9932
|
}
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9933
|
+
/**
|
|
9934
|
+
* Builds the market order
|
|
9935
|
+
* Implements template method hook
|
|
9936
|
+
*/
|
|
9937
|
+
buildOrder(values, config) {
|
|
9938
|
+
const orderlyValues = values;
|
|
9939
|
+
const data = this.baseOrder(orderlyValues);
|
|
9940
|
+
const result = { ...data };
|
|
9941
|
+
delete result.order_price;
|
|
9942
|
+
delete result.total;
|
|
9943
|
+
delete result.trigger_price;
|
|
9944
|
+
if ("isStopOrder" in result) {
|
|
9945
|
+
delete result.isStopOrder;
|
|
9946
|
+
}
|
|
9947
|
+
return result;
|
|
9948
|
+
}
|
|
9949
|
+
/**
|
|
9950
|
+
* Runs validations using validation chain
|
|
9951
|
+
* Implements template method hook
|
|
9952
|
+
*/
|
|
9953
|
+
runValidations(values, configs) {
|
|
9954
|
+
const orderlyValues = values;
|
|
9955
|
+
const result = this.baseValidate(orderlyValues, configs);
|
|
9956
|
+
const chainErrors = this.validationChain.validate(orderlyValues, configs);
|
|
9957
|
+
Object.assign(result, chainErrors);
|
|
9958
|
+
return result;
|
|
9239
9959
|
}
|
|
9240
9960
|
};
|
|
9241
9961
|
|
|
@@ -9267,14 +9987,26 @@ var FOKOrderCreator = class extends LimitOrderCreator {
|
|
|
9267
9987
|
|
|
9268
9988
|
// src/services/orderCreator/generalCreator.ts
|
|
9269
9989
|
var GeneralOrderCreator = class extends BaseOrderCreator {
|
|
9270
|
-
|
|
9990
|
+
constructor() {
|
|
9991
|
+
super(...arguments);
|
|
9992
|
+
this.orderType = void 0;
|
|
9993
|
+
}
|
|
9994
|
+
/**
|
|
9995
|
+
* Builds the general order
|
|
9996
|
+
* Implements template method hook
|
|
9997
|
+
*/
|
|
9998
|
+
buildOrder(data) {
|
|
9271
9999
|
return {
|
|
9272
10000
|
...this.baseOrder(data),
|
|
9273
10001
|
order_price: data.order_price,
|
|
9274
10002
|
order_quantity: data.order_quantity
|
|
9275
10003
|
};
|
|
9276
10004
|
}
|
|
9277
|
-
|
|
10005
|
+
/**
|
|
10006
|
+
* Runs base validations
|
|
10007
|
+
* Implements template method hook
|
|
10008
|
+
*/
|
|
10009
|
+
runValidations(values, configs) {
|
|
9278
10010
|
return super.baseValidate(values, configs);
|
|
9279
10011
|
}
|
|
9280
10012
|
};
|
|
@@ -9383,7 +10115,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
|
|
|
9383
10115
|
distribution_type,
|
|
9384
10116
|
skew,
|
|
9385
10117
|
reduce_only,
|
|
9386
|
-
visible_quantity
|
|
10118
|
+
visible_quantity,
|
|
10119
|
+
margin_mode
|
|
9387
10120
|
} = order;
|
|
9388
10121
|
const prices = calcScaledOrderPrices({
|
|
9389
10122
|
start_price,
|
|
@@ -9409,6 +10142,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
|
|
|
9409
10142
|
order_quantity: qtys[index],
|
|
9410
10143
|
order_price: price,
|
|
9411
10144
|
reduce_only,
|
|
10145
|
+
margin_mode: margin_mode || MarginMode.CROSS,
|
|
10146
|
+
// Default to CROSS if not provided for backward compatibility
|
|
9412
10147
|
// it will be used for identify the scaled order from ws
|
|
9413
10148
|
client_order_id: `scaled_${index}_${now}`
|
|
9414
10149
|
};
|
|
@@ -9512,7 +10247,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9512
10247
|
super(...arguments);
|
|
9513
10248
|
this.orderType = OrderType.SCALED;
|
|
9514
10249
|
}
|
|
9515
|
-
|
|
10250
|
+
/**
|
|
10251
|
+
* Builds the scaled order
|
|
10252
|
+
* Implements template method hook
|
|
10253
|
+
*/
|
|
10254
|
+
buildOrder(values, config) {
|
|
9516
10255
|
const orders = calcScaledOrderBatchBody(values, config.symbol);
|
|
9517
10256
|
const { total_orders, distribution_type, skew } = values;
|
|
9518
10257
|
const order = {
|
|
@@ -9530,6 +10269,7 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9530
10269
|
"reduce_only",
|
|
9531
10270
|
"side",
|
|
9532
10271
|
"order_type",
|
|
10272
|
+
"margin_mode",
|
|
9533
10273
|
"orders",
|
|
9534
10274
|
"total_orders",
|
|
9535
10275
|
"distribution_type",
|
|
@@ -9538,7 +10278,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9538
10278
|
order
|
|
9539
10279
|
);
|
|
9540
10280
|
}
|
|
9541
|
-
|
|
10281
|
+
/**
|
|
10282
|
+
* Runs validations for scaled order
|
|
10283
|
+
* Implements template method hook
|
|
10284
|
+
*/
|
|
10285
|
+
runValidations(values, config) {
|
|
9542
10286
|
const { maxQty, askAndBid, markPrice, symbol } = config;
|
|
9543
10287
|
const { base_dp, quote_dp } = config.symbol;
|
|
9544
10288
|
const { order_quantity, total, total_orders, distribution_type, skew } = values;
|
|
@@ -9607,22 +10351,22 @@ function validatePrice(values, config) {
|
|
|
9607
10351
|
if (!config.markPrice) {
|
|
9608
10352
|
return errors;
|
|
9609
10353
|
}
|
|
9610
|
-
const { minPrice
|
|
10354
|
+
const { minPrice, maxPrice } = getPriceRange({
|
|
9611
10355
|
side: values.side,
|
|
9612
10356
|
basePrice: config.markPrice,
|
|
9613
10357
|
symbolInfo: config.symbol
|
|
9614
10358
|
});
|
|
9615
10359
|
const comparePrice = (key, value) => {
|
|
9616
10360
|
const price = new Decimal(value || 0);
|
|
9617
|
-
if (price.lt(
|
|
10361
|
+
if (price.lt(minPrice)) {
|
|
9618
10362
|
errors[key] = OrderValidation.min(
|
|
9619
10363
|
key,
|
|
9620
|
-
new Decimal(
|
|
10364
|
+
new Decimal(minPrice).todp(quote_dp).toString()
|
|
9621
10365
|
);
|
|
9622
|
-
} else if (price.gt(
|
|
10366
|
+
} else if (price.gt(maxPrice)) {
|
|
9623
10367
|
errors[key] = OrderValidation.max(
|
|
9624
10368
|
key,
|
|
9625
|
-
new Decimal(
|
|
10369
|
+
new Decimal(maxPrice).todp(quote_dp).toString()
|
|
9626
10370
|
);
|
|
9627
10371
|
}
|
|
9628
10372
|
};
|
|
@@ -9630,13 +10374,40 @@ function validatePrice(values, config) {
|
|
|
9630
10374
|
comparePrice("end_price", end_price);
|
|
9631
10375
|
return errors;
|
|
9632
10376
|
}
|
|
9633
|
-
|
|
10377
|
+
|
|
10378
|
+
// src/services/orderCreator/validators/TriggerPriceValidator.ts
|
|
10379
|
+
var TriggerPriceValidator = class extends BaseValidator {
|
|
10380
|
+
constructor() {
|
|
10381
|
+
super();
|
|
10382
|
+
this.strategy = new TriggerPriceValidationStrategy();
|
|
10383
|
+
}
|
|
10384
|
+
doValidate(values, config) {
|
|
10385
|
+
return this.strategy.validate(
|
|
10386
|
+
{
|
|
10387
|
+
trigger_price: values.trigger_price
|
|
10388
|
+
},
|
|
10389
|
+
config
|
|
10390
|
+
);
|
|
10391
|
+
}
|
|
10392
|
+
getFieldName() {
|
|
10393
|
+
return "trigger_price";
|
|
10394
|
+
}
|
|
10395
|
+
};
|
|
10396
|
+
|
|
10397
|
+
// src/services/orderCreator/stopLimitOrderCreator.ts
|
|
9634
10398
|
var StopLimitOrderCreator = class extends BaseOrderCreator {
|
|
9635
10399
|
constructor() {
|
|
9636
10400
|
super(...arguments);
|
|
10401
|
+
this.priceValidationStrategy = new PriceValidationStrategy();
|
|
10402
|
+
this.triggerPriceValidationStrategy = new TriggerPriceValidationStrategy();
|
|
10403
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new TriggerPriceValidator()).addValidator(new PriceValidator());
|
|
9637
10404
|
this.orderType = OrderType.STOP_LIMIT;
|
|
9638
10405
|
}
|
|
9639
|
-
|
|
10406
|
+
/**
|
|
10407
|
+
* Builds the stop-limit order
|
|
10408
|
+
* Implements template method hook
|
|
10409
|
+
*/
|
|
10410
|
+
buildOrder(values, config) {
|
|
9640
10411
|
this.totalToQuantity(values, config);
|
|
9641
10412
|
const order = {
|
|
9642
10413
|
...this.baseOrder(values),
|
|
@@ -9658,84 +10429,82 @@ var StopLimitOrderCreator = class extends BaseOrderCreator {
|
|
|
9658
10429
|
"trigger_price_type",
|
|
9659
10430
|
"side",
|
|
9660
10431
|
"reduce_only",
|
|
10432
|
+
"margin_mode",
|
|
9661
10433
|
"visible_quantity"
|
|
9662
10434
|
],
|
|
9663
10435
|
order
|
|
9664
10436
|
);
|
|
9665
10437
|
}
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
if (price.gt(priceRange?.max)) {
|
|
9707
|
-
errors.order_price = OrderValidation.max(
|
|
9708
|
-
"order_price",
|
|
9709
|
-
new Decimal(priceRange.max).todp(symbol.quote_dp).toString()
|
|
9710
|
-
);
|
|
9711
|
-
}
|
|
9712
|
-
}
|
|
9713
|
-
if (price.lt(quote_min)) {
|
|
9714
|
-
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
9715
|
-
} else {
|
|
9716
|
-
if (price.lt(priceRange?.min)) {
|
|
9717
|
-
errors.order_price = OrderValidation.min(
|
|
9718
|
-
"order_price",
|
|
9719
|
-
new Decimal(priceRange.min).todp(symbol.quote_dp).toString()
|
|
9720
|
-
);
|
|
9721
|
-
}
|
|
9722
|
-
}
|
|
9723
|
-
}
|
|
10438
|
+
/**
|
|
10439
|
+
* Runs validations using validation chain
|
|
10440
|
+
* Implements template method hook
|
|
10441
|
+
*/
|
|
10442
|
+
runValidations(values, config) {
|
|
10443
|
+
const orderlyValues = values;
|
|
10444
|
+
const errors = this.baseValidate(orderlyValues, config);
|
|
10445
|
+
const triggerPrice = values.trigger_price;
|
|
10446
|
+
if (!triggerPrice || triggerPrice === 0) {
|
|
10447
|
+
errors.trigger_price = OrderValidation.required("trigger_price");
|
|
10448
|
+
} else {
|
|
10449
|
+
const triggerError = this.triggerPriceValidationStrategy.validate(
|
|
10450
|
+
{ trigger_price: triggerPrice },
|
|
10451
|
+
config
|
|
10452
|
+
);
|
|
10453
|
+
if (triggerError) {
|
|
10454
|
+
errors.trigger_price = triggerError;
|
|
10455
|
+
}
|
|
10456
|
+
}
|
|
10457
|
+
const valuesWithFields = values;
|
|
10458
|
+
const orderPrice = valuesWithFields.order_price ?? valuesWithFields.price;
|
|
10459
|
+
const triggerPriceForPriceValidation = triggerPrice;
|
|
10460
|
+
const side = valuesWithFields.side ?? orderlyValues.side;
|
|
10461
|
+
if (!orderPrice) {
|
|
10462
|
+
errors.order_price = OrderValidation.required("order_price");
|
|
10463
|
+
} else if (orderPrice && triggerPriceForPriceValidation && side) {
|
|
10464
|
+
const modifiedConfig = {
|
|
10465
|
+
...config,
|
|
10466
|
+
markPrice: Number(triggerPriceForPriceValidation)
|
|
10467
|
+
};
|
|
10468
|
+
const priceError = this.priceValidationStrategy.validate(
|
|
10469
|
+
{
|
|
10470
|
+
order_price: orderPrice,
|
|
10471
|
+
side,
|
|
10472
|
+
order_type: OrderType.LIMIT
|
|
10473
|
+
},
|
|
10474
|
+
modifiedConfig
|
|
10475
|
+
);
|
|
10476
|
+
if (priceError) {
|
|
10477
|
+
errors.order_price = priceError;
|
|
9724
10478
|
}
|
|
9725
|
-
|
|
9726
|
-
|
|
10479
|
+
} else if (orderPrice && triggerPriceForPriceValidation) {
|
|
10480
|
+
const { quote_max, quote_min } = config.symbol;
|
|
10481
|
+
const price = Number(orderPrice);
|
|
10482
|
+
if (quote_max && price > quote_max) {
|
|
10483
|
+
errors.order_price = OrderValidation.max("order_price", quote_max);
|
|
10484
|
+
} else if (quote_min && price < quote_min) {
|
|
10485
|
+
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
10486
|
+
}
|
|
10487
|
+
}
|
|
10488
|
+
return errors;
|
|
9727
10489
|
}
|
|
9728
10490
|
};
|
|
9729
10491
|
var StopMarketOrderCreator = class extends BaseOrderCreator {
|
|
9730
|
-
|
|
10492
|
+
constructor() {
|
|
10493
|
+
super(...arguments);
|
|
10494
|
+
this.triggerPriceValidationStrategy = new TriggerPriceValidationStrategy();
|
|
10495
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new TriggerPriceValidator());
|
|
10496
|
+
}
|
|
10497
|
+
/**
|
|
10498
|
+
* Builds the stop-market order
|
|
10499
|
+
* Implements template method hook
|
|
10500
|
+
*/
|
|
10501
|
+
buildOrder(values) {
|
|
9731
10502
|
const order = {
|
|
9732
10503
|
...this.baseOrder(values),
|
|
9733
|
-
// order_price: values.order_price,
|
|
9734
10504
|
trigger_price: values.trigger_price,
|
|
9735
10505
|
algo_type: AlgoOrderRootType.STOP,
|
|
9736
10506
|
type: OrderType.MARKET,
|
|
9737
10507
|
quantity: values["order_quantity"],
|
|
9738
|
-
// price: values["order_price"],
|
|
9739
10508
|
trigger_price_type: TriggerPriceType.MARK_PRICE
|
|
9740
10509
|
};
|
|
9741
10510
|
return pick(
|
|
@@ -9745,225 +10514,40 @@ var StopMarketOrderCreator = class extends BaseOrderCreator {
|
|
|
9745
10514
|
"algo_type",
|
|
9746
10515
|
"type",
|
|
9747
10516
|
"quantity",
|
|
9748
|
-
// "price",
|
|
9749
10517
|
"trigger_price_type",
|
|
9750
10518
|
"side",
|
|
9751
10519
|
"reduce_only",
|
|
10520
|
+
"margin_mode",
|
|
9752
10521
|
"visible_quantity"
|
|
9753
10522
|
],
|
|
9754
10523
|
order
|
|
9755
10524
|
);
|
|
9756
10525
|
}
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
} else if (trigger_price < quote_min || trigger_price == 0) {
|
|
9767
|
-
errors.trigger_price = OrderValidation.min("trigger_price", quote_min);
|
|
9768
|
-
}
|
|
9769
|
-
return errors;
|
|
9770
|
-
});
|
|
10526
|
+
/**
|
|
10527
|
+
* Runs validations using validation chain
|
|
10528
|
+
* Implements template method hook
|
|
10529
|
+
*/
|
|
10530
|
+
runValidations(values, config) {
|
|
10531
|
+
const errors = this.baseValidate(values, config);
|
|
10532
|
+
const chainErrors = this.validationChain.validate(values, config);
|
|
10533
|
+
Object.assign(errors, chainErrors);
|
|
10534
|
+
return errors;
|
|
9771
10535
|
}
|
|
9772
10536
|
};
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
};
|
|
10537
|
+
|
|
10538
|
+
// src/services/orderCreator/baseAlgoCreator.ts
|
|
9776
10539
|
var BaseAlgoOrderCreator = class {
|
|
10540
|
+
constructor() {
|
|
10541
|
+
this.tpslValidationStrategy = new TPSLValidationStrategy();
|
|
10542
|
+
}
|
|
9777
10543
|
/**
|
|
9778
|
-
*
|
|
10544
|
+
* Validates TP/SL order using TPSLValidationStrategy
|
|
10545
|
+
* Consolidates validation logic from baseBracketOrderCreator
|
|
9779
10546
|
*/
|
|
9780
10547
|
validate(values, config) {
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
tp_trigger_price,
|
|
9785
|
-
sl_trigger_price,
|
|
9786
|
-
side,
|
|
9787
|
-
// tp_enable,
|
|
9788
|
-
// sl_enable,
|
|
9789
|
-
tp_order_type,
|
|
9790
|
-
sl_order_type,
|
|
9791
|
-
tp_order_price,
|
|
9792
|
-
sl_order_price
|
|
9793
|
-
} = values;
|
|
9794
|
-
const qty = Number(values.quantity);
|
|
9795
|
-
const maxQty = config.maxQty;
|
|
9796
|
-
const orderType = values.order_type;
|
|
9797
|
-
const {
|
|
9798
|
-
quote_max,
|
|
9799
|
-
quote_min,
|
|
9800
|
-
price_scope,
|
|
9801
|
-
quote_dp,
|
|
9802
|
-
base_min,
|
|
9803
|
-
min_notional
|
|
9804
|
-
} = config.symbol ?? {};
|
|
9805
|
-
if (!isNaN(qty) && qty > maxQty) {
|
|
9806
|
-
result.quantity = OrderValidation.max("quantity", config.maxQty);
|
|
9807
|
-
}
|
|
9808
|
-
if (!isNaN(qty) && qty < base_min) {
|
|
9809
|
-
result.quantity = OrderValidation.min("quantity", base_min);
|
|
9810
|
-
}
|
|
9811
|
-
if (Number(tp_trigger_price) < 0) {
|
|
9812
|
-
result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
|
|
9813
|
-
}
|
|
9814
|
-
if (Number(sl_trigger_price) < 0) {
|
|
9815
|
-
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
9816
|
-
}
|
|
9817
|
-
if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
|
|
9818
|
-
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
9819
|
-
}
|
|
9820
|
-
if (sl_order_type === OrderType.LIMIT && !sl_order_price) {
|
|
9821
|
-
result.sl_order_price = OrderValidation.required("sl_order_price");
|
|
9822
|
-
}
|
|
9823
|
-
const mark_price = orderType === OrderType.MARKET || orderType == null ? config.markPrice : values.order_price ? Number(values.order_price) : void 0;
|
|
9824
|
-
const tpslSide = side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
|
|
9825
|
-
if (side === OrderSide.BUY && mark_price) {
|
|
9826
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
|
|
9827
|
-
result.sl_trigger_price = OrderValidation.min(
|
|
9828
|
-
"sl_trigger_price",
|
|
9829
|
-
formatPrice2(quote_min, quote_dp)
|
|
9830
|
-
);
|
|
9831
|
-
}
|
|
9832
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) >= mark_price) {
|
|
9833
|
-
result.sl_trigger_price = OrderValidation.max(
|
|
9834
|
-
"sl_trigger_price",
|
|
9835
|
-
formatPrice2(mark_price, quote_dp)
|
|
9836
|
-
);
|
|
9837
|
-
}
|
|
9838
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
|
|
9839
|
-
result.tp_trigger_price = OrderValidation.min(
|
|
9840
|
-
"tp_trigger_price",
|
|
9841
|
-
formatPrice2(mark_price, quote_dp)
|
|
9842
|
-
);
|
|
9843
|
-
}
|
|
9844
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
|
|
9845
|
-
result.tp_trigger_price = OrderValidation.max(
|
|
9846
|
-
"tp_trigger_price",
|
|
9847
|
-
formatPrice2(quote_max, quote_dp)
|
|
9848
|
-
);
|
|
9849
|
-
}
|
|
9850
|
-
if (sl_trigger_price && sl_order_price) {
|
|
9851
|
-
const slOrderPriceRange = getPriceRange({
|
|
9852
|
-
side: tpslSide,
|
|
9853
|
-
basePrice: Number(sl_trigger_price),
|
|
9854
|
-
symbolInfo: config.symbol
|
|
9855
|
-
});
|
|
9856
|
-
if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
|
|
9857
|
-
result.sl_order_price = OrderValidation.min(
|
|
9858
|
-
"sl_order_price",
|
|
9859
|
-
formatPrice2(slOrderPriceRange.minPrice, quote_dp)
|
|
9860
|
-
);
|
|
9861
|
-
}
|
|
9862
|
-
if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
|
|
9863
|
-
result.sl_order_price = OrderValidation.max(
|
|
9864
|
-
"sl_order_price",
|
|
9865
|
-
formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
|
|
9866
|
-
);
|
|
9867
|
-
}
|
|
9868
|
-
if (Number(sl_trigger_price) < Number(sl_order_price)) {
|
|
9869
|
-
result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
|
|
9870
|
-
}
|
|
9871
|
-
}
|
|
9872
|
-
if (tp_trigger_price && tp_order_price) {
|
|
9873
|
-
const tpOrderPriceRange = getPriceRange({
|
|
9874
|
-
side: tpslSide,
|
|
9875
|
-
basePrice: Number(tp_trigger_price),
|
|
9876
|
-
symbolInfo: config.symbol
|
|
9877
|
-
});
|
|
9878
|
-
if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
|
|
9879
|
-
result.tp_order_price = OrderValidation.max(
|
|
9880
|
-
"tp_order_price",
|
|
9881
|
-
formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
|
|
9882
|
-
);
|
|
9883
|
-
}
|
|
9884
|
-
if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
|
|
9885
|
-
result.tp_order_price = OrderValidation.min(
|
|
9886
|
-
"tp_order_price",
|
|
9887
|
-
formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
|
|
9888
|
-
);
|
|
9889
|
-
}
|
|
9890
|
-
if (Number(tp_trigger_price) > Number(tp_order_price)) {
|
|
9891
|
-
result.tp_trigger_price = OrderValidation.priceErrorMin("tp_trigger_price");
|
|
9892
|
-
}
|
|
9893
|
-
}
|
|
9894
|
-
}
|
|
9895
|
-
if (side === OrderSide.SELL && mark_price) {
|
|
9896
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) > quote_max) {
|
|
9897
|
-
result.sl_trigger_price = OrderValidation.max(
|
|
9898
|
-
"sl_trigger_price",
|
|
9899
|
-
formatPrice2(quote_max, quote_dp)
|
|
9900
|
-
);
|
|
9901
|
-
}
|
|
9902
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) <= mark_price) {
|
|
9903
|
-
result.sl_trigger_price = OrderValidation.min(
|
|
9904
|
-
"sl_trigger_price",
|
|
9905
|
-
formatPrice2(mark_price, quote_dp)
|
|
9906
|
-
);
|
|
9907
|
-
}
|
|
9908
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
|
|
9909
|
-
result.tp_trigger_price = OrderValidation.max(
|
|
9910
|
-
"tp_trigger_price",
|
|
9911
|
-
formatPrice2(mark_price, quote_dp)
|
|
9912
|
-
);
|
|
9913
|
-
}
|
|
9914
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) < quote_min) {
|
|
9915
|
-
result.tp_trigger_price = OrderValidation.min(
|
|
9916
|
-
"tp_trigger_price",
|
|
9917
|
-
formatPrice2(quote_min, quote_dp)
|
|
9918
|
-
);
|
|
9919
|
-
}
|
|
9920
|
-
if (sl_trigger_price && sl_order_price) {
|
|
9921
|
-
const slOrderPriceRange = getPriceRange({
|
|
9922
|
-
side: tpslSide,
|
|
9923
|
-
basePrice: Number(sl_trigger_price),
|
|
9924
|
-
symbolInfo: config.symbol
|
|
9925
|
-
});
|
|
9926
|
-
if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
|
|
9927
|
-
result.sl_order_price = OrderValidation.min(
|
|
9928
|
-
"sl_order_price",
|
|
9929
|
-
formatPrice2(slOrderPriceRange.minPrice, quote_dp)
|
|
9930
|
-
);
|
|
9931
|
-
}
|
|
9932
|
-
if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
|
|
9933
|
-
result.sl_order_price = OrderValidation.max(
|
|
9934
|
-
"sl_order_price",
|
|
9935
|
-
formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
|
|
9936
|
-
);
|
|
9937
|
-
}
|
|
9938
|
-
if (Number(sl_trigger_price) > Number(sl_order_price)) {
|
|
9939
|
-
result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
|
|
9940
|
-
}
|
|
9941
|
-
}
|
|
9942
|
-
if (tp_trigger_price && tp_order_price) {
|
|
9943
|
-
const tpOrderPriceRange = getPriceRange({
|
|
9944
|
-
side: tpslSide,
|
|
9945
|
-
basePrice: Number(tp_trigger_price),
|
|
9946
|
-
symbolInfo: config.symbol
|
|
9947
|
-
});
|
|
9948
|
-
if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
|
|
9949
|
-
result.tp_order_price = OrderValidation.min(
|
|
9950
|
-
"tp_order_price",
|
|
9951
|
-
formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
|
|
9952
|
-
);
|
|
9953
|
-
}
|
|
9954
|
-
if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
|
|
9955
|
-
result.tp_order_price = OrderValidation.max(
|
|
9956
|
-
"tp_order_price",
|
|
9957
|
-
formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
|
|
9958
|
-
);
|
|
9959
|
-
}
|
|
9960
|
-
if (Number(tp_trigger_price) < Number(tp_order_price)) {
|
|
9961
|
-
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9962
|
-
}
|
|
9963
|
-
}
|
|
9964
|
-
}
|
|
9965
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
9966
|
-
});
|
|
10548
|
+
return Promise.resolve(
|
|
10549
|
+
this.tpslValidationStrategy.validate(values, config)
|
|
10550
|
+
);
|
|
9967
10551
|
}
|
|
9968
10552
|
};
|
|
9969
10553
|
|
|
@@ -10016,7 +10600,9 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
|
|
|
10016
10600
|
reduce_only: true,
|
|
10017
10601
|
quantity: values.quantity,
|
|
10018
10602
|
symbol: values.symbol,
|
|
10019
|
-
child_orders
|
|
10603
|
+
child_orders,
|
|
10604
|
+
// Include margin_mode for isolated/cross margin support; default CROSS per order entry pattern
|
|
10605
|
+
margin_mode: values.margin_mode || MarginMode.CROSS
|
|
10020
10606
|
};
|
|
10021
10607
|
}
|
|
10022
10608
|
crateUpdateOrder(values, oldValue, config) {
|
|
@@ -10118,7 +10704,9 @@ var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
|
|
|
10118
10704
|
trigger_price_type: TriggerPriceType.MARK_PRICE,
|
|
10119
10705
|
// reduce_only: true,
|
|
10120
10706
|
symbol: values.symbol,
|
|
10121
|
-
child_orders
|
|
10707
|
+
child_orders,
|
|
10708
|
+
// Include margin_mode for isolated/cross margin support; default CROSS per order entry pattern
|
|
10709
|
+
margin_mode: values.margin_mode || MarginMode.CROSS
|
|
10122
10710
|
};
|
|
10123
10711
|
}
|
|
10124
10712
|
crateUpdateOrder(values, oldValue, config) {
|
|
@@ -10155,7 +10743,11 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10155
10743
|
super(...arguments);
|
|
10156
10744
|
this.orderType = OrderType.TRAILING_STOP;
|
|
10157
10745
|
}
|
|
10158
|
-
|
|
10746
|
+
/**
|
|
10747
|
+
* Builds the trailing stop order
|
|
10748
|
+
* Implements template method hook
|
|
10749
|
+
*/
|
|
10750
|
+
buildOrder(values, config) {
|
|
10159
10751
|
const { order_quantity, activated_price, callback_value, callback_rate } = values;
|
|
10160
10752
|
const order = {
|
|
10161
10753
|
...this.baseOrder(values),
|
|
@@ -10176,6 +10768,7 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10176
10768
|
"quantity",
|
|
10177
10769
|
"side",
|
|
10178
10770
|
"reduce_only",
|
|
10771
|
+
"margin_mode",
|
|
10179
10772
|
"visible_quantity",
|
|
10180
10773
|
"activated_price",
|
|
10181
10774
|
"callback_value",
|
|
@@ -10184,28 +10777,34 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10184
10777
|
order
|
|
10185
10778
|
);
|
|
10186
10779
|
}
|
|
10187
|
-
|
|
10780
|
+
/**
|
|
10781
|
+
* Runs validations for trailing stop order
|
|
10782
|
+
* Implements template method hook
|
|
10783
|
+
*/
|
|
10784
|
+
runValidations(values, config) {
|
|
10188
10785
|
const { markPrice, symbol } = config;
|
|
10189
10786
|
const { quote_dp } = config.symbol;
|
|
10190
10787
|
const { side, activated_price, callback_value, callback_rate } = values;
|
|
10191
|
-
const errors =
|
|
10788
|
+
const errors = this.baseValidate(values, config);
|
|
10192
10789
|
if (activated_price) {
|
|
10193
|
-
const { minPrice
|
|
10790
|
+
const { minPrice, maxPrice } = getPriceRange({
|
|
10194
10791
|
side,
|
|
10195
|
-
markPrice,
|
|
10792
|
+
basePrice: markPrice,
|
|
10196
10793
|
symbolInfo: symbol
|
|
10197
10794
|
});
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10795
|
+
if (!isNaN(minPrice) && !isNaN(maxPrice)) {
|
|
10796
|
+
const activatedPrice = new Decimal(activated_price);
|
|
10797
|
+
if (activatedPrice.lt(minPrice) || activatedPrice.equals(0)) {
|
|
10798
|
+
errors.activated_price = OrderValidation.min(
|
|
10799
|
+
"activated_price",
|
|
10800
|
+
new Decimal(minPrice).todp(quote_dp).toString()
|
|
10801
|
+
);
|
|
10802
|
+
} else if (activatedPrice.gt(maxPrice)) {
|
|
10803
|
+
errors.activated_price = OrderValidation.max(
|
|
10804
|
+
"activated_price",
|
|
10805
|
+
new Decimal(maxPrice).todp(quote_dp).toString()
|
|
10806
|
+
);
|
|
10807
|
+
}
|
|
10209
10808
|
}
|
|
10210
10809
|
}
|
|
10211
10810
|
if (!callback_value && !callback_rate) {
|
|
@@ -10237,23 +10836,6 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10237
10836
|
return errors;
|
|
10238
10837
|
}
|
|
10239
10838
|
};
|
|
10240
|
-
function getPriceRange2(inputs) {
|
|
10241
|
-
const { markPrice, side, symbolInfo } = inputs;
|
|
10242
|
-
const { quote_min, quote_max } = symbolInfo;
|
|
10243
|
-
const priceRange = side === OrderSide.BUY ? {
|
|
10244
|
-
min: quote_min,
|
|
10245
|
-
max: markPrice
|
|
10246
|
-
} : {
|
|
10247
|
-
min: markPrice,
|
|
10248
|
-
max: quote_max
|
|
10249
|
-
};
|
|
10250
|
-
const minPrice3 = Math.max(quote_min, priceRange?.min);
|
|
10251
|
-
const maxPrice3 = Math.min(quote_max, priceRange?.max);
|
|
10252
|
-
return {
|
|
10253
|
-
minPrice: minPrice3,
|
|
10254
|
-
maxPrice: maxPrice3
|
|
10255
|
-
};
|
|
10256
|
-
}
|
|
10257
10839
|
|
|
10258
10840
|
// src/services/orderCreator/factory.ts
|
|
10259
10841
|
var OrderFactory = class {
|
|
@@ -10376,27 +10958,63 @@ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
|
|
|
10376
10958
|
markPrice,
|
|
10377
10959
|
totalCollateral,
|
|
10378
10960
|
futures_taker_fee_rate,
|
|
10379
|
-
positions: positions3
|
|
10961
|
+
positions: positions3,
|
|
10962
|
+
symbolLeverage,
|
|
10963
|
+
sumUnitaryFunding
|
|
10380
10964
|
} = inputs;
|
|
10381
10965
|
const orderFee = order.orderFee({
|
|
10382
10966
|
qty: quantity,
|
|
10383
10967
|
price,
|
|
10384
10968
|
futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
|
|
10385
10969
|
});
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10970
|
+
let liqPrice = 0;
|
|
10971
|
+
if (order$1.margin_mode === MarginMode.CROSS) {
|
|
10972
|
+
liqPrice = order.estLiqPrice({
|
|
10973
|
+
markPrice,
|
|
10974
|
+
baseIMR: symbolInfo.base_imr,
|
|
10975
|
+
baseMMR: symbolInfo.base_mmr,
|
|
10976
|
+
totalCollateral,
|
|
10977
|
+
positions: positions3 == null ? [] : positions3,
|
|
10978
|
+
IMR_Factor: imr_factor,
|
|
10979
|
+
orderFee,
|
|
10980
|
+
newOrder: {
|
|
10981
|
+
qty: quantity,
|
|
10982
|
+
price,
|
|
10983
|
+
symbol
|
|
10984
|
+
}
|
|
10985
|
+
});
|
|
10986
|
+
} else {
|
|
10987
|
+
let isolatedPositionMargin = 0, costPosition = 0, positionQty = 0, lastSumUnitaryFunding = 0, leverage = symbolLeverage ?? 1;
|
|
10988
|
+
if (positions3) {
|
|
10989
|
+
const position = positions3.find(
|
|
10990
|
+
(p) => p.symbol === symbol && p.margin_mode === MarginMode.ISOLATED
|
|
10991
|
+
);
|
|
10992
|
+
if (position) {
|
|
10993
|
+
isolatedPositionMargin = position.margin ?? 0;
|
|
10994
|
+
costPosition = position.cost_position ?? 0;
|
|
10995
|
+
positionQty = position.position_qty ?? 0;
|
|
10996
|
+
lastSumUnitaryFunding = position.last_sum_unitary_funding ?? 0;
|
|
10997
|
+
leverage = position.leverage ? Number(position.leverage) : 1;
|
|
10998
|
+
}
|
|
10398
10999
|
}
|
|
10399
|
-
|
|
11000
|
+
liqPrice = order.estLiqPriceIsolated({
|
|
11001
|
+
isolatedPositionMargin,
|
|
11002
|
+
costPosition,
|
|
11003
|
+
positionQty,
|
|
11004
|
+
sumUnitaryFunding,
|
|
11005
|
+
lastSumUnitaryFunding,
|
|
11006
|
+
markPrice,
|
|
11007
|
+
baseIMR: symbolInfo.base_imr,
|
|
11008
|
+
baseMMR: symbolInfo.base_mmr,
|
|
11009
|
+
IMR_Factor: imr_factor,
|
|
11010
|
+
leverage,
|
|
11011
|
+
newOrder: {
|
|
11012
|
+
symbol,
|
|
11013
|
+
qty: quantity,
|
|
11014
|
+
price
|
|
11015
|
+
}
|
|
11016
|
+
});
|
|
11017
|
+
}
|
|
10400
11018
|
if (liqPrice <= 0) return null;
|
|
10401
11019
|
return liqPrice;
|
|
10402
11020
|
};
|
|
@@ -10454,7 +11072,9 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
|
|
|
10454
11072
|
// sl_enable: isEditing
|
|
10455
11073
|
// ? checkIsEnableTpSL(options?.defaultOrder).sl_enable
|
|
10456
11074
|
// : options?.tpslEnable?.sl_enable,
|
|
10457
|
-
position_type: options?.positionType
|
|
11075
|
+
position_type: options?.positionType,
|
|
11076
|
+
// Use defaultOrder.margin_mode when editing; otherwise position.margin_mode; default CROSS for backward compatibility
|
|
11077
|
+
margin_mode: options?.defaultOrder?.margin_mode ?? position?.margin_mode ?? MarginMode.CROSS
|
|
10458
11078
|
});
|
|
10459
11079
|
const symbolInfo = useSymbolsInfo()[position.symbol]();
|
|
10460
11080
|
const { data: markPrice } = useMarkPrice(order.symbol);
|
|
@@ -10757,11 +11377,53 @@ var useMaxLeverage = (symbol) => {
|
|
|
10757
11377
|
};
|
|
10758
11378
|
var useSymbolLeverage = (symbol) => {
|
|
10759
11379
|
const symbolInfo = useSymbolInfo(symbol);
|
|
10760
|
-
const
|
|
11380
|
+
const { state } = useAccount();
|
|
11381
|
+
const [updateMutation, { isMutating }] = useMutation("/v1/client/leverage");
|
|
10761
11382
|
const maxLeverage = useMemo(() => {
|
|
10762
11383
|
const baseIMR = symbolInfo?.("base_imr");
|
|
10763
11384
|
return baseIMR ? 1 / baseIMR : 1;
|
|
10764
11385
|
}, [symbolInfo]);
|
|
11386
|
+
const update = async (data) => {
|
|
11387
|
+
const result = await updateMutation(data);
|
|
11388
|
+
if (result?.success && data.symbol && state.accountId) {
|
|
11389
|
+
const key = ["/v1/client/leverages", state.accountId];
|
|
11390
|
+
mutate(
|
|
11391
|
+
key,
|
|
11392
|
+
(prev) => {
|
|
11393
|
+
if (!prev) {
|
|
11394
|
+
return [
|
|
11395
|
+
{
|
|
11396
|
+
symbol: data.symbol,
|
|
11397
|
+
leverage: data.leverage,
|
|
11398
|
+
margin_mode: data.margin_mode
|
|
11399
|
+
}
|
|
11400
|
+
];
|
|
11401
|
+
}
|
|
11402
|
+
const index = prev.findIndex(
|
|
11403
|
+
(item) => item.symbol === data.symbol && (item.margin_mode ?? MarginMode.CROSS) === (data.margin_mode ?? MarginMode.CROSS)
|
|
11404
|
+
);
|
|
11405
|
+
if (index === -1) {
|
|
11406
|
+
return [
|
|
11407
|
+
...prev,
|
|
11408
|
+
{
|
|
11409
|
+
symbol: data.symbol,
|
|
11410
|
+
leverage: data.leverage,
|
|
11411
|
+
margin_mode: data.margin_mode
|
|
11412
|
+
}
|
|
11413
|
+
];
|
|
11414
|
+
}
|
|
11415
|
+
const next = [...prev];
|
|
11416
|
+
next[index] = {
|
|
11417
|
+
...next[index],
|
|
11418
|
+
leverage: data.leverage
|
|
11419
|
+
};
|
|
11420
|
+
return next;
|
|
11421
|
+
},
|
|
11422
|
+
{ revalidate: false }
|
|
11423
|
+
);
|
|
11424
|
+
}
|
|
11425
|
+
return result;
|
|
11426
|
+
};
|
|
10765
11427
|
return {
|
|
10766
11428
|
maxLeverage,
|
|
10767
11429
|
update,
|
|
@@ -11498,8 +12160,8 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
|
|
|
11498
12160
|
const keys = Object.keys(current);
|
|
11499
12161
|
for (let i = 0; i < keys.length; i++) {
|
|
11500
12162
|
const k = keys[i];
|
|
11501
|
-
|
|
11502
|
-
|
|
12163
|
+
const preveValue = prev[k];
|
|
12164
|
+
const currentValue = current[k];
|
|
11503
12165
|
if (typeof preveValue === "undefined" && typeof currentValue === "undefined")
|
|
11504
12166
|
continue;
|
|
11505
12167
|
if (preveValue !== currentValue) {
|
|
@@ -11512,7 +12174,12 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
|
|
|
11512
12174
|
if (!key) return null;
|
|
11513
12175
|
return { key, value, preValue };
|
|
11514
12176
|
};
|
|
11515
|
-
const
|
|
12177
|
+
const { marginMode: symbolMarginMode } = useMarginModeBySymbol(symbol);
|
|
12178
|
+
const marginMode = typeof symbolOrOrder === "object" && symbolOrOrder.margin_mode ? symbolOrOrder.margin_mode : symbolMarginMode;
|
|
12179
|
+
const maxQty = useMaxQty(symbol, sideValue, {
|
|
12180
|
+
reduceOnly: isReduceOnly,
|
|
12181
|
+
marginMode: marginMode ?? MarginMode.CROSS
|
|
12182
|
+
});
|
|
11516
12183
|
const parseString2Number = (order, key, dp) => {
|
|
11517
12184
|
if (typeof order[key] !== "string") return;
|
|
11518
12185
|
if (order[key] && order[key].startsWith(".")) {
|
|
@@ -12063,7 +12730,7 @@ var DataPaint = class extends BasePaint {
|
|
|
12063
12730
|
);
|
|
12064
12731
|
const { position, fontSize = 14 } = layout;
|
|
12065
12732
|
let left = this._ratio(position.left);
|
|
12066
|
-
|
|
12733
|
+
const top = layout.position.top + offsetTop + this.transformTop;
|
|
12067
12734
|
let prevElementBoundingBox = {};
|
|
12068
12735
|
if (typeof options.data?.position.side !== "undefined") {
|
|
12069
12736
|
prevElementBoundingBox = this._drawText(options.data.position.side, {
|
|
@@ -12094,6 +12761,28 @@ var DataPaint = class extends BasePaint {
|
|
|
12094
12761
|
fontFamily: options.fontFamily
|
|
12095
12762
|
});
|
|
12096
12763
|
}
|
|
12764
|
+
const marginMode = options.data?.position.marginMode;
|
|
12765
|
+
if (marginMode) {
|
|
12766
|
+
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12767
|
+
if (prevElementBoundingBox.width) {
|
|
12768
|
+
prevElementBoundingBox = this._drawText("|", {
|
|
12769
|
+
color: "rgba(255,255,255,0.2)",
|
|
12770
|
+
left,
|
|
12771
|
+
top: this._ratio(top),
|
|
12772
|
+
fontSize: this._ratio(fontSize),
|
|
12773
|
+
fontFamily: options.fontFamily
|
|
12774
|
+
});
|
|
12775
|
+
}
|
|
12776
|
+
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12777
|
+
const marginModeText = marginMode.charAt(0).toUpperCase() + marginMode.slice(1);
|
|
12778
|
+
prevElementBoundingBox = this._drawText(marginModeText, {
|
|
12779
|
+
color: layout.color,
|
|
12780
|
+
left,
|
|
12781
|
+
top: this._ratio(top),
|
|
12782
|
+
fontSize: this._ratio(fontSize),
|
|
12783
|
+
fontFamily: options.fontFamily
|
|
12784
|
+
});
|
|
12785
|
+
}
|
|
12097
12786
|
if (typeof options.data?.position.leverage !== "undefined") {
|
|
12098
12787
|
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12099
12788
|
if (prevElementBoundingBox.width) {
|
|
@@ -12174,8 +12863,8 @@ var DataPaint = class extends BasePaint {
|
|
|
12174
12863
|
(options.data?.position.informations.length ?? 0) === 2;
|
|
12175
12864
|
const col = informations.length > 4 ? 3 : 2;
|
|
12176
12865
|
informations.forEach((info, index) => {
|
|
12177
|
-
|
|
12178
|
-
|
|
12866
|
+
const left = position.left + index % col * this.positionInfoCellWidth;
|
|
12867
|
+
const top = position.top + Math.floor(index / col) * 38 + this.transformTop;
|
|
12179
12868
|
this._drawText(info.title, {
|
|
12180
12869
|
left: this._ratio(left),
|
|
12181
12870
|
top: this._ratio(top),
|
|
@@ -17717,95 +18406,111 @@ var initialOrderState = {
|
|
|
17717
18406
|
trigger_price: "",
|
|
17718
18407
|
tp_trigger_price: "",
|
|
17719
18408
|
sl_trigger_price: "",
|
|
17720
|
-
tp_order_type: OrderType.MARKET,
|
|
17721
|
-
tp_pnl: "",
|
|
17722
|
-
sl_pnl: "",
|
|
17723
|
-
tp_offset_percentage: "",
|
|
17724
|
-
sl_offset_percentage: "",
|
|
17725
|
-
tp_offset: "",
|
|
17726
|
-
sl_offset: "",
|
|
17727
|
-
sl_order_type: OrderType.MARKET,
|
|
17728
18409
|
total: "",
|
|
17729
|
-
|
|
17730
|
-
start_price: "",
|
|
17731
|
-
end_price: "",
|
|
17732
|
-
totalOrders: "",
|
|
17733
|
-
distribution_type: "",
|
|
17734
|
-
skew: "",
|
|
17735
|
-
// symbol: "",
|
|
17736
|
-
// trailing stop order
|
|
17737
|
-
activated_price: "",
|
|
17738
|
-
callback_value: "",
|
|
17739
|
-
callback_rate: ""
|
|
18410
|
+
symbol: ""
|
|
17740
18411
|
};
|
|
17741
|
-
var useOrderStore = (
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17750
|
-
|
|
17751
|
-
produce((draft) => {
|
|
17752
|
-
Object.assign(draft, order);
|
|
17753
|
-
})
|
|
17754
|
-
// (prev) => ({ ...prev, ...order })
|
|
17755
|
-
);
|
|
17756
|
-
};
|
|
17757
|
-
const updateOrderByKey = (key, value) => {
|
|
17758
|
-
setEntry(
|
|
17759
|
-
produce((draft) => {
|
|
17760
|
-
draft[key] = value;
|
|
17761
|
-
})
|
|
17762
|
-
);
|
|
17763
|
-
};
|
|
17764
|
-
const restoreOrder = (order) => {
|
|
17765
|
-
setEntry(produce((draft) => order));
|
|
17766
|
-
};
|
|
17767
|
-
const updateOrderComputed = (data) => {
|
|
17768
|
-
setEstLeverage(data.estLeverage);
|
|
17769
|
-
setEstLiquidationPrice(data.estLiquidationPrice);
|
|
17770
|
-
};
|
|
17771
|
-
const resetOrder = (order) => {
|
|
17772
|
-
setEntry(
|
|
17773
|
-
produce((draft) => ({
|
|
17774
|
-
...draft,
|
|
17775
|
-
...order ?? initialOrderState
|
|
17776
|
-
}))
|
|
17777
|
-
);
|
|
17778
|
-
};
|
|
17779
|
-
const hasTP_SL = () => {
|
|
17780
|
-
return typeof entry.tp_trigger_price !== "undefined" || typeof entry.sl_trigger_price !== "undefined";
|
|
17781
|
-
};
|
|
17782
|
-
return {
|
|
17783
|
-
entry,
|
|
17784
|
-
estLeverage,
|
|
17785
|
-
estLiquidationPrice,
|
|
17786
|
-
errors,
|
|
18412
|
+
var useOrderStore = create()(
|
|
18413
|
+
immer((set, get3) => ({
|
|
18414
|
+
entry: {
|
|
18415
|
+
side: OrderSide.BUY,
|
|
18416
|
+
order_type: OrderType.LIMIT,
|
|
18417
|
+
...initialOrderState
|
|
18418
|
+
},
|
|
18419
|
+
estLeverage: null,
|
|
18420
|
+
estLiquidationPrice: null,
|
|
18421
|
+
errors: {},
|
|
17787
18422
|
actions: {
|
|
17788
|
-
|
|
17789
|
-
|
|
17790
|
-
|
|
17791
|
-
|
|
17792
|
-
|
|
17793
|
-
|
|
18423
|
+
initOrder: (symbol, options) => {
|
|
18424
|
+
set((state) => {
|
|
18425
|
+
state.entry = {
|
|
18426
|
+
...initialOrderState,
|
|
18427
|
+
symbol,
|
|
18428
|
+
side: options?.side ?? OrderSide.BUY,
|
|
18429
|
+
order_type: options?.order_type ?? OrderType.LIMIT,
|
|
18430
|
+
margin_mode: options?.margin_mode ?? MarginMode.CROSS
|
|
18431
|
+
};
|
|
18432
|
+
state.estLeverage = null;
|
|
18433
|
+
state.estLiquidationPrice = null;
|
|
18434
|
+
state.errors = {};
|
|
18435
|
+
});
|
|
18436
|
+
},
|
|
18437
|
+
hasTP_SL: () => {
|
|
18438
|
+
const order = get3().entry;
|
|
18439
|
+
return typeof order.tp_trigger_price !== "undefined" || typeof order.sl_trigger_price !== "undefined";
|
|
18440
|
+
},
|
|
18441
|
+
updateOrderComputed: (data) => {
|
|
18442
|
+
set(
|
|
18443
|
+
(state) => {
|
|
18444
|
+
state.estLeverage = data.estLeverage;
|
|
18445
|
+
state.estLiquidationPrice = data.estLiquidationPrice;
|
|
18446
|
+
},
|
|
18447
|
+
false
|
|
18448
|
+
// "updateOrderComputed"
|
|
18449
|
+
);
|
|
18450
|
+
},
|
|
18451
|
+
updateOrder: (order) => {
|
|
18452
|
+
set(
|
|
18453
|
+
(state) => {
|
|
18454
|
+
state.entry = {
|
|
18455
|
+
...state.entry,
|
|
18456
|
+
...order
|
|
18457
|
+
};
|
|
18458
|
+
},
|
|
18459
|
+
false
|
|
18460
|
+
// "updateOrder"
|
|
18461
|
+
);
|
|
18462
|
+
},
|
|
18463
|
+
updateOrderByKey: (key, value) => {
|
|
18464
|
+
set(
|
|
18465
|
+
(state) => {
|
|
18466
|
+
state.entry[key] = value;
|
|
18467
|
+
},
|
|
18468
|
+
false
|
|
18469
|
+
// "updateOrderByKey"
|
|
18470
|
+
);
|
|
18471
|
+
},
|
|
18472
|
+
restoreOrder: (order) => {
|
|
18473
|
+
set(
|
|
18474
|
+
(state) => {
|
|
18475
|
+
state.entry = order;
|
|
18476
|
+
},
|
|
18477
|
+
false
|
|
18478
|
+
// "restoreOrder"
|
|
18479
|
+
);
|
|
18480
|
+
},
|
|
18481
|
+
resetOrder: (_order) => {
|
|
18482
|
+
set(
|
|
18483
|
+
(state) => {
|
|
18484
|
+
state.entry.order_price = "";
|
|
18485
|
+
state.entry.order_quantity = "";
|
|
18486
|
+
state.entry.trigger_price = "";
|
|
18487
|
+
state.entry.total = "";
|
|
18488
|
+
state.entry.tp_trigger_price = "";
|
|
18489
|
+
state.entry.tp_pnl = "";
|
|
18490
|
+
state.entry.tp_offset = "";
|
|
18491
|
+
state.entry.tp_offset_percentage = "";
|
|
18492
|
+
state.entry.sl_trigger_price = "";
|
|
18493
|
+
state.entry.sl_pnl = "";
|
|
18494
|
+
state.entry.sl_offset = "";
|
|
18495
|
+
state.entry.sl_offset_percentage = "";
|
|
18496
|
+
},
|
|
18497
|
+
true
|
|
18498
|
+
// "resetOrder"
|
|
18499
|
+
);
|
|
18500
|
+
}
|
|
17794
18501
|
}
|
|
17795
|
-
}
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
// src/next/useOrderEntry/useOrderEntry.internal.ts
|
|
18502
|
+
}))
|
|
18503
|
+
);
|
|
17799
18504
|
var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
17800
18505
|
const { symbolInfo, symbolLeverage } = options;
|
|
17801
|
-
const
|
|
17802
|
-
|
|
17803
|
-
|
|
17804
|
-
|
|
17805
|
-
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
18506
|
+
const orderEntity = useOrderStore((state) => state.entry);
|
|
18507
|
+
const orderEntryActions = useOrderStore((state) => state.actions);
|
|
18508
|
+
useEffect(() => {
|
|
18509
|
+
orderEntryActions.initOrder(symbol, options.initialOrder);
|
|
18510
|
+
if (options.initialOrder) {
|
|
18511
|
+
orderEntryActions.updateOrder(options.initialOrder);
|
|
18512
|
+
}
|
|
18513
|
+
}, [symbol]);
|
|
17809
18514
|
const calculate2 = useCallback(
|
|
17810
18515
|
(values, fieldName, value, markPrice, config) => {
|
|
17811
18516
|
const fieldHandler = getCalculateHandler(fieldName);
|
|
@@ -17819,17 +18524,15 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17819
18524
|
},
|
|
17820
18525
|
[]
|
|
17821
18526
|
);
|
|
17822
|
-
useEffect(() => {
|
|
17823
|
-
orderEntryActions.updateOrderByKey("symbol", symbol);
|
|
17824
|
-
}, [orderEntryActions, symbol]);
|
|
17825
18527
|
const setValue = (key, value, additional) => {
|
|
17826
18528
|
if (!symbolInfo) {
|
|
17827
18529
|
orderEntryActions.updateOrderByKey(key, value);
|
|
17828
18530
|
return;
|
|
17829
18531
|
}
|
|
18532
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
17830
18533
|
const { markPrice } = additional ?? { markPrice: 0 };
|
|
17831
18534
|
let newValues = calculate2(
|
|
17832
|
-
{ ...
|
|
18535
|
+
{ ...currentEntry },
|
|
17833
18536
|
key,
|
|
17834
18537
|
value,
|
|
17835
18538
|
markPrice,
|
|
@@ -17910,7 +18613,8 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17910
18613
|
orderEntryActions.updateOrder(values);
|
|
17911
18614
|
return;
|
|
17912
18615
|
}
|
|
17913
|
-
|
|
18616
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
18617
|
+
let newValues = { ...currentEntry };
|
|
17914
18618
|
Object.keys(values).forEach((key) => {
|
|
17915
18619
|
newValues = calculate2(
|
|
17916
18620
|
newValues,
|
|
@@ -17926,10 +18630,11 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17926
18630
|
const onMarkPriceUpdated = useCallback(
|
|
17927
18631
|
(markPrice, baseOn = []) => {
|
|
17928
18632
|
if (!options.symbolInfo) return;
|
|
17929
|
-
|
|
18633
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
18634
|
+
let newValues = { ...currentEntry };
|
|
17930
18635
|
if (baseOn.length === 0) {
|
|
17931
18636
|
newValues = calculate2(
|
|
17932
|
-
{ ...
|
|
18637
|
+
{ ...currentEntry },
|
|
17933
18638
|
"order_price",
|
|
17934
18639
|
markPrice,
|
|
17935
18640
|
markPrice,
|
|
@@ -17940,7 +18645,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17940
18645
|
newValues = calculate2(
|
|
17941
18646
|
{ ...newValues },
|
|
17942
18647
|
key,
|
|
17943
|
-
|
|
18648
|
+
currentEntry[key],
|
|
17944
18649
|
markPrice,
|
|
17945
18650
|
options.symbolInfo
|
|
17946
18651
|
);
|
|
@@ -17961,7 +18666,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17961
18666
|
}
|
|
17962
18667
|
orderEntryActions.updateOrder(newValues);
|
|
17963
18668
|
},
|
|
17964
|
-
[calculate2, options.symbolInfo,
|
|
18669
|
+
[calculate2, options.symbolInfo, orderEntryActions]
|
|
17965
18670
|
);
|
|
17966
18671
|
const validate = (order, creator, options2) => {
|
|
17967
18672
|
return creator?.validate(order, {
|
|
@@ -18010,6 +18715,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18010
18715
|
const lastChangedField = useRef();
|
|
18011
18716
|
const lastOrderTypeExt = useRef();
|
|
18012
18717
|
const lastLevel = useRef();
|
|
18718
|
+
const fundingRates = useFundingRatesStore();
|
|
18013
18719
|
const calculateTPSL_baseOn = useRef({
|
|
18014
18720
|
tp: "",
|
|
18015
18721
|
sl: ""
|
|
@@ -18018,7 +18724,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18018
18724
|
const symbolConfig = useSymbolsInfo();
|
|
18019
18725
|
const accountInfo = useAccountInfo();
|
|
18020
18726
|
const positions3 = usePositions();
|
|
18021
|
-
const
|
|
18727
|
+
const entry = useOrderStore((s) => s.entry);
|
|
18728
|
+
const effectiveMarginMode = options?.initialOrder?.margin_mode ?? entry?.margin_mode ?? MarginMode.CROSS;
|
|
18729
|
+
const symbolLeverage = useLeverageBySymbol(symbol, effectiveMarginMode);
|
|
18022
18730
|
const symbolInfo = symbolConfig[symbol]();
|
|
18023
18731
|
const markPrice = actions.getMarkPriceBySymbol(symbol);
|
|
18024
18732
|
const { orderMetadata } = useOrderlyContext();
|
|
@@ -18040,11 +18748,13 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18040
18748
|
const [doCreateOrder, { isMutating }] = useMutation(
|
|
18041
18749
|
getCreateOrderUrl(formattedOrder)
|
|
18042
18750
|
);
|
|
18043
|
-
const
|
|
18044
|
-
|
|
18045
|
-
|
|
18046
|
-
formattedOrder.reduce_only
|
|
18047
|
-
|
|
18751
|
+
const bestAskBid = askAndBid.current?.[0] || [];
|
|
18752
|
+
const referencePriceFromOrder = bestAskBid.length >= 2 && formattedOrder.order_type && formattedOrder.side ? getOrderReferencePriceFromOrder(formattedOrder, bestAskBid) : null;
|
|
18753
|
+
const maxQtyValue = useMaxQty(symbol, formattedOrder.side, {
|
|
18754
|
+
reduceOnly: formattedOrder.reduce_only,
|
|
18755
|
+
marginMode: effectiveMarginMode,
|
|
18756
|
+
currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
|
|
18757
|
+
});
|
|
18048
18758
|
const maxQty = options.maxQty ?? maxQtyValue;
|
|
18049
18759
|
const updateOrderPrice = () => {
|
|
18050
18760
|
const order_type = formattedOrder.order_type;
|
|
@@ -18134,6 +18844,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18134
18844
|
};
|
|
18135
18845
|
}, []);
|
|
18136
18846
|
useEffect(() => {
|
|
18847
|
+
if (formattedOrder.symbol !== symbol) {
|
|
18848
|
+
return;
|
|
18849
|
+
}
|
|
18137
18850
|
if ((formattedOrder.order_type === OrderType.MARKET || formattedOrder.order_type === OrderType.STOP_MARKET) && markPrice) {
|
|
18138
18851
|
const baseOn = /* @__PURE__ */ new Set();
|
|
18139
18852
|
if (lastChangedField.current) {
|
|
@@ -18147,7 +18860,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18147
18860
|
}
|
|
18148
18861
|
orderEntryActions.onMarkPriceChange(markPrice, Array.from(baseOn));
|
|
18149
18862
|
}
|
|
18150
|
-
}, [markPrice, formattedOrder.order_type]);
|
|
18863
|
+
}, [markPrice, formattedOrder.order_type, formattedOrder.symbol, symbol]);
|
|
18151
18864
|
const prepareData = useCallback(() => {
|
|
18152
18865
|
return {
|
|
18153
18866
|
markPrice: actions.getMarkPriceBySymbol(symbol),
|
|
@@ -18256,7 +18969,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18256
18969
|
}
|
|
18257
18970
|
);
|
|
18258
18971
|
};
|
|
18259
|
-
const { freeCollateral, totalCollateral } = useCollateral();
|
|
18972
|
+
const { freeCollateral, freeCollateralUSDCOnly, totalCollateral } = useCollateral();
|
|
18260
18973
|
const currentPosition = useMemo(() => {
|
|
18261
18974
|
const rows = positions3 ?? [];
|
|
18262
18975
|
const p = Array.isArray(rows) ? rows.find(
|
|
@@ -18269,6 +18982,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18269
18982
|
if (!markPrice2 || !accountInfo || !symbolInfo) {
|
|
18270
18983
|
return null;
|
|
18271
18984
|
}
|
|
18985
|
+
const sumUnitaryFunding = fundingRates[symbol]?.sum_unitary_funding ?? 0;
|
|
18272
18986
|
const estLiqPrice2 = calcEstLiqPrice(formattedOrder, askAndBid.current[0], {
|
|
18273
18987
|
markPrice: markPrice2,
|
|
18274
18988
|
totalCollateral,
|
|
@@ -18276,7 +18990,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18276
18990
|
imr_factor: accountInfo.imr_factor[symbol],
|
|
18277
18991
|
symbol,
|
|
18278
18992
|
positions: positions3,
|
|
18279
|
-
symbolInfo
|
|
18993
|
+
symbolInfo,
|
|
18994
|
+
sumUnitaryFunding,
|
|
18995
|
+
symbolLeverage
|
|
18280
18996
|
});
|
|
18281
18997
|
return estLiqPrice2;
|
|
18282
18998
|
}, [
|
|
@@ -18286,7 +19002,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18286
19002
|
totalCollateral,
|
|
18287
19003
|
symbol,
|
|
18288
19004
|
maxQty,
|
|
18289
|
-
symbolInfo
|
|
19005
|
+
symbolInfo,
|
|
19006
|
+
fundingRates,
|
|
19007
|
+
symbolLeverage
|
|
18290
19008
|
]);
|
|
18291
19009
|
const estLiqPriceDistance = useMemo(() => {
|
|
18292
19010
|
if (!estLiqPrice) {
|
|
@@ -18421,7 +19139,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18421
19139
|
validator: validateOrder,
|
|
18422
19140
|
validate: validateOrder
|
|
18423
19141
|
},
|
|
18424
|
-
freeCollateral,
|
|
19142
|
+
freeCollateral: effectiveMarginMode === MarginMode.ISOLATED ? freeCollateralUSDCOnly : freeCollateral,
|
|
18425
19143
|
setValue: useMemoizedFn(setValue),
|
|
18426
19144
|
setValues: useMemoizedFn(setValues),
|
|
18427
19145
|
symbolInfo: symbolInfo || EMPTY_OBJECT,
|
|
@@ -18431,93 +19149,6 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18431
19149
|
symbolLeverage
|
|
18432
19150
|
};
|
|
18433
19151
|
};
|
|
18434
|
-
var initialOrderState2 = {
|
|
18435
|
-
order_price: "",
|
|
18436
|
-
order_quantity: "",
|
|
18437
|
-
trigger_price: "",
|
|
18438
|
-
tp_trigger_price: "",
|
|
18439
|
-
sl_trigger_price: "",
|
|
18440
|
-
total: "",
|
|
18441
|
-
symbol: ""
|
|
18442
|
-
};
|
|
18443
|
-
var useOrderStore2 = create()(
|
|
18444
|
-
immer((set, get3) => ({
|
|
18445
|
-
entry: {
|
|
18446
|
-
side: OrderSide.BUY,
|
|
18447
|
-
order_type: OrderType.LIMIT,
|
|
18448
|
-
...initialOrderState2
|
|
18449
|
-
},
|
|
18450
|
-
estLeverage: null,
|
|
18451
|
-
estLiquidationPrice: null,
|
|
18452
|
-
errors: {},
|
|
18453
|
-
actions: {
|
|
18454
|
-
hasTP_SL: () => {
|
|
18455
|
-
const order = get3().entry;
|
|
18456
|
-
return typeof order.tp_trigger_price !== "undefined" || typeof order.sl_trigger_price !== "undefined";
|
|
18457
|
-
},
|
|
18458
|
-
updateOrderComputed: (data) => {
|
|
18459
|
-
set(
|
|
18460
|
-
(state) => {
|
|
18461
|
-
state.estLeverage = data.estLeverage;
|
|
18462
|
-
state.estLiquidationPrice = data.estLiquidationPrice;
|
|
18463
|
-
},
|
|
18464
|
-
false
|
|
18465
|
-
// "updateOrderComputed"
|
|
18466
|
-
);
|
|
18467
|
-
},
|
|
18468
|
-
updateOrder: (order) => {
|
|
18469
|
-
set(
|
|
18470
|
-
(state) => {
|
|
18471
|
-
state.entry = {
|
|
18472
|
-
...state.entry,
|
|
18473
|
-
...order
|
|
18474
|
-
};
|
|
18475
|
-
},
|
|
18476
|
-
false
|
|
18477
|
-
// "updateOrder"
|
|
18478
|
-
);
|
|
18479
|
-
},
|
|
18480
|
-
updateOrderByKey: (key, value) => {
|
|
18481
|
-
set(
|
|
18482
|
-
(state) => {
|
|
18483
|
-
state.entry[key] = value;
|
|
18484
|
-
},
|
|
18485
|
-
false
|
|
18486
|
-
// "updateOrderByKey"
|
|
18487
|
-
);
|
|
18488
|
-
},
|
|
18489
|
-
restoreOrder: (order) => {
|
|
18490
|
-
set(
|
|
18491
|
-
(state) => {
|
|
18492
|
-
state.entry = order;
|
|
18493
|
-
},
|
|
18494
|
-
false
|
|
18495
|
-
// "restoreOrder"
|
|
18496
|
-
);
|
|
18497
|
-
},
|
|
18498
|
-
resetOrder: (order) => {
|
|
18499
|
-
set(
|
|
18500
|
-
(state) => {
|
|
18501
|
-
state.entry.order_price = "";
|
|
18502
|
-
state.entry.order_quantity = "";
|
|
18503
|
-
state.entry.trigger_price = "";
|
|
18504
|
-
state.entry.total = "";
|
|
18505
|
-
state.entry.tp_trigger_price = "";
|
|
18506
|
-
state.entry.tp_pnl = "";
|
|
18507
|
-
state.entry.tp_offset = "";
|
|
18508
|
-
state.entry.tp_offset_percentage = "";
|
|
18509
|
-
state.entry.sl_trigger_price = "";
|
|
18510
|
-
state.entry.sl_pnl = "";
|
|
18511
|
-
state.entry.sl_offset = "";
|
|
18512
|
-
state.entry.sl_offset_percentage = "";
|
|
18513
|
-
},
|
|
18514
|
-
true
|
|
18515
|
-
// "resetOrder"
|
|
18516
|
-
);
|
|
18517
|
-
}
|
|
18518
|
-
}
|
|
18519
|
-
}))
|
|
18520
|
-
);
|
|
18521
19152
|
var useOrderEntity = (order, options) => {
|
|
18522
19153
|
const { symbol } = order;
|
|
18523
19154
|
const { maxQty } = options || {};
|
|
@@ -18675,13 +19306,15 @@ var usePositionClose = (options) => {
|
|
|
18675
19306
|
symbol,
|
|
18676
19307
|
order_type: type,
|
|
18677
19308
|
side,
|
|
18678
|
-
reduce_only: true
|
|
19309
|
+
reduce_only: true,
|
|
19310
|
+
// Use position's margin_mode or default to CROSS for backward compatibility
|
|
19311
|
+
margin_mode: position.margin_mode || MarginMode.CROSS
|
|
18679
19312
|
};
|
|
18680
19313
|
if (type === OrderType.LIMIT) {
|
|
18681
19314
|
data.order_price = price;
|
|
18682
19315
|
}
|
|
18683
19316
|
return data;
|
|
18684
|
-
}, [symbol, price, type, quantity]);
|
|
19317
|
+
}, [symbol, price, type, quantity, position.margin_mode]);
|
|
18685
19318
|
const maxQty = useMemo(() => {
|
|
18686
19319
|
if (!position) {
|
|
18687
19320
|
return 0;
|
|
@@ -18883,9 +19516,11 @@ var useTpslPriceChecker = (params) => {
|
|
|
18883
19516
|
prevResultRef.current = currentResult;
|
|
18884
19517
|
return currentResult;
|
|
18885
19518
|
};
|
|
18886
|
-
var useEstLiqPriceBySymbol = (symbol) => {
|
|
19519
|
+
var useEstLiqPriceBySymbol = (symbol, marginMode) => {
|
|
18887
19520
|
const [data] = usePositionStream(symbol);
|
|
18888
|
-
const position = data?.rows?.find(
|
|
19521
|
+
const position = data?.rows?.find(
|
|
19522
|
+
(row) => row.symbol === symbol && row.margin_mode === marginMode
|
|
19523
|
+
);
|
|
18889
19524
|
return useMemo(() => {
|
|
18890
19525
|
return position?.est_liq_price ?? void 0;
|
|
18891
19526
|
}, [position]);
|
|
@@ -18906,7 +19541,63 @@ var useGetEstLiqPrice = (props) => {
|
|
|
18906
19541
|
return estLiqPrice;
|
|
18907
19542
|
}, [estLiqPrice, markPrice, side]);
|
|
18908
19543
|
};
|
|
19544
|
+
var useFeatureFlag = (key) => {
|
|
19545
|
+
const { data: publicFlags, isLoading: publicLoading } = useQuery("/v1/public/feature_flags", {});
|
|
19546
|
+
const publicFlag = useMemo(() => {
|
|
19547
|
+
if (!publicFlags || publicLoading) {
|
|
19548
|
+
return void 0;
|
|
19549
|
+
}
|
|
19550
|
+
return publicFlags.find((flag) => flag.key === key);
|
|
19551
|
+
}, [publicFlags, publicLoading, key]);
|
|
19552
|
+
const shouldQueryPrivate = useMemo(() => {
|
|
19553
|
+
return publicFlag !== void 0;
|
|
19554
|
+
}, [publicFlag]);
|
|
19555
|
+
const { data: privateFlags, isLoading: privateLoading } = usePrivateQuery(shouldQueryPrivate ? "/v1/feature_flags" : null, {});
|
|
19556
|
+
const privateFlag = useMemo(() => {
|
|
19557
|
+
if (!shouldQueryPrivate || !privateFlags || privateLoading) {
|
|
19558
|
+
return void 0;
|
|
19559
|
+
}
|
|
19560
|
+
return privateFlags.find((flag) => flag.key === key);
|
|
19561
|
+
}, [shouldQueryPrivate, privateFlags, privateLoading, key]);
|
|
19562
|
+
return useMemo(() => {
|
|
19563
|
+
if (publicLoading || shouldQueryPrivate && privateLoading) {
|
|
19564
|
+
return {
|
|
19565
|
+
enabled: false,
|
|
19566
|
+
data: void 0
|
|
19567
|
+
};
|
|
19568
|
+
}
|
|
19569
|
+
if (publicFlag === void 0) {
|
|
19570
|
+
return {
|
|
19571
|
+
enabled: true,
|
|
19572
|
+
data: void 0
|
|
19573
|
+
};
|
|
19574
|
+
}
|
|
19575
|
+
if (privateFlag === void 0) {
|
|
19576
|
+
return {
|
|
19577
|
+
enabled: false,
|
|
19578
|
+
data: void 0
|
|
19579
|
+
};
|
|
19580
|
+
}
|
|
19581
|
+
return {
|
|
19582
|
+
enabled: true,
|
|
19583
|
+
data: privateFlag
|
|
19584
|
+
};
|
|
19585
|
+
}, [
|
|
19586
|
+
publicFlag,
|
|
19587
|
+
privateFlag,
|
|
19588
|
+
publicLoading,
|
|
19589
|
+
shouldQueryPrivate,
|
|
19590
|
+
privateLoading,
|
|
19591
|
+
key
|
|
19592
|
+
]);
|
|
19593
|
+
};
|
|
19594
|
+
|
|
19595
|
+
// src/feature-flag/flagKeys.ts
|
|
19596
|
+
var FlagKeys = /* @__PURE__ */ ((FlagKeys2) => {
|
|
19597
|
+
FlagKeys2["IsolatedMargin"] = "isolated-margin";
|
|
19598
|
+
return FlagKeys2;
|
|
19599
|
+
})(FlagKeys || {});
|
|
18909
19600
|
|
|
18910
|
-
export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, ERROR_MSG_CODES, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, ORDERLY_ORDERBOOK_DEPTH_KEY, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, getPriceKey, indexedDBManager, initializeAppDatabase, isCurrentlyClosed, isCurrentlyTrading, noCacheConfig, parseJSON, persistIndexedDB, resetTimestampOffsetState, timestampWaitingMiddleware, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAppStore, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChainInfo, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEstLiqPriceBySymbol, useEventEmitter, useFeeState, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateBySymbol, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetEstLiqPrice, useGetReferralCode, useGetRwaSymbolCloseTimeInterval, useGetRwaSymbolInfo, useGetRwaSymbolOpenStatus, useGetRwaSymbolOpenTimeInterval, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useInitRwaSymbolsRuntime, useInternalTransfer, useKeyStore, useLazyQuery, useLeverage, useLeverageBySymbol, useLocalStorage, useMainTokenStore, useMainnetChainsStore, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxLeverage, useMaxQty, useMaxWithdrawal, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated,
|
|
19601
|
+
export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, ERROR_MSG_CODES, EpochStatus, ExtendedConfigStore, FlagKeys, MaintenanceStatus, MarketsStorageKey, MarketsType, ORDERLY_ORDERBOOK_DEPTH_KEY, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, getPriceKey, indexedDBManager, initializeAppDatabase, isCurrentlyClosed, isCurrentlyTrading, noCacheConfig, parseJSON, persistIndexedDB, resetTimestampOffsetState, timestampWaitingMiddleware, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAppStore, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChainInfo, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEstLiqPriceBySymbol, useEventEmitter, useFeatureFlag, useFeeState, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateBySymbol, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetEstLiqPrice, useGetReferralCode, useGetRwaSymbolCloseTimeInterval, useGetRwaSymbolInfo, useGetRwaSymbolOpenStatus, useGetRwaSymbolOpenTimeInterval, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useInitRwaSymbolsRuntime, useInternalTransfer, useKeyStore, useLazyQuery, useLeverage, useLeverageBySymbol, useLocalStorage, useMainTokenStore, useMainnetChainsStore, useMaintenanceStatus, useMarginModeBySymbol, useMarginModes, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxLeverage, useMaxQty, useMaxWithdrawal, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore, useOrderStream, useOrderbookStream, useOrderlyContext, usePortfolio, usePositionActions, usePositionClose, usePositionStream, usePositions, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useRwaSymbolsInfo, useRwaSymbolsInfoStore, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountAlgoOrderStream, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSwapSupportStore, useSymbolInfo, useSymbolLeverage, useSymbolLeverageMap, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTestTokenStore, useTestnetChainsStore, useTickerStream, useTokenInfo, useTokensInfo, useTpslPriceChecker, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useUpdatedRef, useUserStatistics, useVaultsHistory, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWalletTopic, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
|
|
18911
19602
|
//# sourceMappingURL=index.mjs.map
|
|
18912
19603
|
//# sourceMappingURL=index.mjs.map
|