@orderly.network/hooks 2.10.2-alpha.0 → 3.0.0-beta.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 +195 -60
- package/dist/index.d.ts +195 -60
- package/dist/index.js +1664 -953
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1660 -955
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -10
package/dist/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var net = require('@orderly.network/net');
|
|
4
|
+
var React = require('react');
|
|
4
5
|
var useSWR5 = require('swr');
|
|
5
6
|
var types = require('@orderly.network/types');
|
|
6
|
-
var
|
|
7
|
+
var pluginCore = require('@orderly.network/plugin-core');
|
|
7
8
|
var utils = require('@orderly.network/utils');
|
|
8
9
|
var useSWRMutation = require('swr/mutation');
|
|
9
10
|
var useConstant = require('use-constant');
|
|
@@ -46,8 +47,8 @@ function _interopNamespace(e) {
|
|
|
46
47
|
return Object.freeze(n);
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
var useSWR5__namespace = /*#__PURE__*/_interopNamespace(useSWR5);
|
|
50
50
|
var React__default = /*#__PURE__*/_interopDefault(React);
|
|
51
|
+
var useSWR5__namespace = /*#__PURE__*/_interopNamespace(useSWR5);
|
|
51
52
|
var useSWRMutation__default = /*#__PURE__*/_interopDefault(useSWRMutation);
|
|
52
53
|
var useConstant__default = /*#__PURE__*/_interopDefault(useConstant);
|
|
53
54
|
var useSWRInfinite__default = /*#__PURE__*/_interopDefault(useSWRInfinite);
|
|
@@ -64,9 +65,9 @@ var __export = (target, all) => {
|
|
|
64
65
|
// src/version.ts
|
|
65
66
|
if (typeof window !== "undefined") {
|
|
66
67
|
window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
|
|
67
|
-
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "
|
|
68
|
+
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.0.0-beta.0";
|
|
68
69
|
}
|
|
69
|
-
var version_default = "
|
|
70
|
+
var version_default = "3.0.0-beta.0";
|
|
70
71
|
var fetcher = (url, init2 = {}, queryOptions) => net.get(url, init2, queryOptions?.formatter);
|
|
71
72
|
var noCacheConfig = {
|
|
72
73
|
dedupingInterval: 0,
|
|
@@ -97,21 +98,26 @@ function useConfig(key, defaultValue) {
|
|
|
97
98
|
}
|
|
98
99
|
return configStore;
|
|
99
100
|
}
|
|
100
|
-
|
|
101
|
-
// src/useQuery.ts
|
|
101
|
+
var PLUGIN_ID_HEADER = "X-Orderly-Plugin-Id";
|
|
102
102
|
var useQuery = (query, options) => {
|
|
103
103
|
const apiBaseUrl = useConfig("apiBaseUrl");
|
|
104
|
+
const pluginScope = pluginCore.usePluginScope();
|
|
104
105
|
const { formatter, ...swrOptions } = options || {};
|
|
105
106
|
if (typeof apiBaseUrl === "undefined") {
|
|
106
107
|
throw new types.SDKError("please add OrderlyConfigProvider to your app");
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
const fetcherFn = React.useCallback(
|
|
110
|
+
(url, init2) => {
|
|
111
|
+
const fullUrl = url.startsWith("http") ? url : `${apiBaseUrl}${url}`;
|
|
112
|
+
const headers = new Headers(init2?.headers);
|
|
113
|
+
if (pluginScope?.pluginId) {
|
|
114
|
+
headers.set(PLUGIN_ID_HEADER, pluginScope.pluginId);
|
|
115
|
+
}
|
|
116
|
+
return fetcher(fullUrl, { ...init2, headers }, { formatter });
|
|
117
|
+
},
|
|
118
|
+
[apiBaseUrl, pluginScope?.pluginId, formatter]
|
|
114
119
|
);
|
|
120
|
+
return useSWR5__namespace.default(query, fetcherFn, swrOptions);
|
|
115
121
|
};
|
|
116
122
|
var timestampOffsetPromise = null;
|
|
117
123
|
var timestampOffsetReady = false;
|
|
@@ -1110,12 +1116,12 @@ var findTPSLOrderPriceFromOrder = (order) => {
|
|
|
1110
1116
|
sl_order_price
|
|
1111
1117
|
};
|
|
1112
1118
|
};
|
|
1113
|
-
var findPositionTPSLFromOrders = (orders, symbol) => {
|
|
1119
|
+
var findPositionTPSLFromOrders = (orders, symbol, marginMode = types.MarginMode.CROSS) => {
|
|
1114
1120
|
const fullPositionOrder = orders?.find((order) => {
|
|
1115
|
-
return order.symbol === symbol && order.algo_type === types.AlgoOrderRootType.POSITIONAL_TP_SL && (order.root_algo_status === types.OrderStatus.NEW || order.root_algo_status === types.OrderStatus.REPLACED || order.root_algo_status === types.OrderStatus.PARTIAL_FILLED);
|
|
1121
|
+
return order.symbol === symbol && order.algo_type === types.AlgoOrderRootType.POSITIONAL_TP_SL && order.margin_mode === marginMode && (order.root_algo_status === types.OrderStatus.NEW || order.root_algo_status === types.OrderStatus.REPLACED || order.root_algo_status === types.OrderStatus.PARTIAL_FILLED);
|
|
1116
1122
|
});
|
|
1117
1123
|
const partialPositionOrders = orders?.filter((order) => {
|
|
1118
|
-
return order.symbol === symbol && order.algo_type === types.AlgoOrderRootType.TP_SL && (order.root_algo_status === types.OrderStatus.NEW || order.root_algo_status === types.OrderStatus.REPLACED || order.root_algo_status === types.OrderStatus.PARTIAL_FILLED);
|
|
1124
|
+
return order.symbol === symbol && order.margin_mode === marginMode && order.algo_type === types.AlgoOrderRootType.TP_SL && (order.root_algo_status === types.OrderStatus.NEW || order.root_algo_status === types.OrderStatus.REPLACED || order.root_algo_status === types.OrderStatus.PARTIAL_FILLED);
|
|
1119
1125
|
}).sort((a, b) => {
|
|
1120
1126
|
return b.created_time - a.created_time;
|
|
1121
1127
|
});
|
|
@@ -2140,9 +2146,11 @@ var useAppStore = zustand.create()(
|
|
|
2140
2146
|
totalCollateral: utils.zero,
|
|
2141
2147
|
totalValue: null,
|
|
2142
2148
|
freeCollateral: utils.zero,
|
|
2149
|
+
freeCollateralUSDCOnly: utils.zero,
|
|
2143
2150
|
availableBalance: 0,
|
|
2144
2151
|
unsettledPnL: 0,
|
|
2145
|
-
totalUnrealizedROI: 0
|
|
2152
|
+
totalUnrealizedROI: 0,
|
|
2153
|
+
usdcHolding: 0
|
|
2146
2154
|
},
|
|
2147
2155
|
appState: {
|
|
2148
2156
|
positionsLoading: false,
|
|
@@ -2163,9 +2171,11 @@ var useAppStore = zustand.create()(
|
|
|
2163
2171
|
totalCollateral: utils.zero,
|
|
2164
2172
|
totalValue: null,
|
|
2165
2173
|
freeCollateral: utils.zero,
|
|
2174
|
+
freeCollateralUSDCOnly: utils.zero,
|
|
2166
2175
|
availableBalance: 0,
|
|
2167
2176
|
unsettledPnL: 0,
|
|
2168
|
-
totalUnrealizedROI: 0
|
|
2177
|
+
totalUnrealizedROI: 0,
|
|
2178
|
+
usdcHolding: 0
|
|
2169
2179
|
};
|
|
2170
2180
|
}, false);
|
|
2171
2181
|
},
|
|
@@ -3961,25 +3971,27 @@ var OrderbookService = class _OrderbookService {
|
|
|
3961
3971
|
};
|
|
3962
3972
|
var orderBookService = OrderbookService.getInstance();
|
|
3963
3973
|
var orderbook_service_default = orderBookService;
|
|
3974
|
+
var useMarkPriceStore = zustand.create((set, get3) => ({
|
|
3975
|
+
markPrices: {},
|
|
3976
|
+
// orderBook: {},
|
|
3977
|
+
// ask_bid: [],
|
|
3978
|
+
actions: {
|
|
3979
|
+
updateMarkPrice: (markPrice) => {
|
|
3980
|
+
set({
|
|
3981
|
+
markPrices: markPrice
|
|
3982
|
+
});
|
|
3983
|
+
},
|
|
3984
|
+
getMarkPriceBySymbol: (symbol) => {
|
|
3985
|
+
return get3().markPrices[symbol];
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
}));
|
|
3989
|
+
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
3990
|
+
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
3991
|
+
|
|
3992
|
+
// src/orderly/useMarkPrice.ts
|
|
3964
3993
|
var useMarkPrice = (symbol) => {
|
|
3965
|
-
const
|
|
3966
|
-
const [price, setPrice] = React.useState(0);
|
|
3967
|
-
const symbolRef = React.useRef(symbol);
|
|
3968
|
-
symbolRef.current = symbol;
|
|
3969
|
-
React.useEffect(() => {
|
|
3970
|
-
const unsubscribe = ws.subscribe(`${symbol}@markprice`, {
|
|
3971
|
-
onMessage: (message) => {
|
|
3972
|
-
if (message.symbol !== symbolRef.current) {
|
|
3973
|
-
unsubscribe?.();
|
|
3974
|
-
return;
|
|
3975
|
-
}
|
|
3976
|
-
setPrice(message.price);
|
|
3977
|
-
}
|
|
3978
|
-
});
|
|
3979
|
-
return () => {
|
|
3980
|
-
unsubscribe?.();
|
|
3981
|
-
};
|
|
3982
|
-
}, [symbol]);
|
|
3994
|
+
const price = useMarkPriceBySymbol(symbol);
|
|
3983
3995
|
return { data: price };
|
|
3984
3996
|
};
|
|
3985
3997
|
var useIndexPrice = (symbol) => {
|
|
@@ -4002,6 +4014,12 @@ var useIndexPrice = (symbol) => {
|
|
|
4002
4014
|
};
|
|
4003
4015
|
});
|
|
4004
4016
|
};
|
|
4017
|
+
|
|
4018
|
+
// src/orderly/useMarkPricesStream.ts
|
|
4019
|
+
var useMarkPricesStream = () => {
|
|
4020
|
+
const data = useMarkPriceStore((state) => state.markPrices);
|
|
4021
|
+
return { data };
|
|
4022
|
+
};
|
|
4005
4023
|
var useOpenInterest = (symbol) => {
|
|
4006
4024
|
const ws = useWS();
|
|
4007
4025
|
const symbolRef = React.useRef(symbol);
|
|
@@ -4021,29 +4039,6 @@ var useOpenInterest = (symbol) => {
|
|
|
4021
4039
|
};
|
|
4022
4040
|
});
|
|
4023
4041
|
};
|
|
4024
|
-
var useMarkPriceStore = zustand.create((set, get3) => ({
|
|
4025
|
-
markPrices: {},
|
|
4026
|
-
// orderBook: {},
|
|
4027
|
-
// ask_bid: [],
|
|
4028
|
-
actions: {
|
|
4029
|
-
updateMarkPrice: (markPrice) => {
|
|
4030
|
-
set({
|
|
4031
|
-
markPrices: markPrice
|
|
4032
|
-
});
|
|
4033
|
-
},
|
|
4034
|
-
getMarkPriceBySymbol: (symbol) => {
|
|
4035
|
-
return get3().markPrices[symbol];
|
|
4036
|
-
}
|
|
4037
|
-
}
|
|
4038
|
-
}));
|
|
4039
|
-
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
4040
|
-
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
4041
|
-
|
|
4042
|
-
// src/orderly/useMarkPricesStream.ts
|
|
4043
|
-
var useMarkPricesStream = () => {
|
|
4044
|
-
const data = useMarkPriceStore((state) => state.markPrices);
|
|
4045
|
-
return { data };
|
|
4046
|
-
};
|
|
4047
4042
|
|
|
4048
4043
|
// src/orderly/useTickerStream.ts
|
|
4049
4044
|
var useTickerStream = (symbol) => {
|
|
@@ -4736,6 +4731,94 @@ var useLeverage = () => {
|
|
|
4736
4731
|
maxLeverage: memoizedMaxLeverage
|
|
4737
4732
|
};
|
|
4738
4733
|
};
|
|
4734
|
+
var buildKey = (symbol, marginMode) => `${symbol}_${marginMode ?? types.MarginMode.CROSS}`;
|
|
4735
|
+
var useSymbolLeverageMap = () => {
|
|
4736
|
+
const { data, error, isLoading, mutate: mutate6 } = usePrivateQuery("/v1/client/leverages", {
|
|
4737
|
+
revalidateOnFocus: false,
|
|
4738
|
+
revalidateOnReconnect: false,
|
|
4739
|
+
errorRetryCount: 1
|
|
4740
|
+
});
|
|
4741
|
+
const leverages = React.useMemo(() => {
|
|
4742
|
+
if (!data || !Array.isArray(data)) return {};
|
|
4743
|
+
const map = {};
|
|
4744
|
+
for (const item of data) {
|
|
4745
|
+
const key = buildKey(item.symbol, item.margin_mode);
|
|
4746
|
+
map[key] = item.leverage;
|
|
4747
|
+
}
|
|
4748
|
+
return map;
|
|
4749
|
+
}, [data]);
|
|
4750
|
+
const getSymbolLeverage = (symbol, marginMode) => {
|
|
4751
|
+
if (!symbol) return void 0;
|
|
4752
|
+
const key = buildKey(symbol, marginMode);
|
|
4753
|
+
return leverages[key];
|
|
4754
|
+
};
|
|
4755
|
+
return {
|
|
4756
|
+
leverages,
|
|
4757
|
+
getSymbolLeverage,
|
|
4758
|
+
isLoading,
|
|
4759
|
+
error,
|
|
4760
|
+
refresh: mutate6
|
|
4761
|
+
};
|
|
4762
|
+
};
|
|
4763
|
+
var useMarginModes = () => {
|
|
4764
|
+
const { data, error, isLoading, mutate: mutate6 } = usePrivateQuery("/v1/client/margin_modes", {
|
|
4765
|
+
revalidateOnFocus: false,
|
|
4766
|
+
revalidateOnMount: true
|
|
4767
|
+
});
|
|
4768
|
+
const [setMarginModeInternal, { isMutating }] = useMutation(
|
|
4769
|
+
"/v1/client/margin_mode",
|
|
4770
|
+
"POST"
|
|
4771
|
+
);
|
|
4772
|
+
const marginModes = React.useMemo(() => {
|
|
4773
|
+
if (!data || !Array.isArray(data)) return {};
|
|
4774
|
+
const map = {};
|
|
4775
|
+
for (const item of data) {
|
|
4776
|
+
map[item.symbol] = item.default_margin_mode;
|
|
4777
|
+
}
|
|
4778
|
+
return map;
|
|
4779
|
+
}, [data]);
|
|
4780
|
+
const setMarginMode = (payload) => setMarginModeInternal(payload);
|
|
4781
|
+
const updateMarginMode = React.useCallback(
|
|
4782
|
+
async (payload) => {
|
|
4783
|
+
const result = await setMarginMode(payload);
|
|
4784
|
+
if (result.success) {
|
|
4785
|
+
await mutate6();
|
|
4786
|
+
return result;
|
|
4787
|
+
}
|
|
4788
|
+
throw new Error(result.message ?? "Failed to update margin mode");
|
|
4789
|
+
},
|
|
4790
|
+
[setMarginMode, mutate6]
|
|
4791
|
+
);
|
|
4792
|
+
return {
|
|
4793
|
+
marginModes,
|
|
4794
|
+
isLoading,
|
|
4795
|
+
error,
|
|
4796
|
+
refresh: mutate6,
|
|
4797
|
+
setMarginMode,
|
|
4798
|
+
updateMarginMode,
|
|
4799
|
+
isMutating
|
|
4800
|
+
};
|
|
4801
|
+
};
|
|
4802
|
+
var useMarginModeBySymbol = (symbol, fallback = types.MarginMode.CROSS) => {
|
|
4803
|
+
const { marginModes, isLoading, error, refresh, updateMarginMode } = useMarginModes();
|
|
4804
|
+
const marginMode = fallback === null ? marginModes[symbol] : marginModes[symbol] ?? fallback;
|
|
4805
|
+
const update = React.useCallback(
|
|
4806
|
+
async (mode) => {
|
|
4807
|
+
return updateMarginMode({
|
|
4808
|
+
symbol_list: [symbol],
|
|
4809
|
+
default_margin_mode: mode
|
|
4810
|
+
});
|
|
4811
|
+
},
|
|
4812
|
+
[symbol, updateMarginMode]
|
|
4813
|
+
);
|
|
4814
|
+
return {
|
|
4815
|
+
marginMode,
|
|
4816
|
+
isLoading,
|
|
4817
|
+
error,
|
|
4818
|
+
refresh,
|
|
4819
|
+
update
|
|
4820
|
+
};
|
|
4821
|
+
};
|
|
4739
4822
|
|
|
4740
4823
|
// src/orderly/useOdosQuote.ts
|
|
4741
4824
|
var useOdosQuote = () => {
|
|
@@ -5093,10 +5176,13 @@ var CalculatorService = class {
|
|
|
5093
5176
|
// this.pendingCalc = [];
|
|
5094
5177
|
// }
|
|
5095
5178
|
async handleCalcQueue(context) {
|
|
5096
|
-
const
|
|
5097
|
-
|
|
5179
|
+
const batchCollector = /* @__PURE__ */ new Map();
|
|
5180
|
+
let currentContext = context;
|
|
5181
|
+
while (this.calcQueue.length > 0) {
|
|
5182
|
+
const first = this.calcQueue.shift();
|
|
5183
|
+
if (!first) break;
|
|
5098
5184
|
const { scope, data, options } = first;
|
|
5099
|
-
const ctx =
|
|
5185
|
+
const ctx = currentContext || CalculatorContext.create(scope, data);
|
|
5100
5186
|
const calculators = this.calculators.get(scope);
|
|
5101
5187
|
if (Array.isArray(calculators) && calculators.length) {
|
|
5102
5188
|
try {
|
|
@@ -5104,13 +5190,46 @@ var CalculatorService = class {
|
|
|
5104
5190
|
} catch (e) {
|
|
5105
5191
|
}
|
|
5106
5192
|
if (!options?.skipUpdate) {
|
|
5107
|
-
this.
|
|
5193
|
+
this.collectUpdates(
|
|
5194
|
+
batchCollector,
|
|
5195
|
+
scope,
|
|
5196
|
+
calculators,
|
|
5197
|
+
ctx.outputToValue()
|
|
5198
|
+
);
|
|
5108
5199
|
}
|
|
5109
5200
|
}
|
|
5110
|
-
|
|
5111
|
-
|
|
5201
|
+
currentContext = ctx;
|
|
5202
|
+
}
|
|
5203
|
+
await this.commitBatchUpdates(batchCollector);
|
|
5204
|
+
this.ctx = currentContext;
|
|
5205
|
+
}
|
|
5206
|
+
collectUpdates(collector, scope, calculators, data) {
|
|
5207
|
+
if (!collector.has(scope)) {
|
|
5208
|
+
collector.set(scope, /* @__PURE__ */ new Map());
|
|
5209
|
+
}
|
|
5210
|
+
const scopeCollector = collector.get(scope);
|
|
5211
|
+
for (const calculator of calculators) {
|
|
5212
|
+
const item = data[calculator.name];
|
|
5213
|
+
if (item !== void 0 && item !== null) {
|
|
5214
|
+
scopeCollector.set(calculator.name, item);
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5217
|
+
}
|
|
5218
|
+
async commitBatchUpdates(collector) {
|
|
5219
|
+
if (collector.size === 0) return;
|
|
5220
|
+
for (const [scope, updateMap] of collector.entries()) {
|
|
5221
|
+
const calculators = this.calculators.get(scope);
|
|
5222
|
+
if (!Array.isArray(calculators)) continue;
|
|
5223
|
+
const batchData = {};
|
|
5224
|
+
for (const [calculatorName, data] of updateMap.entries()) {
|
|
5225
|
+
batchData[calculatorName] = data;
|
|
5226
|
+
}
|
|
5227
|
+
try {
|
|
5228
|
+
this.scheduler.update(scope, calculators, batchData);
|
|
5229
|
+
} catch (e) {
|
|
5112
5230
|
}
|
|
5113
5231
|
}
|
|
5232
|
+
collector.clear();
|
|
5114
5233
|
}
|
|
5115
5234
|
stop() {
|
|
5116
5235
|
this.calcQueue = [];
|
|
@@ -5141,6 +5260,18 @@ var cancelIdleCallbackPolyfill = (id) => {
|
|
|
5141
5260
|
var safeRequestIdleCallback = typeof window !== "undefined" && window.requestIdleCallback ? window.requestIdleCallback.bind(window) : requestIdleCallbackPolyfill;
|
|
5142
5261
|
typeof window !== "undefined" && window.cancelIdleCallback ? window.cancelIdleCallback.bind(window) : cancelIdleCallbackPolyfill;
|
|
5143
5262
|
var ShardingScheduler = class {
|
|
5263
|
+
constructor() {
|
|
5264
|
+
/**
|
|
5265
|
+
* Maximum continuous execution time per frame (in milliseconds)
|
|
5266
|
+
* Prevents blocking the main thread for too long
|
|
5267
|
+
*/
|
|
5268
|
+
this.MAX_CONTINUOUS_MS = 5;
|
|
5269
|
+
/**
|
|
5270
|
+
* Minimum remaining idle time threshold (in milliseconds)
|
|
5271
|
+
* Ensures the browser has enough idle time for other tasks
|
|
5272
|
+
*/
|
|
5273
|
+
this.MIN_IDLE_REMAINING = 2;
|
|
5274
|
+
}
|
|
5144
5275
|
// run(calculators: Calculator[]) {}
|
|
5145
5276
|
calc(scope, calculators, data, ctx) {
|
|
5146
5277
|
return new Promise((resolve, reject) => {
|
|
@@ -5181,28 +5312,27 @@ var ShardingScheduler = class {
|
|
|
5181
5312
|
computation(data, processor, onComplete) {
|
|
5182
5313
|
let index = 0;
|
|
5183
5314
|
const results = [];
|
|
5184
|
-
const
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
const
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5315
|
+
const MAX_CONTINUOUS_MS = this.MAX_CONTINUOUS_MS;
|
|
5316
|
+
const MIN_IDLE_REMAINING = this.MIN_IDLE_REMAINING;
|
|
5317
|
+
const processNextShard = (deadline) => {
|
|
5318
|
+
const frameStart = performance.now();
|
|
5319
|
+
while (index < data.length) {
|
|
5320
|
+
const elapsed = performance.now() - frameStart;
|
|
5321
|
+
const remaining = deadline.timeRemaining();
|
|
5322
|
+
if (elapsed > MAX_CONTINUOUS_MS || remaining < MIN_IDLE_REMAINING) {
|
|
5323
|
+
safeRequestIdleCallback(processNextShard, {
|
|
5324
|
+
timeout: 1e3
|
|
5325
|
+
});
|
|
5326
|
+
return;
|
|
5196
5327
|
}
|
|
5328
|
+
const result = processor([data[index]]);
|
|
5329
|
+
if (result && result.length > 0) {
|
|
5330
|
+
results.push(...result);
|
|
5331
|
+
}
|
|
5332
|
+
index++;
|
|
5197
5333
|
}
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
timeout: 1e3
|
|
5201
|
-
});
|
|
5202
|
-
} else {
|
|
5203
|
-
onComplete(results.flat());
|
|
5204
|
-
}
|
|
5205
|
-
}
|
|
5334
|
+
onComplete(results);
|
|
5335
|
+
};
|
|
5206
5336
|
safeRequestIdleCallback(processNextShard, {
|
|
5207
5337
|
timeout: 1e3
|
|
5208
5338
|
});
|
|
@@ -5415,13 +5545,14 @@ var PositionCalculator = class extends BaseCalculator {
|
|
|
5415
5545
|
const unsettlementPnL = unsettlementPnL_total.toNumber();
|
|
5416
5546
|
let totalUnrealizedROI = 0, totalUnrealizedROI_index = 0;
|
|
5417
5547
|
if (portfolio) {
|
|
5418
|
-
const { totalValue, totalCollateral } = portfolio;
|
|
5548
|
+
const { totalValue, totalCollateral: crossMarginCollateral } = portfolio;
|
|
5419
5549
|
rows = rows.map((item) => {
|
|
5420
5550
|
const info = symbolsInfo[item.symbol];
|
|
5551
|
+
const totalCollateral = item.margin_mode === types.MarginMode.ISOLATED ? new utils.Decimal(item.margin ?? 0).add(item.unsettlement_pnl ?? 0).toNumber() : crossMarginCollateral.toNumber();
|
|
5421
5552
|
const est_liq_price = perp.positions.liqPrice({
|
|
5422
5553
|
symbol: item.symbol,
|
|
5423
5554
|
markPrice: item.mark_price,
|
|
5424
|
-
totalCollateral
|
|
5555
|
+
totalCollateral,
|
|
5425
5556
|
positionQty: item.position_qty,
|
|
5426
5557
|
positions: rows,
|
|
5427
5558
|
MMR: item.mmr,
|
|
@@ -5580,7 +5711,9 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5580
5711
|
return {
|
|
5581
5712
|
...item,
|
|
5582
5713
|
holding: data.holding[item.token].holding,
|
|
5583
|
-
frozen: data.holding[item.token].frozen
|
|
5714
|
+
frozen: data.holding[item.token].frozen,
|
|
5715
|
+
isolatedMargin: data.holding[item.token].isolatedMargin,
|
|
5716
|
+
isolatedOrderFrozen: data.holding[item.token].isolatedOrderFrozen
|
|
5584
5717
|
};
|
|
5585
5718
|
}
|
|
5586
5719
|
return item;
|
|
@@ -5616,7 +5749,14 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5616
5749
|
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo) {
|
|
5617
5750
|
return null;
|
|
5618
5751
|
}
|
|
5619
|
-
const
|
|
5752
|
+
const totallCrossUnsettledPnL = positions3.rows.reduce(
|
|
5753
|
+
(sum, pos) => pos.margin_mode === types.MarginMode.ISOLATED ? sum : sum + (pos.unsettled_pnl ?? 0),
|
|
5754
|
+
0
|
|
5755
|
+
);
|
|
5756
|
+
const totalUnsettlementPnL = positions3.rows.reduce(
|
|
5757
|
+
(sum, pos) => sum + (pos.unsettled_pnl ?? 0),
|
|
5758
|
+
0
|
|
5759
|
+
);
|
|
5620
5760
|
const unrealizedPnL = ramda.pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
5621
5761
|
const [USDC_holding, nonUSDC] = parseHolding(
|
|
5622
5762
|
holding,
|
|
@@ -5627,28 +5767,51 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5627
5767
|
const totalCollateral = perp.account.totalCollateral({
|
|
5628
5768
|
USDCHolding: USDC_holding,
|
|
5629
5769
|
nonUSDCHolding: nonUSDC,
|
|
5630
|
-
unsettlementPnL:
|
|
5770
|
+
unsettlementPnL: totallCrossUnsettledPnL,
|
|
5771
|
+
usdcBalancePendingShortQty: usdc?.pending_short ?? 0,
|
|
5772
|
+
usdcBalanceIsolatedOrderFrozen: usdc?.isolated_order_frozen ?? 0
|
|
5631
5773
|
});
|
|
5774
|
+
const sumIsolatedMargin = positions3.rows.reduce((acc, curr) => {
|
|
5775
|
+
if (curr.margin_mode !== types.MarginMode.ISOLATED) {
|
|
5776
|
+
return acc;
|
|
5777
|
+
}
|
|
5778
|
+
return acc.add(curr.margin ?? 0);
|
|
5779
|
+
}, utils.zero);
|
|
5632
5780
|
const totalValue = perp.account.totalValue({
|
|
5633
|
-
totalUnsettlementPnL
|
|
5781
|
+
totalUnsettlementPnL,
|
|
5634
5782
|
USDCHolding: USDC_holding,
|
|
5635
|
-
nonUSDCHolding: nonUSDC
|
|
5783
|
+
nonUSDCHolding: nonUSDC,
|
|
5784
|
+
totalIsolatedPositionMargin: sumIsolatedMargin.toNumber()
|
|
5636
5785
|
});
|
|
5637
5786
|
const totalUnrealizedROI = perp.account.totalUnrealizedROI({
|
|
5638
5787
|
totalUnrealizedPnL: unrealizedPnL,
|
|
5639
5788
|
totalValue: totalValue.toNumber()
|
|
5640
5789
|
});
|
|
5790
|
+
const maxLeverageBySymbol = positions3.rows.reduce(
|
|
5791
|
+
(acc, position) => {
|
|
5792
|
+
if (position.margin_mode !== types.MarginMode.ISOLATED && position.leverage && !acc[position.symbol]) {
|
|
5793
|
+
acc[position.symbol] = position.leverage;
|
|
5794
|
+
}
|
|
5795
|
+
return acc;
|
|
5796
|
+
},
|
|
5797
|
+
{}
|
|
5798
|
+
);
|
|
5641
5799
|
const totalInitialMarginWithOrders = perp.account.totalInitialMarginWithQty({
|
|
5642
5800
|
positions: positions3.rows,
|
|
5801
|
+
orders: [],
|
|
5643
5802
|
markPrices,
|
|
5644
5803
|
IMR_Factors: accountInfo.imr_factor,
|
|
5645
|
-
|
|
5804
|
+
maxLeverageBySymbol,
|
|
5646
5805
|
symbolInfo: createGetter({ ...symbolsInfo })
|
|
5647
5806
|
});
|
|
5648
5807
|
const freeCollateral = perp.account.freeCollateral({
|
|
5649
5808
|
totalCollateral,
|
|
5650
5809
|
totalInitialMarginWithOrders
|
|
5651
5810
|
});
|
|
5811
|
+
const freeCollateralUSDCOnly = perp.account.freeCollateralUSDCOnly({
|
|
5812
|
+
freeCollateral,
|
|
5813
|
+
nonUSDCHolding: nonUSDC
|
|
5814
|
+
});
|
|
5652
5815
|
const availableBalance = perp.account.availableBalance({
|
|
5653
5816
|
USDCHolding: usdc?.holding ?? 0,
|
|
5654
5817
|
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
@@ -5659,8 +5822,10 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5659
5822
|
totalUnrealizedROI,
|
|
5660
5823
|
freeCollateral,
|
|
5661
5824
|
availableBalance,
|
|
5662
|
-
unsettledPnL,
|
|
5663
|
-
holding
|
|
5825
|
+
unsettledPnL: totalUnsettlementPnL,
|
|
5826
|
+
holding,
|
|
5827
|
+
usdcHolding: USDC_holding,
|
|
5828
|
+
freeCollateralUSDCOnly
|
|
5664
5829
|
};
|
|
5665
5830
|
}
|
|
5666
5831
|
update(data, scope) {
|
|
@@ -5669,10 +5834,12 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5669
5834
|
totalCollateral: data.totalCollateral,
|
|
5670
5835
|
totalValue: data.totalValue,
|
|
5671
5836
|
freeCollateral: data.freeCollateral,
|
|
5837
|
+
freeCollateralUSDCOnly: data.freeCollateralUSDCOnly,
|
|
5672
5838
|
availableBalance: data.availableBalance,
|
|
5673
5839
|
totalUnrealizedROI: data.totalUnrealizedROI,
|
|
5674
5840
|
unsettledPnL: data.unsettledPnL,
|
|
5675
|
-
holding: Array.isArray(data.holding) ? data.holding : []
|
|
5841
|
+
holding: Array.isArray(data.holding) ? data.holding : [],
|
|
5842
|
+
usdcHolding: typeof data.usdcHolding === "number" ? data.usdcHolding : data.usdcHolding.toNumber()
|
|
5676
5843
|
});
|
|
5677
5844
|
}
|
|
5678
5845
|
}
|
|
@@ -5803,7 +5970,7 @@ var usePositionStream = (symbol = "all", options) => {
|
|
|
5803
5970
|
}
|
|
5804
5971
|
if (Array.isArray(tpslOrders) && tpslOrders.length) {
|
|
5805
5972
|
rows = rows.map((item) => {
|
|
5806
|
-
const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol);
|
|
5973
|
+
const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol, item.margin_mode);
|
|
5807
5974
|
const full_tp_sl = fullPositionOrder ? findTPSLFromOrder(fullPositionOrder) : void 0;
|
|
5808
5975
|
const partialPossitionOrder = partialPositionOrders && partialPositionOrders.length ? partialPositionOrders[0] : void 0;
|
|
5809
5976
|
const partial_tp_sl = partialPossitionOrder ? findTPSLFromOrder(partialPossitionOrder) : void 0;
|
|
@@ -5935,15 +6102,21 @@ var useOrderStream = (params, options) => {
|
|
|
5935
6102
|
}
|
|
5936
6103
|
};
|
|
5937
6104
|
}, [normalOrderKeyFn, options?.keeplive]);
|
|
5938
|
-
const normalOrdersResponse = usePrivateInfiniteQuery(
|
|
5939
|
-
|
|
5940
|
-
|
|
5941
|
-
|
|
5942
|
-
|
|
5943
|
-
|
|
5944
|
-
|
|
5945
|
-
|
|
5946
|
-
|
|
6105
|
+
const normalOrdersResponse = usePrivateInfiniteQuery(
|
|
6106
|
+
normalOrderKeyFn,
|
|
6107
|
+
{
|
|
6108
|
+
initialSize: 1,
|
|
6109
|
+
formatter: (data) => data,
|
|
6110
|
+
revalidateOnFocus: false
|
|
6111
|
+
}
|
|
6112
|
+
);
|
|
6113
|
+
const algoOrdersResponse = usePrivateInfiniteQuery(
|
|
6114
|
+
algoOrderKeyFn,
|
|
6115
|
+
{
|
|
6116
|
+
formatter: (data) => data,
|
|
6117
|
+
revalidateOnFocus: false
|
|
6118
|
+
}
|
|
6119
|
+
);
|
|
5947
6120
|
const flattenOrders = React.useMemo(() => {
|
|
5948
6121
|
if (!normalOrdersResponse.data || !algoOrdersResponse.data && !sourceTypeAll) {
|
|
5949
6122
|
return null;
|
|
@@ -6061,7 +6234,9 @@ var useOrderStream = (params, options) => {
|
|
|
6061
6234
|
// trailing stop order fields
|
|
6062
6235
|
activated_price: order.activated_price,
|
|
6063
6236
|
callback_value: order.callback_value,
|
|
6064
|
-
callback_rate: order.callback_rate
|
|
6237
|
+
callback_rate: order.callback_rate,
|
|
6238
|
+
// Include margin_mode if present
|
|
6239
|
+
...order.margin_mode && { margin_mode: order.margin_mode }
|
|
6065
6240
|
});
|
|
6066
6241
|
default:
|
|
6067
6242
|
return doUpdateOrder({ ...order, order_id: orderId });
|
|
@@ -6256,7 +6431,14 @@ function formatPortfolio(inputs) {
|
|
|
6256
6431
|
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo || symbolsInfo?.isNil) {
|
|
6257
6432
|
return null;
|
|
6258
6433
|
}
|
|
6259
|
-
const
|
|
6434
|
+
const totallCrossUnsettledPnL = positions3.rows.reduce(
|
|
6435
|
+
(sum, pos) => pos.margin_mode === types.MarginMode.ISOLATED ? sum : sum + (pos.unsettled_pnl ?? 0),
|
|
6436
|
+
0
|
|
6437
|
+
);
|
|
6438
|
+
const totalUnsettlementPnL = positions3.rows.reduce(
|
|
6439
|
+
(sum, pos) => sum + (pos.unsettled_pnl ?? 0),
|
|
6440
|
+
0
|
|
6441
|
+
);
|
|
6260
6442
|
const unrealizedPnL = ramda.pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
6261
6443
|
const [USDC_holding, nonUSDC] = parseHolding(
|
|
6262
6444
|
holding,
|
|
@@ -6267,29 +6449,51 @@ function formatPortfolio(inputs) {
|
|
|
6267
6449
|
const totalCollateral = perp.account.totalCollateral({
|
|
6268
6450
|
USDCHolding: USDC_holding,
|
|
6269
6451
|
nonUSDCHolding: nonUSDC,
|
|
6270
|
-
unsettlementPnL:
|
|
6452
|
+
unsettlementPnL: totallCrossUnsettledPnL,
|
|
6453
|
+
usdcBalancePendingShortQty: usdc?.pending_short ?? 0,
|
|
6454
|
+
usdcBalanceIsolatedOrderFrozen: usdc?.isolated_order_frozen ?? 0
|
|
6271
6455
|
});
|
|
6456
|
+
const sumIsolatedMargin = positions3.rows.reduce((acc, curr) => {
|
|
6457
|
+
if (curr.margin_mode !== types.MarginMode.ISOLATED) {
|
|
6458
|
+
return acc;
|
|
6459
|
+
}
|
|
6460
|
+
return acc.add(curr.margin ?? 0);
|
|
6461
|
+
}, utils.zero);
|
|
6272
6462
|
const totalValue = perp.account.totalValue({
|
|
6273
|
-
totalUnsettlementPnL
|
|
6463
|
+
totalUnsettlementPnL,
|
|
6274
6464
|
USDCHolding: USDC_holding,
|
|
6275
|
-
nonUSDCHolding: nonUSDC
|
|
6465
|
+
nonUSDCHolding: nonUSDC,
|
|
6466
|
+
totalIsolatedPositionMargin: sumIsolatedMargin.toNumber()
|
|
6276
6467
|
});
|
|
6277
6468
|
const totalUnrealizedROI = perp.account.totalUnrealizedROI({
|
|
6278
6469
|
totalUnrealizedPnL: unrealizedPnL,
|
|
6279
6470
|
totalValue: totalValue.toNumber()
|
|
6280
6471
|
});
|
|
6472
|
+
const maxLeverageBySymbol = positions3.rows.reduce(
|
|
6473
|
+
(acc, position) => {
|
|
6474
|
+
if (position.margin_mode !== types.MarginMode.ISOLATED && position.leverage && !acc[position.symbol]) {
|
|
6475
|
+
acc[position.symbol] = position.leverage;
|
|
6476
|
+
}
|
|
6477
|
+
return acc;
|
|
6478
|
+
},
|
|
6479
|
+
{}
|
|
6480
|
+
);
|
|
6281
6481
|
const totalInitialMarginWithOrders = perp.account.totalInitialMarginWithQty({
|
|
6282
6482
|
positions: positions3.rows,
|
|
6483
|
+
orders: [],
|
|
6283
6484
|
markPrices,
|
|
6284
6485
|
IMR_Factors: accountInfo.imr_factor,
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
symbolInfo: symbolsInfo
|
|
6486
|
+
maxLeverageBySymbol,
|
|
6487
|
+
symbolInfo: createGetter({ ...symbolsInfo })
|
|
6288
6488
|
});
|
|
6289
6489
|
const freeCollateral = perp.account.freeCollateral({
|
|
6290
6490
|
totalCollateral,
|
|
6291
6491
|
totalInitialMarginWithOrders
|
|
6292
6492
|
});
|
|
6493
|
+
const freeCollateralUSDCOnly = perp.account.freeCollateralUSDCOnly({
|
|
6494
|
+
freeCollateral,
|
|
6495
|
+
nonUSDCHolding: nonUSDC
|
|
6496
|
+
});
|
|
6293
6497
|
const availableBalance = perp.account.availableBalance({
|
|
6294
6498
|
USDCHolding: usdc?.holding ?? 0,
|
|
6295
6499
|
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
@@ -6300,8 +6504,9 @@ function formatPortfolio(inputs) {
|
|
|
6300
6504
|
totalUnrealizedROI,
|
|
6301
6505
|
freeCollateral,
|
|
6302
6506
|
availableBalance,
|
|
6303
|
-
unsettledPnL,
|
|
6304
|
-
holding
|
|
6507
|
+
unsettledPnL: totalUnsettlementPnL,
|
|
6508
|
+
holding,
|
|
6509
|
+
freeCollateralUSDCOnly
|
|
6305
6510
|
};
|
|
6306
6511
|
}
|
|
6307
6512
|
function formatPositions(data, accountInfo, symbolsInfo, fundingRates) {
|
|
@@ -6821,7 +7026,9 @@ var useSubAccountAlgoOrderStream = (params, options) => {
|
|
|
6821
7026
|
// trailing stop order fields
|
|
6822
7027
|
activated_price: order.activated_price,
|
|
6823
7028
|
callback_value: order.callback_value,
|
|
6824
|
-
callback_rate: order.callback_rate
|
|
7029
|
+
callback_rate: order.callback_rate,
|
|
7030
|
+
// include margin_mode if present (align with useOrderStream)
|
|
7031
|
+
...order.margin_mode && { margin_mode: order.margin_mode }
|
|
6825
7032
|
});
|
|
6826
7033
|
default:
|
|
6827
7034
|
return doUpdateOrder({ ...order, order_id: orderId });
|
|
@@ -7008,120 +7215,122 @@ var useCollateral = (options = { dp: 6 }) => {
|
|
|
7008
7215
|
totalCollateral,
|
|
7009
7216
|
totalValue,
|
|
7010
7217
|
freeCollateral,
|
|
7218
|
+
freeCollateralUSDCOnly,
|
|
7011
7219
|
availableBalance,
|
|
7012
7220
|
unsettledPnL,
|
|
7013
|
-
holding
|
|
7221
|
+
holding,
|
|
7222
|
+
usdcHolding
|
|
7014
7223
|
} = useAppStore((state) => state.portfolio);
|
|
7015
7224
|
const accountInfo = useAppStore((state) => state.accountInfo);
|
|
7016
7225
|
return {
|
|
7017
7226
|
totalCollateral: totalCollateral.toDecimalPlaces(dp).toNumber(),
|
|
7018
7227
|
freeCollateral: freeCollateral.toDecimalPlaces(dp).toNumber(),
|
|
7228
|
+
freeCollateralUSDCOnly: freeCollateralUSDCOnly.toDecimalPlaces(dp).toNumber(),
|
|
7019
7229
|
totalValue: totalValue?.toDecimalPlaces(dp).toNumber() ?? null,
|
|
7020
7230
|
availableBalance,
|
|
7021
7231
|
unsettledPnL,
|
|
7022
7232
|
accountInfo,
|
|
7023
|
-
holding
|
|
7233
|
+
holding,
|
|
7234
|
+
usdcHolding
|
|
7024
7235
|
// @hidden
|
|
7025
7236
|
// positions: positionsPath(positions),
|
|
7026
7237
|
};
|
|
7027
7238
|
};
|
|
7028
|
-
|
|
7029
|
-
|
|
7030
|
-
|
|
7031
|
-
const {
|
|
7032
|
-
|
|
7033
|
-
{
|
|
7034
|
-
revalidateOnFocus: false
|
|
7035
|
-
}
|
|
7036
|
-
);
|
|
7037
|
-
React.useEffect(() => {
|
|
7038
|
-
if (!state.accountId || !symbol) return;
|
|
7039
|
-
const unsubscribe = ws.privateSubscribe("account", {
|
|
7040
|
-
onMessage: (data2) => {
|
|
7041
|
-
const res = data2?.accountDetail?.symbolLeverage || {};
|
|
7042
|
-
if (res.symbol === symbol) {
|
|
7043
|
-
const key = [`/v1/client/leverage?symbol=${symbol}`, state.accountId];
|
|
7044
|
-
useSWR5.mutate(
|
|
7045
|
-
key,
|
|
7046
|
-
(prevData) => {
|
|
7047
|
-
return {
|
|
7048
|
-
...prevData,
|
|
7049
|
-
leverage: res.leverage
|
|
7050
|
-
};
|
|
7051
|
-
},
|
|
7052
|
-
{
|
|
7053
|
-
revalidate: false
|
|
7054
|
-
}
|
|
7055
|
-
);
|
|
7056
|
-
}
|
|
7057
|
-
}
|
|
7058
|
-
});
|
|
7059
|
-
return () => unsubscribe?.();
|
|
7060
|
-
}, [symbol, state.accountId]);
|
|
7061
|
-
return data?.leverage;
|
|
7239
|
+
|
|
7240
|
+
// src/orderly/useLeverageBySymbol.ts
|
|
7241
|
+
var useLeverageBySymbol = (symbol, marginMode) => {
|
|
7242
|
+
const { getSymbolLeverage } = useSymbolLeverageMap();
|
|
7243
|
+
return getSymbolLeverage(symbol, marginMode);
|
|
7062
7244
|
};
|
|
7063
7245
|
|
|
7064
7246
|
// src/orderly/useMaxQty.ts
|
|
7065
|
-
|
|
7247
|
+
function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
|
|
7248
|
+
const reduceOnly = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.reduceOnly ?? false : reduceOnlyOrOptions ?? false;
|
|
7249
|
+
const finalMarginMode = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.marginMode ?? types.MarginMode.CROSS : marginMode ?? types.MarginMode.CROSS;
|
|
7066
7250
|
const positions3 = usePositions();
|
|
7067
7251
|
const accountInfo = useAccountInfo();
|
|
7068
7252
|
const symbolInfo = useSymbolsInfo();
|
|
7069
|
-
const { totalCollateral } = useCollateral();
|
|
7253
|
+
const { totalCollateral, freeCollateralUSDCOnly } = useCollateral();
|
|
7070
7254
|
const { data: markPrices } = useMarkPricesStream();
|
|
7071
|
-
const symbolLeverage = useLeverageBySymbol(symbol);
|
|
7255
|
+
const symbolLeverage = useLeverageBySymbol(symbol, finalMarginMode);
|
|
7072
7256
|
const maxQty = React.useMemo(() => {
|
|
7073
7257
|
if (!symbol) return 0;
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7258
|
+
if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3) {
|
|
7259
|
+
return 0;
|
|
7260
|
+
}
|
|
7261
|
+
const positionsArray = (positions3 === null ? [] : positions3).filter(
|
|
7262
|
+
(position) => position.margin_mode === finalMarginMode
|
|
7077
7263
|
);
|
|
7264
|
+
const positionQty = perp.account.getQtyFromPositions(positionsArray, symbol);
|
|
7078
7265
|
if (reduceOnly) {
|
|
7079
|
-
if (positionQty
|
|
7080
|
-
|
|
7081
|
-
return 0;
|
|
7082
|
-
} else {
|
|
7083
|
-
return Math.abs(positionQty);
|
|
7084
|
-
}
|
|
7085
|
-
}
|
|
7086
|
-
if (positionQty < 0) {
|
|
7087
|
-
if (side === types.OrderSide.BUY) {
|
|
7088
|
-
return Math.abs(positionQty);
|
|
7089
|
-
} else {
|
|
7090
|
-
return 0;
|
|
7091
|
-
}
|
|
7092
|
-
}
|
|
7093
|
-
return 0;
|
|
7266
|
+
if (positionQty === 0) return 0;
|
|
7267
|
+
return side === types.OrderSide.BUY ? positionQty < 0 ? Math.abs(positionQty) : 0 : positionQty > 0 ? positionQty : 0;
|
|
7094
7268
|
}
|
|
7095
|
-
if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3)
|
|
7096
|
-
return 0;
|
|
7097
7269
|
const getSymbolInfo = symbolInfo[symbol];
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
)
|
|
7270
|
+
let currentSymbolPosition;
|
|
7271
|
+
const otherPositions = [];
|
|
7272
|
+
for (const position of positionsArray) {
|
|
7273
|
+
if (position.symbol === symbol) {
|
|
7274
|
+
currentSymbolPosition = position;
|
|
7275
|
+
} else {
|
|
7276
|
+
otherPositions.push(position);
|
|
7277
|
+
}
|
|
7278
|
+
}
|
|
7279
|
+
const markPrice = markPrices[symbol];
|
|
7280
|
+
const baseIMR = getSymbolInfo("base_imr") ?? 0;
|
|
7281
|
+
const IMR_Factor = accountInfo.imr_factor[symbol] ?? 0;
|
|
7282
|
+
const leverage = symbolLeverage || currentSymbolPosition?.leverage || 1;
|
|
7101
7283
|
const buyOrdersQty = currentSymbolPosition?.pending_long_qty ?? 0;
|
|
7102
7284
|
const sellOrdersQty = currentSymbolPosition?.pending_short_qty ?? 0;
|
|
7103
|
-
|
|
7285
|
+
if (finalMarginMode === types.MarginMode.ISOLATED) {
|
|
7286
|
+
const availableBalance = freeCollateralUSDCOnly;
|
|
7287
|
+
const pendingLongOrders = buyOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: buyOrdersQty }] : [];
|
|
7288
|
+
const pendingSellOrders = sellOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: sellOrdersQty }] : [];
|
|
7289
|
+
const markPriceDecimal = new utils.Decimal(markPrice);
|
|
7290
|
+
const leverageDecimal = new utils.Decimal(leverage);
|
|
7291
|
+
const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).div(leverageDecimal).toNumber() : 0;
|
|
7292
|
+
const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).div(leverageDecimal).toNumber() : 0;
|
|
7293
|
+
const symbolMaxNotional = accountInfo.max_notional?.[symbol] ?? perp.positions.maxPositionNotional({
|
|
7294
|
+
leverage,
|
|
7295
|
+
IMRFactor: IMR_Factor
|
|
7296
|
+
});
|
|
7297
|
+
const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : markPrice;
|
|
7298
|
+
return perp.account.maxQtyForIsolatedMargin({
|
|
7299
|
+
symbol,
|
|
7300
|
+
orderSide: side,
|
|
7301
|
+
currentOrderReferencePrice,
|
|
7302
|
+
availableBalance,
|
|
7303
|
+
leverage,
|
|
7304
|
+
baseIMR,
|
|
7305
|
+
IMR_Factor,
|
|
7306
|
+
markPrice,
|
|
7307
|
+
positionQty,
|
|
7308
|
+
pendingLongOrders,
|
|
7309
|
+
pendingSellOrders,
|
|
7310
|
+
isoOrderFrozenLong,
|
|
7311
|
+
isoOrderFrozenShort,
|
|
7312
|
+
symbolMaxNotional
|
|
7313
|
+
});
|
|
7314
|
+
}
|
|
7104
7315
|
const otherIMs = perp.account.otherIMs({
|
|
7105
7316
|
positions: otherPositions,
|
|
7106
7317
|
symbolInfo,
|
|
7107
7318
|
markPrices,
|
|
7108
|
-
IMR_Factors: accountInfo.imr_factor
|
|
7109
|
-
// Not used
|
|
7110
|
-
maxLeverage: accountInfo.max_leverage
|
|
7319
|
+
IMR_Factors: accountInfo.imr_factor
|
|
7111
7320
|
});
|
|
7112
7321
|
return perp.account.maxQty(side, {
|
|
7113
|
-
markPrice
|
|
7322
|
+
markPrice,
|
|
7114
7323
|
symbol,
|
|
7115
7324
|
baseMaxQty: getSymbolInfo("base_max"),
|
|
7116
7325
|
totalCollateral,
|
|
7117
|
-
maxLeverage:
|
|
7326
|
+
maxLeverage: leverage,
|
|
7118
7327
|
takerFeeRate: accountInfo.futures_taker_fee_rate,
|
|
7119
|
-
baseIMR
|
|
7328
|
+
baseIMR,
|
|
7120
7329
|
otherIMs,
|
|
7121
7330
|
positionQty,
|
|
7122
7331
|
buyOrdersQty,
|
|
7123
7332
|
sellOrdersQty,
|
|
7124
|
-
IMR_Factor
|
|
7333
|
+
IMR_Factor
|
|
7125
7334
|
});
|
|
7126
7335
|
}, [
|
|
7127
7336
|
symbol,
|
|
@@ -7131,10 +7340,12 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
|
|
|
7131
7340
|
accountInfo,
|
|
7132
7341
|
symbolInfo,
|
|
7133
7342
|
side,
|
|
7134
|
-
totalCollateral
|
|
7343
|
+
totalCollateral,
|
|
7344
|
+
finalMarginMode,
|
|
7345
|
+
symbolLeverage
|
|
7135
7346
|
]);
|
|
7136
7347
|
return Math.max(maxQty, 0);
|
|
7137
|
-
}
|
|
7348
|
+
}
|
|
7138
7349
|
var useMarginRatio = () => {
|
|
7139
7350
|
const positions3 = usePositionStore((state2) => state2.positions.all);
|
|
7140
7351
|
const { rows, notional } = positions3;
|
|
@@ -8440,54 +8651,92 @@ var usePrivateDataObserver = (options) => {
|
|
|
8440
8651
|
}, [state.accountId, subOrder]);
|
|
8441
8652
|
React.useEffect(() => {
|
|
8442
8653
|
if (!state.accountId) return;
|
|
8443
|
-
const
|
|
8654
|
+
const positionsKey = ["/v1/positions", state.accountId];
|
|
8655
|
+
const leveragesKey = ["/v1/client/leverages", state.accountId];
|
|
8444
8656
|
const unsubscribe = ws.privateSubscribe("account", {
|
|
8445
8657
|
onMessage: (data) => {
|
|
8446
|
-
const { symbol, leverage } = data?.accountDetail?.symbolLeverage || {};
|
|
8447
|
-
if (symbol
|
|
8448
|
-
|
|
8449
|
-
key,
|
|
8450
|
-
(prevPositions) => {
|
|
8451
|
-
if (prevPositions?.rows?.length) {
|
|
8452
|
-
return {
|
|
8453
|
-
...prevPositions,
|
|
8454
|
-
rows: prevPositions.rows.map((row) => {
|
|
8455
|
-
return row.symbol === symbol ? { ...row, leverage } : row;
|
|
8456
|
-
})
|
|
8457
|
-
};
|
|
8458
|
-
}
|
|
8459
|
-
return prevPositions;
|
|
8460
|
-
},
|
|
8461
|
-
{
|
|
8462
|
-
revalidate: false
|
|
8463
|
-
}
|
|
8464
|
-
);
|
|
8658
|
+
const { symbol, leverage, marginMode } = data?.accountDetail?.symbolLeverage || {};
|
|
8659
|
+
if (!symbol || leverage === void 0) {
|
|
8660
|
+
return;
|
|
8465
8661
|
}
|
|
8466
|
-
}
|
|
8467
|
-
});
|
|
8468
|
-
return () => unsubscribe?.();
|
|
8469
|
-
}, [state.accountId]);
|
|
8470
|
-
React.useEffect(() => {
|
|
8471
|
-
if (!state.accountId) {
|
|
8472
|
-
return;
|
|
8473
|
-
}
|
|
8474
|
-
const key = ["/v1/positions", state.accountId];
|
|
8475
|
-
const unsubscribe = ws.privateSubscribe("position", {
|
|
8476
|
-
onMessage: (data) => {
|
|
8477
|
-
const { positions: nextPositions } = data;
|
|
8478
8662
|
useSWR5.mutate(
|
|
8479
|
-
|
|
8663
|
+
positionsKey,
|
|
8480
8664
|
(prevPositions) => {
|
|
8481
|
-
if (
|
|
8482
|
-
|
|
8665
|
+
if (prevPositions?.rows?.length) {
|
|
8666
|
+
return {
|
|
8483
8667
|
...prevPositions,
|
|
8484
8668
|
rows: prevPositions.rows.map((row) => {
|
|
8485
|
-
|
|
8486
|
-
|
|
8487
|
-
|
|
8488
|
-
|
|
8489
|
-
|
|
8490
|
-
|
|
8669
|
+
return row.symbol === symbol && row.margin_mode === marginMode ? { ...row, leverage } : row;
|
|
8670
|
+
})
|
|
8671
|
+
};
|
|
8672
|
+
}
|
|
8673
|
+
return prevPositions;
|
|
8674
|
+
},
|
|
8675
|
+
{
|
|
8676
|
+
revalidate: false
|
|
8677
|
+
}
|
|
8678
|
+
);
|
|
8679
|
+
useSWR5.mutate(
|
|
8680
|
+
leveragesKey,
|
|
8681
|
+
(prev) => {
|
|
8682
|
+
if (!prev) {
|
|
8683
|
+
return [
|
|
8684
|
+
{
|
|
8685
|
+
symbol,
|
|
8686
|
+
leverage,
|
|
8687
|
+
margin_mode: marginMode
|
|
8688
|
+
}
|
|
8689
|
+
];
|
|
8690
|
+
}
|
|
8691
|
+
const index = prev.findIndex(
|
|
8692
|
+
(item) => item.symbol === symbol && (item.margin_mode ?? types.MarginMode.CROSS) === (marginMode ?? types.MarginMode.CROSS)
|
|
8693
|
+
);
|
|
8694
|
+
if (index === -1) {
|
|
8695
|
+
return [
|
|
8696
|
+
...prev,
|
|
8697
|
+
{
|
|
8698
|
+
symbol,
|
|
8699
|
+
leverage,
|
|
8700
|
+
margin_mode: marginMode
|
|
8701
|
+
}
|
|
8702
|
+
];
|
|
8703
|
+
}
|
|
8704
|
+
const next = [...prev];
|
|
8705
|
+
next[index] = {
|
|
8706
|
+
...next[index],
|
|
8707
|
+
leverage
|
|
8708
|
+
};
|
|
8709
|
+
return next;
|
|
8710
|
+
},
|
|
8711
|
+
{
|
|
8712
|
+
revalidate: false
|
|
8713
|
+
}
|
|
8714
|
+
);
|
|
8715
|
+
}
|
|
8716
|
+
});
|
|
8717
|
+
return () => unsubscribe?.();
|
|
8718
|
+
}, [state.accountId]);
|
|
8719
|
+
React.useEffect(() => {
|
|
8720
|
+
if (!state.accountId) {
|
|
8721
|
+
return;
|
|
8722
|
+
}
|
|
8723
|
+
const key = ["/v1/positions", state.accountId];
|
|
8724
|
+
const unsubscribe = ws.privateSubscribe("position", {
|
|
8725
|
+
onMessage: (data) => {
|
|
8726
|
+
const { positions: nextPositions } = data;
|
|
8727
|
+
useSWR5.mutate(
|
|
8728
|
+
key,
|
|
8729
|
+
(prevPositions) => {
|
|
8730
|
+
if (!!prevPositions) {
|
|
8731
|
+
const newPositions = {
|
|
8732
|
+
...prevPositions,
|
|
8733
|
+
rows: prevPositions.rows.map((row) => {
|
|
8734
|
+
const itemIndex = nextPositions.findIndex(
|
|
8735
|
+
(item) => item.symbol === row.symbol && item.marginMode === row.margin_mode
|
|
8736
|
+
);
|
|
8737
|
+
if (itemIndex >= 0) {
|
|
8738
|
+
const itemArr = nextPositions.splice(itemIndex, 1);
|
|
8739
|
+
const item = itemArr[0];
|
|
8491
8740
|
if (item.averageOpenPrice === 0 && item.positionQty !== 0) {
|
|
8492
8741
|
return row;
|
|
8493
8742
|
}
|
|
@@ -8666,6 +8915,61 @@ var OrderValidation = class {
|
|
|
8666
8915
|
|
|
8667
8916
|
// src/services/orderCreator/baseCreator.ts
|
|
8668
8917
|
var BaseOrderCreator = class {
|
|
8918
|
+
/**
|
|
8919
|
+
* Template method for order creation
|
|
8920
|
+
* Defines the algorithm structure with hooks for subclasses
|
|
8921
|
+
*/
|
|
8922
|
+
create(values, config) {
|
|
8923
|
+
this.beforeCreate(values, config);
|
|
8924
|
+
const order = this.buildOrder(values, config);
|
|
8925
|
+
return this.afterCreate(order, config);
|
|
8926
|
+
}
|
|
8927
|
+
/**
|
|
8928
|
+
* Template method for order validation
|
|
8929
|
+
* Defines the algorithm structure with hooks for subclasses
|
|
8930
|
+
*/
|
|
8931
|
+
validate(values, config) {
|
|
8932
|
+
this.beforeValidate(values, config);
|
|
8933
|
+
const errors = this.runValidations(values, config);
|
|
8934
|
+
return Promise.resolve(this.afterValidate(errors, values, config));
|
|
8935
|
+
}
|
|
8936
|
+
/**
|
|
8937
|
+
* Hook method called before order creation
|
|
8938
|
+
* Subclasses can override to perform pre-creation setup
|
|
8939
|
+
* @param values - Order values
|
|
8940
|
+
* @param config - Configuration
|
|
8941
|
+
*/
|
|
8942
|
+
beforeCreate(values, config) {
|
|
8943
|
+
}
|
|
8944
|
+
/**
|
|
8945
|
+
* Hook method called after order creation
|
|
8946
|
+
* Subclasses can override to perform post-creation processing
|
|
8947
|
+
* @param order - The created order
|
|
8948
|
+
* @param config - Configuration
|
|
8949
|
+
* @returns The final order (possibly modified)
|
|
8950
|
+
*/
|
|
8951
|
+
afterCreate(order, config) {
|
|
8952
|
+
return order;
|
|
8953
|
+
}
|
|
8954
|
+
/**
|
|
8955
|
+
* Hook method called before validation
|
|
8956
|
+
* Subclasses can override to perform pre-validation setup
|
|
8957
|
+
* @param values - Order values to validate
|
|
8958
|
+
* @param config - Configuration
|
|
8959
|
+
*/
|
|
8960
|
+
beforeValidate(values, config) {
|
|
8961
|
+
}
|
|
8962
|
+
/**
|
|
8963
|
+
* Hook method called after validation
|
|
8964
|
+
* Subclasses can override to perform post-validation processing
|
|
8965
|
+
* @param errors - Validation errors found
|
|
8966
|
+
* @param values - Original order values
|
|
8967
|
+
* @param config - Configuration
|
|
8968
|
+
* @returns Final validation result (possibly modified)
|
|
8969
|
+
*/
|
|
8970
|
+
afterValidate(errors, values, config) {
|
|
8971
|
+
return errors;
|
|
8972
|
+
}
|
|
8669
8973
|
baseOrder(data) {
|
|
8670
8974
|
const order = {
|
|
8671
8975
|
symbol: data.symbol,
|
|
@@ -8673,7 +8977,8 @@ var BaseOrderCreator = class {
|
|
|
8673
8977
|
side: data.side,
|
|
8674
8978
|
reduce_only: data.reduce_only,
|
|
8675
8979
|
order_quantity: data.order_quantity,
|
|
8676
|
-
total: data.total
|
|
8980
|
+
total: data.total,
|
|
8981
|
+
margin_mode: data.margin_mode || types.MarginMode.CROSS
|
|
8677
8982
|
// slippage: data.slippage,
|
|
8678
8983
|
};
|
|
8679
8984
|
if (data.order_type === types.OrderType.MARKET && !!data.slippage) {
|
|
@@ -8692,10 +8997,21 @@ var BaseOrderCreator = class {
|
|
|
8692
8997
|
child_orders: [bracketOrder]
|
|
8693
8998
|
};
|
|
8694
8999
|
}
|
|
9000
|
+
/**
|
|
9001
|
+
* Base validation method that can be called by subclasses
|
|
9002
|
+
* Validates common order properties like quantity and min notional
|
|
9003
|
+
* @param values - Order values to validate
|
|
9004
|
+
* @param configs - Configuration
|
|
9005
|
+
* @returns Validation result (synchronous, not a Promise)
|
|
9006
|
+
*/
|
|
8695
9007
|
baseValidate(values, configs) {
|
|
8696
9008
|
const errors = {};
|
|
8697
9009
|
const { maxQty, symbol, markPrice } = configs;
|
|
8698
|
-
let
|
|
9010
|
+
let order_quantity = values.order_quantity;
|
|
9011
|
+
const total = values.total;
|
|
9012
|
+
const order_price = values.order_price;
|
|
9013
|
+
const reduce_only = values.reduce_only;
|
|
9014
|
+
const order_type = values.order_type;
|
|
8699
9015
|
const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
|
|
8700
9016
|
if (!order_quantity) {
|
|
8701
9017
|
if (total && order_price) {
|
|
@@ -8740,7 +9056,7 @@ var BaseOrderCreator = class {
|
|
|
8740
9056
|
};
|
|
8741
9057
|
}
|
|
8742
9058
|
this.validateBracketOrder(values, configs, errors);
|
|
8743
|
-
return
|
|
9059
|
+
return errors;
|
|
8744
9060
|
}
|
|
8745
9061
|
totalToQuantity(order, config) {
|
|
8746
9062
|
if (!order.order_quantity && order.total && order.order_price) {
|
|
@@ -8889,7 +9205,11 @@ var BBOOrderCreator = class extends BaseOrderCreator {
|
|
|
8889
9205
|
super(...arguments);
|
|
8890
9206
|
this.orderType = types.OrderType.LIMIT;
|
|
8891
9207
|
}
|
|
8892
|
-
|
|
9208
|
+
/**
|
|
9209
|
+
* Builds the BBO order
|
|
9210
|
+
* Implements template method hook
|
|
9211
|
+
*/
|
|
9212
|
+
buildOrder(values) {
|
|
8893
9213
|
const order = {
|
|
8894
9214
|
...this.baseOrder(values),
|
|
8895
9215
|
level: values.level
|
|
@@ -8902,15 +9222,18 @@ var BBOOrderCreator = class extends BaseOrderCreator {
|
|
|
8902
9222
|
"reduce_only",
|
|
8903
9223
|
"side",
|
|
8904
9224
|
"order_type",
|
|
9225
|
+
"margin_mode",
|
|
8905
9226
|
"level"
|
|
8906
9227
|
],
|
|
8907
9228
|
order
|
|
8908
9229
|
);
|
|
8909
9230
|
}
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
9231
|
+
/**
|
|
9232
|
+
* Runs base validations
|
|
9233
|
+
* Implements template method hook
|
|
9234
|
+
*/
|
|
9235
|
+
runValidations(values, configs) {
|
|
9236
|
+
return this.baseValidate(values, configs);
|
|
8914
9237
|
}
|
|
8915
9238
|
};
|
|
8916
9239
|
function getOrderPrice(order, askAndBid) {
|
|
@@ -8937,6 +9260,24 @@ function getOrderPrice(order, askAndBid) {
|
|
|
8937
9260
|
}
|
|
8938
9261
|
}
|
|
8939
9262
|
}
|
|
9263
|
+
perp.order.getOrderReferencePrice;
|
|
9264
|
+
function getOrderReferencePriceFromOrder(order, askAndBid) {
|
|
9265
|
+
if (!askAndBid || askAndBid.length < 2) return null;
|
|
9266
|
+
if (!order.order_type || !order.side) {
|
|
9267
|
+
return null;
|
|
9268
|
+
}
|
|
9269
|
+
return perp.order.getOrderReferencePrice(
|
|
9270
|
+
{
|
|
9271
|
+
orderType: order.order_type,
|
|
9272
|
+
orderTypeExt: order.order_type_ext,
|
|
9273
|
+
side: order.side,
|
|
9274
|
+
limitPrice: order.order_price ? Number(order.order_price) : void 0,
|
|
9275
|
+
triggerPrice: order.trigger_price ? Number(order.trigger_price) : void 0
|
|
9276
|
+
},
|
|
9277
|
+
askAndBid[0],
|
|
9278
|
+
askAndBid[1]
|
|
9279
|
+
);
|
|
9280
|
+
}
|
|
8940
9281
|
function getPriceRange(inputs) {
|
|
8941
9282
|
const { basePrice, side, symbolInfo } = inputs;
|
|
8942
9283
|
const { price_range, price_scope, quote_min, quote_max } = symbolInfo;
|
|
@@ -8950,97 +9291,170 @@ function getPriceRange(inputs) {
|
|
|
8950
9291
|
min: minPriceNumber,
|
|
8951
9292
|
max: scopePriceNumber
|
|
8952
9293
|
};
|
|
8953
|
-
const
|
|
8954
|
-
const
|
|
9294
|
+
const minPrice = Math.max(quote_min, priceRange?.min);
|
|
9295
|
+
const maxPrice = Math.min(quote_max, priceRange?.max);
|
|
8955
9296
|
return {
|
|
8956
|
-
minPrice
|
|
8957
|
-
maxPrice
|
|
9297
|
+
minPrice,
|
|
9298
|
+
maxPrice
|
|
8958
9299
|
};
|
|
8959
9300
|
}
|
|
8960
9301
|
|
|
8961
|
-
// src/services/orderCreator/
|
|
9302
|
+
// src/services/orderCreator/validators/TPSLValidationStrategy.ts
|
|
8962
9303
|
var formatPrice = (price, quote_dp) => {
|
|
8963
9304
|
return new utils.Decimal(price).toDecimalPlaces(quote_dp).toNumber();
|
|
8964
9305
|
};
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8986
|
-
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8993
|
-
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9306
|
+
var TPSLValidationStrategy = class {
|
|
9307
|
+
/**
|
|
9308
|
+
* Validates TP/SL order values
|
|
9309
|
+
* @param values - TP/SL order values including trigger prices, order prices, etc.
|
|
9310
|
+
* @param config - Configuration with symbol info and mark price
|
|
9311
|
+
* @returns Validation result object with any errors found
|
|
9312
|
+
*/
|
|
9313
|
+
validate(values, config) {
|
|
9314
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
9315
|
+
const {
|
|
9316
|
+
tp_trigger_price,
|
|
9317
|
+
tp_order_price,
|
|
9318
|
+
tp_order_type,
|
|
9319
|
+
sl_trigger_price,
|
|
9320
|
+
sl_order_price,
|
|
9321
|
+
sl_order_type,
|
|
9322
|
+
side,
|
|
9323
|
+
quantity,
|
|
9324
|
+
order_type,
|
|
9325
|
+
order_price
|
|
9326
|
+
} = values;
|
|
9327
|
+
const qty = Number(quantity);
|
|
9328
|
+
const maxQty = config.maxQty;
|
|
9329
|
+
const { quote_max, quote_min, quote_dp, base_min } = config.symbol ?? {};
|
|
9330
|
+
const mark_price = order_type === types.OrderType.MARKET || order_type == null ? config.markPrice : order_price ? Number(order_price) : void 0;
|
|
9331
|
+
const tpslSide = side === types.OrderSide.BUY ? types.OrderSide.SELL : types.OrderSide.BUY;
|
|
9332
|
+
if (!isNaN(qty) && qty > maxQty) {
|
|
9333
|
+
result.quantity = OrderValidation.max("quantity", config.maxQty);
|
|
9334
|
+
}
|
|
9335
|
+
if (!isNaN(qty) && qty < (base_min ?? 0)) {
|
|
9336
|
+
result.quantity = OrderValidation.min("quantity", base_min ?? 0);
|
|
9337
|
+
}
|
|
9338
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null && Number(tp_trigger_price) < 0) {
|
|
9339
|
+
result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
|
|
9340
|
+
}
|
|
9341
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null && Number(sl_trigger_price) < 0) {
|
|
9342
|
+
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
9343
|
+
}
|
|
9344
|
+
if (tp_order_type === types.OrderType.LIMIT && !tp_order_price) {
|
|
9345
|
+
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
9346
|
+
}
|
|
9347
|
+
if (sl_order_type === types.OrderType.LIMIT && !sl_order_price) {
|
|
9348
|
+
result.sl_order_price = OrderValidation.required("sl_order_price");
|
|
9349
|
+
}
|
|
9350
|
+
if (side === types.OrderSide.BUY && mark_price) {
|
|
9351
|
+
this.validateBuySide(
|
|
9352
|
+
{
|
|
9353
|
+
tp_trigger_price,
|
|
9354
|
+
tp_order_price,
|
|
9355
|
+
sl_trigger_price,
|
|
9356
|
+
sl_order_price
|
|
9357
|
+
},
|
|
9358
|
+
{
|
|
9359
|
+
mark_price,
|
|
9360
|
+
quote_min: quote_min ?? 0,
|
|
9361
|
+
quote_max: quote_max ?? 0,
|
|
9362
|
+
quote_dp: quote_dp ?? 0,
|
|
9363
|
+
tpslSide,
|
|
9364
|
+
symbol: config.symbol
|
|
9365
|
+
},
|
|
9366
|
+
result
|
|
9005
9367
|
);
|
|
9006
|
-
}
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9368
|
+
} else if (side === types.OrderSide.SELL && mark_price) {
|
|
9369
|
+
this.validateSellSide(
|
|
9370
|
+
{
|
|
9371
|
+
tp_trigger_price,
|
|
9372
|
+
tp_order_price,
|
|
9373
|
+
sl_trigger_price,
|
|
9374
|
+
sl_order_price
|
|
9375
|
+
},
|
|
9376
|
+
{
|
|
9377
|
+
mark_price,
|
|
9378
|
+
quote_min: quote_min ?? 0,
|
|
9379
|
+
quote_max: quote_max ?? 0,
|
|
9380
|
+
quote_dp: quote_dp ?? 0,
|
|
9381
|
+
tpslSide,
|
|
9382
|
+
symbol: config.symbol
|
|
9383
|
+
},
|
|
9384
|
+
result
|
|
9011
9385
|
);
|
|
9012
9386
|
}
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
|
|
9387
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
9388
|
+
}
|
|
9389
|
+
/**
|
|
9390
|
+
* Validates TP/SL for BUY orders
|
|
9391
|
+
* For BUY orders:
|
|
9392
|
+
* - SL trigger price must be < mark price
|
|
9393
|
+
* - TP trigger price must be > mark price
|
|
9394
|
+
*/
|
|
9395
|
+
validateBuySide(prices, config, result) {
|
|
9396
|
+
const {
|
|
9397
|
+
tp_trigger_price,
|
|
9398
|
+
tp_order_price,
|
|
9399
|
+
sl_trigger_price,
|
|
9400
|
+
sl_order_price
|
|
9401
|
+
} = prices;
|
|
9402
|
+
const { mark_price, quote_min, quote_max, quote_dp, tpslSide, symbol } = config;
|
|
9403
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null) {
|
|
9404
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9405
|
+
if (!isNaN(slTrigger)) {
|
|
9406
|
+
if (quote_min > 0 && slTrigger < quote_min) {
|
|
9407
|
+
result.sl_trigger_price = OrderValidation.min(
|
|
9408
|
+
"sl_trigger_price",
|
|
9409
|
+
formatPrice(quote_min, quote_dp)
|
|
9410
|
+
);
|
|
9411
|
+
}
|
|
9412
|
+
if (slTrigger >= mark_price) {
|
|
9413
|
+
result.sl_trigger_price = OrderValidation.max(
|
|
9414
|
+
"sl_trigger_price",
|
|
9415
|
+
formatPrice(mark_price, quote_dp)
|
|
9416
|
+
);
|
|
9417
|
+
}
|
|
9418
|
+
}
|
|
9018
9419
|
}
|
|
9019
|
-
if (
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
|
|
9023
|
-
|
|
9420
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null) {
|
|
9421
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9422
|
+
if (!isNaN(tpTrigger)) {
|
|
9423
|
+
if (tpTrigger <= mark_price) {
|
|
9424
|
+
result.tp_trigger_price = OrderValidation.min(
|
|
9425
|
+
"tp_trigger_price",
|
|
9426
|
+
formatPrice(mark_price, quote_dp)
|
|
9427
|
+
);
|
|
9428
|
+
}
|
|
9429
|
+
if (quote_max > 0 && tpTrigger > quote_max) {
|
|
9430
|
+
result.tp_trigger_price = OrderValidation.max(
|
|
9431
|
+
"tp_trigger_price",
|
|
9432
|
+
formatPrice(quote_max, quote_dp)
|
|
9433
|
+
);
|
|
9434
|
+
}
|
|
9435
|
+
}
|
|
9024
9436
|
}
|
|
9025
9437
|
if (sl_trigger_price && sl_order_price) {
|
|
9026
9438
|
const priceRange = getPriceRange({
|
|
9027
9439
|
side: tpslSide,
|
|
9028
9440
|
basePrice: Number(sl_trigger_price),
|
|
9029
|
-
symbolInfo:
|
|
9441
|
+
symbolInfo: symbol
|
|
9030
9442
|
});
|
|
9031
|
-
|
|
9443
|
+
const slOrderPrice = Number(sl_order_price);
|
|
9444
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9445
|
+
if (slOrderPrice < priceRange.minPrice) {
|
|
9032
9446
|
result.sl_order_price = OrderValidation.min(
|
|
9033
9447
|
"sl_order_price",
|
|
9034
9448
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9035
9449
|
);
|
|
9036
9450
|
}
|
|
9037
|
-
if (
|
|
9451
|
+
if (slOrderPrice > priceRange.maxPrice) {
|
|
9038
9452
|
result.sl_order_price = OrderValidation.max(
|
|
9039
9453
|
"sl_order_price",
|
|
9040
9454
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9041
9455
|
);
|
|
9042
9456
|
}
|
|
9043
|
-
if (
|
|
9457
|
+
if (slTrigger < slOrderPrice) {
|
|
9044
9458
|
result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
|
|
9045
9459
|
}
|
|
9046
9460
|
}
|
|
@@ -9048,69 +9462,96 @@ async function bracketOrderValidator(values, config) {
|
|
|
9048
9462
|
const priceRange = getPriceRange({
|
|
9049
9463
|
side: tpslSide,
|
|
9050
9464
|
basePrice: Number(tp_trigger_price),
|
|
9051
|
-
symbolInfo:
|
|
9465
|
+
symbolInfo: symbol
|
|
9052
9466
|
});
|
|
9053
|
-
|
|
9467
|
+
const tpOrderPrice = Number(tp_order_price);
|
|
9468
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9469
|
+
if (tpOrderPrice > priceRange.maxPrice) {
|
|
9054
9470
|
result.tp_order_price = OrderValidation.max(
|
|
9055
9471
|
"tp_order_price",
|
|
9056
9472
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9057
9473
|
);
|
|
9058
9474
|
}
|
|
9059
|
-
if (
|
|
9475
|
+
if (tpOrderPrice < priceRange.minPrice) {
|
|
9060
9476
|
result.tp_order_price = OrderValidation.min(
|
|
9061
9477
|
"tp_order_price",
|
|
9062
9478
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9063
9479
|
);
|
|
9064
9480
|
}
|
|
9065
|
-
if (
|
|
9481
|
+
if (tpTrigger > tpOrderPrice) {
|
|
9066
9482
|
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9067
9483
|
}
|
|
9068
9484
|
}
|
|
9069
9485
|
}
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
}
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
|
|
9086
|
-
|
|
9087
|
-
|
|
9486
|
+
/**
|
|
9487
|
+
* Validates TP/SL for SELL orders
|
|
9488
|
+
* For SELL orders:
|
|
9489
|
+
* - SL trigger price must be > mark price
|
|
9490
|
+
* - TP trigger price must be < mark price
|
|
9491
|
+
*/
|
|
9492
|
+
validateSellSide(prices, config, result) {
|
|
9493
|
+
const {
|
|
9494
|
+
tp_trigger_price,
|
|
9495
|
+
tp_order_price,
|
|
9496
|
+
sl_trigger_price,
|
|
9497
|
+
sl_order_price
|
|
9498
|
+
} = prices;
|
|
9499
|
+
const { mark_price, quote_min, quote_max, quote_dp, tpslSide, symbol } = config;
|
|
9500
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null) {
|
|
9501
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9502
|
+
if (!isNaN(slTrigger)) {
|
|
9503
|
+
if (quote_max > 0 && slTrigger > quote_max) {
|
|
9504
|
+
result.sl_trigger_price = OrderValidation.max(
|
|
9505
|
+
"sl_trigger_price",
|
|
9506
|
+
formatPrice(quote_max, quote_dp)
|
|
9507
|
+
);
|
|
9508
|
+
}
|
|
9509
|
+
if (slTrigger <= mark_price) {
|
|
9510
|
+
result.sl_trigger_price = OrderValidation.min(
|
|
9511
|
+
"sl_trigger_price",
|
|
9512
|
+
formatPrice(mark_price, quote_dp)
|
|
9513
|
+
);
|
|
9514
|
+
}
|
|
9515
|
+
}
|
|
9088
9516
|
}
|
|
9089
|
-
if (
|
|
9090
|
-
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
|
|
9517
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null) {
|
|
9518
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9519
|
+
if (!isNaN(tpTrigger)) {
|
|
9520
|
+
if (tpTrigger >= mark_price) {
|
|
9521
|
+
result.tp_trigger_price = OrderValidation.max(
|
|
9522
|
+
"tp_trigger_price",
|
|
9523
|
+
formatPrice(mark_price, quote_dp)
|
|
9524
|
+
);
|
|
9525
|
+
}
|
|
9526
|
+
if (quote_min > 0 && tpTrigger < quote_min) {
|
|
9527
|
+
result.tp_trigger_price = OrderValidation.min(
|
|
9528
|
+
"tp_trigger_price",
|
|
9529
|
+
formatPrice(quote_min, quote_dp)
|
|
9530
|
+
);
|
|
9531
|
+
}
|
|
9532
|
+
}
|
|
9094
9533
|
}
|
|
9095
9534
|
if (sl_trigger_price && sl_order_price) {
|
|
9096
9535
|
const priceRange = getPriceRange({
|
|
9097
9536
|
side: tpslSide,
|
|
9098
9537
|
basePrice: Number(sl_trigger_price),
|
|
9099
|
-
symbolInfo:
|
|
9538
|
+
symbolInfo: symbol
|
|
9100
9539
|
});
|
|
9101
|
-
|
|
9540
|
+
const slOrderPrice = Number(sl_order_price);
|
|
9541
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9542
|
+
if (slOrderPrice < priceRange.minPrice) {
|
|
9102
9543
|
result.sl_order_price = OrderValidation.min(
|
|
9103
9544
|
"sl_order_price",
|
|
9104
9545
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9105
9546
|
);
|
|
9106
9547
|
}
|
|
9107
|
-
if (
|
|
9548
|
+
if (slOrderPrice > priceRange.maxPrice) {
|
|
9108
9549
|
result.sl_order_price = OrderValidation.max(
|
|
9109
9550
|
"sl_order_price",
|
|
9110
9551
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9111
9552
|
);
|
|
9112
9553
|
}
|
|
9113
|
-
if (
|
|
9554
|
+
if (slTrigger > slOrderPrice) {
|
|
9114
9555
|
result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
|
|
9115
9556
|
}
|
|
9116
9557
|
}
|
|
@@ -9118,37 +9559,294 @@ async function bracketOrderValidator(values, config) {
|
|
|
9118
9559
|
const priceRange = getPriceRange({
|
|
9119
9560
|
side: tpslSide,
|
|
9120
9561
|
basePrice: Number(tp_trigger_price),
|
|
9121
|
-
symbolInfo:
|
|
9562
|
+
symbolInfo: symbol
|
|
9122
9563
|
});
|
|
9123
|
-
|
|
9564
|
+
const tpOrderPrice = Number(tp_order_price);
|
|
9565
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9566
|
+
if (tpOrderPrice < priceRange.minPrice) {
|
|
9124
9567
|
result.tp_order_price = OrderValidation.min(
|
|
9125
9568
|
"tp_order_price",
|
|
9126
9569
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9127
9570
|
);
|
|
9128
9571
|
}
|
|
9129
|
-
if (
|
|
9572
|
+
if (tpOrderPrice > priceRange.maxPrice) {
|
|
9130
9573
|
result.tp_order_price = OrderValidation.max(
|
|
9131
9574
|
"tp_order_price",
|
|
9132
9575
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9133
9576
|
);
|
|
9134
9577
|
}
|
|
9135
|
-
if (
|
|
9578
|
+
if (tpTrigger < tpOrderPrice) {
|
|
9136
9579
|
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9137
9580
|
}
|
|
9138
9581
|
}
|
|
9139
9582
|
}
|
|
9140
|
-
|
|
9583
|
+
};
|
|
9584
|
+
|
|
9585
|
+
// src/services/orderCreator/baseBracketOrderCreator.ts
|
|
9586
|
+
async function bracketOrderValidator(values, config) {
|
|
9587
|
+
const strategy = new TPSLValidationStrategy();
|
|
9588
|
+
return strategy.validate(values, config);
|
|
9141
9589
|
}
|
|
9142
|
-
|
|
9590
|
+
|
|
9591
|
+
// src/services/orderCreator/validators/BaseValidator.ts
|
|
9592
|
+
var BaseValidator = class {
|
|
9593
|
+
/**
|
|
9594
|
+
* Sets the next validator in the chain
|
|
9595
|
+
* @param validator - The next validator to call
|
|
9596
|
+
* @returns The next validator for method chaining
|
|
9597
|
+
*/
|
|
9598
|
+
setNext(validator) {
|
|
9599
|
+
this.next = validator;
|
|
9600
|
+
return validator;
|
|
9601
|
+
}
|
|
9602
|
+
/**
|
|
9603
|
+
* Validates values and passes to next validator in chain
|
|
9604
|
+
* @param values - The values to validate
|
|
9605
|
+
* @param config - Configuration for validation
|
|
9606
|
+
* @param errors - Accumulated validation errors
|
|
9607
|
+
* @returns Updated validation result
|
|
9608
|
+
*/
|
|
9609
|
+
validate(values, config, errors) {
|
|
9610
|
+
const result = this.doValidate(values, config);
|
|
9611
|
+
if (result) {
|
|
9612
|
+
errors[this.getFieldName()] = result;
|
|
9613
|
+
}
|
|
9614
|
+
return this.next?.validate(values, config, errors) ?? errors;
|
|
9615
|
+
}
|
|
9616
|
+
};
|
|
9617
|
+
var PriceValidationStrategy = class {
|
|
9618
|
+
/**
|
|
9619
|
+
* Validates order price against symbol constraints and price range
|
|
9620
|
+
* @param values - Object containing order_price, side, and order_type
|
|
9621
|
+
* @param config - Configuration with symbol info and mark price
|
|
9622
|
+
* @returns Validation error if price is invalid, undefined otherwise
|
|
9623
|
+
*/
|
|
9624
|
+
validate(values, config) {
|
|
9625
|
+
const { order_price, side } = values;
|
|
9626
|
+
if (!order_price) {
|
|
9627
|
+
return OrderValidation.required("order_price");
|
|
9628
|
+
}
|
|
9629
|
+
const price = new utils.Decimal(order_price);
|
|
9630
|
+
const { symbol } = config;
|
|
9631
|
+
const { quote_max, quote_min, quote_dp, price_range, price_scope } = symbol;
|
|
9632
|
+
const maxPriceNumber = perp.order.maxPrice(config.markPrice, price_range);
|
|
9633
|
+
const minPriceNumber = perp.order.minPrice(config.markPrice, price_range);
|
|
9634
|
+
const scopePriceNumber = perp.order.scopePrice(
|
|
9635
|
+
config.markPrice,
|
|
9636
|
+
price_scope,
|
|
9637
|
+
side
|
|
9638
|
+
);
|
|
9639
|
+
const priceRange = side === types.OrderSide.BUY ? {
|
|
9640
|
+
min: scopePriceNumber,
|
|
9641
|
+
max: maxPriceNumber
|
|
9642
|
+
} : {
|
|
9643
|
+
min: minPriceNumber,
|
|
9644
|
+
max: scopePriceNumber
|
|
9645
|
+
};
|
|
9646
|
+
if (price.gt(quote_max)) {
|
|
9647
|
+
return OrderValidation.max("order_price", quote_max);
|
|
9648
|
+
}
|
|
9649
|
+
if (price.lt(quote_min)) {
|
|
9650
|
+
return OrderValidation.min("order_price", quote_min);
|
|
9651
|
+
}
|
|
9652
|
+
if (price.gt(priceRange.max)) {
|
|
9653
|
+
return OrderValidation.max(
|
|
9654
|
+
"order_price",
|
|
9655
|
+
new utils.Decimal(priceRange.max).todp(quote_dp).toString()
|
|
9656
|
+
);
|
|
9657
|
+
}
|
|
9658
|
+
if (price.lt(priceRange.min)) {
|
|
9659
|
+
return OrderValidation.min(
|
|
9660
|
+
"order_price",
|
|
9661
|
+
new utils.Decimal(priceRange.min).todp(quote_dp).toString()
|
|
9662
|
+
);
|
|
9663
|
+
}
|
|
9664
|
+
return void 0;
|
|
9665
|
+
}
|
|
9666
|
+
};
|
|
9667
|
+
var TriggerPriceValidationStrategy = class {
|
|
9668
|
+
/**
|
|
9669
|
+
* Validates trigger price against symbol constraints
|
|
9670
|
+
* @param values - Object containing trigger_price
|
|
9671
|
+
* @param config - Configuration with symbol info
|
|
9672
|
+
* @returns Validation error if trigger price is invalid, undefined otherwise
|
|
9673
|
+
*/
|
|
9674
|
+
validate(values, config) {
|
|
9675
|
+
const { trigger_price } = values;
|
|
9676
|
+
const { symbol } = config;
|
|
9677
|
+
const { quote_max, quote_min } = symbol;
|
|
9678
|
+
if (!trigger_price) {
|
|
9679
|
+
return OrderValidation.required("trigger_price");
|
|
9680
|
+
}
|
|
9681
|
+
const triggerPrice = Number(trigger_price);
|
|
9682
|
+
if (triggerPrice > quote_max) {
|
|
9683
|
+
return OrderValidation.max("trigger_price", quote_max);
|
|
9684
|
+
}
|
|
9685
|
+
if (triggerPrice < quote_min || triggerPrice === 0) {
|
|
9686
|
+
return OrderValidation.min("trigger_price", quote_min);
|
|
9687
|
+
}
|
|
9688
|
+
return void 0;
|
|
9689
|
+
}
|
|
9690
|
+
};
|
|
9691
|
+
|
|
9692
|
+
// src/services/orderCreator/validators/PriceValidator.ts
|
|
9693
|
+
var PriceValidator = class extends BaseValidator {
|
|
9694
|
+
constructor() {
|
|
9695
|
+
super();
|
|
9696
|
+
this.strategy = new PriceValidationStrategy();
|
|
9697
|
+
}
|
|
9698
|
+
doValidate(values, config) {
|
|
9699
|
+
return this.strategy.validate(
|
|
9700
|
+
{
|
|
9701
|
+
order_price: values.order_price,
|
|
9702
|
+
side: values.side,
|
|
9703
|
+
order_type: values.order_type
|
|
9704
|
+
},
|
|
9705
|
+
config
|
|
9706
|
+
);
|
|
9707
|
+
}
|
|
9708
|
+
getFieldName() {
|
|
9709
|
+
return "order_price";
|
|
9710
|
+
}
|
|
9711
|
+
};
|
|
9712
|
+
var QuantityValidationStrategy = class {
|
|
9713
|
+
/**
|
|
9714
|
+
* Validates order quantity against symbol constraints
|
|
9715
|
+
* Also handles conversion from total to quantity if needed
|
|
9716
|
+
* @param values - Object containing order_quantity, total, and order_price
|
|
9717
|
+
* @param config - Configuration with symbol info and max quantity
|
|
9718
|
+
* @returns Validation error if quantity is invalid, undefined otherwise
|
|
9719
|
+
*/
|
|
9720
|
+
validate(values, config) {
|
|
9721
|
+
let { order_quantity, total, order_price } = values;
|
|
9722
|
+
const { maxQty, symbol } = config;
|
|
9723
|
+
const { base_min, base_dp, quote_dp } = symbol;
|
|
9724
|
+
if (!order_quantity && total && order_price) {
|
|
9725
|
+
const totalNumber = new utils.Decimal(total);
|
|
9726
|
+
const qty2 = totalNumber.dividedBy(order_price).toFixed(quote_dp);
|
|
9727
|
+
order_quantity = qty2;
|
|
9728
|
+
}
|
|
9729
|
+
if (!order_quantity) {
|
|
9730
|
+
return OrderValidation.required("order_quantity");
|
|
9731
|
+
}
|
|
9732
|
+
const qty = new utils.Decimal(order_quantity);
|
|
9733
|
+
if (qty.lt(base_min)) {
|
|
9734
|
+
return OrderValidation.min(
|
|
9735
|
+
"order_quantity",
|
|
9736
|
+
new utils.Decimal(base_min).todp(base_dp).toString()
|
|
9737
|
+
);
|
|
9738
|
+
}
|
|
9739
|
+
if (qty.gt(maxQty)) {
|
|
9740
|
+
return OrderValidation.max(
|
|
9741
|
+
"order_quantity",
|
|
9742
|
+
new utils.Decimal(maxQty).todp(base_dp).toString()
|
|
9743
|
+
);
|
|
9744
|
+
}
|
|
9745
|
+
return void 0;
|
|
9746
|
+
}
|
|
9747
|
+
};
|
|
9748
|
+
|
|
9749
|
+
// src/services/orderCreator/validators/QuantityValidator.ts
|
|
9750
|
+
var QuantityValidator = class extends BaseValidator {
|
|
9751
|
+
constructor() {
|
|
9752
|
+
super();
|
|
9753
|
+
this.strategy = new QuantityValidationStrategy();
|
|
9754
|
+
}
|
|
9755
|
+
doValidate(values, config) {
|
|
9756
|
+
return this.strategy.validate(
|
|
9757
|
+
{
|
|
9758
|
+
order_quantity: values.order_quantity,
|
|
9759
|
+
total: values.total,
|
|
9760
|
+
order_price: values.order_price
|
|
9761
|
+
},
|
|
9762
|
+
config
|
|
9763
|
+
);
|
|
9764
|
+
}
|
|
9765
|
+
getFieldName() {
|
|
9766
|
+
return "order_quantity";
|
|
9767
|
+
}
|
|
9768
|
+
};
|
|
9769
|
+
|
|
9770
|
+
// src/services/orderCreator/validators/ValidationChain.ts
|
|
9771
|
+
var ValidationChain = class {
|
|
9772
|
+
constructor() {
|
|
9773
|
+
this.validators = [];
|
|
9774
|
+
}
|
|
9775
|
+
/**
|
|
9776
|
+
* Adds a validator to the chain
|
|
9777
|
+
* @param validator - The validator to add
|
|
9778
|
+
* @returns This chain instance for method chaining
|
|
9779
|
+
*/
|
|
9780
|
+
addValidator(validator) {
|
|
9781
|
+
this.validators.push(validator);
|
|
9782
|
+
if (!this.head) {
|
|
9783
|
+
this.head = validator;
|
|
9784
|
+
} else {
|
|
9785
|
+
let current = this.head;
|
|
9786
|
+
while (current && current.next) {
|
|
9787
|
+
current = current.next;
|
|
9788
|
+
}
|
|
9789
|
+
if (current) {
|
|
9790
|
+
current.setNext(validator);
|
|
9791
|
+
}
|
|
9792
|
+
}
|
|
9793
|
+
return this;
|
|
9794
|
+
}
|
|
9795
|
+
/**
|
|
9796
|
+
* Adds multiple validators to the chain
|
|
9797
|
+
* @param validators - Array of validators to add
|
|
9798
|
+
* @returns This chain instance for method chaining
|
|
9799
|
+
*/
|
|
9800
|
+
addValidators(validators) {
|
|
9801
|
+
validators.forEach((validator) => this.addValidator(validator));
|
|
9802
|
+
return this;
|
|
9803
|
+
}
|
|
9804
|
+
/**
|
|
9805
|
+
* Validates values using all validators in the chain
|
|
9806
|
+
* @param values - The values to validate
|
|
9807
|
+
* @param config - Configuration for validation
|
|
9808
|
+
* @returns Validation result with all errors found
|
|
9809
|
+
*/
|
|
9810
|
+
validate(values, config) {
|
|
9811
|
+
const errors = {};
|
|
9812
|
+
if (this.head) {
|
|
9813
|
+
return this.head.validate(values, config, errors);
|
|
9814
|
+
}
|
|
9815
|
+
return errors;
|
|
9816
|
+
}
|
|
9817
|
+
/**
|
|
9818
|
+
* Clears all validators from the chain
|
|
9819
|
+
*/
|
|
9820
|
+
clear() {
|
|
9821
|
+
this.validators = [];
|
|
9822
|
+
this.head = void 0;
|
|
9823
|
+
}
|
|
9824
|
+
/**
|
|
9825
|
+
* Gets the number of validators in the chain
|
|
9826
|
+
* @returns The number of validators
|
|
9827
|
+
*/
|
|
9828
|
+
get length() {
|
|
9829
|
+
return this.validators.length;
|
|
9830
|
+
}
|
|
9831
|
+
};
|
|
9832
|
+
|
|
9833
|
+
// src/services/orderCreator/limitOrderCreator.ts
|
|
9143
9834
|
var LimitOrderCreator = class extends BaseOrderCreator {
|
|
9144
9835
|
constructor() {
|
|
9145
9836
|
super(...arguments);
|
|
9837
|
+
// private priceValidationStrategy = new PriceValidationStrategy();
|
|
9838
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new PriceValidator());
|
|
9146
9839
|
this.orderType = types.OrderType.LIMIT;
|
|
9147
9840
|
}
|
|
9148
|
-
|
|
9841
|
+
/**
|
|
9842
|
+
* Builds the limit order
|
|
9843
|
+
* Implements template method hook
|
|
9844
|
+
*/
|
|
9845
|
+
buildOrder(values, config) {
|
|
9846
|
+
const orderlyValues = values;
|
|
9149
9847
|
const order = {
|
|
9150
|
-
...this.baseOrder(
|
|
9151
|
-
order_price:
|
|
9848
|
+
...this.baseOrder(orderlyValues),
|
|
9849
|
+
order_price: orderlyValues.order_price
|
|
9152
9850
|
};
|
|
9153
9851
|
this.totalToQuantity(order, config);
|
|
9154
9852
|
return ramda.pick(
|
|
@@ -9157,61 +9855,26 @@ var LimitOrderCreator = class extends BaseOrderCreator {
|
|
|
9157
9855
|
"order_price",
|
|
9158
9856
|
"order_quantity",
|
|
9159
9857
|
"visible_quantity",
|
|
9160
|
-
"reduce_only",
|
|
9161
|
-
"side",
|
|
9162
|
-
"order_type",
|
|
9163
|
-
"
|
|
9164
|
-
"
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
|
|
9173
|
-
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
const scopePriceNumber = scopePrice(
|
|
9181
|
-
config.markPrice,
|
|
9182
|
-
price_scope,
|
|
9183
|
-
side
|
|
9184
|
-
);
|
|
9185
|
-
const priceRange = side === "BUY" ? {
|
|
9186
|
-
min: scopePriceNumber,
|
|
9187
|
-
max: maxPriceNumber
|
|
9188
|
-
} : {
|
|
9189
|
-
min: minPriceNumber,
|
|
9190
|
-
max: scopePriceNumber
|
|
9191
|
-
};
|
|
9192
|
-
if (price.gt(quote_max)) {
|
|
9193
|
-
errors.order_price = OrderValidation.max("order_price", quote_max);
|
|
9194
|
-
} else {
|
|
9195
|
-
if (price.gt(priceRange?.max)) {
|
|
9196
|
-
errors.order_price = OrderValidation.max(
|
|
9197
|
-
"order_price",
|
|
9198
|
-
new utils.Decimal(priceRange.max).todp(symbol.quote_dp).toString()
|
|
9199
|
-
);
|
|
9200
|
-
}
|
|
9201
|
-
}
|
|
9202
|
-
if (price.lt(quote_min)) {
|
|
9203
|
-
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
9204
|
-
} else {
|
|
9205
|
-
if (price.lt(priceRange?.min)) {
|
|
9206
|
-
errors.order_price = OrderValidation.min(
|
|
9207
|
-
"order_price",
|
|
9208
|
-
new utils.Decimal(priceRange.min).todp(symbol.quote_dp).toString()
|
|
9209
|
-
);
|
|
9210
|
-
}
|
|
9211
|
-
}
|
|
9212
|
-
}
|
|
9213
|
-
return errors;
|
|
9214
|
-
});
|
|
9858
|
+
"reduce_only",
|
|
9859
|
+
"side",
|
|
9860
|
+
"order_type",
|
|
9861
|
+
"margin_mode",
|
|
9862
|
+
"algo_type",
|
|
9863
|
+
"child_orders"
|
|
9864
|
+
],
|
|
9865
|
+
order
|
|
9866
|
+
);
|
|
9867
|
+
}
|
|
9868
|
+
/**
|
|
9869
|
+
* Runs validations using validation chain
|
|
9870
|
+
* Implements template method hook
|
|
9871
|
+
*/
|
|
9872
|
+
runValidations(values, config) {
|
|
9873
|
+
const orderlyValues = values;
|
|
9874
|
+
const errors = this.baseValidate(orderlyValues, config);
|
|
9875
|
+
const chainErrors = this.validationChain.validate(orderlyValues, config);
|
|
9876
|
+
Object.assign(errors, chainErrors);
|
|
9877
|
+
return errors;
|
|
9215
9878
|
}
|
|
9216
9879
|
};
|
|
9217
9880
|
|
|
@@ -9234,34 +9897,81 @@ var BracketLimitOrderCreator = class extends LimitOrderCreator {
|
|
|
9234
9897
|
}
|
|
9235
9898
|
};
|
|
9236
9899
|
|
|
9900
|
+
// src/services/orderCreator/validators/SlippageValidationStrategy.ts
|
|
9901
|
+
var SlippageValidationStrategy = class {
|
|
9902
|
+
/**
|
|
9903
|
+
* Validates slippage against estimated slippage
|
|
9904
|
+
* @param values - Object containing slippage value
|
|
9905
|
+
* @param config - Configuration with estimated slippage
|
|
9906
|
+
* @returns Validation error if slippage exceeds estimated, undefined otherwise
|
|
9907
|
+
*/
|
|
9908
|
+
validate(values, config) {
|
|
9909
|
+
const slippage = Number(values.slippage);
|
|
9910
|
+
const estSlippage = Number.isNaN(config.estSlippage) ? 0 : Number(config.estSlippage) * 100;
|
|
9911
|
+
if (!isNaN(slippage) && estSlippage > slippage) {
|
|
9912
|
+
return {
|
|
9913
|
+
type: "max",
|
|
9914
|
+
message: "Estimated slippage exceeds your maximum allowed slippage.",
|
|
9915
|
+
value: estSlippage
|
|
9916
|
+
};
|
|
9917
|
+
}
|
|
9918
|
+
return void 0;
|
|
9919
|
+
}
|
|
9920
|
+
};
|
|
9921
|
+
|
|
9922
|
+
// src/services/orderCreator/validators/SlippageValidator.ts
|
|
9923
|
+
var SlippageValidator = class extends BaseValidator {
|
|
9924
|
+
constructor() {
|
|
9925
|
+
super();
|
|
9926
|
+
this.strategy = new SlippageValidationStrategy();
|
|
9927
|
+
}
|
|
9928
|
+
doValidate(values, config) {
|
|
9929
|
+
return this.strategy.validate(
|
|
9930
|
+
{
|
|
9931
|
+
slippage: values.slippage
|
|
9932
|
+
},
|
|
9933
|
+
config
|
|
9934
|
+
);
|
|
9935
|
+
}
|
|
9936
|
+
getFieldName() {
|
|
9937
|
+
return "slippage";
|
|
9938
|
+
}
|
|
9939
|
+
};
|
|
9940
|
+
|
|
9237
9941
|
// src/services/orderCreator/marketOrderCreator.ts
|
|
9238
9942
|
var MarketOrderCreator = class extends BaseOrderCreator {
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
delete data["isStopOrder"];
|
|
9245
|
-
return {
|
|
9246
|
-
...data
|
|
9247
|
-
};
|
|
9943
|
+
constructor() {
|
|
9944
|
+
super(...arguments);
|
|
9945
|
+
this.slippageValidationStrategy = new SlippageValidationStrategy();
|
|
9946
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new SlippageValidator());
|
|
9947
|
+
this.orderType = types.OrderType.MARKET;
|
|
9248
9948
|
}
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
9263
|
-
|
|
9264
|
-
|
|
9949
|
+
/**
|
|
9950
|
+
* Builds the market order
|
|
9951
|
+
* Implements template method hook
|
|
9952
|
+
*/
|
|
9953
|
+
buildOrder(values, config) {
|
|
9954
|
+
const orderlyValues = values;
|
|
9955
|
+
const data = this.baseOrder(orderlyValues);
|
|
9956
|
+
const result = { ...data };
|
|
9957
|
+
delete result.order_price;
|
|
9958
|
+
delete result.total;
|
|
9959
|
+
delete result.trigger_price;
|
|
9960
|
+
if ("isStopOrder" in result) {
|
|
9961
|
+
delete result.isStopOrder;
|
|
9962
|
+
}
|
|
9963
|
+
return result;
|
|
9964
|
+
}
|
|
9965
|
+
/**
|
|
9966
|
+
* Runs validations using validation chain
|
|
9967
|
+
* Implements template method hook
|
|
9968
|
+
*/
|
|
9969
|
+
runValidations(values, configs) {
|
|
9970
|
+
const orderlyValues = values;
|
|
9971
|
+
const result = this.baseValidate(orderlyValues, configs);
|
|
9972
|
+
const chainErrors = this.validationChain.validate(orderlyValues, configs);
|
|
9973
|
+
Object.assign(result, chainErrors);
|
|
9974
|
+
return result;
|
|
9265
9975
|
}
|
|
9266
9976
|
};
|
|
9267
9977
|
|
|
@@ -9293,14 +10003,26 @@ var FOKOrderCreator = class extends LimitOrderCreator {
|
|
|
9293
10003
|
|
|
9294
10004
|
// src/services/orderCreator/generalCreator.ts
|
|
9295
10005
|
var GeneralOrderCreator = class extends BaseOrderCreator {
|
|
9296
|
-
|
|
10006
|
+
constructor() {
|
|
10007
|
+
super(...arguments);
|
|
10008
|
+
this.orderType = void 0;
|
|
10009
|
+
}
|
|
10010
|
+
/**
|
|
10011
|
+
* Builds the general order
|
|
10012
|
+
* Implements template method hook
|
|
10013
|
+
*/
|
|
10014
|
+
buildOrder(data) {
|
|
9297
10015
|
return {
|
|
9298
10016
|
...this.baseOrder(data),
|
|
9299
10017
|
order_price: data.order_price,
|
|
9300
10018
|
order_quantity: data.order_quantity
|
|
9301
10019
|
};
|
|
9302
10020
|
}
|
|
9303
|
-
|
|
10021
|
+
/**
|
|
10022
|
+
* Runs base validations
|
|
10023
|
+
* Implements template method hook
|
|
10024
|
+
*/
|
|
10025
|
+
runValidations(values, configs) {
|
|
9304
10026
|
return super.baseValidate(values, configs);
|
|
9305
10027
|
}
|
|
9306
10028
|
};
|
|
@@ -9409,7 +10131,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
|
|
|
9409
10131
|
distribution_type,
|
|
9410
10132
|
skew,
|
|
9411
10133
|
reduce_only,
|
|
9412
|
-
visible_quantity
|
|
10134
|
+
visible_quantity,
|
|
10135
|
+
margin_mode
|
|
9413
10136
|
} = order;
|
|
9414
10137
|
const prices = calcScaledOrderPrices({
|
|
9415
10138
|
start_price,
|
|
@@ -9435,6 +10158,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
|
|
|
9435
10158
|
order_quantity: qtys[index],
|
|
9436
10159
|
order_price: price,
|
|
9437
10160
|
reduce_only,
|
|
10161
|
+
margin_mode: margin_mode || types.MarginMode.CROSS,
|
|
10162
|
+
// Default to CROSS if not provided for backward compatibility
|
|
9438
10163
|
// it will be used for identify the scaled order from ws
|
|
9439
10164
|
client_order_id: `scaled_${index}_${now}`
|
|
9440
10165
|
};
|
|
@@ -9538,7 +10263,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9538
10263
|
super(...arguments);
|
|
9539
10264
|
this.orderType = types.OrderType.SCALED;
|
|
9540
10265
|
}
|
|
9541
|
-
|
|
10266
|
+
/**
|
|
10267
|
+
* Builds the scaled order
|
|
10268
|
+
* Implements template method hook
|
|
10269
|
+
*/
|
|
10270
|
+
buildOrder(values, config) {
|
|
9542
10271
|
const orders = calcScaledOrderBatchBody(values, config.symbol);
|
|
9543
10272
|
const { total_orders, distribution_type, skew } = values;
|
|
9544
10273
|
const order = {
|
|
@@ -9556,6 +10285,7 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9556
10285
|
"reduce_only",
|
|
9557
10286
|
"side",
|
|
9558
10287
|
"order_type",
|
|
10288
|
+
"margin_mode",
|
|
9559
10289
|
"orders",
|
|
9560
10290
|
"total_orders",
|
|
9561
10291
|
"distribution_type",
|
|
@@ -9564,7 +10294,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9564
10294
|
order
|
|
9565
10295
|
);
|
|
9566
10296
|
}
|
|
9567
|
-
|
|
10297
|
+
/**
|
|
10298
|
+
* Runs validations for scaled order
|
|
10299
|
+
* Implements template method hook
|
|
10300
|
+
*/
|
|
10301
|
+
runValidations(values, config) {
|
|
9568
10302
|
const { maxQty, askAndBid, markPrice, symbol } = config;
|
|
9569
10303
|
const { base_dp, quote_dp } = config.symbol;
|
|
9570
10304
|
const { order_quantity, total, total_orders, distribution_type, skew } = values;
|
|
@@ -9633,22 +10367,22 @@ function validatePrice(values, config) {
|
|
|
9633
10367
|
if (!config.markPrice) {
|
|
9634
10368
|
return errors;
|
|
9635
10369
|
}
|
|
9636
|
-
const { minPrice
|
|
10370
|
+
const { minPrice, maxPrice } = getPriceRange({
|
|
9637
10371
|
side: values.side,
|
|
9638
10372
|
basePrice: config.markPrice,
|
|
9639
10373
|
symbolInfo: config.symbol
|
|
9640
10374
|
});
|
|
9641
10375
|
const comparePrice = (key, value) => {
|
|
9642
10376
|
const price = new utils.Decimal(value || 0);
|
|
9643
|
-
if (price.lt(
|
|
10377
|
+
if (price.lt(minPrice)) {
|
|
9644
10378
|
errors[key] = OrderValidation.min(
|
|
9645
10379
|
key,
|
|
9646
|
-
new utils.Decimal(
|
|
10380
|
+
new utils.Decimal(minPrice).todp(quote_dp).toString()
|
|
9647
10381
|
);
|
|
9648
|
-
} else if (price.gt(
|
|
10382
|
+
} else if (price.gt(maxPrice)) {
|
|
9649
10383
|
errors[key] = OrderValidation.max(
|
|
9650
10384
|
key,
|
|
9651
|
-
new utils.Decimal(
|
|
10385
|
+
new utils.Decimal(maxPrice).todp(quote_dp).toString()
|
|
9652
10386
|
);
|
|
9653
10387
|
}
|
|
9654
10388
|
};
|
|
@@ -9656,13 +10390,40 @@ function validatePrice(values, config) {
|
|
|
9656
10390
|
comparePrice("end_price", end_price);
|
|
9657
10391
|
return errors;
|
|
9658
10392
|
}
|
|
9659
|
-
|
|
10393
|
+
|
|
10394
|
+
// src/services/orderCreator/validators/TriggerPriceValidator.ts
|
|
10395
|
+
var TriggerPriceValidator = class extends BaseValidator {
|
|
10396
|
+
constructor() {
|
|
10397
|
+
super();
|
|
10398
|
+
this.strategy = new TriggerPriceValidationStrategy();
|
|
10399
|
+
}
|
|
10400
|
+
doValidate(values, config) {
|
|
10401
|
+
return this.strategy.validate(
|
|
10402
|
+
{
|
|
10403
|
+
trigger_price: values.trigger_price
|
|
10404
|
+
},
|
|
10405
|
+
config
|
|
10406
|
+
);
|
|
10407
|
+
}
|
|
10408
|
+
getFieldName() {
|
|
10409
|
+
return "trigger_price";
|
|
10410
|
+
}
|
|
10411
|
+
};
|
|
10412
|
+
|
|
10413
|
+
// src/services/orderCreator/stopLimitOrderCreator.ts
|
|
9660
10414
|
var StopLimitOrderCreator = class extends BaseOrderCreator {
|
|
9661
10415
|
constructor() {
|
|
9662
10416
|
super(...arguments);
|
|
10417
|
+
this.priceValidationStrategy = new PriceValidationStrategy();
|
|
10418
|
+
this.triggerPriceValidationStrategy = new TriggerPriceValidationStrategy();
|
|
10419
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new TriggerPriceValidator()).addValidator(new PriceValidator());
|
|
9663
10420
|
this.orderType = types.OrderType.STOP_LIMIT;
|
|
9664
10421
|
}
|
|
9665
|
-
|
|
10422
|
+
/**
|
|
10423
|
+
* Builds the stop-limit order
|
|
10424
|
+
* Implements template method hook
|
|
10425
|
+
*/
|
|
10426
|
+
buildOrder(values, config) {
|
|
9666
10427
|
this.totalToQuantity(values, config);
|
|
9667
10428
|
const order = {
|
|
9668
10429
|
...this.baseOrder(values),
|
|
@@ -9684,84 +10445,82 @@ var StopLimitOrderCreator = class extends BaseOrderCreator {
|
|
|
9684
10445
|
"trigger_price_type",
|
|
9685
10446
|
"side",
|
|
9686
10447
|
"reduce_only",
|
|
10448
|
+
"margin_mode",
|
|
9687
10449
|
"visible_quantity"
|
|
9688
10450
|
],
|
|
9689
10451
|
order
|
|
9690
10452
|
);
|
|
9691
10453
|
}
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
|
|
9711
|
-
|
|
9712
|
-
|
|
9713
|
-
|
|
9714
|
-
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9721
|
-
|
|
9722
|
-
|
|
9723
|
-
|
|
9724
|
-
|
|
9725
|
-
|
|
9726
|
-
|
|
9727
|
-
|
|
9728
|
-
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
if (price.gt(priceRange?.max)) {
|
|
9733
|
-
errors.order_price = OrderValidation.max(
|
|
9734
|
-
"order_price",
|
|
9735
|
-
new utils.Decimal(priceRange.max).todp(symbol.quote_dp).toString()
|
|
9736
|
-
);
|
|
9737
|
-
}
|
|
9738
|
-
}
|
|
9739
|
-
if (price.lt(quote_min)) {
|
|
9740
|
-
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
9741
|
-
} else {
|
|
9742
|
-
if (price.lt(priceRange?.min)) {
|
|
9743
|
-
errors.order_price = OrderValidation.min(
|
|
9744
|
-
"order_price",
|
|
9745
|
-
new utils.Decimal(priceRange.min).todp(symbol.quote_dp).toString()
|
|
9746
|
-
);
|
|
9747
|
-
}
|
|
9748
|
-
}
|
|
9749
|
-
}
|
|
10454
|
+
/**
|
|
10455
|
+
* Runs validations using validation chain
|
|
10456
|
+
* Implements template method hook
|
|
10457
|
+
*/
|
|
10458
|
+
runValidations(values, config) {
|
|
10459
|
+
const orderlyValues = values;
|
|
10460
|
+
const errors = this.baseValidate(orderlyValues, config);
|
|
10461
|
+
const triggerPrice = values.trigger_price;
|
|
10462
|
+
if (!triggerPrice || triggerPrice === 0) {
|
|
10463
|
+
errors.trigger_price = OrderValidation.required("trigger_price");
|
|
10464
|
+
} else {
|
|
10465
|
+
const triggerError = this.triggerPriceValidationStrategy.validate(
|
|
10466
|
+
{ trigger_price: triggerPrice },
|
|
10467
|
+
config
|
|
10468
|
+
);
|
|
10469
|
+
if (triggerError) {
|
|
10470
|
+
errors.trigger_price = triggerError;
|
|
10471
|
+
}
|
|
10472
|
+
}
|
|
10473
|
+
const valuesWithFields = values;
|
|
10474
|
+
const orderPrice = valuesWithFields.order_price ?? valuesWithFields.price;
|
|
10475
|
+
const triggerPriceForPriceValidation = triggerPrice;
|
|
10476
|
+
const side = valuesWithFields.side ?? orderlyValues.side;
|
|
10477
|
+
if (!orderPrice) {
|
|
10478
|
+
errors.order_price = OrderValidation.required("order_price");
|
|
10479
|
+
} else if (orderPrice && triggerPriceForPriceValidation && side) {
|
|
10480
|
+
const modifiedConfig = {
|
|
10481
|
+
...config,
|
|
10482
|
+
markPrice: Number(triggerPriceForPriceValidation)
|
|
10483
|
+
};
|
|
10484
|
+
const priceError = this.priceValidationStrategy.validate(
|
|
10485
|
+
{
|
|
10486
|
+
order_price: orderPrice,
|
|
10487
|
+
side,
|
|
10488
|
+
order_type: types.OrderType.LIMIT
|
|
10489
|
+
},
|
|
10490
|
+
modifiedConfig
|
|
10491
|
+
);
|
|
10492
|
+
if (priceError) {
|
|
10493
|
+
errors.order_price = priceError;
|
|
9750
10494
|
}
|
|
9751
|
-
|
|
9752
|
-
|
|
10495
|
+
} else if (orderPrice && triggerPriceForPriceValidation) {
|
|
10496
|
+
const { quote_max, quote_min } = config.symbol;
|
|
10497
|
+
const price = Number(orderPrice);
|
|
10498
|
+
if (quote_max && price > quote_max) {
|
|
10499
|
+
errors.order_price = OrderValidation.max("order_price", quote_max);
|
|
10500
|
+
} else if (quote_min && price < quote_min) {
|
|
10501
|
+
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
10502
|
+
}
|
|
10503
|
+
}
|
|
10504
|
+
return errors;
|
|
9753
10505
|
}
|
|
9754
10506
|
};
|
|
9755
10507
|
var StopMarketOrderCreator = class extends BaseOrderCreator {
|
|
9756
|
-
|
|
10508
|
+
constructor() {
|
|
10509
|
+
super(...arguments);
|
|
10510
|
+
this.triggerPriceValidationStrategy = new TriggerPriceValidationStrategy();
|
|
10511
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new TriggerPriceValidator());
|
|
10512
|
+
}
|
|
10513
|
+
/**
|
|
10514
|
+
* Builds the stop-market order
|
|
10515
|
+
* Implements template method hook
|
|
10516
|
+
*/
|
|
10517
|
+
buildOrder(values) {
|
|
9757
10518
|
const order = {
|
|
9758
10519
|
...this.baseOrder(values),
|
|
9759
|
-
// order_price: values.order_price,
|
|
9760
10520
|
trigger_price: values.trigger_price,
|
|
9761
10521
|
algo_type: types.AlgoOrderRootType.STOP,
|
|
9762
10522
|
type: types.OrderType.MARKET,
|
|
9763
10523
|
quantity: values["order_quantity"],
|
|
9764
|
-
// price: values["order_price"],
|
|
9765
10524
|
trigger_price_type: types.TriggerPriceType.MARK_PRICE
|
|
9766
10525
|
};
|
|
9767
10526
|
return ramda.pick(
|
|
@@ -9771,225 +10530,40 @@ var StopMarketOrderCreator = class extends BaseOrderCreator {
|
|
|
9771
10530
|
"algo_type",
|
|
9772
10531
|
"type",
|
|
9773
10532
|
"quantity",
|
|
9774
|
-
// "price",
|
|
9775
10533
|
"trigger_price_type",
|
|
9776
10534
|
"side",
|
|
9777
10535
|
"reduce_only",
|
|
10536
|
+
"margin_mode",
|
|
9778
10537
|
"visible_quantity"
|
|
9779
10538
|
],
|
|
9780
10539
|
order
|
|
9781
10540
|
);
|
|
9782
10541
|
}
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
} else if (trigger_price < quote_min || trigger_price == 0) {
|
|
9793
|
-
errors.trigger_price = OrderValidation.min("trigger_price", quote_min);
|
|
9794
|
-
}
|
|
9795
|
-
return errors;
|
|
9796
|
-
});
|
|
10542
|
+
/**
|
|
10543
|
+
* Runs validations using validation chain
|
|
10544
|
+
* Implements template method hook
|
|
10545
|
+
*/
|
|
10546
|
+
runValidations(values, config) {
|
|
10547
|
+
const errors = this.baseValidate(values, config);
|
|
10548
|
+
const chainErrors = this.validationChain.validate(values, config);
|
|
10549
|
+
Object.assign(errors, chainErrors);
|
|
10550
|
+
return errors;
|
|
9797
10551
|
}
|
|
9798
10552
|
};
|
|
9799
|
-
|
|
9800
|
-
|
|
9801
|
-
};
|
|
10553
|
+
|
|
10554
|
+
// src/services/orderCreator/baseAlgoCreator.ts
|
|
9802
10555
|
var BaseAlgoOrderCreator = class {
|
|
10556
|
+
constructor() {
|
|
10557
|
+
this.tpslValidationStrategy = new TPSLValidationStrategy();
|
|
10558
|
+
}
|
|
9803
10559
|
/**
|
|
9804
|
-
*
|
|
10560
|
+
* Validates TP/SL order using TPSLValidationStrategy
|
|
10561
|
+
* Consolidates validation logic from baseBracketOrderCreator
|
|
9805
10562
|
*/
|
|
9806
10563
|
validate(values, config) {
|
|
9807
|
-
|
|
9808
|
-
|
|
9809
|
-
|
|
9810
|
-
tp_trigger_price,
|
|
9811
|
-
sl_trigger_price,
|
|
9812
|
-
side,
|
|
9813
|
-
// tp_enable,
|
|
9814
|
-
// sl_enable,
|
|
9815
|
-
tp_order_type,
|
|
9816
|
-
sl_order_type,
|
|
9817
|
-
tp_order_price,
|
|
9818
|
-
sl_order_price
|
|
9819
|
-
} = values;
|
|
9820
|
-
const qty = Number(values.quantity);
|
|
9821
|
-
const maxQty = config.maxQty;
|
|
9822
|
-
const orderType = values.order_type;
|
|
9823
|
-
const {
|
|
9824
|
-
quote_max,
|
|
9825
|
-
quote_min,
|
|
9826
|
-
price_scope,
|
|
9827
|
-
quote_dp,
|
|
9828
|
-
base_min,
|
|
9829
|
-
min_notional
|
|
9830
|
-
} = config.symbol ?? {};
|
|
9831
|
-
if (!isNaN(qty) && qty > maxQty) {
|
|
9832
|
-
result.quantity = OrderValidation.max("quantity", config.maxQty);
|
|
9833
|
-
}
|
|
9834
|
-
if (!isNaN(qty) && qty < base_min) {
|
|
9835
|
-
result.quantity = OrderValidation.min("quantity", base_min);
|
|
9836
|
-
}
|
|
9837
|
-
if (Number(tp_trigger_price) < 0) {
|
|
9838
|
-
result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
|
|
9839
|
-
}
|
|
9840
|
-
if (Number(sl_trigger_price) < 0) {
|
|
9841
|
-
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
9842
|
-
}
|
|
9843
|
-
if (tp_order_type === types.OrderType.LIMIT && !tp_order_price) {
|
|
9844
|
-
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
9845
|
-
}
|
|
9846
|
-
if (sl_order_type === types.OrderType.LIMIT && !sl_order_price) {
|
|
9847
|
-
result.sl_order_price = OrderValidation.required("sl_order_price");
|
|
9848
|
-
}
|
|
9849
|
-
const mark_price = orderType === types.OrderType.MARKET || orderType == null ? config.markPrice : values.order_price ? Number(values.order_price) : void 0;
|
|
9850
|
-
const tpslSide = side === types.OrderSide.BUY ? types.OrderSide.SELL : types.OrderSide.BUY;
|
|
9851
|
-
if (side === types.OrderSide.BUY && mark_price) {
|
|
9852
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
|
|
9853
|
-
result.sl_trigger_price = OrderValidation.min(
|
|
9854
|
-
"sl_trigger_price",
|
|
9855
|
-
formatPrice2(quote_min, quote_dp)
|
|
9856
|
-
);
|
|
9857
|
-
}
|
|
9858
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) >= mark_price) {
|
|
9859
|
-
result.sl_trigger_price = OrderValidation.max(
|
|
9860
|
-
"sl_trigger_price",
|
|
9861
|
-
formatPrice2(mark_price, quote_dp)
|
|
9862
|
-
);
|
|
9863
|
-
}
|
|
9864
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
|
|
9865
|
-
result.tp_trigger_price = OrderValidation.min(
|
|
9866
|
-
"tp_trigger_price",
|
|
9867
|
-
formatPrice2(mark_price, quote_dp)
|
|
9868
|
-
);
|
|
9869
|
-
}
|
|
9870
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
|
|
9871
|
-
result.tp_trigger_price = OrderValidation.max(
|
|
9872
|
-
"tp_trigger_price",
|
|
9873
|
-
formatPrice2(quote_max, quote_dp)
|
|
9874
|
-
);
|
|
9875
|
-
}
|
|
9876
|
-
if (sl_trigger_price && sl_order_price) {
|
|
9877
|
-
const slOrderPriceRange = getPriceRange({
|
|
9878
|
-
side: tpslSide,
|
|
9879
|
-
basePrice: Number(sl_trigger_price),
|
|
9880
|
-
symbolInfo: config.symbol
|
|
9881
|
-
});
|
|
9882
|
-
if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
|
|
9883
|
-
result.sl_order_price = OrderValidation.min(
|
|
9884
|
-
"sl_order_price",
|
|
9885
|
-
formatPrice2(slOrderPriceRange.minPrice, quote_dp)
|
|
9886
|
-
);
|
|
9887
|
-
}
|
|
9888
|
-
if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
|
|
9889
|
-
result.sl_order_price = OrderValidation.max(
|
|
9890
|
-
"sl_order_price",
|
|
9891
|
-
formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
|
|
9892
|
-
);
|
|
9893
|
-
}
|
|
9894
|
-
if (Number(sl_trigger_price) < Number(sl_order_price)) {
|
|
9895
|
-
result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
|
|
9896
|
-
}
|
|
9897
|
-
}
|
|
9898
|
-
if (tp_trigger_price && tp_order_price) {
|
|
9899
|
-
const tpOrderPriceRange = getPriceRange({
|
|
9900
|
-
side: tpslSide,
|
|
9901
|
-
basePrice: Number(tp_trigger_price),
|
|
9902
|
-
symbolInfo: config.symbol
|
|
9903
|
-
});
|
|
9904
|
-
if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
|
|
9905
|
-
result.tp_order_price = OrderValidation.max(
|
|
9906
|
-
"tp_order_price",
|
|
9907
|
-
formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
|
|
9908
|
-
);
|
|
9909
|
-
}
|
|
9910
|
-
if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
|
|
9911
|
-
result.tp_order_price = OrderValidation.min(
|
|
9912
|
-
"tp_order_price",
|
|
9913
|
-
formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
|
|
9914
|
-
);
|
|
9915
|
-
}
|
|
9916
|
-
if (Number(tp_trigger_price) > Number(tp_order_price)) {
|
|
9917
|
-
result.tp_trigger_price = OrderValidation.priceErrorMin("tp_trigger_price");
|
|
9918
|
-
}
|
|
9919
|
-
}
|
|
9920
|
-
}
|
|
9921
|
-
if (side === types.OrderSide.SELL && mark_price) {
|
|
9922
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) > quote_max) {
|
|
9923
|
-
result.sl_trigger_price = OrderValidation.max(
|
|
9924
|
-
"sl_trigger_price",
|
|
9925
|
-
formatPrice2(quote_max, quote_dp)
|
|
9926
|
-
);
|
|
9927
|
-
}
|
|
9928
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) <= mark_price) {
|
|
9929
|
-
result.sl_trigger_price = OrderValidation.min(
|
|
9930
|
-
"sl_trigger_price",
|
|
9931
|
-
formatPrice2(mark_price, quote_dp)
|
|
9932
|
-
);
|
|
9933
|
-
}
|
|
9934
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
|
|
9935
|
-
result.tp_trigger_price = OrderValidation.max(
|
|
9936
|
-
"tp_trigger_price",
|
|
9937
|
-
formatPrice2(mark_price, quote_dp)
|
|
9938
|
-
);
|
|
9939
|
-
}
|
|
9940
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) < quote_min) {
|
|
9941
|
-
result.tp_trigger_price = OrderValidation.min(
|
|
9942
|
-
"tp_trigger_price",
|
|
9943
|
-
formatPrice2(quote_min, quote_dp)
|
|
9944
|
-
);
|
|
9945
|
-
}
|
|
9946
|
-
if (sl_trigger_price && sl_order_price) {
|
|
9947
|
-
const slOrderPriceRange = getPriceRange({
|
|
9948
|
-
side: tpslSide,
|
|
9949
|
-
basePrice: Number(sl_trigger_price),
|
|
9950
|
-
symbolInfo: config.symbol
|
|
9951
|
-
});
|
|
9952
|
-
if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
|
|
9953
|
-
result.sl_order_price = OrderValidation.min(
|
|
9954
|
-
"sl_order_price",
|
|
9955
|
-
formatPrice2(slOrderPriceRange.minPrice, quote_dp)
|
|
9956
|
-
);
|
|
9957
|
-
}
|
|
9958
|
-
if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
|
|
9959
|
-
result.sl_order_price = OrderValidation.max(
|
|
9960
|
-
"sl_order_price",
|
|
9961
|
-
formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
|
|
9962
|
-
);
|
|
9963
|
-
}
|
|
9964
|
-
if (Number(sl_trigger_price) > Number(sl_order_price)) {
|
|
9965
|
-
result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
|
|
9966
|
-
}
|
|
9967
|
-
}
|
|
9968
|
-
if (tp_trigger_price && tp_order_price) {
|
|
9969
|
-
const tpOrderPriceRange = getPriceRange({
|
|
9970
|
-
side: tpslSide,
|
|
9971
|
-
basePrice: Number(tp_trigger_price),
|
|
9972
|
-
symbolInfo: config.symbol
|
|
9973
|
-
});
|
|
9974
|
-
if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
|
|
9975
|
-
result.tp_order_price = OrderValidation.min(
|
|
9976
|
-
"tp_order_price",
|
|
9977
|
-
formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
|
|
9978
|
-
);
|
|
9979
|
-
}
|
|
9980
|
-
if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
|
|
9981
|
-
result.tp_order_price = OrderValidation.max(
|
|
9982
|
-
"tp_order_price",
|
|
9983
|
-
formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
|
|
9984
|
-
);
|
|
9985
|
-
}
|
|
9986
|
-
if (Number(tp_trigger_price) < Number(tp_order_price)) {
|
|
9987
|
-
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9988
|
-
}
|
|
9989
|
-
}
|
|
9990
|
-
}
|
|
9991
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
9992
|
-
});
|
|
10564
|
+
return Promise.resolve(
|
|
10565
|
+
this.tpslValidationStrategy.validate(values, config)
|
|
10566
|
+
);
|
|
9993
10567
|
}
|
|
9994
10568
|
};
|
|
9995
10569
|
|
|
@@ -10042,7 +10616,9 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
|
|
|
10042
10616
|
reduce_only: true,
|
|
10043
10617
|
quantity: values.quantity,
|
|
10044
10618
|
symbol: values.symbol,
|
|
10045
|
-
child_orders
|
|
10619
|
+
child_orders,
|
|
10620
|
+
// Include margin_mode for isolated/cross margin support; default CROSS per order entry pattern
|
|
10621
|
+
margin_mode: values.margin_mode || types.MarginMode.CROSS
|
|
10046
10622
|
};
|
|
10047
10623
|
}
|
|
10048
10624
|
crateUpdateOrder(values, oldValue, config) {
|
|
@@ -10144,7 +10720,9 @@ var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
|
|
|
10144
10720
|
trigger_price_type: types.TriggerPriceType.MARK_PRICE,
|
|
10145
10721
|
// reduce_only: true,
|
|
10146
10722
|
symbol: values.symbol,
|
|
10147
|
-
child_orders
|
|
10723
|
+
child_orders,
|
|
10724
|
+
// Include margin_mode for isolated/cross margin support; default CROSS per order entry pattern
|
|
10725
|
+
margin_mode: values.margin_mode || types.MarginMode.CROSS
|
|
10148
10726
|
};
|
|
10149
10727
|
}
|
|
10150
10728
|
crateUpdateOrder(values, oldValue, config) {
|
|
@@ -10181,7 +10759,11 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10181
10759
|
super(...arguments);
|
|
10182
10760
|
this.orderType = types.OrderType.TRAILING_STOP;
|
|
10183
10761
|
}
|
|
10184
|
-
|
|
10762
|
+
/**
|
|
10763
|
+
* Builds the trailing stop order
|
|
10764
|
+
* Implements template method hook
|
|
10765
|
+
*/
|
|
10766
|
+
buildOrder(values, config) {
|
|
10185
10767
|
const { order_quantity, activated_price, callback_value, callback_rate } = values;
|
|
10186
10768
|
const order = {
|
|
10187
10769
|
...this.baseOrder(values),
|
|
@@ -10202,6 +10784,7 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10202
10784
|
"quantity",
|
|
10203
10785
|
"side",
|
|
10204
10786
|
"reduce_only",
|
|
10787
|
+
"margin_mode",
|
|
10205
10788
|
"visible_quantity",
|
|
10206
10789
|
"activated_price",
|
|
10207
10790
|
"callback_value",
|
|
@@ -10210,28 +10793,34 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10210
10793
|
order
|
|
10211
10794
|
);
|
|
10212
10795
|
}
|
|
10213
|
-
|
|
10796
|
+
/**
|
|
10797
|
+
* Runs validations for trailing stop order
|
|
10798
|
+
* Implements template method hook
|
|
10799
|
+
*/
|
|
10800
|
+
runValidations(values, config) {
|
|
10214
10801
|
const { markPrice, symbol } = config;
|
|
10215
10802
|
const { quote_dp } = config.symbol;
|
|
10216
10803
|
const { side, activated_price, callback_value, callback_rate } = values;
|
|
10217
|
-
const errors =
|
|
10804
|
+
const errors = this.baseValidate(values, config);
|
|
10218
10805
|
if (activated_price) {
|
|
10219
|
-
const { minPrice
|
|
10806
|
+
const { minPrice, maxPrice } = getPriceRange({
|
|
10220
10807
|
side,
|
|
10221
|
-
markPrice,
|
|
10808
|
+
basePrice: markPrice,
|
|
10222
10809
|
symbolInfo: symbol
|
|
10223
10810
|
});
|
|
10224
|
-
|
|
10225
|
-
|
|
10226
|
-
|
|
10227
|
-
|
|
10228
|
-
|
|
10229
|
-
|
|
10230
|
-
|
|
10231
|
-
|
|
10232
|
-
|
|
10233
|
-
|
|
10234
|
-
|
|
10811
|
+
if (!isNaN(minPrice) && !isNaN(maxPrice)) {
|
|
10812
|
+
const activatedPrice = new utils.Decimal(activated_price);
|
|
10813
|
+
if (activatedPrice.lt(minPrice) || activatedPrice.equals(0)) {
|
|
10814
|
+
errors.activated_price = OrderValidation.min(
|
|
10815
|
+
"activated_price",
|
|
10816
|
+
new utils.Decimal(minPrice).todp(quote_dp).toString()
|
|
10817
|
+
);
|
|
10818
|
+
} else if (activatedPrice.gt(maxPrice)) {
|
|
10819
|
+
errors.activated_price = OrderValidation.max(
|
|
10820
|
+
"activated_price",
|
|
10821
|
+
new utils.Decimal(maxPrice).todp(quote_dp).toString()
|
|
10822
|
+
);
|
|
10823
|
+
}
|
|
10235
10824
|
}
|
|
10236
10825
|
}
|
|
10237
10826
|
if (!callback_value && !callback_rate) {
|
|
@@ -10263,23 +10852,6 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10263
10852
|
return errors;
|
|
10264
10853
|
}
|
|
10265
10854
|
};
|
|
10266
|
-
function getPriceRange2(inputs) {
|
|
10267
|
-
const { markPrice, side, symbolInfo } = inputs;
|
|
10268
|
-
const { quote_min, quote_max } = symbolInfo;
|
|
10269
|
-
const priceRange = side === types.OrderSide.BUY ? {
|
|
10270
|
-
min: quote_min,
|
|
10271
|
-
max: markPrice
|
|
10272
|
-
} : {
|
|
10273
|
-
min: markPrice,
|
|
10274
|
-
max: quote_max
|
|
10275
|
-
};
|
|
10276
|
-
const minPrice3 = Math.max(quote_min, priceRange?.min);
|
|
10277
|
-
const maxPrice3 = Math.min(quote_max, priceRange?.max);
|
|
10278
|
-
return {
|
|
10279
|
-
minPrice: minPrice3,
|
|
10280
|
-
maxPrice: maxPrice3
|
|
10281
|
-
};
|
|
10282
|
-
}
|
|
10283
10855
|
|
|
10284
10856
|
// src/services/orderCreator/factory.ts
|
|
10285
10857
|
var OrderFactory = class {
|
|
@@ -10402,27 +10974,63 @@ var calcEstLiqPrice = (order, askAndBid, inputs) => {
|
|
|
10402
10974
|
markPrice,
|
|
10403
10975
|
totalCollateral,
|
|
10404
10976
|
futures_taker_fee_rate,
|
|
10405
|
-
positions: positions3
|
|
10977
|
+
positions: positions3,
|
|
10978
|
+
// leverage,
|
|
10979
|
+
sumUnitaryFunding
|
|
10406
10980
|
} = inputs;
|
|
10407
10981
|
const orderFee = perp.order.orderFee({
|
|
10408
10982
|
qty: quantity,
|
|
10409
10983
|
price,
|
|
10410
10984
|
futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
|
|
10411
10985
|
});
|
|
10412
|
-
|
|
10413
|
-
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
|
|
10419
|
-
|
|
10420
|
-
|
|
10421
|
-
|
|
10422
|
-
|
|
10423
|
-
|
|
10986
|
+
let liqPrice = 0;
|
|
10987
|
+
if (order.margin_mode === types.MarginMode.CROSS) {
|
|
10988
|
+
liqPrice = perp.order.estLiqPrice({
|
|
10989
|
+
markPrice,
|
|
10990
|
+
baseIMR: symbolInfo.base_imr,
|
|
10991
|
+
baseMMR: symbolInfo.base_mmr,
|
|
10992
|
+
totalCollateral,
|
|
10993
|
+
positions: positions3 == null ? [] : positions3,
|
|
10994
|
+
IMR_Factor: imr_factor,
|
|
10995
|
+
orderFee,
|
|
10996
|
+
newOrder: {
|
|
10997
|
+
qty: quantity,
|
|
10998
|
+
price,
|
|
10999
|
+
symbol
|
|
11000
|
+
}
|
|
11001
|
+
});
|
|
11002
|
+
} else {
|
|
11003
|
+
let isolatedPositionMargin = 0, costPosition = 0, positionQty = 0, lastSumUnitaryFunding = 0, leverage = 1;
|
|
11004
|
+
if (positions3) {
|
|
11005
|
+
const position = positions3.find(
|
|
11006
|
+
(p) => p.symbol === symbol && p.margin_mode === types.MarginMode.ISOLATED
|
|
11007
|
+
);
|
|
11008
|
+
if (position) {
|
|
11009
|
+
isolatedPositionMargin = position.margin ?? 0;
|
|
11010
|
+
costPosition = position.cost_position ?? 0;
|
|
11011
|
+
positionQty = position.position_qty ?? 0;
|
|
11012
|
+
lastSumUnitaryFunding = position.last_sum_unitary_funding ?? 0;
|
|
11013
|
+
leverage = position.leverage ? Number(position.leverage) : 1;
|
|
11014
|
+
}
|
|
10424
11015
|
}
|
|
10425
|
-
|
|
11016
|
+
liqPrice = perp.order.estLiqPriceIsolated({
|
|
11017
|
+
isolatedPositionMargin,
|
|
11018
|
+
costPosition,
|
|
11019
|
+
positionQty,
|
|
11020
|
+
sumUnitaryFunding,
|
|
11021
|
+
lastSumUnitaryFunding,
|
|
11022
|
+
markPrice,
|
|
11023
|
+
baseIMR: symbolInfo.base_imr,
|
|
11024
|
+
baseMMR: symbolInfo.base_mmr,
|
|
11025
|
+
IMR_Factor: imr_factor,
|
|
11026
|
+
leverage,
|
|
11027
|
+
newOrder: {
|
|
11028
|
+
symbol,
|
|
11029
|
+
qty: quantity,
|
|
11030
|
+
price
|
|
11031
|
+
}
|
|
11032
|
+
});
|
|
11033
|
+
}
|
|
10426
11034
|
if (liqPrice <= 0) return null;
|
|
10427
11035
|
return liqPrice;
|
|
10428
11036
|
};
|
|
@@ -10480,7 +11088,9 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
|
|
|
10480
11088
|
// sl_enable: isEditing
|
|
10481
11089
|
// ? checkIsEnableTpSL(options?.defaultOrder).sl_enable
|
|
10482
11090
|
// : options?.tpslEnable?.sl_enable,
|
|
10483
|
-
position_type: options?.positionType
|
|
11091
|
+
position_type: options?.positionType,
|
|
11092
|
+
// Use defaultOrder.margin_mode when editing; otherwise position.margin_mode; default CROSS for backward compatibility
|
|
11093
|
+
margin_mode: options?.defaultOrder?.margin_mode ?? position?.margin_mode ?? types.MarginMode.CROSS
|
|
10484
11094
|
});
|
|
10485
11095
|
const symbolInfo = useSymbolsInfo()[position.symbol]();
|
|
10486
11096
|
const { data: markPrice } = useMarkPrice(order.symbol);
|
|
@@ -10783,11 +11393,53 @@ var useMaxLeverage = (symbol) => {
|
|
|
10783
11393
|
};
|
|
10784
11394
|
var useSymbolLeverage = (symbol) => {
|
|
10785
11395
|
const symbolInfo = useSymbolInfo(symbol);
|
|
10786
|
-
const
|
|
11396
|
+
const { state } = useAccount();
|
|
11397
|
+
const [updateMutation, { isMutating }] = useMutation("/v1/client/leverage");
|
|
10787
11398
|
const maxLeverage = React.useMemo(() => {
|
|
10788
11399
|
const baseIMR = symbolInfo?.("base_imr");
|
|
10789
11400
|
return baseIMR ? 1 / baseIMR : 1;
|
|
10790
11401
|
}, [symbolInfo]);
|
|
11402
|
+
const update = async (data) => {
|
|
11403
|
+
const result = await updateMutation(data);
|
|
11404
|
+
if (result?.success && data.symbol && state.accountId) {
|
|
11405
|
+
const key = ["/v1/client/leverages", state.accountId];
|
|
11406
|
+
useSWR5.mutate(
|
|
11407
|
+
key,
|
|
11408
|
+
(prev) => {
|
|
11409
|
+
if (!prev) {
|
|
11410
|
+
return [
|
|
11411
|
+
{
|
|
11412
|
+
symbol: data.symbol,
|
|
11413
|
+
leverage: data.leverage,
|
|
11414
|
+
margin_mode: data.margin_mode
|
|
11415
|
+
}
|
|
11416
|
+
];
|
|
11417
|
+
}
|
|
11418
|
+
const index = prev.findIndex(
|
|
11419
|
+
(item) => item.symbol === data.symbol && (item.margin_mode ?? types.MarginMode.CROSS) === (data.margin_mode ?? types.MarginMode.CROSS)
|
|
11420
|
+
);
|
|
11421
|
+
if (index === -1) {
|
|
11422
|
+
return [
|
|
11423
|
+
...prev,
|
|
11424
|
+
{
|
|
11425
|
+
symbol: data.symbol,
|
|
11426
|
+
leverage: data.leverage,
|
|
11427
|
+
margin_mode: data.margin_mode
|
|
11428
|
+
}
|
|
11429
|
+
];
|
|
11430
|
+
}
|
|
11431
|
+
const next = [...prev];
|
|
11432
|
+
next[index] = {
|
|
11433
|
+
...next[index],
|
|
11434
|
+
leverage: data.leverage
|
|
11435
|
+
};
|
|
11436
|
+
return next;
|
|
11437
|
+
},
|
|
11438
|
+
{ revalidate: false }
|
|
11439
|
+
);
|
|
11440
|
+
}
|
|
11441
|
+
return result;
|
|
11442
|
+
};
|
|
10791
11443
|
return {
|
|
10792
11444
|
maxLeverage,
|
|
10793
11445
|
update,
|
|
@@ -11524,8 +12176,8 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
|
|
|
11524
12176
|
const keys = Object.keys(current);
|
|
11525
12177
|
for (let i = 0; i < keys.length; i++) {
|
|
11526
12178
|
const k = keys[i];
|
|
11527
|
-
|
|
11528
|
-
|
|
12179
|
+
const preveValue = prev[k];
|
|
12180
|
+
const currentValue = current[k];
|
|
11529
12181
|
if (typeof preveValue === "undefined" && typeof currentValue === "undefined")
|
|
11530
12182
|
continue;
|
|
11531
12183
|
if (preveValue !== currentValue) {
|
|
@@ -11538,7 +12190,12 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
|
|
|
11538
12190
|
if (!key) return null;
|
|
11539
12191
|
return { key, value, preValue };
|
|
11540
12192
|
};
|
|
11541
|
-
const
|
|
12193
|
+
const { marginMode: symbolMarginMode } = useMarginModeBySymbol(symbol);
|
|
12194
|
+
const marginMode = typeof symbolOrOrder === "object" && symbolOrOrder.margin_mode ? symbolOrOrder.margin_mode : symbolMarginMode;
|
|
12195
|
+
const maxQty = useMaxQty(symbol, sideValue, {
|
|
12196
|
+
reduceOnly: isReduceOnly,
|
|
12197
|
+
marginMode: marginMode ?? types.MarginMode.CROSS
|
|
12198
|
+
});
|
|
11542
12199
|
const parseString2Number = (order, key, dp) => {
|
|
11543
12200
|
if (typeof order[key] !== "string") return;
|
|
11544
12201
|
if (order[key] && order[key].startsWith(".")) {
|
|
@@ -12089,7 +12746,7 @@ var DataPaint = class extends BasePaint {
|
|
|
12089
12746
|
);
|
|
12090
12747
|
const { position, fontSize = 14 } = layout;
|
|
12091
12748
|
let left = this._ratio(position.left);
|
|
12092
|
-
|
|
12749
|
+
const top = layout.position.top + offsetTop + this.transformTop;
|
|
12093
12750
|
let prevElementBoundingBox = {};
|
|
12094
12751
|
if (typeof options.data?.position.side !== "undefined") {
|
|
12095
12752
|
prevElementBoundingBox = this._drawText(options.data.position.side, {
|
|
@@ -12120,6 +12777,28 @@ var DataPaint = class extends BasePaint {
|
|
|
12120
12777
|
fontFamily: options.fontFamily
|
|
12121
12778
|
});
|
|
12122
12779
|
}
|
|
12780
|
+
const marginMode = options.data?.position.marginMode;
|
|
12781
|
+
if (marginMode) {
|
|
12782
|
+
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12783
|
+
if (prevElementBoundingBox.width) {
|
|
12784
|
+
prevElementBoundingBox = this._drawText("|", {
|
|
12785
|
+
color: "rgba(255,255,255,0.2)",
|
|
12786
|
+
left,
|
|
12787
|
+
top: this._ratio(top),
|
|
12788
|
+
fontSize: this._ratio(fontSize),
|
|
12789
|
+
fontFamily: options.fontFamily
|
|
12790
|
+
});
|
|
12791
|
+
}
|
|
12792
|
+
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12793
|
+
const marginModeText = marginMode.charAt(0).toUpperCase() + marginMode.slice(1);
|
|
12794
|
+
prevElementBoundingBox = this._drawText(marginModeText, {
|
|
12795
|
+
color: layout.color,
|
|
12796
|
+
left,
|
|
12797
|
+
top: this._ratio(top),
|
|
12798
|
+
fontSize: this._ratio(fontSize),
|
|
12799
|
+
fontFamily: options.fontFamily
|
|
12800
|
+
});
|
|
12801
|
+
}
|
|
12123
12802
|
if (typeof options.data?.position.leverage !== "undefined") {
|
|
12124
12803
|
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12125
12804
|
if (prevElementBoundingBox.width) {
|
|
@@ -12200,8 +12879,8 @@ var DataPaint = class extends BasePaint {
|
|
|
12200
12879
|
(options.data?.position.informations.length ?? 0) === 2;
|
|
12201
12880
|
const col = informations.length > 4 ? 3 : 2;
|
|
12202
12881
|
informations.forEach((info, index) => {
|
|
12203
|
-
|
|
12204
|
-
|
|
12882
|
+
const left = position.left + index % col * this.positionInfoCellWidth;
|
|
12883
|
+
const top = position.top + Math.floor(index / col) * 38 + this.transformTop;
|
|
12205
12884
|
this._drawText(info.title, {
|
|
12206
12885
|
left: this._ratio(left),
|
|
12207
12886
|
top: this._ratio(top),
|
|
@@ -17743,95 +18422,111 @@ var initialOrderState = {
|
|
|
17743
18422
|
trigger_price: "",
|
|
17744
18423
|
tp_trigger_price: "",
|
|
17745
18424
|
sl_trigger_price: "",
|
|
17746
|
-
tp_order_type: types.OrderType.MARKET,
|
|
17747
|
-
tp_pnl: "",
|
|
17748
|
-
sl_pnl: "",
|
|
17749
|
-
tp_offset_percentage: "",
|
|
17750
|
-
sl_offset_percentage: "",
|
|
17751
|
-
tp_offset: "",
|
|
17752
|
-
sl_offset: "",
|
|
17753
|
-
sl_order_type: types.OrderType.MARKET,
|
|
17754
18425
|
total: "",
|
|
17755
|
-
|
|
17756
|
-
start_price: "",
|
|
17757
|
-
end_price: "",
|
|
17758
|
-
totalOrders: "",
|
|
17759
|
-
distribution_type: "",
|
|
17760
|
-
skew: "",
|
|
17761
|
-
// symbol: "",
|
|
17762
|
-
// trailing stop order
|
|
17763
|
-
activated_price: "",
|
|
17764
|
-
callback_value: "",
|
|
17765
|
-
callback_rate: ""
|
|
18426
|
+
symbol: ""
|
|
17766
18427
|
};
|
|
17767
|
-
var useOrderStore = (
|
|
17768
|
-
|
|
17769
|
-
|
|
17770
|
-
|
|
17771
|
-
|
|
17772
|
-
|
|
17773
|
-
|
|
17774
|
-
|
|
17775
|
-
|
|
17776
|
-
|
|
17777
|
-
immer$1.produce((draft) => {
|
|
17778
|
-
Object.assign(draft, order);
|
|
17779
|
-
})
|
|
17780
|
-
// (prev) => ({ ...prev, ...order })
|
|
17781
|
-
);
|
|
17782
|
-
};
|
|
17783
|
-
const updateOrderByKey = (key, value) => {
|
|
17784
|
-
setEntry(
|
|
17785
|
-
immer$1.produce((draft) => {
|
|
17786
|
-
draft[key] = value;
|
|
17787
|
-
})
|
|
17788
|
-
);
|
|
17789
|
-
};
|
|
17790
|
-
const restoreOrder = (order) => {
|
|
17791
|
-
setEntry(immer$1.produce((draft) => order));
|
|
17792
|
-
};
|
|
17793
|
-
const updateOrderComputed = (data) => {
|
|
17794
|
-
setEstLeverage(data.estLeverage);
|
|
17795
|
-
setEstLiquidationPrice(data.estLiquidationPrice);
|
|
17796
|
-
};
|
|
17797
|
-
const resetOrder = (order) => {
|
|
17798
|
-
setEntry(
|
|
17799
|
-
immer$1.produce((draft) => ({
|
|
17800
|
-
...draft,
|
|
17801
|
-
...order ?? initialOrderState
|
|
17802
|
-
}))
|
|
17803
|
-
);
|
|
17804
|
-
};
|
|
17805
|
-
const hasTP_SL = () => {
|
|
17806
|
-
return typeof entry.tp_trigger_price !== "undefined" || typeof entry.sl_trigger_price !== "undefined";
|
|
17807
|
-
};
|
|
17808
|
-
return {
|
|
17809
|
-
entry,
|
|
17810
|
-
estLeverage,
|
|
17811
|
-
estLiquidationPrice,
|
|
17812
|
-
errors,
|
|
18428
|
+
var useOrderStore = zustand.create()(
|
|
18429
|
+
immer.immer((set, get3) => ({
|
|
18430
|
+
entry: {
|
|
18431
|
+
side: types.OrderSide.BUY,
|
|
18432
|
+
order_type: types.OrderType.LIMIT,
|
|
18433
|
+
...initialOrderState
|
|
18434
|
+
},
|
|
18435
|
+
estLeverage: null,
|
|
18436
|
+
estLiquidationPrice: null,
|
|
18437
|
+
errors: {},
|
|
17813
18438
|
actions: {
|
|
17814
|
-
|
|
17815
|
-
|
|
17816
|
-
|
|
17817
|
-
|
|
17818
|
-
|
|
17819
|
-
|
|
18439
|
+
initOrder: (symbol, options) => {
|
|
18440
|
+
set((state) => {
|
|
18441
|
+
state.entry = {
|
|
18442
|
+
...initialOrderState,
|
|
18443
|
+
symbol,
|
|
18444
|
+
side: options?.side ?? types.OrderSide.BUY,
|
|
18445
|
+
order_type: options?.order_type ?? types.OrderType.LIMIT,
|
|
18446
|
+
margin_mode: options?.margin_mode ?? types.MarginMode.CROSS
|
|
18447
|
+
};
|
|
18448
|
+
state.estLeverage = null;
|
|
18449
|
+
state.estLiquidationPrice = null;
|
|
18450
|
+
state.errors = {};
|
|
18451
|
+
});
|
|
18452
|
+
},
|
|
18453
|
+
hasTP_SL: () => {
|
|
18454
|
+
const order = get3().entry;
|
|
18455
|
+
return typeof order.tp_trigger_price !== "undefined" || typeof order.sl_trigger_price !== "undefined";
|
|
18456
|
+
},
|
|
18457
|
+
updateOrderComputed: (data) => {
|
|
18458
|
+
set(
|
|
18459
|
+
(state) => {
|
|
18460
|
+
state.estLeverage = data.estLeverage;
|
|
18461
|
+
state.estLiquidationPrice = data.estLiquidationPrice;
|
|
18462
|
+
},
|
|
18463
|
+
false
|
|
18464
|
+
// "updateOrderComputed"
|
|
18465
|
+
);
|
|
18466
|
+
},
|
|
18467
|
+
updateOrder: (order) => {
|
|
18468
|
+
set(
|
|
18469
|
+
(state) => {
|
|
18470
|
+
state.entry = {
|
|
18471
|
+
...state.entry,
|
|
18472
|
+
...order
|
|
18473
|
+
};
|
|
18474
|
+
},
|
|
18475
|
+
false
|
|
18476
|
+
// "updateOrder"
|
|
18477
|
+
);
|
|
18478
|
+
},
|
|
18479
|
+
updateOrderByKey: (key, value) => {
|
|
18480
|
+
set(
|
|
18481
|
+
(state) => {
|
|
18482
|
+
state.entry[key] = value;
|
|
18483
|
+
},
|
|
18484
|
+
false
|
|
18485
|
+
// "updateOrderByKey"
|
|
18486
|
+
);
|
|
18487
|
+
},
|
|
18488
|
+
restoreOrder: (order) => {
|
|
18489
|
+
set(
|
|
18490
|
+
(state) => {
|
|
18491
|
+
state.entry = order;
|
|
18492
|
+
},
|
|
18493
|
+
false
|
|
18494
|
+
// "restoreOrder"
|
|
18495
|
+
);
|
|
18496
|
+
},
|
|
18497
|
+
resetOrder: (_order) => {
|
|
18498
|
+
set(
|
|
18499
|
+
(state) => {
|
|
18500
|
+
state.entry.order_price = "";
|
|
18501
|
+
state.entry.order_quantity = "";
|
|
18502
|
+
state.entry.trigger_price = "";
|
|
18503
|
+
state.entry.total = "";
|
|
18504
|
+
state.entry.tp_trigger_price = "";
|
|
18505
|
+
state.entry.tp_pnl = "";
|
|
18506
|
+
state.entry.tp_offset = "";
|
|
18507
|
+
state.entry.tp_offset_percentage = "";
|
|
18508
|
+
state.entry.sl_trigger_price = "";
|
|
18509
|
+
state.entry.sl_pnl = "";
|
|
18510
|
+
state.entry.sl_offset = "";
|
|
18511
|
+
state.entry.sl_offset_percentage = "";
|
|
18512
|
+
},
|
|
18513
|
+
true
|
|
18514
|
+
// "resetOrder"
|
|
18515
|
+
);
|
|
18516
|
+
}
|
|
17820
18517
|
}
|
|
17821
|
-
}
|
|
17822
|
-
|
|
17823
|
-
|
|
17824
|
-
// src/next/useOrderEntry/useOrderEntry.internal.ts
|
|
18518
|
+
}))
|
|
18519
|
+
);
|
|
17825
18520
|
var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
17826
18521
|
const { symbolInfo, symbolLeverage } = options;
|
|
17827
|
-
const
|
|
17828
|
-
|
|
17829
|
-
|
|
17830
|
-
|
|
17831
|
-
|
|
17832
|
-
|
|
17833
|
-
|
|
17834
|
-
|
|
18522
|
+
const orderEntity = useOrderStore((state) => state.entry);
|
|
18523
|
+
const orderEntryActions = useOrderStore((state) => state.actions);
|
|
18524
|
+
React.useEffect(() => {
|
|
18525
|
+
orderEntryActions.initOrder(symbol, options.initialOrder);
|
|
18526
|
+
if (options.initialOrder) {
|
|
18527
|
+
orderEntryActions.updateOrder(options.initialOrder);
|
|
18528
|
+
}
|
|
18529
|
+
}, [symbol]);
|
|
17835
18530
|
const calculate2 = React.useCallback(
|
|
17836
18531
|
(values, fieldName, value, markPrice, config) => {
|
|
17837
18532
|
const fieldHandler = getCalculateHandler(fieldName);
|
|
@@ -17845,17 +18540,15 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17845
18540
|
},
|
|
17846
18541
|
[]
|
|
17847
18542
|
);
|
|
17848
|
-
React.useEffect(() => {
|
|
17849
|
-
orderEntryActions.updateOrderByKey("symbol", symbol);
|
|
17850
|
-
}, [orderEntryActions, symbol]);
|
|
17851
18543
|
const setValue = (key, value, additional) => {
|
|
17852
18544
|
if (!symbolInfo) {
|
|
17853
18545
|
orderEntryActions.updateOrderByKey(key, value);
|
|
17854
18546
|
return;
|
|
17855
18547
|
}
|
|
18548
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
17856
18549
|
const { markPrice } = additional ?? { markPrice: 0 };
|
|
17857
18550
|
let newValues = calculate2(
|
|
17858
|
-
{ ...
|
|
18551
|
+
{ ...currentEntry },
|
|
17859
18552
|
key,
|
|
17860
18553
|
value,
|
|
17861
18554
|
markPrice,
|
|
@@ -17936,7 +18629,8 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17936
18629
|
orderEntryActions.updateOrder(values);
|
|
17937
18630
|
return;
|
|
17938
18631
|
}
|
|
17939
|
-
|
|
18632
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
18633
|
+
let newValues = { ...currentEntry };
|
|
17940
18634
|
Object.keys(values).forEach((key) => {
|
|
17941
18635
|
newValues = calculate2(
|
|
17942
18636
|
newValues,
|
|
@@ -17952,10 +18646,11 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17952
18646
|
const onMarkPriceUpdated = React.useCallback(
|
|
17953
18647
|
(markPrice, baseOn = []) => {
|
|
17954
18648
|
if (!options.symbolInfo) return;
|
|
17955
|
-
|
|
18649
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
18650
|
+
let newValues = { ...currentEntry };
|
|
17956
18651
|
if (baseOn.length === 0) {
|
|
17957
18652
|
newValues = calculate2(
|
|
17958
|
-
{ ...
|
|
18653
|
+
{ ...currentEntry },
|
|
17959
18654
|
"order_price",
|
|
17960
18655
|
markPrice,
|
|
17961
18656
|
markPrice,
|
|
@@ -17966,7 +18661,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17966
18661
|
newValues = calculate2(
|
|
17967
18662
|
{ ...newValues },
|
|
17968
18663
|
key,
|
|
17969
|
-
|
|
18664
|
+
currentEntry[key],
|
|
17970
18665
|
markPrice,
|
|
17971
18666
|
options.symbolInfo
|
|
17972
18667
|
);
|
|
@@ -17987,7 +18682,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17987
18682
|
}
|
|
17988
18683
|
orderEntryActions.updateOrder(newValues);
|
|
17989
18684
|
},
|
|
17990
|
-
[calculate2, options.symbolInfo,
|
|
18685
|
+
[calculate2, options.symbolInfo, orderEntryActions]
|
|
17991
18686
|
);
|
|
17992
18687
|
const validate = (order, creator, options2) => {
|
|
17993
18688
|
return creator?.validate(order, {
|
|
@@ -18036,6 +18731,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18036
18731
|
const lastChangedField = React.useRef();
|
|
18037
18732
|
const lastOrderTypeExt = React.useRef();
|
|
18038
18733
|
const lastLevel = React.useRef();
|
|
18734
|
+
const fundingRates = useFundingRatesStore();
|
|
18039
18735
|
const calculateTPSL_baseOn = React.useRef({
|
|
18040
18736
|
tp: "",
|
|
18041
18737
|
sl: ""
|
|
@@ -18044,7 +18740,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18044
18740
|
const symbolConfig = useSymbolsInfo();
|
|
18045
18741
|
const accountInfo = useAccountInfo();
|
|
18046
18742
|
const positions3 = usePositions();
|
|
18047
|
-
const
|
|
18743
|
+
const entry = useOrderStore((s) => s.entry);
|
|
18744
|
+
const effectiveMarginMode = options?.initialOrder?.margin_mode ?? entry?.margin_mode ?? types.MarginMode.CROSS;
|
|
18745
|
+
const symbolLeverage = useLeverageBySymbol(symbol, effectiveMarginMode);
|
|
18048
18746
|
const symbolInfo = symbolConfig[symbol]();
|
|
18049
18747
|
const markPrice = actions.getMarkPriceBySymbol(symbol);
|
|
18050
18748
|
const { orderMetadata } = useOrderlyContext();
|
|
@@ -18066,12 +18764,39 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18066
18764
|
const [doCreateOrder, { isMutating }] = useMutation(
|
|
18067
18765
|
getCreateOrderUrl(formattedOrder)
|
|
18068
18766
|
);
|
|
18069
|
-
const
|
|
18070
|
-
|
|
18071
|
-
|
|
18072
|
-
formattedOrder.reduce_only
|
|
18073
|
-
|
|
18767
|
+
const bestAskBid = askAndBid.current?.[0] || [];
|
|
18768
|
+
const referencePriceFromOrder = bestAskBid.length >= 2 && formattedOrder.order_type && formattedOrder.side ? getOrderReferencePriceFromOrder(formattedOrder, bestAskBid) : null;
|
|
18769
|
+
const maxBuyQtyValue = useMaxQty(symbol, types.OrderSide.BUY, {
|
|
18770
|
+
reduceOnly: formattedOrder.reduce_only,
|
|
18771
|
+
marginMode: effectiveMarginMode,
|
|
18772
|
+
currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
|
|
18773
|
+
});
|
|
18774
|
+
const maxSellQtyValue = useMaxQty(symbol, types.OrderSide.SELL, {
|
|
18775
|
+
reduceOnly: formattedOrder.reduce_only,
|
|
18776
|
+
marginMode: effectiveMarginMode,
|
|
18777
|
+
currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
|
|
18778
|
+
});
|
|
18779
|
+
const maxQtyValue = formattedOrder.side === types.OrderSide.BUY ? maxBuyQtyValue : maxSellQtyValue;
|
|
18074
18780
|
const maxQty = options.maxQty ?? maxQtyValue;
|
|
18781
|
+
const maxQtys = React.useMemo(
|
|
18782
|
+
() => ({
|
|
18783
|
+
maxBuy: formattedOrder.side === types.OrderSide.BUY ? (
|
|
18784
|
+
// @ts-ignore
|
|
18785
|
+
options.maxQty ?? maxBuyQtyValue
|
|
18786
|
+
) : maxBuyQtyValue,
|
|
18787
|
+
maxSell: formattedOrder.side === types.OrderSide.SELL ? (
|
|
18788
|
+
// @ts-ignore
|
|
18789
|
+
options.maxQty ?? maxSellQtyValue
|
|
18790
|
+
) : maxSellQtyValue
|
|
18791
|
+
}),
|
|
18792
|
+
[
|
|
18793
|
+
formattedOrder.side,
|
|
18794
|
+
maxBuyQtyValue,
|
|
18795
|
+
maxSellQtyValue,
|
|
18796
|
+
// @ts-ignore
|
|
18797
|
+
options.maxQty
|
|
18798
|
+
]
|
|
18799
|
+
);
|
|
18075
18800
|
const updateOrderPrice = () => {
|
|
18076
18801
|
const order_type = formattedOrder.order_type;
|
|
18077
18802
|
const order_type_ext = formattedOrder.order_type_ext ?? lastOrderTypeExt.current;
|
|
@@ -18160,6 +18885,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18160
18885
|
};
|
|
18161
18886
|
}, []);
|
|
18162
18887
|
React.useEffect(() => {
|
|
18888
|
+
if (formattedOrder.symbol !== symbol) {
|
|
18889
|
+
return;
|
|
18890
|
+
}
|
|
18163
18891
|
if ((formattedOrder.order_type === types.OrderType.MARKET || formattedOrder.order_type === types.OrderType.STOP_MARKET) && markPrice) {
|
|
18164
18892
|
const baseOn = /* @__PURE__ */ new Set();
|
|
18165
18893
|
if (lastChangedField.current) {
|
|
@@ -18173,7 +18901,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18173
18901
|
}
|
|
18174
18902
|
orderEntryActions.onMarkPriceChange(markPrice, Array.from(baseOn));
|
|
18175
18903
|
}
|
|
18176
|
-
}, [markPrice, formattedOrder.order_type]);
|
|
18904
|
+
}, [markPrice, formattedOrder.order_type, formattedOrder.symbol, symbol]);
|
|
18177
18905
|
const prepareData = React.useCallback(() => {
|
|
18178
18906
|
return {
|
|
18179
18907
|
markPrice: actions.getMarkPriceBySymbol(symbol),
|
|
@@ -18282,7 +19010,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18282
19010
|
}
|
|
18283
19011
|
);
|
|
18284
19012
|
};
|
|
18285
|
-
const { freeCollateral, totalCollateral } = useCollateral();
|
|
19013
|
+
const { freeCollateral, freeCollateralUSDCOnly, totalCollateral } = useCollateral();
|
|
18286
19014
|
const currentPosition = React.useMemo(() => {
|
|
18287
19015
|
const rows = positions3 ?? [];
|
|
18288
19016
|
const p = Array.isArray(rows) ? rows.find(
|
|
@@ -18295,6 +19023,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18295
19023
|
if (!markPrice2 || !accountInfo || !symbolInfo) {
|
|
18296
19024
|
return null;
|
|
18297
19025
|
}
|
|
19026
|
+
const sumUnitaryFunding = fundingRates[symbol]?.sum_unitary_funding ?? 0;
|
|
18298
19027
|
const estLiqPrice2 = calcEstLiqPrice(formattedOrder, askAndBid.current[0], {
|
|
18299
19028
|
markPrice: markPrice2,
|
|
18300
19029
|
totalCollateral,
|
|
@@ -18302,7 +19031,8 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18302
19031
|
imr_factor: accountInfo.imr_factor[symbol],
|
|
18303
19032
|
symbol,
|
|
18304
19033
|
positions: positions3,
|
|
18305
|
-
symbolInfo
|
|
19034
|
+
symbolInfo,
|
|
19035
|
+
sumUnitaryFunding
|
|
18306
19036
|
});
|
|
18307
19037
|
return estLiqPrice2;
|
|
18308
19038
|
}, [
|
|
@@ -18312,7 +19042,8 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18312
19042
|
totalCollateral,
|
|
18313
19043
|
symbol,
|
|
18314
19044
|
maxQty,
|
|
18315
|
-
symbolInfo
|
|
19045
|
+
symbolInfo,
|
|
19046
|
+
fundingRates
|
|
18316
19047
|
]);
|
|
18317
19048
|
const estLiqPriceDistance = React.useMemo(() => {
|
|
18318
19049
|
if (!estLiqPrice) {
|
|
@@ -18435,6 +19166,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18435
19166
|
resetMetaState,
|
|
18436
19167
|
formattedOrder,
|
|
18437
19168
|
maxQty,
|
|
19169
|
+
maxQtys,
|
|
18438
19170
|
estLiqPrice,
|
|
18439
19171
|
estLiqPriceDistance,
|
|
18440
19172
|
currentPosition,
|
|
@@ -18447,7 +19179,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18447
19179
|
validator: validateOrder,
|
|
18448
19180
|
validate: validateOrder
|
|
18449
19181
|
},
|
|
18450
|
-
freeCollateral,
|
|
19182
|
+
freeCollateral: effectiveMarginMode === types.MarginMode.ISOLATED ? freeCollateralUSDCOnly : freeCollateral,
|
|
18451
19183
|
setValue: useMemoizedFn(setValue),
|
|
18452
19184
|
setValues: useMemoizedFn(setValues),
|
|
18453
19185
|
symbolInfo: symbolInfo || types.EMPTY_OBJECT,
|
|
@@ -18457,93 +19189,6 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18457
19189
|
symbolLeverage
|
|
18458
19190
|
};
|
|
18459
19191
|
};
|
|
18460
|
-
var initialOrderState2 = {
|
|
18461
|
-
order_price: "",
|
|
18462
|
-
order_quantity: "",
|
|
18463
|
-
trigger_price: "",
|
|
18464
|
-
tp_trigger_price: "",
|
|
18465
|
-
sl_trigger_price: "",
|
|
18466
|
-
total: "",
|
|
18467
|
-
symbol: ""
|
|
18468
|
-
};
|
|
18469
|
-
var useOrderStore2 = zustand.create()(
|
|
18470
|
-
immer.immer((set, get3) => ({
|
|
18471
|
-
entry: {
|
|
18472
|
-
side: types.OrderSide.BUY,
|
|
18473
|
-
order_type: types.OrderType.LIMIT,
|
|
18474
|
-
...initialOrderState2
|
|
18475
|
-
},
|
|
18476
|
-
estLeverage: null,
|
|
18477
|
-
estLiquidationPrice: null,
|
|
18478
|
-
errors: {},
|
|
18479
|
-
actions: {
|
|
18480
|
-
hasTP_SL: () => {
|
|
18481
|
-
const order = get3().entry;
|
|
18482
|
-
return typeof order.tp_trigger_price !== "undefined" || typeof order.sl_trigger_price !== "undefined";
|
|
18483
|
-
},
|
|
18484
|
-
updateOrderComputed: (data) => {
|
|
18485
|
-
set(
|
|
18486
|
-
(state) => {
|
|
18487
|
-
state.estLeverage = data.estLeverage;
|
|
18488
|
-
state.estLiquidationPrice = data.estLiquidationPrice;
|
|
18489
|
-
},
|
|
18490
|
-
false
|
|
18491
|
-
// "updateOrderComputed"
|
|
18492
|
-
);
|
|
18493
|
-
},
|
|
18494
|
-
updateOrder: (order) => {
|
|
18495
|
-
set(
|
|
18496
|
-
(state) => {
|
|
18497
|
-
state.entry = {
|
|
18498
|
-
...state.entry,
|
|
18499
|
-
...order
|
|
18500
|
-
};
|
|
18501
|
-
},
|
|
18502
|
-
false
|
|
18503
|
-
// "updateOrder"
|
|
18504
|
-
);
|
|
18505
|
-
},
|
|
18506
|
-
updateOrderByKey: (key, value) => {
|
|
18507
|
-
set(
|
|
18508
|
-
(state) => {
|
|
18509
|
-
state.entry[key] = value;
|
|
18510
|
-
},
|
|
18511
|
-
false
|
|
18512
|
-
// "updateOrderByKey"
|
|
18513
|
-
);
|
|
18514
|
-
},
|
|
18515
|
-
restoreOrder: (order) => {
|
|
18516
|
-
set(
|
|
18517
|
-
(state) => {
|
|
18518
|
-
state.entry = order;
|
|
18519
|
-
},
|
|
18520
|
-
false
|
|
18521
|
-
// "restoreOrder"
|
|
18522
|
-
);
|
|
18523
|
-
},
|
|
18524
|
-
resetOrder: (order) => {
|
|
18525
|
-
set(
|
|
18526
|
-
(state) => {
|
|
18527
|
-
state.entry.order_price = "";
|
|
18528
|
-
state.entry.order_quantity = "";
|
|
18529
|
-
state.entry.trigger_price = "";
|
|
18530
|
-
state.entry.total = "";
|
|
18531
|
-
state.entry.tp_trigger_price = "";
|
|
18532
|
-
state.entry.tp_pnl = "";
|
|
18533
|
-
state.entry.tp_offset = "";
|
|
18534
|
-
state.entry.tp_offset_percentage = "";
|
|
18535
|
-
state.entry.sl_trigger_price = "";
|
|
18536
|
-
state.entry.sl_pnl = "";
|
|
18537
|
-
state.entry.sl_offset = "";
|
|
18538
|
-
state.entry.sl_offset_percentage = "";
|
|
18539
|
-
},
|
|
18540
|
-
true
|
|
18541
|
-
// "resetOrder"
|
|
18542
|
-
);
|
|
18543
|
-
}
|
|
18544
|
-
}
|
|
18545
|
-
}))
|
|
18546
|
-
);
|
|
18547
19192
|
var useOrderEntity = (order, options) => {
|
|
18548
19193
|
const { symbol } = order;
|
|
18549
19194
|
const { maxQty } = options || {};
|
|
@@ -18701,13 +19346,15 @@ var usePositionClose = (options) => {
|
|
|
18701
19346
|
symbol,
|
|
18702
19347
|
order_type: type,
|
|
18703
19348
|
side,
|
|
18704
|
-
reduce_only: true
|
|
19349
|
+
reduce_only: true,
|
|
19350
|
+
// Use position's margin_mode or default to CROSS for backward compatibility
|
|
19351
|
+
margin_mode: position.margin_mode || types.MarginMode.CROSS
|
|
18705
19352
|
};
|
|
18706
19353
|
if (type === types.OrderType.LIMIT) {
|
|
18707
19354
|
data.order_price = price;
|
|
18708
19355
|
}
|
|
18709
19356
|
return data;
|
|
18710
|
-
}, [symbol, price, type, quantity]);
|
|
19357
|
+
}, [symbol, price, type, quantity, position.margin_mode]);
|
|
18711
19358
|
const maxQty = React.useMemo(() => {
|
|
18712
19359
|
if (!position) {
|
|
18713
19360
|
return 0;
|
|
@@ -18909,9 +19556,11 @@ var useTpslPriceChecker = (params) => {
|
|
|
18909
19556
|
prevResultRef.current = currentResult;
|
|
18910
19557
|
return currentResult;
|
|
18911
19558
|
};
|
|
18912
|
-
var useEstLiqPriceBySymbol = (symbol) => {
|
|
19559
|
+
var useEstLiqPriceBySymbol = (symbol, marginMode) => {
|
|
18913
19560
|
const [data] = usePositionStream(symbol);
|
|
18914
|
-
const position = data?.rows?.find(
|
|
19561
|
+
const position = data?.rows?.find(
|
|
19562
|
+
(row) => row.symbol === symbol && row.margin_mode === marginMode
|
|
19563
|
+
);
|
|
18915
19564
|
return React.useMemo(() => {
|
|
18916
19565
|
return position?.est_liq_price ?? void 0;
|
|
18917
19566
|
}, [position]);
|
|
@@ -18932,6 +19581,62 @@ var useGetEstLiqPrice = (props) => {
|
|
|
18932
19581
|
return estLiqPrice;
|
|
18933
19582
|
}, [estLiqPrice, markPrice, side]);
|
|
18934
19583
|
};
|
|
19584
|
+
var useFeatureFlag = (key) => {
|
|
19585
|
+
const { data: publicFlags, isLoading: publicLoading } = useQuery("/v1/public/feature_flags", {});
|
|
19586
|
+
const publicFlag = React.useMemo(() => {
|
|
19587
|
+
if (!publicFlags || publicLoading) {
|
|
19588
|
+
return void 0;
|
|
19589
|
+
}
|
|
19590
|
+
return publicFlags.find((flag) => flag.key === key);
|
|
19591
|
+
}, [publicFlags, publicLoading, key]);
|
|
19592
|
+
const shouldQueryPrivate = React.useMemo(() => {
|
|
19593
|
+
return publicFlag !== void 0;
|
|
19594
|
+
}, [publicFlag]);
|
|
19595
|
+
const { data: privateFlags, isLoading: privateLoading } = usePrivateQuery(shouldQueryPrivate ? "/v1/feature_flags" : null, {});
|
|
19596
|
+
const privateFlag = React.useMemo(() => {
|
|
19597
|
+
if (!shouldQueryPrivate || !privateFlags || privateLoading) {
|
|
19598
|
+
return void 0;
|
|
19599
|
+
}
|
|
19600
|
+
return privateFlags.find((flag) => flag.key === key);
|
|
19601
|
+
}, [shouldQueryPrivate, privateFlags, privateLoading, key]);
|
|
19602
|
+
return React.useMemo(() => {
|
|
19603
|
+
if (publicLoading || shouldQueryPrivate && privateLoading) {
|
|
19604
|
+
return {
|
|
19605
|
+
enabled: false,
|
|
19606
|
+
data: void 0
|
|
19607
|
+
};
|
|
19608
|
+
}
|
|
19609
|
+
if (publicFlag === void 0) {
|
|
19610
|
+
return {
|
|
19611
|
+
enabled: true,
|
|
19612
|
+
data: void 0
|
|
19613
|
+
};
|
|
19614
|
+
}
|
|
19615
|
+
if (privateFlag === void 0) {
|
|
19616
|
+
return {
|
|
19617
|
+
enabled: false,
|
|
19618
|
+
data: void 0
|
|
19619
|
+
};
|
|
19620
|
+
}
|
|
19621
|
+
return {
|
|
19622
|
+
enabled: true,
|
|
19623
|
+
data: privateFlag
|
|
19624
|
+
};
|
|
19625
|
+
}, [
|
|
19626
|
+
publicFlag,
|
|
19627
|
+
privateFlag,
|
|
19628
|
+
publicLoading,
|
|
19629
|
+
shouldQueryPrivate,
|
|
19630
|
+
privateLoading,
|
|
19631
|
+
key
|
|
19632
|
+
]);
|
|
19633
|
+
};
|
|
19634
|
+
|
|
19635
|
+
// src/feature-flag/flagKeys.ts
|
|
19636
|
+
var FlagKeys = /* @__PURE__ */ ((FlagKeys2) => {
|
|
19637
|
+
FlagKeys2["IsolatedMargin"] = "isolated-margin";
|
|
19638
|
+
return FlagKeys2;
|
|
19639
|
+
})(FlagKeys || {});
|
|
18935
19640
|
|
|
18936
19641
|
exports.swr = useSWR5__namespace;
|
|
18937
19642
|
Object.defineProperty(exports, "unstable_serialize", {
|
|
@@ -18956,6 +19661,7 @@ exports.ENVType = ENVType2;
|
|
|
18956
19661
|
exports.ERROR_MSG_CODES = ERROR_MSG_CODES;
|
|
18957
19662
|
exports.EpochStatus = EpochStatus;
|
|
18958
19663
|
exports.ExtendedConfigStore = ExtendedConfigStore;
|
|
19664
|
+
exports.FlagKeys = FlagKeys;
|
|
18959
19665
|
exports.MaintenanceStatus = MaintenanceStatus;
|
|
18960
19666
|
exports.MarketsStorageKey = MarketsStorageKey;
|
|
18961
19667
|
exports.MarketsType = MarketsType;
|
|
@@ -19013,6 +19719,7 @@ exports.useDistributionHistory = useDistributionHistory;
|
|
|
19013
19719
|
exports.useEpochInfo = useEpochInfo;
|
|
19014
19720
|
exports.useEstLiqPriceBySymbol = useEstLiqPriceBySymbol;
|
|
19015
19721
|
exports.useEventEmitter = useEventEmitter;
|
|
19722
|
+
exports.useFeatureFlag = useFeatureFlag;
|
|
19016
19723
|
exports.useFeeState = useFeeState;
|
|
19017
19724
|
exports.useFundingDetails = useFundingDetails;
|
|
19018
19725
|
exports.useFundingFeeHistory = useFundingFeeHistory;
|
|
@@ -19043,6 +19750,8 @@ exports.useLocalStorage = useLocalStorage;
|
|
|
19043
19750
|
exports.useMainTokenStore = useMainTokenStore;
|
|
19044
19751
|
exports.useMainnetChainsStore = useMainnetChainsStore;
|
|
19045
19752
|
exports.useMaintenanceStatus = useMaintenanceStatus;
|
|
19753
|
+
exports.useMarginModeBySymbol = useMarginModeBySymbol;
|
|
19754
|
+
exports.useMarginModes = useMarginModes;
|
|
19046
19755
|
exports.useMarginRatio = useMarginRatio;
|
|
19047
19756
|
exports.useMarkPrice = useMarkPrice;
|
|
19048
19757
|
exports.useMarkPriceBySymbol = useMarkPriceBySymbol;
|
|
@@ -19065,7 +19774,7 @@ exports.useOdosQuote = useOdosQuote;
|
|
|
19065
19774
|
exports.useOrderEntity = useOrderEntity;
|
|
19066
19775
|
exports.useOrderEntry = useOrderEntry2;
|
|
19067
19776
|
exports.useOrderEntry_deprecated = useOrderEntry;
|
|
19068
|
-
exports.useOrderStore =
|
|
19777
|
+
exports.useOrderStore = useOrderStore;
|
|
19069
19778
|
exports.useOrderStream = useOrderStream;
|
|
19070
19779
|
exports.useOrderbookStream = useOrderbookStream;
|
|
19071
19780
|
exports.useOrderlyContext = useOrderlyContext;
|
|
@@ -19073,6 +19782,7 @@ exports.usePortfolio = usePortfolio;
|
|
|
19073
19782
|
exports.usePositionActions = usePositionActions;
|
|
19074
19783
|
exports.usePositionClose = usePositionClose;
|
|
19075
19784
|
exports.usePositionStream = usePositionStream;
|
|
19785
|
+
exports.usePositions = usePositions;
|
|
19076
19786
|
exports.usePoster = usePoster;
|
|
19077
19787
|
exports.usePreLoadData = usePreLoadData;
|
|
19078
19788
|
exports.usePrivateDataObserver = usePrivateDataObserver;
|
|
@@ -19102,6 +19812,7 @@ exports.useSubAccountWS = useSubAccountWS;
|
|
|
19102
19812
|
exports.useSwapSupportStore = useSwapSupportStore;
|
|
19103
19813
|
exports.useSymbolInfo = useSymbolInfo;
|
|
19104
19814
|
exports.useSymbolLeverage = useSymbolLeverage;
|
|
19815
|
+
exports.useSymbolLeverageMap = useSymbolLeverageMap;
|
|
19105
19816
|
exports.useSymbolPriceRange = useSymbolPriceRange;
|
|
19106
19817
|
exports.useSymbolsInfo = useSymbolsInfo;
|
|
19107
19818
|
exports.useSymbolsInfoStore = useSymbolsInfoStore;
|