@orderly.network/hooks 2.10.2 → 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.mjs
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { get, WS, mutate as mutate$1 } from '@orderly.network/net';
|
|
2
|
+
import React, { createContext, useContext, useCallback, useState, useEffect, useMemo, useRef, useId, useLayoutEffect } from 'react';
|
|
2
3
|
import useSWR5__default, { mutate } from 'swr';
|
|
3
4
|
import * as useSWR5 from 'swr';
|
|
4
5
|
export { useSWR5 as swr };
|
|
5
6
|
export { unstable_serialize, default as useSWR, useSWRConfig } from 'swr';
|
|
6
|
-
import { TesnetTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderType, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, EMPTY_LIST, EMPTY_OBJECT, isNativeTokenChecker, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, ETHEREUM_MAINNET_CHAINID, LedgerWalletKey, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, SolanaChains, PositionType, DistributionType, TriggerPriceType } from '@orderly.network/types';
|
|
7
|
-
import
|
|
7
|
+
import { TesnetTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, MarginMode, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderType, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, EMPTY_LIST, EMPTY_OBJECT, isNativeTokenChecker, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_TESTNET_CHAINID, ARBITRUM_MAINNET_CHAINID, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, ETHEREUM_MAINNET_CHAINID, LedgerWalletKey, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, SolanaChains, PositionType, DistributionType, TriggerPriceType } from '@orderly.network/types';
|
|
8
|
+
import { usePluginScope } from '@orderly.network/plugin-core';
|
|
8
9
|
import { zero, windowGuard, getTimestamp, getGlobalObject, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, getBBOType, camelCaseToUnderscoreCase, commify, todpIfNeed, getTPSLDirection } from '@orderly.network/utils';
|
|
9
10
|
import useSWRMutation from 'swr/mutation';
|
|
10
11
|
import useConstant from 'use-constant';
|
|
@@ -38,9 +39,9 @@ var __export = (target, all) => {
|
|
|
38
39
|
// src/version.ts
|
|
39
40
|
if (typeof window !== "undefined") {
|
|
40
41
|
window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
|
|
41
|
-
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "
|
|
42
|
+
window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "3.0.0-beta.0";
|
|
42
43
|
}
|
|
43
|
-
var version_default = "
|
|
44
|
+
var version_default = "3.0.0-beta.0";
|
|
44
45
|
var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
|
|
45
46
|
var noCacheConfig = {
|
|
46
47
|
dedupingInterval: 0,
|
|
@@ -71,21 +72,26 @@ function useConfig(key, defaultValue) {
|
|
|
71
72
|
}
|
|
72
73
|
return configStore;
|
|
73
74
|
}
|
|
74
|
-
|
|
75
|
-
// src/useQuery.ts
|
|
75
|
+
var PLUGIN_ID_HEADER = "X-Orderly-Plugin-Id";
|
|
76
76
|
var useQuery = (query, options) => {
|
|
77
77
|
const apiBaseUrl = useConfig("apiBaseUrl");
|
|
78
|
+
const pluginScope = usePluginScope();
|
|
78
79
|
const { formatter, ...swrOptions } = options || {};
|
|
79
80
|
if (typeof apiBaseUrl === "undefined") {
|
|
80
81
|
throw new SDKError("please add OrderlyConfigProvider to your app");
|
|
81
82
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
const fetcherFn = useCallback(
|
|
84
|
+
(url, init2) => {
|
|
85
|
+
const fullUrl = url.startsWith("http") ? url : `${apiBaseUrl}${url}`;
|
|
86
|
+
const headers = new Headers(init2?.headers);
|
|
87
|
+
if (pluginScope?.pluginId) {
|
|
88
|
+
headers.set(PLUGIN_ID_HEADER, pluginScope.pluginId);
|
|
89
|
+
}
|
|
90
|
+
return fetcher(fullUrl, { ...init2, headers }, { formatter });
|
|
91
|
+
},
|
|
92
|
+
[apiBaseUrl, pluginScope?.pluginId, formatter]
|
|
88
93
|
);
|
|
94
|
+
return useSWR5__default(query, fetcherFn, swrOptions);
|
|
89
95
|
};
|
|
90
96
|
var timestampOffsetPromise = null;
|
|
91
97
|
var timestampOffsetReady = false;
|
|
@@ -1084,12 +1090,12 @@ var findTPSLOrderPriceFromOrder = (order) => {
|
|
|
1084
1090
|
sl_order_price
|
|
1085
1091
|
};
|
|
1086
1092
|
};
|
|
1087
|
-
var findPositionTPSLFromOrders = (orders, symbol) => {
|
|
1093
|
+
var findPositionTPSLFromOrders = (orders, symbol, marginMode = MarginMode.CROSS) => {
|
|
1088
1094
|
const fullPositionOrder = orders?.find((order) => {
|
|
1089
|
-
return order.symbol === symbol && order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1095
|
+
return order.symbol === symbol && order.algo_type === AlgoOrderRootType.POSITIONAL_TP_SL && order.margin_mode === marginMode && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1090
1096
|
});
|
|
1091
1097
|
const partialPositionOrders = orders?.filter((order) => {
|
|
1092
|
-
return order.symbol === symbol && order.algo_type === AlgoOrderRootType.TP_SL && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1098
|
+
return order.symbol === symbol && order.margin_mode === marginMode && order.algo_type === AlgoOrderRootType.TP_SL && (order.root_algo_status === OrderStatus.NEW || order.root_algo_status === OrderStatus.REPLACED || order.root_algo_status === OrderStatus.PARTIAL_FILLED);
|
|
1093
1099
|
}).sort((a, b) => {
|
|
1094
1100
|
return b.created_time - a.created_time;
|
|
1095
1101
|
});
|
|
@@ -2114,9 +2120,11 @@ var useAppStore = create()(
|
|
|
2114
2120
|
totalCollateral: zero,
|
|
2115
2121
|
totalValue: null,
|
|
2116
2122
|
freeCollateral: zero,
|
|
2123
|
+
freeCollateralUSDCOnly: zero,
|
|
2117
2124
|
availableBalance: 0,
|
|
2118
2125
|
unsettledPnL: 0,
|
|
2119
|
-
totalUnrealizedROI: 0
|
|
2126
|
+
totalUnrealizedROI: 0,
|
|
2127
|
+
usdcHolding: 0
|
|
2120
2128
|
},
|
|
2121
2129
|
appState: {
|
|
2122
2130
|
positionsLoading: false,
|
|
@@ -2137,9 +2145,11 @@ var useAppStore = create()(
|
|
|
2137
2145
|
totalCollateral: zero,
|
|
2138
2146
|
totalValue: null,
|
|
2139
2147
|
freeCollateral: zero,
|
|
2148
|
+
freeCollateralUSDCOnly: zero,
|
|
2140
2149
|
availableBalance: 0,
|
|
2141
2150
|
unsettledPnL: 0,
|
|
2142
|
-
totalUnrealizedROI: 0
|
|
2151
|
+
totalUnrealizedROI: 0,
|
|
2152
|
+
usdcHolding: 0
|
|
2143
2153
|
};
|
|
2144
2154
|
}, false);
|
|
2145
2155
|
},
|
|
@@ -3935,25 +3945,27 @@ var OrderbookService = class _OrderbookService {
|
|
|
3935
3945
|
};
|
|
3936
3946
|
var orderBookService = OrderbookService.getInstance();
|
|
3937
3947
|
var orderbook_service_default = orderBookService;
|
|
3948
|
+
var useMarkPriceStore = create((set, get3) => ({
|
|
3949
|
+
markPrices: {},
|
|
3950
|
+
// orderBook: {},
|
|
3951
|
+
// ask_bid: [],
|
|
3952
|
+
actions: {
|
|
3953
|
+
updateMarkPrice: (markPrice) => {
|
|
3954
|
+
set({
|
|
3955
|
+
markPrices: markPrice
|
|
3956
|
+
});
|
|
3957
|
+
},
|
|
3958
|
+
getMarkPriceBySymbol: (symbol) => {
|
|
3959
|
+
return get3().markPrices[symbol];
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
}));
|
|
3963
|
+
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
3964
|
+
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
3965
|
+
|
|
3966
|
+
// src/orderly/useMarkPrice.ts
|
|
3938
3967
|
var useMarkPrice = (symbol) => {
|
|
3939
|
-
const
|
|
3940
|
-
const [price, setPrice] = useState(0);
|
|
3941
|
-
const symbolRef = useRef(symbol);
|
|
3942
|
-
symbolRef.current = symbol;
|
|
3943
|
-
useEffect(() => {
|
|
3944
|
-
const unsubscribe = ws.subscribe(`${symbol}@markprice`, {
|
|
3945
|
-
onMessage: (message) => {
|
|
3946
|
-
if (message.symbol !== symbolRef.current) {
|
|
3947
|
-
unsubscribe?.();
|
|
3948
|
-
return;
|
|
3949
|
-
}
|
|
3950
|
-
setPrice(message.price);
|
|
3951
|
-
}
|
|
3952
|
-
});
|
|
3953
|
-
return () => {
|
|
3954
|
-
unsubscribe?.();
|
|
3955
|
-
};
|
|
3956
|
-
}, [symbol]);
|
|
3968
|
+
const price = useMarkPriceBySymbol(symbol);
|
|
3957
3969
|
return { data: price };
|
|
3958
3970
|
};
|
|
3959
3971
|
var useIndexPrice = (symbol) => {
|
|
@@ -3976,6 +3988,12 @@ var useIndexPrice = (symbol) => {
|
|
|
3976
3988
|
};
|
|
3977
3989
|
});
|
|
3978
3990
|
};
|
|
3991
|
+
|
|
3992
|
+
// src/orderly/useMarkPricesStream.ts
|
|
3993
|
+
var useMarkPricesStream = () => {
|
|
3994
|
+
const data = useMarkPriceStore((state) => state.markPrices);
|
|
3995
|
+
return { data };
|
|
3996
|
+
};
|
|
3979
3997
|
var useOpenInterest = (symbol) => {
|
|
3980
3998
|
const ws = useWS();
|
|
3981
3999
|
const symbolRef = useRef(symbol);
|
|
@@ -3995,29 +4013,6 @@ var useOpenInterest = (symbol) => {
|
|
|
3995
4013
|
};
|
|
3996
4014
|
});
|
|
3997
4015
|
};
|
|
3998
|
-
var useMarkPriceStore = create((set, get3) => ({
|
|
3999
|
-
markPrices: {},
|
|
4000
|
-
// orderBook: {},
|
|
4001
|
-
// ask_bid: [],
|
|
4002
|
-
actions: {
|
|
4003
|
-
updateMarkPrice: (markPrice) => {
|
|
4004
|
-
set({
|
|
4005
|
-
markPrices: markPrice
|
|
4006
|
-
});
|
|
4007
|
-
},
|
|
4008
|
-
getMarkPriceBySymbol: (symbol) => {
|
|
4009
|
-
return get3().markPrices[symbol];
|
|
4010
|
-
}
|
|
4011
|
-
}
|
|
4012
|
-
}));
|
|
4013
|
-
var useMarkPriceBySymbol = (symbol) => useMarkPriceStore((state) => state.actions.getMarkPriceBySymbol(symbol));
|
|
4014
|
-
var useMarkPriceActions = () => useMarkPriceStore((state) => state.actions);
|
|
4015
|
-
|
|
4016
|
-
// src/orderly/useMarkPricesStream.ts
|
|
4017
|
-
var useMarkPricesStream = () => {
|
|
4018
|
-
const data = useMarkPriceStore((state) => state.markPrices);
|
|
4019
|
-
return { data };
|
|
4020
|
-
};
|
|
4021
4016
|
|
|
4022
4017
|
// src/orderly/useTickerStream.ts
|
|
4023
4018
|
var useTickerStream = (symbol) => {
|
|
@@ -4710,6 +4705,94 @@ var useLeverage = () => {
|
|
|
4710
4705
|
maxLeverage: memoizedMaxLeverage
|
|
4711
4706
|
};
|
|
4712
4707
|
};
|
|
4708
|
+
var buildKey = (symbol, marginMode) => `${symbol}_${marginMode ?? MarginMode.CROSS}`;
|
|
4709
|
+
var useSymbolLeverageMap = () => {
|
|
4710
|
+
const { data, error, isLoading, mutate: mutate6 } = usePrivateQuery("/v1/client/leverages", {
|
|
4711
|
+
revalidateOnFocus: false,
|
|
4712
|
+
revalidateOnReconnect: false,
|
|
4713
|
+
errorRetryCount: 1
|
|
4714
|
+
});
|
|
4715
|
+
const leverages = useMemo(() => {
|
|
4716
|
+
if (!data || !Array.isArray(data)) return {};
|
|
4717
|
+
const map = {};
|
|
4718
|
+
for (const item of data) {
|
|
4719
|
+
const key = buildKey(item.symbol, item.margin_mode);
|
|
4720
|
+
map[key] = item.leverage;
|
|
4721
|
+
}
|
|
4722
|
+
return map;
|
|
4723
|
+
}, [data]);
|
|
4724
|
+
const getSymbolLeverage = (symbol, marginMode) => {
|
|
4725
|
+
if (!symbol) return void 0;
|
|
4726
|
+
const key = buildKey(symbol, marginMode);
|
|
4727
|
+
return leverages[key];
|
|
4728
|
+
};
|
|
4729
|
+
return {
|
|
4730
|
+
leverages,
|
|
4731
|
+
getSymbolLeverage,
|
|
4732
|
+
isLoading,
|
|
4733
|
+
error,
|
|
4734
|
+
refresh: mutate6
|
|
4735
|
+
};
|
|
4736
|
+
};
|
|
4737
|
+
var useMarginModes = () => {
|
|
4738
|
+
const { data, error, isLoading, mutate: mutate6 } = usePrivateQuery("/v1/client/margin_modes", {
|
|
4739
|
+
revalidateOnFocus: false,
|
|
4740
|
+
revalidateOnMount: true
|
|
4741
|
+
});
|
|
4742
|
+
const [setMarginModeInternal, { isMutating }] = useMutation(
|
|
4743
|
+
"/v1/client/margin_mode",
|
|
4744
|
+
"POST"
|
|
4745
|
+
);
|
|
4746
|
+
const marginModes = useMemo(() => {
|
|
4747
|
+
if (!data || !Array.isArray(data)) return {};
|
|
4748
|
+
const map = {};
|
|
4749
|
+
for (const item of data) {
|
|
4750
|
+
map[item.symbol] = item.default_margin_mode;
|
|
4751
|
+
}
|
|
4752
|
+
return map;
|
|
4753
|
+
}, [data]);
|
|
4754
|
+
const setMarginMode = (payload) => setMarginModeInternal(payload);
|
|
4755
|
+
const updateMarginMode = useCallback(
|
|
4756
|
+
async (payload) => {
|
|
4757
|
+
const result = await setMarginMode(payload);
|
|
4758
|
+
if (result.success) {
|
|
4759
|
+
await mutate6();
|
|
4760
|
+
return result;
|
|
4761
|
+
}
|
|
4762
|
+
throw new Error(result.message ?? "Failed to update margin mode");
|
|
4763
|
+
},
|
|
4764
|
+
[setMarginMode, mutate6]
|
|
4765
|
+
);
|
|
4766
|
+
return {
|
|
4767
|
+
marginModes,
|
|
4768
|
+
isLoading,
|
|
4769
|
+
error,
|
|
4770
|
+
refresh: mutate6,
|
|
4771
|
+
setMarginMode,
|
|
4772
|
+
updateMarginMode,
|
|
4773
|
+
isMutating
|
|
4774
|
+
};
|
|
4775
|
+
};
|
|
4776
|
+
var useMarginModeBySymbol = (symbol, fallback = MarginMode.CROSS) => {
|
|
4777
|
+
const { marginModes, isLoading, error, refresh, updateMarginMode } = useMarginModes();
|
|
4778
|
+
const marginMode = fallback === null ? marginModes[symbol] : marginModes[symbol] ?? fallback;
|
|
4779
|
+
const update = useCallback(
|
|
4780
|
+
async (mode) => {
|
|
4781
|
+
return updateMarginMode({
|
|
4782
|
+
symbol_list: [symbol],
|
|
4783
|
+
default_margin_mode: mode
|
|
4784
|
+
});
|
|
4785
|
+
},
|
|
4786
|
+
[symbol, updateMarginMode]
|
|
4787
|
+
);
|
|
4788
|
+
return {
|
|
4789
|
+
marginMode,
|
|
4790
|
+
isLoading,
|
|
4791
|
+
error,
|
|
4792
|
+
refresh,
|
|
4793
|
+
update
|
|
4794
|
+
};
|
|
4795
|
+
};
|
|
4713
4796
|
|
|
4714
4797
|
// src/orderly/useOdosQuote.ts
|
|
4715
4798
|
var useOdosQuote = () => {
|
|
@@ -5067,10 +5150,13 @@ var CalculatorService = class {
|
|
|
5067
5150
|
// this.pendingCalc = [];
|
|
5068
5151
|
// }
|
|
5069
5152
|
async handleCalcQueue(context) {
|
|
5070
|
-
const
|
|
5071
|
-
|
|
5153
|
+
const batchCollector = /* @__PURE__ */ new Map();
|
|
5154
|
+
let currentContext = context;
|
|
5155
|
+
while (this.calcQueue.length > 0) {
|
|
5156
|
+
const first = this.calcQueue.shift();
|
|
5157
|
+
if (!first) break;
|
|
5072
5158
|
const { scope, data, options } = first;
|
|
5073
|
-
const ctx =
|
|
5159
|
+
const ctx = currentContext || CalculatorContext.create(scope, data);
|
|
5074
5160
|
const calculators = this.calculators.get(scope);
|
|
5075
5161
|
if (Array.isArray(calculators) && calculators.length) {
|
|
5076
5162
|
try {
|
|
@@ -5078,13 +5164,46 @@ var CalculatorService = class {
|
|
|
5078
5164
|
} catch (e) {
|
|
5079
5165
|
}
|
|
5080
5166
|
if (!options?.skipUpdate) {
|
|
5081
|
-
this.
|
|
5167
|
+
this.collectUpdates(
|
|
5168
|
+
batchCollector,
|
|
5169
|
+
scope,
|
|
5170
|
+
calculators,
|
|
5171
|
+
ctx.outputToValue()
|
|
5172
|
+
);
|
|
5082
5173
|
}
|
|
5083
5174
|
}
|
|
5084
|
-
|
|
5085
|
-
|
|
5175
|
+
currentContext = ctx;
|
|
5176
|
+
}
|
|
5177
|
+
await this.commitBatchUpdates(batchCollector);
|
|
5178
|
+
this.ctx = currentContext;
|
|
5179
|
+
}
|
|
5180
|
+
collectUpdates(collector, scope, calculators, data) {
|
|
5181
|
+
if (!collector.has(scope)) {
|
|
5182
|
+
collector.set(scope, /* @__PURE__ */ new Map());
|
|
5183
|
+
}
|
|
5184
|
+
const scopeCollector = collector.get(scope);
|
|
5185
|
+
for (const calculator of calculators) {
|
|
5186
|
+
const item = data[calculator.name];
|
|
5187
|
+
if (item !== void 0 && item !== null) {
|
|
5188
|
+
scopeCollector.set(calculator.name, item);
|
|
5189
|
+
}
|
|
5190
|
+
}
|
|
5191
|
+
}
|
|
5192
|
+
async commitBatchUpdates(collector) {
|
|
5193
|
+
if (collector.size === 0) return;
|
|
5194
|
+
for (const [scope, updateMap] of collector.entries()) {
|
|
5195
|
+
const calculators = this.calculators.get(scope);
|
|
5196
|
+
if (!Array.isArray(calculators)) continue;
|
|
5197
|
+
const batchData = {};
|
|
5198
|
+
for (const [calculatorName, data] of updateMap.entries()) {
|
|
5199
|
+
batchData[calculatorName] = data;
|
|
5200
|
+
}
|
|
5201
|
+
try {
|
|
5202
|
+
this.scheduler.update(scope, calculators, batchData);
|
|
5203
|
+
} catch (e) {
|
|
5086
5204
|
}
|
|
5087
5205
|
}
|
|
5206
|
+
collector.clear();
|
|
5088
5207
|
}
|
|
5089
5208
|
stop() {
|
|
5090
5209
|
this.calcQueue = [];
|
|
@@ -5115,6 +5234,18 @@ var cancelIdleCallbackPolyfill = (id) => {
|
|
|
5115
5234
|
var safeRequestIdleCallback = typeof window !== "undefined" && window.requestIdleCallback ? window.requestIdleCallback.bind(window) : requestIdleCallbackPolyfill;
|
|
5116
5235
|
typeof window !== "undefined" && window.cancelIdleCallback ? window.cancelIdleCallback.bind(window) : cancelIdleCallbackPolyfill;
|
|
5117
5236
|
var ShardingScheduler = class {
|
|
5237
|
+
constructor() {
|
|
5238
|
+
/**
|
|
5239
|
+
* Maximum continuous execution time per frame (in milliseconds)
|
|
5240
|
+
* Prevents blocking the main thread for too long
|
|
5241
|
+
*/
|
|
5242
|
+
this.MAX_CONTINUOUS_MS = 5;
|
|
5243
|
+
/**
|
|
5244
|
+
* Minimum remaining idle time threshold (in milliseconds)
|
|
5245
|
+
* Ensures the browser has enough idle time for other tasks
|
|
5246
|
+
*/
|
|
5247
|
+
this.MIN_IDLE_REMAINING = 2;
|
|
5248
|
+
}
|
|
5118
5249
|
// run(calculators: Calculator[]) {}
|
|
5119
5250
|
calc(scope, calculators, data, ctx) {
|
|
5120
5251
|
return new Promise((resolve, reject) => {
|
|
@@ -5155,28 +5286,27 @@ var ShardingScheduler = class {
|
|
|
5155
5286
|
computation(data, processor, onComplete) {
|
|
5156
5287
|
let index = 0;
|
|
5157
5288
|
const results = [];
|
|
5158
|
-
const
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5163
|
-
const
|
|
5164
|
-
|
|
5165
|
-
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5289
|
+
const MAX_CONTINUOUS_MS = this.MAX_CONTINUOUS_MS;
|
|
5290
|
+
const MIN_IDLE_REMAINING = this.MIN_IDLE_REMAINING;
|
|
5291
|
+
const processNextShard = (deadline) => {
|
|
5292
|
+
const frameStart = performance.now();
|
|
5293
|
+
while (index < data.length) {
|
|
5294
|
+
const elapsed = performance.now() - frameStart;
|
|
5295
|
+
const remaining = deadline.timeRemaining();
|
|
5296
|
+
if (elapsed > MAX_CONTINUOUS_MS || remaining < MIN_IDLE_REMAINING) {
|
|
5297
|
+
safeRequestIdleCallback(processNextShard, {
|
|
5298
|
+
timeout: 1e3
|
|
5299
|
+
});
|
|
5300
|
+
return;
|
|
5170
5301
|
}
|
|
5302
|
+
const result = processor([data[index]]);
|
|
5303
|
+
if (result && result.length > 0) {
|
|
5304
|
+
results.push(...result);
|
|
5305
|
+
}
|
|
5306
|
+
index++;
|
|
5171
5307
|
}
|
|
5172
|
-
|
|
5173
|
-
|
|
5174
|
-
timeout: 1e3
|
|
5175
|
-
});
|
|
5176
|
-
} else {
|
|
5177
|
-
onComplete(results.flat());
|
|
5178
|
-
}
|
|
5179
|
-
}
|
|
5308
|
+
onComplete(results);
|
|
5309
|
+
};
|
|
5180
5310
|
safeRequestIdleCallback(processNextShard, {
|
|
5181
5311
|
timeout: 1e3
|
|
5182
5312
|
});
|
|
@@ -5389,13 +5519,14 @@ var PositionCalculator = class extends BaseCalculator {
|
|
|
5389
5519
|
const unsettlementPnL = unsettlementPnL_total.toNumber();
|
|
5390
5520
|
let totalUnrealizedROI = 0, totalUnrealizedROI_index = 0;
|
|
5391
5521
|
if (portfolio) {
|
|
5392
|
-
const { totalValue, totalCollateral } = portfolio;
|
|
5522
|
+
const { totalValue, totalCollateral: crossMarginCollateral } = portfolio;
|
|
5393
5523
|
rows = rows.map((item) => {
|
|
5394
5524
|
const info = symbolsInfo[item.symbol];
|
|
5525
|
+
const totalCollateral = item.margin_mode === MarginMode.ISOLATED ? new Decimal(item.margin ?? 0).add(item.unsettlement_pnl ?? 0).toNumber() : crossMarginCollateral.toNumber();
|
|
5395
5526
|
const est_liq_price = positions.liqPrice({
|
|
5396
5527
|
symbol: item.symbol,
|
|
5397
5528
|
markPrice: item.mark_price,
|
|
5398
|
-
totalCollateral
|
|
5529
|
+
totalCollateral,
|
|
5399
5530
|
positionQty: item.position_qty,
|
|
5400
5531
|
positions: rows,
|
|
5401
5532
|
MMR: item.mmr,
|
|
@@ -5554,7 +5685,9 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5554
5685
|
return {
|
|
5555
5686
|
...item,
|
|
5556
5687
|
holding: data.holding[item.token].holding,
|
|
5557
|
-
frozen: data.holding[item.token].frozen
|
|
5688
|
+
frozen: data.holding[item.token].frozen,
|
|
5689
|
+
isolatedMargin: data.holding[item.token].isolatedMargin,
|
|
5690
|
+
isolatedOrderFrozen: data.holding[item.token].isolatedOrderFrozen
|
|
5558
5691
|
};
|
|
5559
5692
|
}
|
|
5560
5693
|
return item;
|
|
@@ -5590,7 +5723,14 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5590
5723
|
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo) {
|
|
5591
5724
|
return null;
|
|
5592
5725
|
}
|
|
5593
|
-
const
|
|
5726
|
+
const totallCrossUnsettledPnL = positions3.rows.reduce(
|
|
5727
|
+
(sum, pos) => pos.margin_mode === MarginMode.ISOLATED ? sum : sum + (pos.unsettled_pnl ?? 0),
|
|
5728
|
+
0
|
|
5729
|
+
);
|
|
5730
|
+
const totalUnsettlementPnL = positions3.rows.reduce(
|
|
5731
|
+
(sum, pos) => sum + (pos.unsettled_pnl ?? 0),
|
|
5732
|
+
0
|
|
5733
|
+
);
|
|
5594
5734
|
const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
5595
5735
|
const [USDC_holding, nonUSDC] = parseHolding(
|
|
5596
5736
|
holding,
|
|
@@ -5601,28 +5741,51 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5601
5741
|
const totalCollateral = account.totalCollateral({
|
|
5602
5742
|
USDCHolding: USDC_holding,
|
|
5603
5743
|
nonUSDCHolding: nonUSDC,
|
|
5604
|
-
unsettlementPnL:
|
|
5744
|
+
unsettlementPnL: totallCrossUnsettledPnL,
|
|
5745
|
+
usdcBalancePendingShortQty: usdc?.pending_short ?? 0,
|
|
5746
|
+
usdcBalanceIsolatedOrderFrozen: usdc?.isolated_order_frozen ?? 0
|
|
5605
5747
|
});
|
|
5748
|
+
const sumIsolatedMargin = positions3.rows.reduce((acc, curr) => {
|
|
5749
|
+
if (curr.margin_mode !== MarginMode.ISOLATED) {
|
|
5750
|
+
return acc;
|
|
5751
|
+
}
|
|
5752
|
+
return acc.add(curr.margin ?? 0);
|
|
5753
|
+
}, zero);
|
|
5606
5754
|
const totalValue = account.totalValue({
|
|
5607
|
-
totalUnsettlementPnL
|
|
5755
|
+
totalUnsettlementPnL,
|
|
5608
5756
|
USDCHolding: USDC_holding,
|
|
5609
|
-
nonUSDCHolding: nonUSDC
|
|
5757
|
+
nonUSDCHolding: nonUSDC,
|
|
5758
|
+
totalIsolatedPositionMargin: sumIsolatedMargin.toNumber()
|
|
5610
5759
|
});
|
|
5611
5760
|
const totalUnrealizedROI = account.totalUnrealizedROI({
|
|
5612
5761
|
totalUnrealizedPnL: unrealizedPnL,
|
|
5613
5762
|
totalValue: totalValue.toNumber()
|
|
5614
5763
|
});
|
|
5764
|
+
const maxLeverageBySymbol = positions3.rows.reduce(
|
|
5765
|
+
(acc, position) => {
|
|
5766
|
+
if (position.margin_mode !== MarginMode.ISOLATED && position.leverage && !acc[position.symbol]) {
|
|
5767
|
+
acc[position.symbol] = position.leverage;
|
|
5768
|
+
}
|
|
5769
|
+
return acc;
|
|
5770
|
+
},
|
|
5771
|
+
{}
|
|
5772
|
+
);
|
|
5615
5773
|
const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
|
|
5616
5774
|
positions: positions3.rows,
|
|
5775
|
+
orders: [],
|
|
5617
5776
|
markPrices,
|
|
5618
5777
|
IMR_Factors: accountInfo.imr_factor,
|
|
5619
|
-
|
|
5778
|
+
maxLeverageBySymbol,
|
|
5620
5779
|
symbolInfo: createGetter({ ...symbolsInfo })
|
|
5621
5780
|
});
|
|
5622
5781
|
const freeCollateral = account.freeCollateral({
|
|
5623
5782
|
totalCollateral,
|
|
5624
5783
|
totalInitialMarginWithOrders
|
|
5625
5784
|
});
|
|
5785
|
+
const freeCollateralUSDCOnly = account.freeCollateralUSDCOnly({
|
|
5786
|
+
freeCollateral,
|
|
5787
|
+
nonUSDCHolding: nonUSDC
|
|
5788
|
+
});
|
|
5626
5789
|
const availableBalance = account.availableBalance({
|
|
5627
5790
|
USDCHolding: usdc?.holding ?? 0,
|
|
5628
5791
|
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
@@ -5633,8 +5796,10 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5633
5796
|
totalUnrealizedROI,
|
|
5634
5797
|
freeCollateral,
|
|
5635
5798
|
availableBalance,
|
|
5636
|
-
unsettledPnL,
|
|
5637
|
-
holding
|
|
5799
|
+
unsettledPnL: totalUnsettlementPnL,
|
|
5800
|
+
holding,
|
|
5801
|
+
usdcHolding: USDC_holding,
|
|
5802
|
+
freeCollateralUSDCOnly
|
|
5638
5803
|
};
|
|
5639
5804
|
}
|
|
5640
5805
|
update(data, scope) {
|
|
@@ -5643,10 +5808,12 @@ var PortfolioCalculator = class extends BaseCalculator {
|
|
|
5643
5808
|
totalCollateral: data.totalCollateral,
|
|
5644
5809
|
totalValue: data.totalValue,
|
|
5645
5810
|
freeCollateral: data.freeCollateral,
|
|
5811
|
+
freeCollateralUSDCOnly: data.freeCollateralUSDCOnly,
|
|
5646
5812
|
availableBalance: data.availableBalance,
|
|
5647
5813
|
totalUnrealizedROI: data.totalUnrealizedROI,
|
|
5648
5814
|
unsettledPnL: data.unsettledPnL,
|
|
5649
|
-
holding: Array.isArray(data.holding) ? data.holding : []
|
|
5815
|
+
holding: Array.isArray(data.holding) ? data.holding : [],
|
|
5816
|
+
usdcHolding: typeof data.usdcHolding === "number" ? data.usdcHolding : data.usdcHolding.toNumber()
|
|
5650
5817
|
});
|
|
5651
5818
|
}
|
|
5652
5819
|
}
|
|
@@ -5777,7 +5944,7 @@ var usePositionStream = (symbol = "all", options) => {
|
|
|
5777
5944
|
}
|
|
5778
5945
|
if (Array.isArray(tpslOrders) && tpslOrders.length) {
|
|
5779
5946
|
rows = rows.map((item) => {
|
|
5780
|
-
const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol);
|
|
5947
|
+
const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol, item.margin_mode);
|
|
5781
5948
|
const full_tp_sl = fullPositionOrder ? findTPSLFromOrder(fullPositionOrder) : void 0;
|
|
5782
5949
|
const partialPossitionOrder = partialPositionOrders && partialPositionOrders.length ? partialPositionOrders[0] : void 0;
|
|
5783
5950
|
const partial_tp_sl = partialPossitionOrder ? findTPSLFromOrder(partialPossitionOrder) : void 0;
|
|
@@ -5909,15 +6076,21 @@ var useOrderStream = (params, options) => {
|
|
|
5909
6076
|
}
|
|
5910
6077
|
};
|
|
5911
6078
|
}, [normalOrderKeyFn, options?.keeplive]);
|
|
5912
|
-
const normalOrdersResponse = usePrivateInfiniteQuery(
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
6079
|
+
const normalOrdersResponse = usePrivateInfiniteQuery(
|
|
6080
|
+
normalOrderKeyFn,
|
|
6081
|
+
{
|
|
6082
|
+
initialSize: 1,
|
|
6083
|
+
formatter: (data) => data,
|
|
6084
|
+
revalidateOnFocus: false
|
|
6085
|
+
}
|
|
6086
|
+
);
|
|
6087
|
+
const algoOrdersResponse = usePrivateInfiniteQuery(
|
|
6088
|
+
algoOrderKeyFn,
|
|
6089
|
+
{
|
|
6090
|
+
formatter: (data) => data,
|
|
6091
|
+
revalidateOnFocus: false
|
|
6092
|
+
}
|
|
6093
|
+
);
|
|
5921
6094
|
const flattenOrders = useMemo(() => {
|
|
5922
6095
|
if (!normalOrdersResponse.data || !algoOrdersResponse.data && !sourceTypeAll) {
|
|
5923
6096
|
return null;
|
|
@@ -6035,7 +6208,9 @@ var useOrderStream = (params, options) => {
|
|
|
6035
6208
|
// trailing stop order fields
|
|
6036
6209
|
activated_price: order.activated_price,
|
|
6037
6210
|
callback_value: order.callback_value,
|
|
6038
|
-
callback_rate: order.callback_rate
|
|
6211
|
+
callback_rate: order.callback_rate,
|
|
6212
|
+
// Include margin_mode if present
|
|
6213
|
+
...order.margin_mode && { margin_mode: order.margin_mode }
|
|
6039
6214
|
});
|
|
6040
6215
|
default:
|
|
6041
6216
|
return doUpdateOrder({ ...order, order_id: orderId });
|
|
@@ -6230,7 +6405,14 @@ function formatPortfolio(inputs) {
|
|
|
6230
6405
|
if (!holding || !positions3 || !Array.isArray(positions3.rows) || !markPrices || !indexPrices || !accountInfo || symbolsInfo?.isNil) {
|
|
6231
6406
|
return null;
|
|
6232
6407
|
}
|
|
6233
|
-
const
|
|
6408
|
+
const totallCrossUnsettledPnL = positions3.rows.reduce(
|
|
6409
|
+
(sum, pos) => pos.margin_mode === MarginMode.ISOLATED ? sum : sum + (pos.unsettled_pnl ?? 0),
|
|
6410
|
+
0
|
|
6411
|
+
);
|
|
6412
|
+
const totalUnsettlementPnL = positions3.rows.reduce(
|
|
6413
|
+
(sum, pos) => sum + (pos.unsettled_pnl ?? 0),
|
|
6414
|
+
0
|
|
6415
|
+
);
|
|
6234
6416
|
const unrealizedPnL = pathOr(0, ["total_unreal_pnl"])(positions3);
|
|
6235
6417
|
const [USDC_holding, nonUSDC] = parseHolding(
|
|
6236
6418
|
holding,
|
|
@@ -6241,29 +6423,51 @@ function formatPortfolio(inputs) {
|
|
|
6241
6423
|
const totalCollateral = account.totalCollateral({
|
|
6242
6424
|
USDCHolding: USDC_holding,
|
|
6243
6425
|
nonUSDCHolding: nonUSDC,
|
|
6244
|
-
unsettlementPnL:
|
|
6426
|
+
unsettlementPnL: totallCrossUnsettledPnL,
|
|
6427
|
+
usdcBalancePendingShortQty: usdc?.pending_short ?? 0,
|
|
6428
|
+
usdcBalanceIsolatedOrderFrozen: usdc?.isolated_order_frozen ?? 0
|
|
6245
6429
|
});
|
|
6430
|
+
const sumIsolatedMargin = positions3.rows.reduce((acc, curr) => {
|
|
6431
|
+
if (curr.margin_mode !== MarginMode.ISOLATED) {
|
|
6432
|
+
return acc;
|
|
6433
|
+
}
|
|
6434
|
+
return acc.add(curr.margin ?? 0);
|
|
6435
|
+
}, zero);
|
|
6246
6436
|
const totalValue = account.totalValue({
|
|
6247
|
-
totalUnsettlementPnL
|
|
6437
|
+
totalUnsettlementPnL,
|
|
6248
6438
|
USDCHolding: USDC_holding,
|
|
6249
|
-
nonUSDCHolding: nonUSDC
|
|
6439
|
+
nonUSDCHolding: nonUSDC,
|
|
6440
|
+
totalIsolatedPositionMargin: sumIsolatedMargin.toNumber()
|
|
6250
6441
|
});
|
|
6251
6442
|
const totalUnrealizedROI = account.totalUnrealizedROI({
|
|
6252
6443
|
totalUnrealizedPnL: unrealizedPnL,
|
|
6253
6444
|
totalValue: totalValue.toNumber()
|
|
6254
6445
|
});
|
|
6446
|
+
const maxLeverageBySymbol = positions3.rows.reduce(
|
|
6447
|
+
(acc, position) => {
|
|
6448
|
+
if (position.margin_mode !== MarginMode.ISOLATED && position.leverage && !acc[position.symbol]) {
|
|
6449
|
+
acc[position.symbol] = position.leverage;
|
|
6450
|
+
}
|
|
6451
|
+
return acc;
|
|
6452
|
+
},
|
|
6453
|
+
{}
|
|
6454
|
+
);
|
|
6255
6455
|
const totalInitialMarginWithOrders = account.totalInitialMarginWithQty({
|
|
6256
6456
|
positions: positions3.rows,
|
|
6457
|
+
orders: [],
|
|
6257
6458
|
markPrices,
|
|
6258
6459
|
IMR_Factors: accountInfo.imr_factor,
|
|
6259
|
-
|
|
6260
|
-
|
|
6261
|
-
symbolInfo: symbolsInfo
|
|
6460
|
+
maxLeverageBySymbol,
|
|
6461
|
+
symbolInfo: createGetter({ ...symbolsInfo })
|
|
6262
6462
|
});
|
|
6263
6463
|
const freeCollateral = account.freeCollateral({
|
|
6264
6464
|
totalCollateral,
|
|
6265
6465
|
totalInitialMarginWithOrders
|
|
6266
6466
|
});
|
|
6467
|
+
const freeCollateralUSDCOnly = account.freeCollateralUSDCOnly({
|
|
6468
|
+
freeCollateral,
|
|
6469
|
+
nonUSDCHolding: nonUSDC
|
|
6470
|
+
});
|
|
6267
6471
|
const availableBalance = account.availableBalance({
|
|
6268
6472
|
USDCHolding: usdc?.holding ?? 0,
|
|
6269
6473
|
unsettlementPnL: positions3.total_unsettled_pnl ?? 0
|
|
@@ -6274,8 +6478,9 @@ function formatPortfolio(inputs) {
|
|
|
6274
6478
|
totalUnrealizedROI,
|
|
6275
6479
|
freeCollateral,
|
|
6276
6480
|
availableBalance,
|
|
6277
|
-
unsettledPnL,
|
|
6278
|
-
holding
|
|
6481
|
+
unsettledPnL: totalUnsettlementPnL,
|
|
6482
|
+
holding,
|
|
6483
|
+
freeCollateralUSDCOnly
|
|
6279
6484
|
};
|
|
6280
6485
|
}
|
|
6281
6486
|
function formatPositions(data, accountInfo, symbolsInfo, fundingRates) {
|
|
@@ -6795,7 +7000,9 @@ var useSubAccountAlgoOrderStream = (params, options) => {
|
|
|
6795
7000
|
// trailing stop order fields
|
|
6796
7001
|
activated_price: order.activated_price,
|
|
6797
7002
|
callback_value: order.callback_value,
|
|
6798
|
-
callback_rate: order.callback_rate
|
|
7003
|
+
callback_rate: order.callback_rate,
|
|
7004
|
+
// include margin_mode if present (align with useOrderStream)
|
|
7005
|
+
...order.margin_mode && { margin_mode: order.margin_mode }
|
|
6799
7006
|
});
|
|
6800
7007
|
default:
|
|
6801
7008
|
return doUpdateOrder({ ...order, order_id: orderId });
|
|
@@ -6982,120 +7189,122 @@ var useCollateral = (options = { dp: 6 }) => {
|
|
|
6982
7189
|
totalCollateral,
|
|
6983
7190
|
totalValue,
|
|
6984
7191
|
freeCollateral,
|
|
7192
|
+
freeCollateralUSDCOnly,
|
|
6985
7193
|
availableBalance,
|
|
6986
7194
|
unsettledPnL,
|
|
6987
|
-
holding
|
|
7195
|
+
holding,
|
|
7196
|
+
usdcHolding
|
|
6988
7197
|
} = useAppStore((state) => state.portfolio);
|
|
6989
7198
|
const accountInfo = useAppStore((state) => state.accountInfo);
|
|
6990
7199
|
return {
|
|
6991
7200
|
totalCollateral: totalCollateral.toDecimalPlaces(dp).toNumber(),
|
|
6992
7201
|
freeCollateral: freeCollateral.toDecimalPlaces(dp).toNumber(),
|
|
7202
|
+
freeCollateralUSDCOnly: freeCollateralUSDCOnly.toDecimalPlaces(dp).toNumber(),
|
|
6993
7203
|
totalValue: totalValue?.toDecimalPlaces(dp).toNumber() ?? null,
|
|
6994
7204
|
availableBalance,
|
|
6995
7205
|
unsettledPnL,
|
|
6996
7206
|
accountInfo,
|
|
6997
|
-
holding
|
|
7207
|
+
holding,
|
|
7208
|
+
usdcHolding
|
|
6998
7209
|
// @hidden
|
|
6999
7210
|
// positions: positionsPath(positions),
|
|
7000
7211
|
};
|
|
7001
7212
|
};
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
const {
|
|
7006
|
-
|
|
7007
|
-
{
|
|
7008
|
-
revalidateOnFocus: false
|
|
7009
|
-
}
|
|
7010
|
-
);
|
|
7011
|
-
useEffect(() => {
|
|
7012
|
-
if (!state.accountId || !symbol) return;
|
|
7013
|
-
const unsubscribe = ws.privateSubscribe("account", {
|
|
7014
|
-
onMessage: (data2) => {
|
|
7015
|
-
const res = data2?.accountDetail?.symbolLeverage || {};
|
|
7016
|
-
if (res.symbol === symbol) {
|
|
7017
|
-
const key = [`/v1/client/leverage?symbol=${symbol}`, state.accountId];
|
|
7018
|
-
mutate(
|
|
7019
|
-
key,
|
|
7020
|
-
(prevData) => {
|
|
7021
|
-
return {
|
|
7022
|
-
...prevData,
|
|
7023
|
-
leverage: res.leverage
|
|
7024
|
-
};
|
|
7025
|
-
},
|
|
7026
|
-
{
|
|
7027
|
-
revalidate: false
|
|
7028
|
-
}
|
|
7029
|
-
);
|
|
7030
|
-
}
|
|
7031
|
-
}
|
|
7032
|
-
});
|
|
7033
|
-
return () => unsubscribe?.();
|
|
7034
|
-
}, [symbol, state.accountId]);
|
|
7035
|
-
return data?.leverage;
|
|
7213
|
+
|
|
7214
|
+
// src/orderly/useLeverageBySymbol.ts
|
|
7215
|
+
var useLeverageBySymbol = (symbol, marginMode) => {
|
|
7216
|
+
const { getSymbolLeverage } = useSymbolLeverageMap();
|
|
7217
|
+
return getSymbolLeverage(symbol, marginMode);
|
|
7036
7218
|
};
|
|
7037
7219
|
|
|
7038
7220
|
// src/orderly/useMaxQty.ts
|
|
7039
|
-
|
|
7221
|
+
function useMaxQty(symbol, side, reduceOnlyOrOptions, marginMode) {
|
|
7222
|
+
const reduceOnly = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.reduceOnly ?? false : reduceOnlyOrOptions ?? false;
|
|
7223
|
+
const finalMarginMode = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null ? reduceOnlyOrOptions.marginMode ?? MarginMode.CROSS : marginMode ?? MarginMode.CROSS;
|
|
7040
7224
|
const positions3 = usePositions();
|
|
7041
7225
|
const accountInfo = useAccountInfo();
|
|
7042
7226
|
const symbolInfo = useSymbolsInfo();
|
|
7043
|
-
const { totalCollateral } = useCollateral();
|
|
7227
|
+
const { totalCollateral, freeCollateralUSDCOnly } = useCollateral();
|
|
7044
7228
|
const { data: markPrices } = useMarkPricesStream();
|
|
7045
|
-
const symbolLeverage = useLeverageBySymbol(symbol);
|
|
7229
|
+
const symbolLeverage = useLeverageBySymbol(symbol, finalMarginMode);
|
|
7046
7230
|
const maxQty = useMemo(() => {
|
|
7047
7231
|
if (!symbol) return 0;
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7232
|
+
if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3) {
|
|
7233
|
+
return 0;
|
|
7234
|
+
}
|
|
7235
|
+
const positionsArray = (positions3 === null ? [] : positions3).filter(
|
|
7236
|
+
(position) => position.margin_mode === finalMarginMode
|
|
7051
7237
|
);
|
|
7238
|
+
const positionQty = account.getQtyFromPositions(positionsArray, symbol);
|
|
7052
7239
|
if (reduceOnly) {
|
|
7053
|
-
if (positionQty
|
|
7054
|
-
|
|
7055
|
-
return 0;
|
|
7056
|
-
} else {
|
|
7057
|
-
return Math.abs(positionQty);
|
|
7058
|
-
}
|
|
7059
|
-
}
|
|
7060
|
-
if (positionQty < 0) {
|
|
7061
|
-
if (side === OrderSide.BUY) {
|
|
7062
|
-
return Math.abs(positionQty);
|
|
7063
|
-
} else {
|
|
7064
|
-
return 0;
|
|
7065
|
-
}
|
|
7066
|
-
}
|
|
7067
|
-
return 0;
|
|
7240
|
+
if (positionQty === 0) return 0;
|
|
7241
|
+
return side === OrderSide.BUY ? positionQty < 0 ? Math.abs(positionQty) : 0 : positionQty > 0 ? positionQty : 0;
|
|
7068
7242
|
}
|
|
7069
|
-
if (!markPrices || !markPrices[symbol] || !accountInfo || !positions3)
|
|
7070
|
-
return 0;
|
|
7071
7243
|
const getSymbolInfo = symbolInfo[symbol];
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
)
|
|
7244
|
+
let currentSymbolPosition;
|
|
7245
|
+
const otherPositions = [];
|
|
7246
|
+
for (const position of positionsArray) {
|
|
7247
|
+
if (position.symbol === symbol) {
|
|
7248
|
+
currentSymbolPosition = position;
|
|
7249
|
+
} else {
|
|
7250
|
+
otherPositions.push(position);
|
|
7251
|
+
}
|
|
7252
|
+
}
|
|
7253
|
+
const markPrice = markPrices[symbol];
|
|
7254
|
+
const baseIMR = getSymbolInfo("base_imr") ?? 0;
|
|
7255
|
+
const IMR_Factor = accountInfo.imr_factor[symbol] ?? 0;
|
|
7256
|
+
const leverage = symbolLeverage || currentSymbolPosition?.leverage || 1;
|
|
7075
7257
|
const buyOrdersQty = currentSymbolPosition?.pending_long_qty ?? 0;
|
|
7076
7258
|
const sellOrdersQty = currentSymbolPosition?.pending_short_qty ?? 0;
|
|
7077
|
-
|
|
7259
|
+
if (finalMarginMode === MarginMode.ISOLATED) {
|
|
7260
|
+
const availableBalance = freeCollateralUSDCOnly;
|
|
7261
|
+
const pendingLongOrders = buyOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: buyOrdersQty }] : [];
|
|
7262
|
+
const pendingSellOrders = sellOrdersQty > 0 ? [{ referencePrice: markPrice, quantity: sellOrdersQty }] : [];
|
|
7263
|
+
const markPriceDecimal = new Decimal(markPrice);
|
|
7264
|
+
const leverageDecimal = new Decimal(leverage);
|
|
7265
|
+
const isoOrderFrozenLong = buyOrdersQty > 0 ? markPriceDecimal.mul(buyOrdersQty).div(leverageDecimal).toNumber() : 0;
|
|
7266
|
+
const isoOrderFrozenShort = sellOrdersQty > 0 ? markPriceDecimal.mul(sellOrdersQty).div(leverageDecimal).toNumber() : 0;
|
|
7267
|
+
const symbolMaxNotional = accountInfo.max_notional?.[symbol] ?? positions.maxPositionNotional({
|
|
7268
|
+
leverage,
|
|
7269
|
+
IMRFactor: IMR_Factor
|
|
7270
|
+
});
|
|
7271
|
+
const currentOrderReferencePrice = typeof reduceOnlyOrOptions === "object" && reduceOnlyOrOptions !== null && typeof reduceOnlyOrOptions.currentOrderReferencePrice === "number" && reduceOnlyOrOptions.currentOrderReferencePrice > 0 ? reduceOnlyOrOptions.currentOrderReferencePrice : markPrice;
|
|
7272
|
+
return account.maxQtyForIsolatedMargin({
|
|
7273
|
+
symbol,
|
|
7274
|
+
orderSide: side,
|
|
7275
|
+
currentOrderReferencePrice,
|
|
7276
|
+
availableBalance,
|
|
7277
|
+
leverage,
|
|
7278
|
+
baseIMR,
|
|
7279
|
+
IMR_Factor,
|
|
7280
|
+
markPrice,
|
|
7281
|
+
positionQty,
|
|
7282
|
+
pendingLongOrders,
|
|
7283
|
+
pendingSellOrders,
|
|
7284
|
+
isoOrderFrozenLong,
|
|
7285
|
+
isoOrderFrozenShort,
|
|
7286
|
+
symbolMaxNotional
|
|
7287
|
+
});
|
|
7288
|
+
}
|
|
7078
7289
|
const otherIMs = account.otherIMs({
|
|
7079
7290
|
positions: otherPositions,
|
|
7080
7291
|
symbolInfo,
|
|
7081
7292
|
markPrices,
|
|
7082
|
-
IMR_Factors: accountInfo.imr_factor
|
|
7083
|
-
// Not used
|
|
7084
|
-
maxLeverage: accountInfo.max_leverage
|
|
7293
|
+
IMR_Factors: accountInfo.imr_factor
|
|
7085
7294
|
});
|
|
7086
7295
|
return account.maxQty(side, {
|
|
7087
|
-
markPrice
|
|
7296
|
+
markPrice,
|
|
7088
7297
|
symbol,
|
|
7089
7298
|
baseMaxQty: getSymbolInfo("base_max"),
|
|
7090
7299
|
totalCollateral,
|
|
7091
|
-
maxLeverage:
|
|
7300
|
+
maxLeverage: leverage,
|
|
7092
7301
|
takerFeeRate: accountInfo.futures_taker_fee_rate,
|
|
7093
|
-
baseIMR
|
|
7302
|
+
baseIMR,
|
|
7094
7303
|
otherIMs,
|
|
7095
7304
|
positionQty,
|
|
7096
7305
|
buyOrdersQty,
|
|
7097
7306
|
sellOrdersQty,
|
|
7098
|
-
IMR_Factor
|
|
7307
|
+
IMR_Factor
|
|
7099
7308
|
});
|
|
7100
7309
|
}, [
|
|
7101
7310
|
symbol,
|
|
@@ -7105,10 +7314,12 @@ var useMaxQty = (symbol, side, reduceOnly = false) => {
|
|
|
7105
7314
|
accountInfo,
|
|
7106
7315
|
symbolInfo,
|
|
7107
7316
|
side,
|
|
7108
|
-
totalCollateral
|
|
7317
|
+
totalCollateral,
|
|
7318
|
+
finalMarginMode,
|
|
7319
|
+
symbolLeverage
|
|
7109
7320
|
]);
|
|
7110
7321
|
return Math.max(maxQty, 0);
|
|
7111
|
-
}
|
|
7322
|
+
}
|
|
7112
7323
|
var useMarginRatio = () => {
|
|
7113
7324
|
const positions3 = usePositionStore((state2) => state2.positions.all);
|
|
7114
7325
|
const { rows, notional } = positions3;
|
|
@@ -8414,56 +8625,94 @@ var usePrivateDataObserver = (options) => {
|
|
|
8414
8625
|
}, [state.accountId, subOrder]);
|
|
8415
8626
|
useEffect(() => {
|
|
8416
8627
|
if (!state.accountId) return;
|
|
8417
|
-
const
|
|
8628
|
+
const positionsKey = ["/v1/positions", state.accountId];
|
|
8629
|
+
const leveragesKey = ["/v1/client/leverages", state.accountId];
|
|
8418
8630
|
const unsubscribe = ws.privateSubscribe("account", {
|
|
8419
8631
|
onMessage: (data) => {
|
|
8420
|
-
const { symbol, leverage } = data?.accountDetail?.symbolLeverage || {};
|
|
8421
|
-
if (symbol
|
|
8422
|
-
|
|
8423
|
-
key,
|
|
8424
|
-
(prevPositions) => {
|
|
8425
|
-
if (prevPositions?.rows?.length) {
|
|
8426
|
-
return {
|
|
8427
|
-
...prevPositions,
|
|
8428
|
-
rows: prevPositions.rows.map((row) => {
|
|
8429
|
-
return row.symbol === symbol ? { ...row, leverage } : row;
|
|
8430
|
-
})
|
|
8431
|
-
};
|
|
8432
|
-
}
|
|
8433
|
-
return prevPositions;
|
|
8434
|
-
},
|
|
8435
|
-
{
|
|
8436
|
-
revalidate: false
|
|
8437
|
-
}
|
|
8438
|
-
);
|
|
8632
|
+
const { symbol, leverage, marginMode } = data?.accountDetail?.symbolLeverage || {};
|
|
8633
|
+
if (!symbol || leverage === void 0) {
|
|
8634
|
+
return;
|
|
8439
8635
|
}
|
|
8440
|
-
}
|
|
8441
|
-
});
|
|
8442
|
-
return () => unsubscribe?.();
|
|
8443
|
-
}, [state.accountId]);
|
|
8444
|
-
useEffect(() => {
|
|
8445
|
-
if (!state.accountId) {
|
|
8446
|
-
return;
|
|
8447
|
-
}
|
|
8448
|
-
const key = ["/v1/positions", state.accountId];
|
|
8449
|
-
const unsubscribe = ws.privateSubscribe("position", {
|
|
8450
|
-
onMessage: (data) => {
|
|
8451
|
-
const { positions: nextPositions } = data;
|
|
8452
8636
|
mutate(
|
|
8453
|
-
|
|
8637
|
+
positionsKey,
|
|
8454
8638
|
(prevPositions) => {
|
|
8455
|
-
if (
|
|
8456
|
-
|
|
8639
|
+
if (prevPositions?.rows?.length) {
|
|
8640
|
+
return {
|
|
8457
8641
|
...prevPositions,
|
|
8458
8642
|
rows: prevPositions.rows.map((row) => {
|
|
8459
|
-
|
|
8460
|
-
|
|
8461
|
-
|
|
8462
|
-
|
|
8463
|
-
|
|
8464
|
-
|
|
8465
|
-
|
|
8466
|
-
|
|
8643
|
+
return row.symbol === symbol && row.margin_mode === marginMode ? { ...row, leverage } : row;
|
|
8644
|
+
})
|
|
8645
|
+
};
|
|
8646
|
+
}
|
|
8647
|
+
return prevPositions;
|
|
8648
|
+
},
|
|
8649
|
+
{
|
|
8650
|
+
revalidate: false
|
|
8651
|
+
}
|
|
8652
|
+
);
|
|
8653
|
+
mutate(
|
|
8654
|
+
leveragesKey,
|
|
8655
|
+
(prev) => {
|
|
8656
|
+
if (!prev) {
|
|
8657
|
+
return [
|
|
8658
|
+
{
|
|
8659
|
+
symbol,
|
|
8660
|
+
leverage,
|
|
8661
|
+
margin_mode: marginMode
|
|
8662
|
+
}
|
|
8663
|
+
];
|
|
8664
|
+
}
|
|
8665
|
+
const index = prev.findIndex(
|
|
8666
|
+
(item) => item.symbol === symbol && (item.margin_mode ?? MarginMode.CROSS) === (marginMode ?? MarginMode.CROSS)
|
|
8667
|
+
);
|
|
8668
|
+
if (index === -1) {
|
|
8669
|
+
return [
|
|
8670
|
+
...prev,
|
|
8671
|
+
{
|
|
8672
|
+
symbol,
|
|
8673
|
+
leverage,
|
|
8674
|
+
margin_mode: marginMode
|
|
8675
|
+
}
|
|
8676
|
+
];
|
|
8677
|
+
}
|
|
8678
|
+
const next = [...prev];
|
|
8679
|
+
next[index] = {
|
|
8680
|
+
...next[index],
|
|
8681
|
+
leverage
|
|
8682
|
+
};
|
|
8683
|
+
return next;
|
|
8684
|
+
},
|
|
8685
|
+
{
|
|
8686
|
+
revalidate: false
|
|
8687
|
+
}
|
|
8688
|
+
);
|
|
8689
|
+
}
|
|
8690
|
+
});
|
|
8691
|
+
return () => unsubscribe?.();
|
|
8692
|
+
}, [state.accountId]);
|
|
8693
|
+
useEffect(() => {
|
|
8694
|
+
if (!state.accountId) {
|
|
8695
|
+
return;
|
|
8696
|
+
}
|
|
8697
|
+
const key = ["/v1/positions", state.accountId];
|
|
8698
|
+
const unsubscribe = ws.privateSubscribe("position", {
|
|
8699
|
+
onMessage: (data) => {
|
|
8700
|
+
const { positions: nextPositions } = data;
|
|
8701
|
+
mutate(
|
|
8702
|
+
key,
|
|
8703
|
+
(prevPositions) => {
|
|
8704
|
+
if (!!prevPositions) {
|
|
8705
|
+
const newPositions = {
|
|
8706
|
+
...prevPositions,
|
|
8707
|
+
rows: prevPositions.rows.map((row) => {
|
|
8708
|
+
const itemIndex = nextPositions.findIndex(
|
|
8709
|
+
(item) => item.symbol === row.symbol && item.marginMode === row.margin_mode
|
|
8710
|
+
);
|
|
8711
|
+
if (itemIndex >= 0) {
|
|
8712
|
+
const itemArr = nextPositions.splice(itemIndex, 1);
|
|
8713
|
+
const item = itemArr[0];
|
|
8714
|
+
if (item.averageOpenPrice === 0 && item.positionQty !== 0) {
|
|
8715
|
+
return row;
|
|
8467
8716
|
}
|
|
8468
8717
|
return object2underscore(item);
|
|
8469
8718
|
}
|
|
@@ -8640,6 +8889,61 @@ var OrderValidation = class {
|
|
|
8640
8889
|
|
|
8641
8890
|
// src/services/orderCreator/baseCreator.ts
|
|
8642
8891
|
var BaseOrderCreator = class {
|
|
8892
|
+
/**
|
|
8893
|
+
* Template method for order creation
|
|
8894
|
+
* Defines the algorithm structure with hooks for subclasses
|
|
8895
|
+
*/
|
|
8896
|
+
create(values, config) {
|
|
8897
|
+
this.beforeCreate(values, config);
|
|
8898
|
+
const order = this.buildOrder(values, config);
|
|
8899
|
+
return this.afterCreate(order, config);
|
|
8900
|
+
}
|
|
8901
|
+
/**
|
|
8902
|
+
* Template method for order validation
|
|
8903
|
+
* Defines the algorithm structure with hooks for subclasses
|
|
8904
|
+
*/
|
|
8905
|
+
validate(values, config) {
|
|
8906
|
+
this.beforeValidate(values, config);
|
|
8907
|
+
const errors = this.runValidations(values, config);
|
|
8908
|
+
return Promise.resolve(this.afterValidate(errors, values, config));
|
|
8909
|
+
}
|
|
8910
|
+
/**
|
|
8911
|
+
* Hook method called before order creation
|
|
8912
|
+
* Subclasses can override to perform pre-creation setup
|
|
8913
|
+
* @param values - Order values
|
|
8914
|
+
* @param config - Configuration
|
|
8915
|
+
*/
|
|
8916
|
+
beforeCreate(values, config) {
|
|
8917
|
+
}
|
|
8918
|
+
/**
|
|
8919
|
+
* Hook method called after order creation
|
|
8920
|
+
* Subclasses can override to perform post-creation processing
|
|
8921
|
+
* @param order - The created order
|
|
8922
|
+
* @param config - Configuration
|
|
8923
|
+
* @returns The final order (possibly modified)
|
|
8924
|
+
*/
|
|
8925
|
+
afterCreate(order, config) {
|
|
8926
|
+
return order;
|
|
8927
|
+
}
|
|
8928
|
+
/**
|
|
8929
|
+
* Hook method called before validation
|
|
8930
|
+
* Subclasses can override to perform pre-validation setup
|
|
8931
|
+
* @param values - Order values to validate
|
|
8932
|
+
* @param config - Configuration
|
|
8933
|
+
*/
|
|
8934
|
+
beforeValidate(values, config) {
|
|
8935
|
+
}
|
|
8936
|
+
/**
|
|
8937
|
+
* Hook method called after validation
|
|
8938
|
+
* Subclasses can override to perform post-validation processing
|
|
8939
|
+
* @param errors - Validation errors found
|
|
8940
|
+
* @param values - Original order values
|
|
8941
|
+
* @param config - Configuration
|
|
8942
|
+
* @returns Final validation result (possibly modified)
|
|
8943
|
+
*/
|
|
8944
|
+
afterValidate(errors, values, config) {
|
|
8945
|
+
return errors;
|
|
8946
|
+
}
|
|
8643
8947
|
baseOrder(data) {
|
|
8644
8948
|
const order = {
|
|
8645
8949
|
symbol: data.symbol,
|
|
@@ -8647,7 +8951,8 @@ var BaseOrderCreator = class {
|
|
|
8647
8951
|
side: data.side,
|
|
8648
8952
|
reduce_only: data.reduce_only,
|
|
8649
8953
|
order_quantity: data.order_quantity,
|
|
8650
|
-
total: data.total
|
|
8954
|
+
total: data.total,
|
|
8955
|
+
margin_mode: data.margin_mode || MarginMode.CROSS
|
|
8651
8956
|
// slippage: data.slippage,
|
|
8652
8957
|
};
|
|
8653
8958
|
if (data.order_type === OrderType.MARKET && !!data.slippage) {
|
|
@@ -8666,10 +8971,21 @@ var BaseOrderCreator = class {
|
|
|
8666
8971
|
child_orders: [bracketOrder]
|
|
8667
8972
|
};
|
|
8668
8973
|
}
|
|
8974
|
+
/**
|
|
8975
|
+
* Base validation method that can be called by subclasses
|
|
8976
|
+
* Validates common order properties like quantity and min notional
|
|
8977
|
+
* @param values - Order values to validate
|
|
8978
|
+
* @param configs - Configuration
|
|
8979
|
+
* @returns Validation result (synchronous, not a Promise)
|
|
8980
|
+
*/
|
|
8669
8981
|
baseValidate(values, configs) {
|
|
8670
8982
|
const errors = {};
|
|
8671
8983
|
const { maxQty, symbol, markPrice } = configs;
|
|
8672
|
-
let
|
|
8984
|
+
let order_quantity = values.order_quantity;
|
|
8985
|
+
const total = values.total;
|
|
8986
|
+
const order_price = values.order_price;
|
|
8987
|
+
const reduce_only = values.reduce_only;
|
|
8988
|
+
const order_type = values.order_type;
|
|
8673
8989
|
const { min_notional, base_tick, quote_dp, quote_tick, base_dp } = symbol || {};
|
|
8674
8990
|
if (!order_quantity) {
|
|
8675
8991
|
if (total && order_price) {
|
|
@@ -8714,7 +9030,7 @@ var BaseOrderCreator = class {
|
|
|
8714
9030
|
};
|
|
8715
9031
|
}
|
|
8716
9032
|
this.validateBracketOrder(values, configs, errors);
|
|
8717
|
-
return
|
|
9033
|
+
return errors;
|
|
8718
9034
|
}
|
|
8719
9035
|
totalToQuantity(order, config) {
|
|
8720
9036
|
if (!order.order_quantity && order.total && order.order_price) {
|
|
@@ -8863,7 +9179,11 @@ var BBOOrderCreator = class extends BaseOrderCreator {
|
|
|
8863
9179
|
super(...arguments);
|
|
8864
9180
|
this.orderType = OrderType.LIMIT;
|
|
8865
9181
|
}
|
|
8866
|
-
|
|
9182
|
+
/**
|
|
9183
|
+
* Builds the BBO order
|
|
9184
|
+
* Implements template method hook
|
|
9185
|
+
*/
|
|
9186
|
+
buildOrder(values) {
|
|
8867
9187
|
const order = {
|
|
8868
9188
|
...this.baseOrder(values),
|
|
8869
9189
|
level: values.level
|
|
@@ -8876,15 +9196,18 @@ var BBOOrderCreator = class extends BaseOrderCreator {
|
|
|
8876
9196
|
"reduce_only",
|
|
8877
9197
|
"side",
|
|
8878
9198
|
"order_type",
|
|
9199
|
+
"margin_mode",
|
|
8879
9200
|
"level"
|
|
8880
9201
|
],
|
|
8881
9202
|
order
|
|
8882
9203
|
);
|
|
8883
9204
|
}
|
|
8884
|
-
|
|
8885
|
-
|
|
8886
|
-
|
|
8887
|
-
|
|
9205
|
+
/**
|
|
9206
|
+
* Runs base validations
|
|
9207
|
+
* Implements template method hook
|
|
9208
|
+
*/
|
|
9209
|
+
runValidations(values, configs) {
|
|
9210
|
+
return this.baseValidate(values, configs);
|
|
8888
9211
|
}
|
|
8889
9212
|
};
|
|
8890
9213
|
function getOrderPrice(order, askAndBid) {
|
|
@@ -8911,6 +9234,24 @@ function getOrderPrice(order, askAndBid) {
|
|
|
8911
9234
|
}
|
|
8912
9235
|
}
|
|
8913
9236
|
}
|
|
9237
|
+
order.getOrderReferencePrice;
|
|
9238
|
+
function getOrderReferencePriceFromOrder(order$1, askAndBid) {
|
|
9239
|
+
if (!askAndBid || askAndBid.length < 2) return null;
|
|
9240
|
+
if (!order$1.order_type || !order$1.side) {
|
|
9241
|
+
return null;
|
|
9242
|
+
}
|
|
9243
|
+
return order.getOrderReferencePrice(
|
|
9244
|
+
{
|
|
9245
|
+
orderType: order$1.order_type,
|
|
9246
|
+
orderTypeExt: order$1.order_type_ext,
|
|
9247
|
+
side: order$1.side,
|
|
9248
|
+
limitPrice: order$1.order_price ? Number(order$1.order_price) : void 0,
|
|
9249
|
+
triggerPrice: order$1.trigger_price ? Number(order$1.trigger_price) : void 0
|
|
9250
|
+
},
|
|
9251
|
+
askAndBid[0],
|
|
9252
|
+
askAndBid[1]
|
|
9253
|
+
);
|
|
9254
|
+
}
|
|
8914
9255
|
function getPriceRange(inputs) {
|
|
8915
9256
|
const { basePrice, side, symbolInfo } = inputs;
|
|
8916
9257
|
const { price_range, price_scope, quote_min, quote_max } = symbolInfo;
|
|
@@ -8924,97 +9265,170 @@ function getPriceRange(inputs) {
|
|
|
8924
9265
|
min: minPriceNumber,
|
|
8925
9266
|
max: scopePriceNumber
|
|
8926
9267
|
};
|
|
8927
|
-
const
|
|
8928
|
-
const
|
|
9268
|
+
const minPrice = Math.max(quote_min, priceRange?.min);
|
|
9269
|
+
const maxPrice = Math.min(quote_max, priceRange?.max);
|
|
8929
9270
|
return {
|
|
8930
|
-
minPrice
|
|
8931
|
-
maxPrice
|
|
9271
|
+
minPrice,
|
|
9272
|
+
maxPrice
|
|
8932
9273
|
};
|
|
8933
9274
|
}
|
|
8934
9275
|
|
|
8935
|
-
// src/services/orderCreator/
|
|
9276
|
+
// src/services/orderCreator/validators/TPSLValidationStrategy.ts
|
|
8936
9277
|
var formatPrice = (price, quote_dp) => {
|
|
8937
9278
|
return new Decimal(price).toDecimalPlaces(quote_dp).toNumber();
|
|
8938
9279
|
};
|
|
8939
|
-
|
|
8940
|
-
|
|
8941
|
-
|
|
8942
|
-
|
|
8943
|
-
|
|
8944
|
-
|
|
8945
|
-
|
|
8946
|
-
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8953
|
-
|
|
8954
|
-
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
|
|
8959
|
-
|
|
8960
|
-
|
|
8961
|
-
|
|
8962
|
-
|
|
8963
|
-
|
|
8964
|
-
|
|
8965
|
-
|
|
8966
|
-
|
|
8967
|
-
|
|
8968
|
-
|
|
8969
|
-
|
|
8970
|
-
|
|
8971
|
-
|
|
8972
|
-
|
|
8973
|
-
|
|
8974
|
-
|
|
8975
|
-
|
|
8976
|
-
|
|
8977
|
-
|
|
8978
|
-
|
|
9280
|
+
var TPSLValidationStrategy = class {
|
|
9281
|
+
/**
|
|
9282
|
+
* Validates TP/SL order values
|
|
9283
|
+
* @param values - TP/SL order values including trigger prices, order prices, etc.
|
|
9284
|
+
* @param config - Configuration with symbol info and mark price
|
|
9285
|
+
* @returns Validation result object with any errors found
|
|
9286
|
+
*/
|
|
9287
|
+
validate(values, config) {
|
|
9288
|
+
const result = /* @__PURE__ */ Object.create(null);
|
|
9289
|
+
const {
|
|
9290
|
+
tp_trigger_price,
|
|
9291
|
+
tp_order_price,
|
|
9292
|
+
tp_order_type,
|
|
9293
|
+
sl_trigger_price,
|
|
9294
|
+
sl_order_price,
|
|
9295
|
+
sl_order_type,
|
|
9296
|
+
side,
|
|
9297
|
+
quantity,
|
|
9298
|
+
order_type,
|
|
9299
|
+
order_price
|
|
9300
|
+
} = values;
|
|
9301
|
+
const qty = Number(quantity);
|
|
9302
|
+
const maxQty = config.maxQty;
|
|
9303
|
+
const { quote_max, quote_min, quote_dp, base_min } = config.symbol ?? {};
|
|
9304
|
+
const mark_price = order_type === OrderType.MARKET || order_type == null ? config.markPrice : order_price ? Number(order_price) : void 0;
|
|
9305
|
+
const tpslSide = side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
|
|
9306
|
+
if (!isNaN(qty) && qty > maxQty) {
|
|
9307
|
+
result.quantity = OrderValidation.max("quantity", config.maxQty);
|
|
9308
|
+
}
|
|
9309
|
+
if (!isNaN(qty) && qty < (base_min ?? 0)) {
|
|
9310
|
+
result.quantity = OrderValidation.min("quantity", base_min ?? 0);
|
|
9311
|
+
}
|
|
9312
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null && Number(tp_trigger_price) < 0) {
|
|
9313
|
+
result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
|
|
9314
|
+
}
|
|
9315
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null && Number(sl_trigger_price) < 0) {
|
|
9316
|
+
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
9317
|
+
}
|
|
9318
|
+
if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
|
|
9319
|
+
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
9320
|
+
}
|
|
9321
|
+
if (sl_order_type === OrderType.LIMIT && !sl_order_price) {
|
|
9322
|
+
result.sl_order_price = OrderValidation.required("sl_order_price");
|
|
9323
|
+
}
|
|
9324
|
+
if (side === OrderSide.BUY && mark_price) {
|
|
9325
|
+
this.validateBuySide(
|
|
9326
|
+
{
|
|
9327
|
+
tp_trigger_price,
|
|
9328
|
+
tp_order_price,
|
|
9329
|
+
sl_trigger_price,
|
|
9330
|
+
sl_order_price
|
|
9331
|
+
},
|
|
9332
|
+
{
|
|
9333
|
+
mark_price,
|
|
9334
|
+
quote_min: quote_min ?? 0,
|
|
9335
|
+
quote_max: quote_max ?? 0,
|
|
9336
|
+
quote_dp: quote_dp ?? 0,
|
|
9337
|
+
tpslSide,
|
|
9338
|
+
symbol: config.symbol
|
|
9339
|
+
},
|
|
9340
|
+
result
|
|
8979
9341
|
);
|
|
8980
|
-
}
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
9342
|
+
} else if (side === OrderSide.SELL && mark_price) {
|
|
9343
|
+
this.validateSellSide(
|
|
9344
|
+
{
|
|
9345
|
+
tp_trigger_price,
|
|
9346
|
+
tp_order_price,
|
|
9347
|
+
sl_trigger_price,
|
|
9348
|
+
sl_order_price
|
|
9349
|
+
},
|
|
9350
|
+
{
|
|
9351
|
+
mark_price,
|
|
9352
|
+
quote_min: quote_min ?? 0,
|
|
9353
|
+
quote_max: quote_max ?? 0,
|
|
9354
|
+
quote_dp: quote_dp ?? 0,
|
|
9355
|
+
tpslSide,
|
|
9356
|
+
symbol: config.symbol
|
|
9357
|
+
},
|
|
9358
|
+
result
|
|
8985
9359
|
);
|
|
8986
9360
|
}
|
|
8987
|
-
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
9361
|
+
return Object.keys(result).length > 0 ? result : null;
|
|
9362
|
+
}
|
|
9363
|
+
/**
|
|
9364
|
+
* Validates TP/SL for BUY orders
|
|
9365
|
+
* For BUY orders:
|
|
9366
|
+
* - SL trigger price must be < mark price
|
|
9367
|
+
* - TP trigger price must be > mark price
|
|
9368
|
+
*/
|
|
9369
|
+
validateBuySide(prices, config, result) {
|
|
9370
|
+
const {
|
|
9371
|
+
tp_trigger_price,
|
|
9372
|
+
tp_order_price,
|
|
9373
|
+
sl_trigger_price,
|
|
9374
|
+
sl_order_price
|
|
9375
|
+
} = prices;
|
|
9376
|
+
const { mark_price, quote_min, quote_max, quote_dp, tpslSide, symbol } = config;
|
|
9377
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null) {
|
|
9378
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9379
|
+
if (!isNaN(slTrigger)) {
|
|
9380
|
+
if (quote_min > 0 && slTrigger < quote_min) {
|
|
9381
|
+
result.sl_trigger_price = OrderValidation.min(
|
|
9382
|
+
"sl_trigger_price",
|
|
9383
|
+
formatPrice(quote_min, quote_dp)
|
|
9384
|
+
);
|
|
9385
|
+
}
|
|
9386
|
+
if (slTrigger >= mark_price) {
|
|
9387
|
+
result.sl_trigger_price = OrderValidation.max(
|
|
9388
|
+
"sl_trigger_price",
|
|
9389
|
+
formatPrice(mark_price, quote_dp)
|
|
9390
|
+
);
|
|
9391
|
+
}
|
|
9392
|
+
}
|
|
8992
9393
|
}
|
|
8993
|
-
if (
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
|
|
8997
|
-
|
|
9394
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null) {
|
|
9395
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9396
|
+
if (!isNaN(tpTrigger)) {
|
|
9397
|
+
if (tpTrigger <= mark_price) {
|
|
9398
|
+
result.tp_trigger_price = OrderValidation.min(
|
|
9399
|
+
"tp_trigger_price",
|
|
9400
|
+
formatPrice(mark_price, quote_dp)
|
|
9401
|
+
);
|
|
9402
|
+
}
|
|
9403
|
+
if (quote_max > 0 && tpTrigger > quote_max) {
|
|
9404
|
+
result.tp_trigger_price = OrderValidation.max(
|
|
9405
|
+
"tp_trigger_price",
|
|
9406
|
+
formatPrice(quote_max, quote_dp)
|
|
9407
|
+
);
|
|
9408
|
+
}
|
|
9409
|
+
}
|
|
8998
9410
|
}
|
|
8999
9411
|
if (sl_trigger_price && sl_order_price) {
|
|
9000
9412
|
const priceRange = getPriceRange({
|
|
9001
9413
|
side: tpslSide,
|
|
9002
9414
|
basePrice: Number(sl_trigger_price),
|
|
9003
|
-
symbolInfo:
|
|
9415
|
+
symbolInfo: symbol
|
|
9004
9416
|
});
|
|
9005
|
-
|
|
9417
|
+
const slOrderPrice = Number(sl_order_price);
|
|
9418
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9419
|
+
if (slOrderPrice < priceRange.minPrice) {
|
|
9006
9420
|
result.sl_order_price = OrderValidation.min(
|
|
9007
9421
|
"sl_order_price",
|
|
9008
9422
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9009
9423
|
);
|
|
9010
9424
|
}
|
|
9011
|
-
if (
|
|
9425
|
+
if (slOrderPrice > priceRange.maxPrice) {
|
|
9012
9426
|
result.sl_order_price = OrderValidation.max(
|
|
9013
9427
|
"sl_order_price",
|
|
9014
9428
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9015
9429
|
);
|
|
9016
9430
|
}
|
|
9017
|
-
if (
|
|
9431
|
+
if (slTrigger < slOrderPrice) {
|
|
9018
9432
|
result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
|
|
9019
9433
|
}
|
|
9020
9434
|
}
|
|
@@ -9022,69 +9436,96 @@ async function bracketOrderValidator(values, config) {
|
|
|
9022
9436
|
const priceRange = getPriceRange({
|
|
9023
9437
|
side: tpslSide,
|
|
9024
9438
|
basePrice: Number(tp_trigger_price),
|
|
9025
|
-
symbolInfo:
|
|
9439
|
+
symbolInfo: symbol
|
|
9026
9440
|
});
|
|
9027
|
-
|
|
9441
|
+
const tpOrderPrice = Number(tp_order_price);
|
|
9442
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9443
|
+
if (tpOrderPrice > priceRange.maxPrice) {
|
|
9028
9444
|
result.tp_order_price = OrderValidation.max(
|
|
9029
9445
|
"tp_order_price",
|
|
9030
9446
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9031
9447
|
);
|
|
9032
9448
|
}
|
|
9033
|
-
if (
|
|
9449
|
+
if (tpOrderPrice < priceRange.minPrice) {
|
|
9034
9450
|
result.tp_order_price = OrderValidation.min(
|
|
9035
9451
|
"tp_order_price",
|
|
9036
9452
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9037
9453
|
);
|
|
9038
9454
|
}
|
|
9039
|
-
if (
|
|
9455
|
+
if (tpTrigger > tpOrderPrice) {
|
|
9040
9456
|
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9041
9457
|
}
|
|
9042
9458
|
}
|
|
9043
9459
|
}
|
|
9044
|
-
|
|
9045
|
-
|
|
9046
|
-
|
|
9047
|
-
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
}
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
9460
|
+
/**
|
|
9461
|
+
* Validates TP/SL for SELL orders
|
|
9462
|
+
* For SELL orders:
|
|
9463
|
+
* - SL trigger price must be > mark price
|
|
9464
|
+
* - TP trigger price must be < mark price
|
|
9465
|
+
*/
|
|
9466
|
+
validateSellSide(prices, config, result) {
|
|
9467
|
+
const {
|
|
9468
|
+
tp_trigger_price,
|
|
9469
|
+
tp_order_price,
|
|
9470
|
+
sl_trigger_price,
|
|
9471
|
+
sl_order_price
|
|
9472
|
+
} = prices;
|
|
9473
|
+
const { mark_price, quote_min, quote_max, quote_dp, tpslSide, symbol } = config;
|
|
9474
|
+
if (sl_trigger_price !== void 0 && sl_trigger_price !== "" && sl_trigger_price !== null) {
|
|
9475
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9476
|
+
if (!isNaN(slTrigger)) {
|
|
9477
|
+
if (quote_max > 0 && slTrigger > quote_max) {
|
|
9478
|
+
result.sl_trigger_price = OrderValidation.max(
|
|
9479
|
+
"sl_trigger_price",
|
|
9480
|
+
formatPrice(quote_max, quote_dp)
|
|
9481
|
+
);
|
|
9482
|
+
}
|
|
9483
|
+
if (slTrigger <= mark_price) {
|
|
9484
|
+
result.sl_trigger_price = OrderValidation.min(
|
|
9485
|
+
"sl_trigger_price",
|
|
9486
|
+
formatPrice(mark_price, quote_dp)
|
|
9487
|
+
);
|
|
9488
|
+
}
|
|
9489
|
+
}
|
|
9062
9490
|
}
|
|
9063
|
-
if (
|
|
9064
|
-
|
|
9065
|
-
|
|
9066
|
-
|
|
9067
|
-
|
|
9491
|
+
if (tp_trigger_price !== void 0 && tp_trigger_price !== "" && tp_trigger_price !== null) {
|
|
9492
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9493
|
+
if (!isNaN(tpTrigger)) {
|
|
9494
|
+
if (tpTrigger >= mark_price) {
|
|
9495
|
+
result.tp_trigger_price = OrderValidation.max(
|
|
9496
|
+
"tp_trigger_price",
|
|
9497
|
+
formatPrice(mark_price, quote_dp)
|
|
9498
|
+
);
|
|
9499
|
+
}
|
|
9500
|
+
if (quote_min > 0 && tpTrigger < quote_min) {
|
|
9501
|
+
result.tp_trigger_price = OrderValidation.min(
|
|
9502
|
+
"tp_trigger_price",
|
|
9503
|
+
formatPrice(quote_min, quote_dp)
|
|
9504
|
+
);
|
|
9505
|
+
}
|
|
9506
|
+
}
|
|
9068
9507
|
}
|
|
9069
9508
|
if (sl_trigger_price && sl_order_price) {
|
|
9070
9509
|
const priceRange = getPriceRange({
|
|
9071
9510
|
side: tpslSide,
|
|
9072
9511
|
basePrice: Number(sl_trigger_price),
|
|
9073
|
-
symbolInfo:
|
|
9512
|
+
symbolInfo: symbol
|
|
9074
9513
|
});
|
|
9075
|
-
|
|
9514
|
+
const slOrderPrice = Number(sl_order_price);
|
|
9515
|
+
const slTrigger = Number(sl_trigger_price);
|
|
9516
|
+
if (slOrderPrice < priceRange.minPrice) {
|
|
9076
9517
|
result.sl_order_price = OrderValidation.min(
|
|
9077
9518
|
"sl_order_price",
|
|
9078
9519
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9079
9520
|
);
|
|
9080
9521
|
}
|
|
9081
|
-
if (
|
|
9522
|
+
if (slOrderPrice > priceRange.maxPrice) {
|
|
9082
9523
|
result.sl_order_price = OrderValidation.max(
|
|
9083
9524
|
"sl_order_price",
|
|
9084
9525
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9085
9526
|
);
|
|
9086
9527
|
}
|
|
9087
|
-
if (
|
|
9528
|
+
if (slTrigger > slOrderPrice) {
|
|
9088
9529
|
result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
|
|
9089
9530
|
}
|
|
9090
9531
|
}
|
|
@@ -9092,37 +9533,294 @@ async function bracketOrderValidator(values, config) {
|
|
|
9092
9533
|
const priceRange = getPriceRange({
|
|
9093
9534
|
side: tpslSide,
|
|
9094
9535
|
basePrice: Number(tp_trigger_price),
|
|
9095
|
-
symbolInfo:
|
|
9536
|
+
symbolInfo: symbol
|
|
9096
9537
|
});
|
|
9097
|
-
|
|
9538
|
+
const tpOrderPrice = Number(tp_order_price);
|
|
9539
|
+
const tpTrigger = Number(tp_trigger_price);
|
|
9540
|
+
if (tpOrderPrice < priceRange.minPrice) {
|
|
9098
9541
|
result.tp_order_price = OrderValidation.min(
|
|
9099
9542
|
"tp_order_price",
|
|
9100
9543
|
formatPrice(priceRange.minPrice, quote_dp)
|
|
9101
9544
|
);
|
|
9102
9545
|
}
|
|
9103
|
-
if (
|
|
9546
|
+
if (tpOrderPrice > priceRange.maxPrice) {
|
|
9104
9547
|
result.tp_order_price = OrderValidation.max(
|
|
9105
9548
|
"tp_order_price",
|
|
9106
9549
|
formatPrice(priceRange.maxPrice, quote_dp)
|
|
9107
9550
|
);
|
|
9108
9551
|
}
|
|
9109
|
-
if (
|
|
9552
|
+
if (tpTrigger < tpOrderPrice) {
|
|
9110
9553
|
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9111
9554
|
}
|
|
9112
9555
|
}
|
|
9113
9556
|
}
|
|
9114
|
-
|
|
9557
|
+
};
|
|
9558
|
+
|
|
9559
|
+
// src/services/orderCreator/baseBracketOrderCreator.ts
|
|
9560
|
+
async function bracketOrderValidator(values, config) {
|
|
9561
|
+
const strategy = new TPSLValidationStrategy();
|
|
9562
|
+
return strategy.validate(values, config);
|
|
9115
9563
|
}
|
|
9116
|
-
|
|
9564
|
+
|
|
9565
|
+
// src/services/orderCreator/validators/BaseValidator.ts
|
|
9566
|
+
var BaseValidator = class {
|
|
9567
|
+
/**
|
|
9568
|
+
* Sets the next validator in the chain
|
|
9569
|
+
* @param validator - The next validator to call
|
|
9570
|
+
* @returns The next validator for method chaining
|
|
9571
|
+
*/
|
|
9572
|
+
setNext(validator) {
|
|
9573
|
+
this.next = validator;
|
|
9574
|
+
return validator;
|
|
9575
|
+
}
|
|
9576
|
+
/**
|
|
9577
|
+
* Validates values and passes to next validator in chain
|
|
9578
|
+
* @param values - The values to validate
|
|
9579
|
+
* @param config - Configuration for validation
|
|
9580
|
+
* @param errors - Accumulated validation errors
|
|
9581
|
+
* @returns Updated validation result
|
|
9582
|
+
*/
|
|
9583
|
+
validate(values, config, errors) {
|
|
9584
|
+
const result = this.doValidate(values, config);
|
|
9585
|
+
if (result) {
|
|
9586
|
+
errors[this.getFieldName()] = result;
|
|
9587
|
+
}
|
|
9588
|
+
return this.next?.validate(values, config, errors) ?? errors;
|
|
9589
|
+
}
|
|
9590
|
+
};
|
|
9591
|
+
var PriceValidationStrategy = class {
|
|
9592
|
+
/**
|
|
9593
|
+
* Validates order price against symbol constraints and price range
|
|
9594
|
+
* @param values - Object containing order_price, side, and order_type
|
|
9595
|
+
* @param config - Configuration with symbol info and mark price
|
|
9596
|
+
* @returns Validation error if price is invalid, undefined otherwise
|
|
9597
|
+
*/
|
|
9598
|
+
validate(values, config) {
|
|
9599
|
+
const { order_price, side } = values;
|
|
9600
|
+
if (!order_price) {
|
|
9601
|
+
return OrderValidation.required("order_price");
|
|
9602
|
+
}
|
|
9603
|
+
const price = new Decimal(order_price);
|
|
9604
|
+
const { symbol } = config;
|
|
9605
|
+
const { quote_max, quote_min, quote_dp, price_range, price_scope } = symbol;
|
|
9606
|
+
const maxPriceNumber = order.maxPrice(config.markPrice, price_range);
|
|
9607
|
+
const minPriceNumber = order.minPrice(config.markPrice, price_range);
|
|
9608
|
+
const scopePriceNumber = order.scopePrice(
|
|
9609
|
+
config.markPrice,
|
|
9610
|
+
price_scope,
|
|
9611
|
+
side
|
|
9612
|
+
);
|
|
9613
|
+
const priceRange = side === OrderSide.BUY ? {
|
|
9614
|
+
min: scopePriceNumber,
|
|
9615
|
+
max: maxPriceNumber
|
|
9616
|
+
} : {
|
|
9617
|
+
min: minPriceNumber,
|
|
9618
|
+
max: scopePriceNumber
|
|
9619
|
+
};
|
|
9620
|
+
if (price.gt(quote_max)) {
|
|
9621
|
+
return OrderValidation.max("order_price", quote_max);
|
|
9622
|
+
}
|
|
9623
|
+
if (price.lt(quote_min)) {
|
|
9624
|
+
return OrderValidation.min("order_price", quote_min);
|
|
9625
|
+
}
|
|
9626
|
+
if (price.gt(priceRange.max)) {
|
|
9627
|
+
return OrderValidation.max(
|
|
9628
|
+
"order_price",
|
|
9629
|
+
new Decimal(priceRange.max).todp(quote_dp).toString()
|
|
9630
|
+
);
|
|
9631
|
+
}
|
|
9632
|
+
if (price.lt(priceRange.min)) {
|
|
9633
|
+
return OrderValidation.min(
|
|
9634
|
+
"order_price",
|
|
9635
|
+
new Decimal(priceRange.min).todp(quote_dp).toString()
|
|
9636
|
+
);
|
|
9637
|
+
}
|
|
9638
|
+
return void 0;
|
|
9639
|
+
}
|
|
9640
|
+
};
|
|
9641
|
+
var TriggerPriceValidationStrategy = class {
|
|
9642
|
+
/**
|
|
9643
|
+
* Validates trigger price against symbol constraints
|
|
9644
|
+
* @param values - Object containing trigger_price
|
|
9645
|
+
* @param config - Configuration with symbol info
|
|
9646
|
+
* @returns Validation error if trigger price is invalid, undefined otherwise
|
|
9647
|
+
*/
|
|
9648
|
+
validate(values, config) {
|
|
9649
|
+
const { trigger_price } = values;
|
|
9650
|
+
const { symbol } = config;
|
|
9651
|
+
const { quote_max, quote_min } = symbol;
|
|
9652
|
+
if (!trigger_price) {
|
|
9653
|
+
return OrderValidation.required("trigger_price");
|
|
9654
|
+
}
|
|
9655
|
+
const triggerPrice = Number(trigger_price);
|
|
9656
|
+
if (triggerPrice > quote_max) {
|
|
9657
|
+
return OrderValidation.max("trigger_price", quote_max);
|
|
9658
|
+
}
|
|
9659
|
+
if (triggerPrice < quote_min || triggerPrice === 0) {
|
|
9660
|
+
return OrderValidation.min("trigger_price", quote_min);
|
|
9661
|
+
}
|
|
9662
|
+
return void 0;
|
|
9663
|
+
}
|
|
9664
|
+
};
|
|
9665
|
+
|
|
9666
|
+
// src/services/orderCreator/validators/PriceValidator.ts
|
|
9667
|
+
var PriceValidator = class extends BaseValidator {
|
|
9668
|
+
constructor() {
|
|
9669
|
+
super();
|
|
9670
|
+
this.strategy = new PriceValidationStrategy();
|
|
9671
|
+
}
|
|
9672
|
+
doValidate(values, config) {
|
|
9673
|
+
return this.strategy.validate(
|
|
9674
|
+
{
|
|
9675
|
+
order_price: values.order_price,
|
|
9676
|
+
side: values.side,
|
|
9677
|
+
order_type: values.order_type
|
|
9678
|
+
},
|
|
9679
|
+
config
|
|
9680
|
+
);
|
|
9681
|
+
}
|
|
9682
|
+
getFieldName() {
|
|
9683
|
+
return "order_price";
|
|
9684
|
+
}
|
|
9685
|
+
};
|
|
9686
|
+
var QuantityValidationStrategy = class {
|
|
9687
|
+
/**
|
|
9688
|
+
* Validates order quantity against symbol constraints
|
|
9689
|
+
* Also handles conversion from total to quantity if needed
|
|
9690
|
+
* @param values - Object containing order_quantity, total, and order_price
|
|
9691
|
+
* @param config - Configuration with symbol info and max quantity
|
|
9692
|
+
* @returns Validation error if quantity is invalid, undefined otherwise
|
|
9693
|
+
*/
|
|
9694
|
+
validate(values, config) {
|
|
9695
|
+
let { order_quantity, total, order_price } = values;
|
|
9696
|
+
const { maxQty, symbol } = config;
|
|
9697
|
+
const { base_min, base_dp, quote_dp } = symbol;
|
|
9698
|
+
if (!order_quantity && total && order_price) {
|
|
9699
|
+
const totalNumber = new Decimal(total);
|
|
9700
|
+
const qty2 = totalNumber.dividedBy(order_price).toFixed(quote_dp);
|
|
9701
|
+
order_quantity = qty2;
|
|
9702
|
+
}
|
|
9703
|
+
if (!order_quantity) {
|
|
9704
|
+
return OrderValidation.required("order_quantity");
|
|
9705
|
+
}
|
|
9706
|
+
const qty = new Decimal(order_quantity);
|
|
9707
|
+
if (qty.lt(base_min)) {
|
|
9708
|
+
return OrderValidation.min(
|
|
9709
|
+
"order_quantity",
|
|
9710
|
+
new Decimal(base_min).todp(base_dp).toString()
|
|
9711
|
+
);
|
|
9712
|
+
}
|
|
9713
|
+
if (qty.gt(maxQty)) {
|
|
9714
|
+
return OrderValidation.max(
|
|
9715
|
+
"order_quantity",
|
|
9716
|
+
new Decimal(maxQty).todp(base_dp).toString()
|
|
9717
|
+
);
|
|
9718
|
+
}
|
|
9719
|
+
return void 0;
|
|
9720
|
+
}
|
|
9721
|
+
};
|
|
9722
|
+
|
|
9723
|
+
// src/services/orderCreator/validators/QuantityValidator.ts
|
|
9724
|
+
var QuantityValidator = class extends BaseValidator {
|
|
9725
|
+
constructor() {
|
|
9726
|
+
super();
|
|
9727
|
+
this.strategy = new QuantityValidationStrategy();
|
|
9728
|
+
}
|
|
9729
|
+
doValidate(values, config) {
|
|
9730
|
+
return this.strategy.validate(
|
|
9731
|
+
{
|
|
9732
|
+
order_quantity: values.order_quantity,
|
|
9733
|
+
total: values.total,
|
|
9734
|
+
order_price: values.order_price
|
|
9735
|
+
},
|
|
9736
|
+
config
|
|
9737
|
+
);
|
|
9738
|
+
}
|
|
9739
|
+
getFieldName() {
|
|
9740
|
+
return "order_quantity";
|
|
9741
|
+
}
|
|
9742
|
+
};
|
|
9743
|
+
|
|
9744
|
+
// src/services/orderCreator/validators/ValidationChain.ts
|
|
9745
|
+
var ValidationChain = class {
|
|
9746
|
+
constructor() {
|
|
9747
|
+
this.validators = [];
|
|
9748
|
+
}
|
|
9749
|
+
/**
|
|
9750
|
+
* Adds a validator to the chain
|
|
9751
|
+
* @param validator - The validator to add
|
|
9752
|
+
* @returns This chain instance for method chaining
|
|
9753
|
+
*/
|
|
9754
|
+
addValidator(validator) {
|
|
9755
|
+
this.validators.push(validator);
|
|
9756
|
+
if (!this.head) {
|
|
9757
|
+
this.head = validator;
|
|
9758
|
+
} else {
|
|
9759
|
+
let current = this.head;
|
|
9760
|
+
while (current && current.next) {
|
|
9761
|
+
current = current.next;
|
|
9762
|
+
}
|
|
9763
|
+
if (current) {
|
|
9764
|
+
current.setNext(validator);
|
|
9765
|
+
}
|
|
9766
|
+
}
|
|
9767
|
+
return this;
|
|
9768
|
+
}
|
|
9769
|
+
/**
|
|
9770
|
+
* Adds multiple validators to the chain
|
|
9771
|
+
* @param validators - Array of validators to add
|
|
9772
|
+
* @returns This chain instance for method chaining
|
|
9773
|
+
*/
|
|
9774
|
+
addValidators(validators) {
|
|
9775
|
+
validators.forEach((validator) => this.addValidator(validator));
|
|
9776
|
+
return this;
|
|
9777
|
+
}
|
|
9778
|
+
/**
|
|
9779
|
+
* Validates values using all validators in the chain
|
|
9780
|
+
* @param values - The values to validate
|
|
9781
|
+
* @param config - Configuration for validation
|
|
9782
|
+
* @returns Validation result with all errors found
|
|
9783
|
+
*/
|
|
9784
|
+
validate(values, config) {
|
|
9785
|
+
const errors = {};
|
|
9786
|
+
if (this.head) {
|
|
9787
|
+
return this.head.validate(values, config, errors);
|
|
9788
|
+
}
|
|
9789
|
+
return errors;
|
|
9790
|
+
}
|
|
9791
|
+
/**
|
|
9792
|
+
* Clears all validators from the chain
|
|
9793
|
+
*/
|
|
9794
|
+
clear() {
|
|
9795
|
+
this.validators = [];
|
|
9796
|
+
this.head = void 0;
|
|
9797
|
+
}
|
|
9798
|
+
/**
|
|
9799
|
+
* Gets the number of validators in the chain
|
|
9800
|
+
* @returns The number of validators
|
|
9801
|
+
*/
|
|
9802
|
+
get length() {
|
|
9803
|
+
return this.validators.length;
|
|
9804
|
+
}
|
|
9805
|
+
};
|
|
9806
|
+
|
|
9807
|
+
// src/services/orderCreator/limitOrderCreator.ts
|
|
9117
9808
|
var LimitOrderCreator = class extends BaseOrderCreator {
|
|
9118
9809
|
constructor() {
|
|
9119
9810
|
super(...arguments);
|
|
9811
|
+
// private priceValidationStrategy = new PriceValidationStrategy();
|
|
9812
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new PriceValidator());
|
|
9120
9813
|
this.orderType = OrderType.LIMIT;
|
|
9121
9814
|
}
|
|
9122
|
-
|
|
9815
|
+
/**
|
|
9816
|
+
* Builds the limit order
|
|
9817
|
+
* Implements template method hook
|
|
9818
|
+
*/
|
|
9819
|
+
buildOrder(values, config) {
|
|
9820
|
+
const orderlyValues = values;
|
|
9123
9821
|
const order = {
|
|
9124
|
-
...this.baseOrder(
|
|
9125
|
-
order_price:
|
|
9822
|
+
...this.baseOrder(orderlyValues),
|
|
9823
|
+
order_price: orderlyValues.order_price
|
|
9126
9824
|
};
|
|
9127
9825
|
this.totalToQuantity(order, config);
|
|
9128
9826
|
return pick(
|
|
@@ -9131,61 +9829,26 @@ var LimitOrderCreator = class extends BaseOrderCreator {
|
|
|
9131
9829
|
"order_price",
|
|
9132
9830
|
"order_quantity",
|
|
9133
9831
|
"visible_quantity",
|
|
9134
|
-
"reduce_only",
|
|
9135
|
-
"side",
|
|
9136
|
-
"order_type",
|
|
9137
|
-
"
|
|
9138
|
-
"
|
|
9139
|
-
|
|
9140
|
-
|
|
9141
|
-
|
|
9142
|
-
|
|
9143
|
-
|
|
9144
|
-
|
|
9145
|
-
|
|
9146
|
-
|
|
9147
|
-
|
|
9148
|
-
|
|
9149
|
-
|
|
9150
|
-
|
|
9151
|
-
|
|
9152
|
-
|
|
9153
|
-
|
|
9154
|
-
const scopePriceNumber = scopePrice(
|
|
9155
|
-
config.markPrice,
|
|
9156
|
-
price_scope,
|
|
9157
|
-
side
|
|
9158
|
-
);
|
|
9159
|
-
const priceRange = side === "BUY" ? {
|
|
9160
|
-
min: scopePriceNumber,
|
|
9161
|
-
max: maxPriceNumber
|
|
9162
|
-
} : {
|
|
9163
|
-
min: minPriceNumber,
|
|
9164
|
-
max: scopePriceNumber
|
|
9165
|
-
};
|
|
9166
|
-
if (price.gt(quote_max)) {
|
|
9167
|
-
errors.order_price = OrderValidation.max("order_price", quote_max);
|
|
9168
|
-
} else {
|
|
9169
|
-
if (price.gt(priceRange?.max)) {
|
|
9170
|
-
errors.order_price = OrderValidation.max(
|
|
9171
|
-
"order_price",
|
|
9172
|
-
new Decimal(priceRange.max).todp(symbol.quote_dp).toString()
|
|
9173
|
-
);
|
|
9174
|
-
}
|
|
9175
|
-
}
|
|
9176
|
-
if (price.lt(quote_min)) {
|
|
9177
|
-
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
9178
|
-
} else {
|
|
9179
|
-
if (price.lt(priceRange?.min)) {
|
|
9180
|
-
errors.order_price = OrderValidation.min(
|
|
9181
|
-
"order_price",
|
|
9182
|
-
new Decimal(priceRange.min).todp(symbol.quote_dp).toString()
|
|
9183
|
-
);
|
|
9184
|
-
}
|
|
9185
|
-
}
|
|
9186
|
-
}
|
|
9187
|
-
return errors;
|
|
9188
|
-
});
|
|
9832
|
+
"reduce_only",
|
|
9833
|
+
"side",
|
|
9834
|
+
"order_type",
|
|
9835
|
+
"margin_mode",
|
|
9836
|
+
"algo_type",
|
|
9837
|
+
"child_orders"
|
|
9838
|
+
],
|
|
9839
|
+
order
|
|
9840
|
+
);
|
|
9841
|
+
}
|
|
9842
|
+
/**
|
|
9843
|
+
* Runs validations using validation chain
|
|
9844
|
+
* Implements template method hook
|
|
9845
|
+
*/
|
|
9846
|
+
runValidations(values, config) {
|
|
9847
|
+
const orderlyValues = values;
|
|
9848
|
+
const errors = this.baseValidate(orderlyValues, config);
|
|
9849
|
+
const chainErrors = this.validationChain.validate(orderlyValues, config);
|
|
9850
|
+
Object.assign(errors, chainErrors);
|
|
9851
|
+
return errors;
|
|
9189
9852
|
}
|
|
9190
9853
|
};
|
|
9191
9854
|
|
|
@@ -9208,34 +9871,81 @@ var BracketLimitOrderCreator = class extends LimitOrderCreator {
|
|
|
9208
9871
|
}
|
|
9209
9872
|
};
|
|
9210
9873
|
|
|
9874
|
+
// src/services/orderCreator/validators/SlippageValidationStrategy.ts
|
|
9875
|
+
var SlippageValidationStrategy = class {
|
|
9876
|
+
/**
|
|
9877
|
+
* Validates slippage against estimated slippage
|
|
9878
|
+
* @param values - Object containing slippage value
|
|
9879
|
+
* @param config - Configuration with estimated slippage
|
|
9880
|
+
* @returns Validation error if slippage exceeds estimated, undefined otherwise
|
|
9881
|
+
*/
|
|
9882
|
+
validate(values, config) {
|
|
9883
|
+
const slippage = Number(values.slippage);
|
|
9884
|
+
const estSlippage = Number.isNaN(config.estSlippage) ? 0 : Number(config.estSlippage) * 100;
|
|
9885
|
+
if (!isNaN(slippage) && estSlippage > slippage) {
|
|
9886
|
+
return {
|
|
9887
|
+
type: "max",
|
|
9888
|
+
message: "Estimated slippage exceeds your maximum allowed slippage.",
|
|
9889
|
+
value: estSlippage
|
|
9890
|
+
};
|
|
9891
|
+
}
|
|
9892
|
+
return void 0;
|
|
9893
|
+
}
|
|
9894
|
+
};
|
|
9895
|
+
|
|
9896
|
+
// src/services/orderCreator/validators/SlippageValidator.ts
|
|
9897
|
+
var SlippageValidator = class extends BaseValidator {
|
|
9898
|
+
constructor() {
|
|
9899
|
+
super();
|
|
9900
|
+
this.strategy = new SlippageValidationStrategy();
|
|
9901
|
+
}
|
|
9902
|
+
doValidate(values, config) {
|
|
9903
|
+
return this.strategy.validate(
|
|
9904
|
+
{
|
|
9905
|
+
slippage: values.slippage
|
|
9906
|
+
},
|
|
9907
|
+
config
|
|
9908
|
+
);
|
|
9909
|
+
}
|
|
9910
|
+
getFieldName() {
|
|
9911
|
+
return "slippage";
|
|
9912
|
+
}
|
|
9913
|
+
};
|
|
9914
|
+
|
|
9211
9915
|
// src/services/orderCreator/marketOrderCreator.ts
|
|
9212
9916
|
var MarketOrderCreator = class extends BaseOrderCreator {
|
|
9213
|
-
|
|
9214
|
-
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9218
|
-
delete data["isStopOrder"];
|
|
9219
|
-
return {
|
|
9220
|
-
...data
|
|
9221
|
-
};
|
|
9917
|
+
constructor() {
|
|
9918
|
+
super(...arguments);
|
|
9919
|
+
this.slippageValidationStrategy = new SlippageValidationStrategy();
|
|
9920
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new SlippageValidator());
|
|
9921
|
+
this.orderType = OrderType.MARKET;
|
|
9222
9922
|
}
|
|
9223
|
-
|
|
9224
|
-
|
|
9225
|
-
|
|
9226
|
-
|
|
9227
|
-
|
|
9228
|
-
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9237
|
-
|
|
9238
|
-
|
|
9923
|
+
/**
|
|
9924
|
+
* Builds the market order
|
|
9925
|
+
* Implements template method hook
|
|
9926
|
+
*/
|
|
9927
|
+
buildOrder(values, config) {
|
|
9928
|
+
const orderlyValues = values;
|
|
9929
|
+
const data = this.baseOrder(orderlyValues);
|
|
9930
|
+
const result = { ...data };
|
|
9931
|
+
delete result.order_price;
|
|
9932
|
+
delete result.total;
|
|
9933
|
+
delete result.trigger_price;
|
|
9934
|
+
if ("isStopOrder" in result) {
|
|
9935
|
+
delete result.isStopOrder;
|
|
9936
|
+
}
|
|
9937
|
+
return result;
|
|
9938
|
+
}
|
|
9939
|
+
/**
|
|
9940
|
+
* Runs validations using validation chain
|
|
9941
|
+
* Implements template method hook
|
|
9942
|
+
*/
|
|
9943
|
+
runValidations(values, configs) {
|
|
9944
|
+
const orderlyValues = values;
|
|
9945
|
+
const result = this.baseValidate(orderlyValues, configs);
|
|
9946
|
+
const chainErrors = this.validationChain.validate(orderlyValues, configs);
|
|
9947
|
+
Object.assign(result, chainErrors);
|
|
9948
|
+
return result;
|
|
9239
9949
|
}
|
|
9240
9950
|
};
|
|
9241
9951
|
|
|
@@ -9267,14 +9977,26 @@ var FOKOrderCreator = class extends LimitOrderCreator {
|
|
|
9267
9977
|
|
|
9268
9978
|
// src/services/orderCreator/generalCreator.ts
|
|
9269
9979
|
var GeneralOrderCreator = class extends BaseOrderCreator {
|
|
9270
|
-
|
|
9980
|
+
constructor() {
|
|
9981
|
+
super(...arguments);
|
|
9982
|
+
this.orderType = void 0;
|
|
9983
|
+
}
|
|
9984
|
+
/**
|
|
9985
|
+
* Builds the general order
|
|
9986
|
+
* Implements template method hook
|
|
9987
|
+
*/
|
|
9988
|
+
buildOrder(data) {
|
|
9271
9989
|
return {
|
|
9272
9990
|
...this.baseOrder(data),
|
|
9273
9991
|
order_price: data.order_price,
|
|
9274
9992
|
order_quantity: data.order_quantity
|
|
9275
9993
|
};
|
|
9276
9994
|
}
|
|
9277
|
-
|
|
9995
|
+
/**
|
|
9996
|
+
* Runs base validations
|
|
9997
|
+
* Implements template method hook
|
|
9998
|
+
*/
|
|
9999
|
+
runValidations(values, configs) {
|
|
9278
10000
|
return super.baseValidate(values, configs);
|
|
9279
10001
|
}
|
|
9280
10002
|
};
|
|
@@ -9383,7 +10105,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
|
|
|
9383
10105
|
distribution_type,
|
|
9384
10106
|
skew,
|
|
9385
10107
|
reduce_only,
|
|
9386
|
-
visible_quantity
|
|
10108
|
+
visible_quantity,
|
|
10109
|
+
margin_mode
|
|
9387
10110
|
} = order;
|
|
9388
10111
|
const prices = calcScaledOrderPrices({
|
|
9389
10112
|
start_price,
|
|
@@ -9409,6 +10132,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
|
|
|
9409
10132
|
order_quantity: qtys[index],
|
|
9410
10133
|
order_price: price,
|
|
9411
10134
|
reduce_only,
|
|
10135
|
+
margin_mode: margin_mode || MarginMode.CROSS,
|
|
10136
|
+
// Default to CROSS if not provided for backward compatibility
|
|
9412
10137
|
// it will be used for identify the scaled order from ws
|
|
9413
10138
|
client_order_id: `scaled_${index}_${now}`
|
|
9414
10139
|
};
|
|
@@ -9512,7 +10237,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9512
10237
|
super(...arguments);
|
|
9513
10238
|
this.orderType = OrderType.SCALED;
|
|
9514
10239
|
}
|
|
9515
|
-
|
|
10240
|
+
/**
|
|
10241
|
+
* Builds the scaled order
|
|
10242
|
+
* Implements template method hook
|
|
10243
|
+
*/
|
|
10244
|
+
buildOrder(values, config) {
|
|
9516
10245
|
const orders = calcScaledOrderBatchBody(values, config.symbol);
|
|
9517
10246
|
const { total_orders, distribution_type, skew } = values;
|
|
9518
10247
|
const order = {
|
|
@@ -9530,6 +10259,7 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9530
10259
|
"reduce_only",
|
|
9531
10260
|
"side",
|
|
9532
10261
|
"order_type",
|
|
10262
|
+
"margin_mode",
|
|
9533
10263
|
"orders",
|
|
9534
10264
|
"total_orders",
|
|
9535
10265
|
"distribution_type",
|
|
@@ -9538,7 +10268,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
|
|
|
9538
10268
|
order
|
|
9539
10269
|
);
|
|
9540
10270
|
}
|
|
9541
|
-
|
|
10271
|
+
/**
|
|
10272
|
+
* Runs validations for scaled order
|
|
10273
|
+
* Implements template method hook
|
|
10274
|
+
*/
|
|
10275
|
+
runValidations(values, config) {
|
|
9542
10276
|
const { maxQty, askAndBid, markPrice, symbol } = config;
|
|
9543
10277
|
const { base_dp, quote_dp } = config.symbol;
|
|
9544
10278
|
const { order_quantity, total, total_orders, distribution_type, skew } = values;
|
|
@@ -9607,22 +10341,22 @@ function validatePrice(values, config) {
|
|
|
9607
10341
|
if (!config.markPrice) {
|
|
9608
10342
|
return errors;
|
|
9609
10343
|
}
|
|
9610
|
-
const { minPrice
|
|
10344
|
+
const { minPrice, maxPrice } = getPriceRange({
|
|
9611
10345
|
side: values.side,
|
|
9612
10346
|
basePrice: config.markPrice,
|
|
9613
10347
|
symbolInfo: config.symbol
|
|
9614
10348
|
});
|
|
9615
10349
|
const comparePrice = (key, value) => {
|
|
9616
10350
|
const price = new Decimal(value || 0);
|
|
9617
|
-
if (price.lt(
|
|
10351
|
+
if (price.lt(minPrice)) {
|
|
9618
10352
|
errors[key] = OrderValidation.min(
|
|
9619
10353
|
key,
|
|
9620
|
-
new Decimal(
|
|
10354
|
+
new Decimal(minPrice).todp(quote_dp).toString()
|
|
9621
10355
|
);
|
|
9622
|
-
} else if (price.gt(
|
|
10356
|
+
} else if (price.gt(maxPrice)) {
|
|
9623
10357
|
errors[key] = OrderValidation.max(
|
|
9624
10358
|
key,
|
|
9625
|
-
new Decimal(
|
|
10359
|
+
new Decimal(maxPrice).todp(quote_dp).toString()
|
|
9626
10360
|
);
|
|
9627
10361
|
}
|
|
9628
10362
|
};
|
|
@@ -9630,13 +10364,40 @@ function validatePrice(values, config) {
|
|
|
9630
10364
|
comparePrice("end_price", end_price);
|
|
9631
10365
|
return errors;
|
|
9632
10366
|
}
|
|
9633
|
-
|
|
10367
|
+
|
|
10368
|
+
// src/services/orderCreator/validators/TriggerPriceValidator.ts
|
|
10369
|
+
var TriggerPriceValidator = class extends BaseValidator {
|
|
10370
|
+
constructor() {
|
|
10371
|
+
super();
|
|
10372
|
+
this.strategy = new TriggerPriceValidationStrategy();
|
|
10373
|
+
}
|
|
10374
|
+
doValidate(values, config) {
|
|
10375
|
+
return this.strategy.validate(
|
|
10376
|
+
{
|
|
10377
|
+
trigger_price: values.trigger_price
|
|
10378
|
+
},
|
|
10379
|
+
config
|
|
10380
|
+
);
|
|
10381
|
+
}
|
|
10382
|
+
getFieldName() {
|
|
10383
|
+
return "trigger_price";
|
|
10384
|
+
}
|
|
10385
|
+
};
|
|
10386
|
+
|
|
10387
|
+
// src/services/orderCreator/stopLimitOrderCreator.ts
|
|
9634
10388
|
var StopLimitOrderCreator = class extends BaseOrderCreator {
|
|
9635
10389
|
constructor() {
|
|
9636
10390
|
super(...arguments);
|
|
10391
|
+
this.priceValidationStrategy = new PriceValidationStrategy();
|
|
10392
|
+
this.triggerPriceValidationStrategy = new TriggerPriceValidationStrategy();
|
|
10393
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new TriggerPriceValidator()).addValidator(new PriceValidator());
|
|
9637
10394
|
this.orderType = OrderType.STOP_LIMIT;
|
|
9638
10395
|
}
|
|
9639
|
-
|
|
10396
|
+
/**
|
|
10397
|
+
* Builds the stop-limit order
|
|
10398
|
+
* Implements template method hook
|
|
10399
|
+
*/
|
|
10400
|
+
buildOrder(values, config) {
|
|
9640
10401
|
this.totalToQuantity(values, config);
|
|
9641
10402
|
const order = {
|
|
9642
10403
|
...this.baseOrder(values),
|
|
@@ -9658,84 +10419,82 @@ var StopLimitOrderCreator = class extends BaseOrderCreator {
|
|
|
9658
10419
|
"trigger_price_type",
|
|
9659
10420
|
"side",
|
|
9660
10421
|
"reduce_only",
|
|
10422
|
+
"margin_mode",
|
|
9661
10423
|
"visible_quantity"
|
|
9662
10424
|
],
|
|
9663
10425
|
order
|
|
9664
10426
|
);
|
|
9665
10427
|
}
|
|
9666
|
-
|
|
9667
|
-
|
|
9668
|
-
|
|
9669
|
-
|
|
9670
|
-
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
9675
|
-
|
|
9676
|
-
|
|
9677
|
-
|
|
9678
|
-
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
|
|
9682
|
-
|
|
9683
|
-
|
|
9684
|
-
|
|
9685
|
-
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
|
|
9703
|
-
|
|
9704
|
-
|
|
9705
|
-
|
|
9706
|
-
if (price.gt(priceRange?.max)) {
|
|
9707
|
-
errors.order_price = OrderValidation.max(
|
|
9708
|
-
"order_price",
|
|
9709
|
-
new Decimal(priceRange.max).todp(symbol.quote_dp).toString()
|
|
9710
|
-
);
|
|
9711
|
-
}
|
|
9712
|
-
}
|
|
9713
|
-
if (price.lt(quote_min)) {
|
|
9714
|
-
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
9715
|
-
} else {
|
|
9716
|
-
if (price.lt(priceRange?.min)) {
|
|
9717
|
-
errors.order_price = OrderValidation.min(
|
|
9718
|
-
"order_price",
|
|
9719
|
-
new Decimal(priceRange.min).todp(symbol.quote_dp).toString()
|
|
9720
|
-
);
|
|
9721
|
-
}
|
|
9722
|
-
}
|
|
9723
|
-
}
|
|
10428
|
+
/**
|
|
10429
|
+
* Runs validations using validation chain
|
|
10430
|
+
* Implements template method hook
|
|
10431
|
+
*/
|
|
10432
|
+
runValidations(values, config) {
|
|
10433
|
+
const orderlyValues = values;
|
|
10434
|
+
const errors = this.baseValidate(orderlyValues, config);
|
|
10435
|
+
const triggerPrice = values.trigger_price;
|
|
10436
|
+
if (!triggerPrice || triggerPrice === 0) {
|
|
10437
|
+
errors.trigger_price = OrderValidation.required("trigger_price");
|
|
10438
|
+
} else {
|
|
10439
|
+
const triggerError = this.triggerPriceValidationStrategy.validate(
|
|
10440
|
+
{ trigger_price: triggerPrice },
|
|
10441
|
+
config
|
|
10442
|
+
);
|
|
10443
|
+
if (triggerError) {
|
|
10444
|
+
errors.trigger_price = triggerError;
|
|
10445
|
+
}
|
|
10446
|
+
}
|
|
10447
|
+
const valuesWithFields = values;
|
|
10448
|
+
const orderPrice = valuesWithFields.order_price ?? valuesWithFields.price;
|
|
10449
|
+
const triggerPriceForPriceValidation = triggerPrice;
|
|
10450
|
+
const side = valuesWithFields.side ?? orderlyValues.side;
|
|
10451
|
+
if (!orderPrice) {
|
|
10452
|
+
errors.order_price = OrderValidation.required("order_price");
|
|
10453
|
+
} else if (orderPrice && triggerPriceForPriceValidation && side) {
|
|
10454
|
+
const modifiedConfig = {
|
|
10455
|
+
...config,
|
|
10456
|
+
markPrice: Number(triggerPriceForPriceValidation)
|
|
10457
|
+
};
|
|
10458
|
+
const priceError = this.priceValidationStrategy.validate(
|
|
10459
|
+
{
|
|
10460
|
+
order_price: orderPrice,
|
|
10461
|
+
side,
|
|
10462
|
+
order_type: OrderType.LIMIT
|
|
10463
|
+
},
|
|
10464
|
+
modifiedConfig
|
|
10465
|
+
);
|
|
10466
|
+
if (priceError) {
|
|
10467
|
+
errors.order_price = priceError;
|
|
9724
10468
|
}
|
|
9725
|
-
|
|
9726
|
-
|
|
10469
|
+
} else if (orderPrice && triggerPriceForPriceValidation) {
|
|
10470
|
+
const { quote_max, quote_min } = config.symbol;
|
|
10471
|
+
const price = Number(orderPrice);
|
|
10472
|
+
if (quote_max && price > quote_max) {
|
|
10473
|
+
errors.order_price = OrderValidation.max("order_price", quote_max);
|
|
10474
|
+
} else if (quote_min && price < quote_min) {
|
|
10475
|
+
errors.order_price = OrderValidation.min("order_price", quote_min);
|
|
10476
|
+
}
|
|
10477
|
+
}
|
|
10478
|
+
return errors;
|
|
9727
10479
|
}
|
|
9728
10480
|
};
|
|
9729
10481
|
var StopMarketOrderCreator = class extends BaseOrderCreator {
|
|
9730
|
-
|
|
10482
|
+
constructor() {
|
|
10483
|
+
super(...arguments);
|
|
10484
|
+
this.triggerPriceValidationStrategy = new TriggerPriceValidationStrategy();
|
|
10485
|
+
this.validationChain = new ValidationChain().addValidator(new QuantityValidator()).addValidator(new TriggerPriceValidator());
|
|
10486
|
+
}
|
|
10487
|
+
/**
|
|
10488
|
+
* Builds the stop-market order
|
|
10489
|
+
* Implements template method hook
|
|
10490
|
+
*/
|
|
10491
|
+
buildOrder(values) {
|
|
9731
10492
|
const order = {
|
|
9732
10493
|
...this.baseOrder(values),
|
|
9733
|
-
// order_price: values.order_price,
|
|
9734
10494
|
trigger_price: values.trigger_price,
|
|
9735
10495
|
algo_type: AlgoOrderRootType.STOP,
|
|
9736
10496
|
type: OrderType.MARKET,
|
|
9737
10497
|
quantity: values["order_quantity"],
|
|
9738
|
-
// price: values["order_price"],
|
|
9739
10498
|
trigger_price_type: TriggerPriceType.MARK_PRICE
|
|
9740
10499
|
};
|
|
9741
10500
|
return pick(
|
|
@@ -9745,225 +10504,40 @@ var StopMarketOrderCreator = class extends BaseOrderCreator {
|
|
|
9745
10504
|
"algo_type",
|
|
9746
10505
|
"type",
|
|
9747
10506
|
"quantity",
|
|
9748
|
-
// "price",
|
|
9749
10507
|
"trigger_price_type",
|
|
9750
10508
|
"side",
|
|
9751
10509
|
"reduce_only",
|
|
10510
|
+
"margin_mode",
|
|
9752
10511
|
"visible_quantity"
|
|
9753
10512
|
],
|
|
9754
10513
|
order
|
|
9755
10514
|
);
|
|
9756
10515
|
}
|
|
9757
|
-
|
|
9758
|
-
|
|
9759
|
-
|
|
9760
|
-
|
|
9761
|
-
|
|
9762
|
-
|
|
9763
|
-
|
|
9764
|
-
|
|
9765
|
-
|
|
9766
|
-
} else if (trigger_price < quote_min || trigger_price == 0) {
|
|
9767
|
-
errors.trigger_price = OrderValidation.min("trigger_price", quote_min);
|
|
9768
|
-
}
|
|
9769
|
-
return errors;
|
|
9770
|
-
});
|
|
10516
|
+
/**
|
|
10517
|
+
* Runs validations using validation chain
|
|
10518
|
+
* Implements template method hook
|
|
10519
|
+
*/
|
|
10520
|
+
runValidations(values, config) {
|
|
10521
|
+
const errors = this.baseValidate(values, config);
|
|
10522
|
+
const chainErrors = this.validationChain.validate(values, config);
|
|
10523
|
+
Object.assign(errors, chainErrors);
|
|
10524
|
+
return errors;
|
|
9771
10525
|
}
|
|
9772
10526
|
};
|
|
9773
|
-
|
|
9774
|
-
|
|
9775
|
-
};
|
|
10527
|
+
|
|
10528
|
+
// src/services/orderCreator/baseAlgoCreator.ts
|
|
9776
10529
|
var BaseAlgoOrderCreator = class {
|
|
10530
|
+
constructor() {
|
|
10531
|
+
this.tpslValidationStrategy = new TPSLValidationStrategy();
|
|
10532
|
+
}
|
|
9777
10533
|
/**
|
|
9778
|
-
*
|
|
10534
|
+
* Validates TP/SL order using TPSLValidationStrategy
|
|
10535
|
+
* Consolidates validation logic from baseBracketOrderCreator
|
|
9779
10536
|
*/
|
|
9780
10537
|
validate(values, config) {
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
tp_trigger_price,
|
|
9785
|
-
sl_trigger_price,
|
|
9786
|
-
side,
|
|
9787
|
-
// tp_enable,
|
|
9788
|
-
// sl_enable,
|
|
9789
|
-
tp_order_type,
|
|
9790
|
-
sl_order_type,
|
|
9791
|
-
tp_order_price,
|
|
9792
|
-
sl_order_price
|
|
9793
|
-
} = values;
|
|
9794
|
-
const qty = Number(values.quantity);
|
|
9795
|
-
const maxQty = config.maxQty;
|
|
9796
|
-
const orderType = values.order_type;
|
|
9797
|
-
const {
|
|
9798
|
-
quote_max,
|
|
9799
|
-
quote_min,
|
|
9800
|
-
price_scope,
|
|
9801
|
-
quote_dp,
|
|
9802
|
-
base_min,
|
|
9803
|
-
min_notional
|
|
9804
|
-
} = config.symbol ?? {};
|
|
9805
|
-
if (!isNaN(qty) && qty > maxQty) {
|
|
9806
|
-
result.quantity = OrderValidation.max("quantity", config.maxQty);
|
|
9807
|
-
}
|
|
9808
|
-
if (!isNaN(qty) && qty < base_min) {
|
|
9809
|
-
result.quantity = OrderValidation.min("quantity", base_min);
|
|
9810
|
-
}
|
|
9811
|
-
if (Number(tp_trigger_price) < 0) {
|
|
9812
|
-
result.tp_trigger_price = OrderValidation.min("tp_trigger_price", 0);
|
|
9813
|
-
}
|
|
9814
|
-
if (Number(sl_trigger_price) < 0) {
|
|
9815
|
-
result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
|
|
9816
|
-
}
|
|
9817
|
-
if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
|
|
9818
|
-
result.tp_order_price = OrderValidation.required("tp_order_price");
|
|
9819
|
-
}
|
|
9820
|
-
if (sl_order_type === OrderType.LIMIT && !sl_order_price) {
|
|
9821
|
-
result.sl_order_price = OrderValidation.required("sl_order_price");
|
|
9822
|
-
}
|
|
9823
|
-
const mark_price = orderType === OrderType.MARKET || orderType == null ? config.markPrice : values.order_price ? Number(values.order_price) : void 0;
|
|
9824
|
-
const tpslSide = side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
|
|
9825
|
-
if (side === OrderSide.BUY && mark_price) {
|
|
9826
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
|
|
9827
|
-
result.sl_trigger_price = OrderValidation.min(
|
|
9828
|
-
"sl_trigger_price",
|
|
9829
|
-
formatPrice2(quote_min, quote_dp)
|
|
9830
|
-
);
|
|
9831
|
-
}
|
|
9832
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) >= mark_price) {
|
|
9833
|
-
result.sl_trigger_price = OrderValidation.max(
|
|
9834
|
-
"sl_trigger_price",
|
|
9835
|
-
formatPrice2(mark_price, quote_dp)
|
|
9836
|
-
);
|
|
9837
|
-
}
|
|
9838
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
|
|
9839
|
-
result.tp_trigger_price = OrderValidation.min(
|
|
9840
|
-
"tp_trigger_price",
|
|
9841
|
-
formatPrice2(mark_price, quote_dp)
|
|
9842
|
-
);
|
|
9843
|
-
}
|
|
9844
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
|
|
9845
|
-
result.tp_trigger_price = OrderValidation.max(
|
|
9846
|
-
"tp_trigger_price",
|
|
9847
|
-
formatPrice2(quote_max, quote_dp)
|
|
9848
|
-
);
|
|
9849
|
-
}
|
|
9850
|
-
if (sl_trigger_price && sl_order_price) {
|
|
9851
|
-
const slOrderPriceRange = getPriceRange({
|
|
9852
|
-
side: tpslSide,
|
|
9853
|
-
basePrice: Number(sl_trigger_price),
|
|
9854
|
-
symbolInfo: config.symbol
|
|
9855
|
-
});
|
|
9856
|
-
if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
|
|
9857
|
-
result.sl_order_price = OrderValidation.min(
|
|
9858
|
-
"sl_order_price",
|
|
9859
|
-
formatPrice2(slOrderPriceRange.minPrice, quote_dp)
|
|
9860
|
-
);
|
|
9861
|
-
}
|
|
9862
|
-
if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
|
|
9863
|
-
result.sl_order_price = OrderValidation.max(
|
|
9864
|
-
"sl_order_price",
|
|
9865
|
-
formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
|
|
9866
|
-
);
|
|
9867
|
-
}
|
|
9868
|
-
if (Number(sl_trigger_price) < Number(sl_order_price)) {
|
|
9869
|
-
result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
|
|
9870
|
-
}
|
|
9871
|
-
}
|
|
9872
|
-
if (tp_trigger_price && tp_order_price) {
|
|
9873
|
-
const tpOrderPriceRange = getPriceRange({
|
|
9874
|
-
side: tpslSide,
|
|
9875
|
-
basePrice: Number(tp_trigger_price),
|
|
9876
|
-
symbolInfo: config.symbol
|
|
9877
|
-
});
|
|
9878
|
-
if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
|
|
9879
|
-
result.tp_order_price = OrderValidation.max(
|
|
9880
|
-
"tp_order_price",
|
|
9881
|
-
formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
|
|
9882
|
-
);
|
|
9883
|
-
}
|
|
9884
|
-
if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
|
|
9885
|
-
result.tp_order_price = OrderValidation.min(
|
|
9886
|
-
"tp_order_price",
|
|
9887
|
-
formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
|
|
9888
|
-
);
|
|
9889
|
-
}
|
|
9890
|
-
if (Number(tp_trigger_price) > Number(tp_order_price)) {
|
|
9891
|
-
result.tp_trigger_price = OrderValidation.priceErrorMin("tp_trigger_price");
|
|
9892
|
-
}
|
|
9893
|
-
}
|
|
9894
|
-
}
|
|
9895
|
-
if (side === OrderSide.SELL && mark_price) {
|
|
9896
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) > quote_max) {
|
|
9897
|
-
result.sl_trigger_price = OrderValidation.max(
|
|
9898
|
-
"sl_trigger_price",
|
|
9899
|
-
formatPrice2(quote_max, quote_dp)
|
|
9900
|
-
);
|
|
9901
|
-
}
|
|
9902
|
-
if (!!sl_trigger_price && Number(sl_trigger_price) <= mark_price) {
|
|
9903
|
-
result.sl_trigger_price = OrderValidation.min(
|
|
9904
|
-
"sl_trigger_price",
|
|
9905
|
-
formatPrice2(mark_price, quote_dp)
|
|
9906
|
-
);
|
|
9907
|
-
}
|
|
9908
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
|
|
9909
|
-
result.tp_trigger_price = OrderValidation.max(
|
|
9910
|
-
"tp_trigger_price",
|
|
9911
|
-
formatPrice2(mark_price, quote_dp)
|
|
9912
|
-
);
|
|
9913
|
-
}
|
|
9914
|
-
if (!!tp_trigger_price && Number(tp_trigger_price) < quote_min) {
|
|
9915
|
-
result.tp_trigger_price = OrderValidation.min(
|
|
9916
|
-
"tp_trigger_price",
|
|
9917
|
-
formatPrice2(quote_min, quote_dp)
|
|
9918
|
-
);
|
|
9919
|
-
}
|
|
9920
|
-
if (sl_trigger_price && sl_order_price) {
|
|
9921
|
-
const slOrderPriceRange = getPriceRange({
|
|
9922
|
-
side: tpslSide,
|
|
9923
|
-
basePrice: Number(sl_trigger_price),
|
|
9924
|
-
symbolInfo: config.symbol
|
|
9925
|
-
});
|
|
9926
|
-
if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
|
|
9927
|
-
result.sl_order_price = OrderValidation.min(
|
|
9928
|
-
"sl_order_price",
|
|
9929
|
-
formatPrice2(slOrderPriceRange.minPrice, quote_dp)
|
|
9930
|
-
);
|
|
9931
|
-
}
|
|
9932
|
-
if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
|
|
9933
|
-
result.sl_order_price = OrderValidation.max(
|
|
9934
|
-
"sl_order_price",
|
|
9935
|
-
formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
|
|
9936
|
-
);
|
|
9937
|
-
}
|
|
9938
|
-
if (Number(sl_trigger_price) > Number(sl_order_price)) {
|
|
9939
|
-
result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
|
|
9940
|
-
}
|
|
9941
|
-
}
|
|
9942
|
-
if (tp_trigger_price && tp_order_price) {
|
|
9943
|
-
const tpOrderPriceRange = getPriceRange({
|
|
9944
|
-
side: tpslSide,
|
|
9945
|
-
basePrice: Number(tp_trigger_price),
|
|
9946
|
-
symbolInfo: config.symbol
|
|
9947
|
-
});
|
|
9948
|
-
if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
|
|
9949
|
-
result.tp_order_price = OrderValidation.min(
|
|
9950
|
-
"tp_order_price",
|
|
9951
|
-
formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
|
|
9952
|
-
);
|
|
9953
|
-
}
|
|
9954
|
-
if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
|
|
9955
|
-
result.tp_order_price = OrderValidation.max(
|
|
9956
|
-
"tp_order_price",
|
|
9957
|
-
formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
|
|
9958
|
-
);
|
|
9959
|
-
}
|
|
9960
|
-
if (Number(tp_trigger_price) < Number(tp_order_price)) {
|
|
9961
|
-
result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
|
|
9962
|
-
}
|
|
9963
|
-
}
|
|
9964
|
-
}
|
|
9965
|
-
return Object.keys(result).length > 0 ? result : null;
|
|
9966
|
-
});
|
|
10538
|
+
return Promise.resolve(
|
|
10539
|
+
this.tpslValidationStrategy.validate(values, config)
|
|
10540
|
+
);
|
|
9967
10541
|
}
|
|
9968
10542
|
};
|
|
9969
10543
|
|
|
@@ -10016,7 +10590,9 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
|
|
|
10016
10590
|
reduce_only: true,
|
|
10017
10591
|
quantity: values.quantity,
|
|
10018
10592
|
symbol: values.symbol,
|
|
10019
|
-
child_orders
|
|
10593
|
+
child_orders,
|
|
10594
|
+
// Include margin_mode for isolated/cross margin support; default CROSS per order entry pattern
|
|
10595
|
+
margin_mode: values.margin_mode || MarginMode.CROSS
|
|
10020
10596
|
};
|
|
10021
10597
|
}
|
|
10022
10598
|
crateUpdateOrder(values, oldValue, config) {
|
|
@@ -10118,7 +10694,9 @@ var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
|
|
|
10118
10694
|
trigger_price_type: TriggerPriceType.MARK_PRICE,
|
|
10119
10695
|
// reduce_only: true,
|
|
10120
10696
|
symbol: values.symbol,
|
|
10121
|
-
child_orders
|
|
10697
|
+
child_orders,
|
|
10698
|
+
// Include margin_mode for isolated/cross margin support; default CROSS per order entry pattern
|
|
10699
|
+
margin_mode: values.margin_mode || MarginMode.CROSS
|
|
10122
10700
|
};
|
|
10123
10701
|
}
|
|
10124
10702
|
crateUpdateOrder(values, oldValue, config) {
|
|
@@ -10155,7 +10733,11 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10155
10733
|
super(...arguments);
|
|
10156
10734
|
this.orderType = OrderType.TRAILING_STOP;
|
|
10157
10735
|
}
|
|
10158
|
-
|
|
10736
|
+
/**
|
|
10737
|
+
* Builds the trailing stop order
|
|
10738
|
+
* Implements template method hook
|
|
10739
|
+
*/
|
|
10740
|
+
buildOrder(values, config) {
|
|
10159
10741
|
const { order_quantity, activated_price, callback_value, callback_rate } = values;
|
|
10160
10742
|
const order = {
|
|
10161
10743
|
...this.baseOrder(values),
|
|
@@ -10176,6 +10758,7 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10176
10758
|
"quantity",
|
|
10177
10759
|
"side",
|
|
10178
10760
|
"reduce_only",
|
|
10761
|
+
"margin_mode",
|
|
10179
10762
|
"visible_quantity",
|
|
10180
10763
|
"activated_price",
|
|
10181
10764
|
"callback_value",
|
|
@@ -10184,28 +10767,34 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10184
10767
|
order
|
|
10185
10768
|
);
|
|
10186
10769
|
}
|
|
10187
|
-
|
|
10770
|
+
/**
|
|
10771
|
+
* Runs validations for trailing stop order
|
|
10772
|
+
* Implements template method hook
|
|
10773
|
+
*/
|
|
10774
|
+
runValidations(values, config) {
|
|
10188
10775
|
const { markPrice, symbol } = config;
|
|
10189
10776
|
const { quote_dp } = config.symbol;
|
|
10190
10777
|
const { side, activated_price, callback_value, callback_rate } = values;
|
|
10191
|
-
const errors =
|
|
10778
|
+
const errors = this.baseValidate(values, config);
|
|
10192
10779
|
if (activated_price) {
|
|
10193
|
-
const { minPrice
|
|
10780
|
+
const { minPrice, maxPrice } = getPriceRange({
|
|
10194
10781
|
side,
|
|
10195
|
-
markPrice,
|
|
10782
|
+
basePrice: markPrice,
|
|
10196
10783
|
symbolInfo: symbol
|
|
10197
10784
|
});
|
|
10198
|
-
|
|
10199
|
-
|
|
10200
|
-
|
|
10201
|
-
|
|
10202
|
-
|
|
10203
|
-
|
|
10204
|
-
|
|
10205
|
-
|
|
10206
|
-
|
|
10207
|
-
|
|
10208
|
-
|
|
10785
|
+
if (!isNaN(minPrice) && !isNaN(maxPrice)) {
|
|
10786
|
+
const activatedPrice = new Decimal(activated_price);
|
|
10787
|
+
if (activatedPrice.lt(minPrice) || activatedPrice.equals(0)) {
|
|
10788
|
+
errors.activated_price = OrderValidation.min(
|
|
10789
|
+
"activated_price",
|
|
10790
|
+
new Decimal(minPrice).todp(quote_dp).toString()
|
|
10791
|
+
);
|
|
10792
|
+
} else if (activatedPrice.gt(maxPrice)) {
|
|
10793
|
+
errors.activated_price = OrderValidation.max(
|
|
10794
|
+
"activated_price",
|
|
10795
|
+
new Decimal(maxPrice).todp(quote_dp).toString()
|
|
10796
|
+
);
|
|
10797
|
+
}
|
|
10209
10798
|
}
|
|
10210
10799
|
}
|
|
10211
10800
|
if (!callback_value && !callback_rate) {
|
|
@@ -10237,23 +10826,6 @@ var TrailingStopOrderCreator = class extends BaseOrderCreator {
|
|
|
10237
10826
|
return errors;
|
|
10238
10827
|
}
|
|
10239
10828
|
};
|
|
10240
|
-
function getPriceRange2(inputs) {
|
|
10241
|
-
const { markPrice, side, symbolInfo } = inputs;
|
|
10242
|
-
const { quote_min, quote_max } = symbolInfo;
|
|
10243
|
-
const priceRange = side === OrderSide.BUY ? {
|
|
10244
|
-
min: quote_min,
|
|
10245
|
-
max: markPrice
|
|
10246
|
-
} : {
|
|
10247
|
-
min: markPrice,
|
|
10248
|
-
max: quote_max
|
|
10249
|
-
};
|
|
10250
|
-
const minPrice3 = Math.max(quote_min, priceRange?.min);
|
|
10251
|
-
const maxPrice3 = Math.min(quote_max, priceRange?.max);
|
|
10252
|
-
return {
|
|
10253
|
-
minPrice: minPrice3,
|
|
10254
|
-
maxPrice: maxPrice3
|
|
10255
|
-
};
|
|
10256
|
-
}
|
|
10257
10829
|
|
|
10258
10830
|
// src/services/orderCreator/factory.ts
|
|
10259
10831
|
var OrderFactory = class {
|
|
@@ -10376,27 +10948,63 @@ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
|
|
|
10376
10948
|
markPrice,
|
|
10377
10949
|
totalCollateral,
|
|
10378
10950
|
futures_taker_fee_rate,
|
|
10379
|
-
positions: positions3
|
|
10951
|
+
positions: positions3,
|
|
10952
|
+
// leverage,
|
|
10953
|
+
sumUnitaryFunding
|
|
10380
10954
|
} = inputs;
|
|
10381
10955
|
const orderFee = order.orderFee({
|
|
10382
10956
|
qty: quantity,
|
|
10383
10957
|
price,
|
|
10384
10958
|
futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
|
|
10385
10959
|
});
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
|
|
10395
|
-
|
|
10396
|
-
|
|
10397
|
-
|
|
10960
|
+
let liqPrice = 0;
|
|
10961
|
+
if (order$1.margin_mode === MarginMode.CROSS) {
|
|
10962
|
+
liqPrice = order.estLiqPrice({
|
|
10963
|
+
markPrice,
|
|
10964
|
+
baseIMR: symbolInfo.base_imr,
|
|
10965
|
+
baseMMR: symbolInfo.base_mmr,
|
|
10966
|
+
totalCollateral,
|
|
10967
|
+
positions: positions3 == null ? [] : positions3,
|
|
10968
|
+
IMR_Factor: imr_factor,
|
|
10969
|
+
orderFee,
|
|
10970
|
+
newOrder: {
|
|
10971
|
+
qty: quantity,
|
|
10972
|
+
price,
|
|
10973
|
+
symbol
|
|
10974
|
+
}
|
|
10975
|
+
});
|
|
10976
|
+
} else {
|
|
10977
|
+
let isolatedPositionMargin = 0, costPosition = 0, positionQty = 0, lastSumUnitaryFunding = 0, leverage = 1;
|
|
10978
|
+
if (positions3) {
|
|
10979
|
+
const position = positions3.find(
|
|
10980
|
+
(p) => p.symbol === symbol && p.margin_mode === MarginMode.ISOLATED
|
|
10981
|
+
);
|
|
10982
|
+
if (position) {
|
|
10983
|
+
isolatedPositionMargin = position.margin ?? 0;
|
|
10984
|
+
costPosition = position.cost_position ?? 0;
|
|
10985
|
+
positionQty = position.position_qty ?? 0;
|
|
10986
|
+
lastSumUnitaryFunding = position.last_sum_unitary_funding ?? 0;
|
|
10987
|
+
leverage = position.leverage ? Number(position.leverage) : 1;
|
|
10988
|
+
}
|
|
10398
10989
|
}
|
|
10399
|
-
|
|
10990
|
+
liqPrice = order.estLiqPriceIsolated({
|
|
10991
|
+
isolatedPositionMargin,
|
|
10992
|
+
costPosition,
|
|
10993
|
+
positionQty,
|
|
10994
|
+
sumUnitaryFunding,
|
|
10995
|
+
lastSumUnitaryFunding,
|
|
10996
|
+
markPrice,
|
|
10997
|
+
baseIMR: symbolInfo.base_imr,
|
|
10998
|
+
baseMMR: symbolInfo.base_mmr,
|
|
10999
|
+
IMR_Factor: imr_factor,
|
|
11000
|
+
leverage,
|
|
11001
|
+
newOrder: {
|
|
11002
|
+
symbol,
|
|
11003
|
+
qty: quantity,
|
|
11004
|
+
price
|
|
11005
|
+
}
|
|
11006
|
+
});
|
|
11007
|
+
}
|
|
10400
11008
|
if (liqPrice <= 0) return null;
|
|
10401
11009
|
return liqPrice;
|
|
10402
11010
|
};
|
|
@@ -10454,7 +11062,9 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
|
|
|
10454
11062
|
// sl_enable: isEditing
|
|
10455
11063
|
// ? checkIsEnableTpSL(options?.defaultOrder).sl_enable
|
|
10456
11064
|
// : options?.tpslEnable?.sl_enable,
|
|
10457
|
-
position_type: options?.positionType
|
|
11065
|
+
position_type: options?.positionType,
|
|
11066
|
+
// Use defaultOrder.margin_mode when editing; otherwise position.margin_mode; default CROSS for backward compatibility
|
|
11067
|
+
margin_mode: options?.defaultOrder?.margin_mode ?? position?.margin_mode ?? MarginMode.CROSS
|
|
10458
11068
|
});
|
|
10459
11069
|
const symbolInfo = useSymbolsInfo()[position.symbol]();
|
|
10460
11070
|
const { data: markPrice } = useMarkPrice(order.symbol);
|
|
@@ -10757,11 +11367,53 @@ var useMaxLeverage = (symbol) => {
|
|
|
10757
11367
|
};
|
|
10758
11368
|
var useSymbolLeverage = (symbol) => {
|
|
10759
11369
|
const symbolInfo = useSymbolInfo(symbol);
|
|
10760
|
-
const
|
|
11370
|
+
const { state } = useAccount();
|
|
11371
|
+
const [updateMutation, { isMutating }] = useMutation("/v1/client/leverage");
|
|
10761
11372
|
const maxLeverage = useMemo(() => {
|
|
10762
11373
|
const baseIMR = symbolInfo?.("base_imr");
|
|
10763
11374
|
return baseIMR ? 1 / baseIMR : 1;
|
|
10764
11375
|
}, [symbolInfo]);
|
|
11376
|
+
const update = async (data) => {
|
|
11377
|
+
const result = await updateMutation(data);
|
|
11378
|
+
if (result?.success && data.symbol && state.accountId) {
|
|
11379
|
+
const key = ["/v1/client/leverages", state.accountId];
|
|
11380
|
+
mutate(
|
|
11381
|
+
key,
|
|
11382
|
+
(prev) => {
|
|
11383
|
+
if (!prev) {
|
|
11384
|
+
return [
|
|
11385
|
+
{
|
|
11386
|
+
symbol: data.symbol,
|
|
11387
|
+
leverage: data.leverage,
|
|
11388
|
+
margin_mode: data.margin_mode
|
|
11389
|
+
}
|
|
11390
|
+
];
|
|
11391
|
+
}
|
|
11392
|
+
const index = prev.findIndex(
|
|
11393
|
+
(item) => item.symbol === data.symbol && (item.margin_mode ?? MarginMode.CROSS) === (data.margin_mode ?? MarginMode.CROSS)
|
|
11394
|
+
);
|
|
11395
|
+
if (index === -1) {
|
|
11396
|
+
return [
|
|
11397
|
+
...prev,
|
|
11398
|
+
{
|
|
11399
|
+
symbol: data.symbol,
|
|
11400
|
+
leverage: data.leverage,
|
|
11401
|
+
margin_mode: data.margin_mode
|
|
11402
|
+
}
|
|
11403
|
+
];
|
|
11404
|
+
}
|
|
11405
|
+
const next = [...prev];
|
|
11406
|
+
next[index] = {
|
|
11407
|
+
...next[index],
|
|
11408
|
+
leverage: data.leverage
|
|
11409
|
+
};
|
|
11410
|
+
return next;
|
|
11411
|
+
},
|
|
11412
|
+
{ revalidate: false }
|
|
11413
|
+
);
|
|
11414
|
+
}
|
|
11415
|
+
return result;
|
|
11416
|
+
};
|
|
10765
11417
|
return {
|
|
10766
11418
|
maxLeverage,
|
|
10767
11419
|
update,
|
|
@@ -11498,8 +12150,8 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
|
|
|
11498
12150
|
const keys = Object.keys(current);
|
|
11499
12151
|
for (let i = 0; i < keys.length; i++) {
|
|
11500
12152
|
const k = keys[i];
|
|
11501
|
-
|
|
11502
|
-
|
|
12153
|
+
const preveValue = prev[k];
|
|
12154
|
+
const currentValue = current[k];
|
|
11503
12155
|
if (typeof preveValue === "undefined" && typeof currentValue === "undefined")
|
|
11504
12156
|
continue;
|
|
11505
12157
|
if (preveValue !== currentValue) {
|
|
@@ -11512,7 +12164,12 @@ function useOrderEntry(symbolOrOrder, sideOrOptions, reduceOnly, options) {
|
|
|
11512
12164
|
if (!key) return null;
|
|
11513
12165
|
return { key, value, preValue };
|
|
11514
12166
|
};
|
|
11515
|
-
const
|
|
12167
|
+
const { marginMode: symbolMarginMode } = useMarginModeBySymbol(symbol);
|
|
12168
|
+
const marginMode = typeof symbolOrOrder === "object" && symbolOrOrder.margin_mode ? symbolOrOrder.margin_mode : symbolMarginMode;
|
|
12169
|
+
const maxQty = useMaxQty(symbol, sideValue, {
|
|
12170
|
+
reduceOnly: isReduceOnly,
|
|
12171
|
+
marginMode: marginMode ?? MarginMode.CROSS
|
|
12172
|
+
});
|
|
11516
12173
|
const parseString2Number = (order, key, dp) => {
|
|
11517
12174
|
if (typeof order[key] !== "string") return;
|
|
11518
12175
|
if (order[key] && order[key].startsWith(".")) {
|
|
@@ -12063,7 +12720,7 @@ var DataPaint = class extends BasePaint {
|
|
|
12063
12720
|
);
|
|
12064
12721
|
const { position, fontSize = 14 } = layout;
|
|
12065
12722
|
let left = this._ratio(position.left);
|
|
12066
|
-
|
|
12723
|
+
const top = layout.position.top + offsetTop + this.transformTop;
|
|
12067
12724
|
let prevElementBoundingBox = {};
|
|
12068
12725
|
if (typeof options.data?.position.side !== "undefined") {
|
|
12069
12726
|
prevElementBoundingBox = this._drawText(options.data.position.side, {
|
|
@@ -12094,6 +12751,28 @@ var DataPaint = class extends BasePaint {
|
|
|
12094
12751
|
fontFamily: options.fontFamily
|
|
12095
12752
|
});
|
|
12096
12753
|
}
|
|
12754
|
+
const marginMode = options.data?.position.marginMode;
|
|
12755
|
+
if (marginMode) {
|
|
12756
|
+
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12757
|
+
if (prevElementBoundingBox.width) {
|
|
12758
|
+
prevElementBoundingBox = this._drawText("|", {
|
|
12759
|
+
color: "rgba(255,255,255,0.2)",
|
|
12760
|
+
left,
|
|
12761
|
+
top: this._ratio(top),
|
|
12762
|
+
fontSize: this._ratio(fontSize),
|
|
12763
|
+
fontFamily: options.fontFamily
|
|
12764
|
+
});
|
|
12765
|
+
}
|
|
12766
|
+
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12767
|
+
const marginModeText = marginMode.charAt(0).toUpperCase() + marginMode.slice(1);
|
|
12768
|
+
prevElementBoundingBox = this._drawText(marginModeText, {
|
|
12769
|
+
color: layout.color,
|
|
12770
|
+
left,
|
|
12771
|
+
top: this._ratio(top),
|
|
12772
|
+
fontSize: this._ratio(fontSize),
|
|
12773
|
+
fontFamily: options.fontFamily
|
|
12774
|
+
});
|
|
12775
|
+
}
|
|
12097
12776
|
if (typeof options.data?.position.leverage !== "undefined") {
|
|
12098
12777
|
left += (prevElementBoundingBox.width ?? 0) + this._ratio(7);
|
|
12099
12778
|
if (prevElementBoundingBox.width) {
|
|
@@ -12174,8 +12853,8 @@ var DataPaint = class extends BasePaint {
|
|
|
12174
12853
|
(options.data?.position.informations.length ?? 0) === 2;
|
|
12175
12854
|
const col = informations.length > 4 ? 3 : 2;
|
|
12176
12855
|
informations.forEach((info, index) => {
|
|
12177
|
-
|
|
12178
|
-
|
|
12856
|
+
const left = position.left + index % col * this.positionInfoCellWidth;
|
|
12857
|
+
const top = position.top + Math.floor(index / col) * 38 + this.transformTop;
|
|
12179
12858
|
this._drawText(info.title, {
|
|
12180
12859
|
left: this._ratio(left),
|
|
12181
12860
|
top: this._ratio(top),
|
|
@@ -17717,95 +18396,111 @@ var initialOrderState = {
|
|
|
17717
18396
|
trigger_price: "",
|
|
17718
18397
|
tp_trigger_price: "",
|
|
17719
18398
|
sl_trigger_price: "",
|
|
17720
|
-
tp_order_type: OrderType.MARKET,
|
|
17721
|
-
tp_pnl: "",
|
|
17722
|
-
sl_pnl: "",
|
|
17723
|
-
tp_offset_percentage: "",
|
|
17724
|
-
sl_offset_percentage: "",
|
|
17725
|
-
tp_offset: "",
|
|
17726
|
-
sl_offset: "",
|
|
17727
|
-
sl_order_type: OrderType.MARKET,
|
|
17728
18399
|
total: "",
|
|
17729
|
-
|
|
17730
|
-
start_price: "",
|
|
17731
|
-
end_price: "",
|
|
17732
|
-
totalOrders: "",
|
|
17733
|
-
distribution_type: "",
|
|
17734
|
-
skew: "",
|
|
17735
|
-
// symbol: "",
|
|
17736
|
-
// trailing stop order
|
|
17737
|
-
activated_price: "",
|
|
17738
|
-
callback_value: "",
|
|
17739
|
-
callback_rate: ""
|
|
18400
|
+
symbol: ""
|
|
17740
18401
|
};
|
|
17741
|
-
var useOrderStore = (
|
|
17742
|
-
|
|
17743
|
-
|
|
17744
|
-
|
|
17745
|
-
|
|
17746
|
-
|
|
17747
|
-
|
|
17748
|
-
|
|
17749
|
-
|
|
17750
|
-
|
|
17751
|
-
produce((draft) => {
|
|
17752
|
-
Object.assign(draft, order);
|
|
17753
|
-
})
|
|
17754
|
-
// (prev) => ({ ...prev, ...order })
|
|
17755
|
-
);
|
|
17756
|
-
};
|
|
17757
|
-
const updateOrderByKey = (key, value) => {
|
|
17758
|
-
setEntry(
|
|
17759
|
-
produce((draft) => {
|
|
17760
|
-
draft[key] = value;
|
|
17761
|
-
})
|
|
17762
|
-
);
|
|
17763
|
-
};
|
|
17764
|
-
const restoreOrder = (order) => {
|
|
17765
|
-
setEntry(produce((draft) => order));
|
|
17766
|
-
};
|
|
17767
|
-
const updateOrderComputed = (data) => {
|
|
17768
|
-
setEstLeverage(data.estLeverage);
|
|
17769
|
-
setEstLiquidationPrice(data.estLiquidationPrice);
|
|
17770
|
-
};
|
|
17771
|
-
const resetOrder = (order) => {
|
|
17772
|
-
setEntry(
|
|
17773
|
-
produce((draft) => ({
|
|
17774
|
-
...draft,
|
|
17775
|
-
...order ?? initialOrderState
|
|
17776
|
-
}))
|
|
17777
|
-
);
|
|
17778
|
-
};
|
|
17779
|
-
const hasTP_SL = () => {
|
|
17780
|
-
return typeof entry.tp_trigger_price !== "undefined" || typeof entry.sl_trigger_price !== "undefined";
|
|
17781
|
-
};
|
|
17782
|
-
return {
|
|
17783
|
-
entry,
|
|
17784
|
-
estLeverage,
|
|
17785
|
-
estLiquidationPrice,
|
|
17786
|
-
errors,
|
|
18402
|
+
var useOrderStore = create()(
|
|
18403
|
+
immer((set, get3) => ({
|
|
18404
|
+
entry: {
|
|
18405
|
+
side: OrderSide.BUY,
|
|
18406
|
+
order_type: OrderType.LIMIT,
|
|
18407
|
+
...initialOrderState
|
|
18408
|
+
},
|
|
18409
|
+
estLeverage: null,
|
|
18410
|
+
estLiquidationPrice: null,
|
|
18411
|
+
errors: {},
|
|
17787
18412
|
actions: {
|
|
17788
|
-
|
|
17789
|
-
|
|
17790
|
-
|
|
17791
|
-
|
|
17792
|
-
|
|
17793
|
-
|
|
18413
|
+
initOrder: (symbol, options) => {
|
|
18414
|
+
set((state) => {
|
|
18415
|
+
state.entry = {
|
|
18416
|
+
...initialOrderState,
|
|
18417
|
+
symbol,
|
|
18418
|
+
side: options?.side ?? OrderSide.BUY,
|
|
18419
|
+
order_type: options?.order_type ?? OrderType.LIMIT,
|
|
18420
|
+
margin_mode: options?.margin_mode ?? MarginMode.CROSS
|
|
18421
|
+
};
|
|
18422
|
+
state.estLeverage = null;
|
|
18423
|
+
state.estLiquidationPrice = null;
|
|
18424
|
+
state.errors = {};
|
|
18425
|
+
});
|
|
18426
|
+
},
|
|
18427
|
+
hasTP_SL: () => {
|
|
18428
|
+
const order = get3().entry;
|
|
18429
|
+
return typeof order.tp_trigger_price !== "undefined" || typeof order.sl_trigger_price !== "undefined";
|
|
18430
|
+
},
|
|
18431
|
+
updateOrderComputed: (data) => {
|
|
18432
|
+
set(
|
|
18433
|
+
(state) => {
|
|
18434
|
+
state.estLeverage = data.estLeverage;
|
|
18435
|
+
state.estLiquidationPrice = data.estLiquidationPrice;
|
|
18436
|
+
},
|
|
18437
|
+
false
|
|
18438
|
+
// "updateOrderComputed"
|
|
18439
|
+
);
|
|
18440
|
+
},
|
|
18441
|
+
updateOrder: (order) => {
|
|
18442
|
+
set(
|
|
18443
|
+
(state) => {
|
|
18444
|
+
state.entry = {
|
|
18445
|
+
...state.entry,
|
|
18446
|
+
...order
|
|
18447
|
+
};
|
|
18448
|
+
},
|
|
18449
|
+
false
|
|
18450
|
+
// "updateOrder"
|
|
18451
|
+
);
|
|
18452
|
+
},
|
|
18453
|
+
updateOrderByKey: (key, value) => {
|
|
18454
|
+
set(
|
|
18455
|
+
(state) => {
|
|
18456
|
+
state.entry[key] = value;
|
|
18457
|
+
},
|
|
18458
|
+
false
|
|
18459
|
+
// "updateOrderByKey"
|
|
18460
|
+
);
|
|
18461
|
+
},
|
|
18462
|
+
restoreOrder: (order) => {
|
|
18463
|
+
set(
|
|
18464
|
+
(state) => {
|
|
18465
|
+
state.entry = order;
|
|
18466
|
+
},
|
|
18467
|
+
false
|
|
18468
|
+
// "restoreOrder"
|
|
18469
|
+
);
|
|
18470
|
+
},
|
|
18471
|
+
resetOrder: (_order) => {
|
|
18472
|
+
set(
|
|
18473
|
+
(state) => {
|
|
18474
|
+
state.entry.order_price = "";
|
|
18475
|
+
state.entry.order_quantity = "";
|
|
18476
|
+
state.entry.trigger_price = "";
|
|
18477
|
+
state.entry.total = "";
|
|
18478
|
+
state.entry.tp_trigger_price = "";
|
|
18479
|
+
state.entry.tp_pnl = "";
|
|
18480
|
+
state.entry.tp_offset = "";
|
|
18481
|
+
state.entry.tp_offset_percentage = "";
|
|
18482
|
+
state.entry.sl_trigger_price = "";
|
|
18483
|
+
state.entry.sl_pnl = "";
|
|
18484
|
+
state.entry.sl_offset = "";
|
|
18485
|
+
state.entry.sl_offset_percentage = "";
|
|
18486
|
+
},
|
|
18487
|
+
true
|
|
18488
|
+
// "resetOrder"
|
|
18489
|
+
);
|
|
18490
|
+
}
|
|
17794
18491
|
}
|
|
17795
|
-
}
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
// src/next/useOrderEntry/useOrderEntry.internal.ts
|
|
18492
|
+
}))
|
|
18493
|
+
);
|
|
17799
18494
|
var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
17800
18495
|
const { symbolInfo, symbolLeverage } = options;
|
|
17801
|
-
const
|
|
17802
|
-
|
|
17803
|
-
|
|
17804
|
-
|
|
17805
|
-
|
|
17806
|
-
|
|
17807
|
-
|
|
17808
|
-
|
|
18496
|
+
const orderEntity = useOrderStore((state) => state.entry);
|
|
18497
|
+
const orderEntryActions = useOrderStore((state) => state.actions);
|
|
18498
|
+
useEffect(() => {
|
|
18499
|
+
orderEntryActions.initOrder(symbol, options.initialOrder);
|
|
18500
|
+
if (options.initialOrder) {
|
|
18501
|
+
orderEntryActions.updateOrder(options.initialOrder);
|
|
18502
|
+
}
|
|
18503
|
+
}, [symbol]);
|
|
17809
18504
|
const calculate2 = useCallback(
|
|
17810
18505
|
(values, fieldName, value, markPrice, config) => {
|
|
17811
18506
|
const fieldHandler = getCalculateHandler(fieldName);
|
|
@@ -17819,17 +18514,15 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17819
18514
|
},
|
|
17820
18515
|
[]
|
|
17821
18516
|
);
|
|
17822
|
-
useEffect(() => {
|
|
17823
|
-
orderEntryActions.updateOrderByKey("symbol", symbol);
|
|
17824
|
-
}, [orderEntryActions, symbol]);
|
|
17825
18517
|
const setValue = (key, value, additional) => {
|
|
17826
18518
|
if (!symbolInfo) {
|
|
17827
18519
|
orderEntryActions.updateOrderByKey(key, value);
|
|
17828
18520
|
return;
|
|
17829
18521
|
}
|
|
18522
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
17830
18523
|
const { markPrice } = additional ?? { markPrice: 0 };
|
|
17831
18524
|
let newValues = calculate2(
|
|
17832
|
-
{ ...
|
|
18525
|
+
{ ...currentEntry },
|
|
17833
18526
|
key,
|
|
17834
18527
|
value,
|
|
17835
18528
|
markPrice,
|
|
@@ -17910,7 +18603,8 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17910
18603
|
orderEntryActions.updateOrder(values);
|
|
17911
18604
|
return;
|
|
17912
18605
|
}
|
|
17913
|
-
|
|
18606
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
18607
|
+
let newValues = { ...currentEntry };
|
|
17914
18608
|
Object.keys(values).forEach((key) => {
|
|
17915
18609
|
newValues = calculate2(
|
|
17916
18610
|
newValues,
|
|
@@ -17926,10 +18620,11 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17926
18620
|
const onMarkPriceUpdated = useCallback(
|
|
17927
18621
|
(markPrice, baseOn = []) => {
|
|
17928
18622
|
if (!options.symbolInfo) return;
|
|
17929
|
-
|
|
18623
|
+
const currentEntry = useOrderStore.getState().entry;
|
|
18624
|
+
let newValues = { ...currentEntry };
|
|
17930
18625
|
if (baseOn.length === 0) {
|
|
17931
18626
|
newValues = calculate2(
|
|
17932
|
-
{ ...
|
|
18627
|
+
{ ...currentEntry },
|
|
17933
18628
|
"order_price",
|
|
17934
18629
|
markPrice,
|
|
17935
18630
|
markPrice,
|
|
@@ -17940,7 +18635,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17940
18635
|
newValues = calculate2(
|
|
17941
18636
|
{ ...newValues },
|
|
17942
18637
|
key,
|
|
17943
|
-
|
|
18638
|
+
currentEntry[key],
|
|
17944
18639
|
markPrice,
|
|
17945
18640
|
options.symbolInfo
|
|
17946
18641
|
);
|
|
@@ -17961,7 +18656,7 @@ var useOrderEntryNextInternal = (symbol, options = {}) => {
|
|
|
17961
18656
|
}
|
|
17962
18657
|
orderEntryActions.updateOrder(newValues);
|
|
17963
18658
|
},
|
|
17964
|
-
[calculate2, options.symbolInfo,
|
|
18659
|
+
[calculate2, options.symbolInfo, orderEntryActions]
|
|
17965
18660
|
);
|
|
17966
18661
|
const validate = (order, creator, options2) => {
|
|
17967
18662
|
return creator?.validate(order, {
|
|
@@ -18010,6 +18705,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18010
18705
|
const lastChangedField = useRef();
|
|
18011
18706
|
const lastOrderTypeExt = useRef();
|
|
18012
18707
|
const lastLevel = useRef();
|
|
18708
|
+
const fundingRates = useFundingRatesStore();
|
|
18013
18709
|
const calculateTPSL_baseOn = useRef({
|
|
18014
18710
|
tp: "",
|
|
18015
18711
|
sl: ""
|
|
@@ -18018,7 +18714,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18018
18714
|
const symbolConfig = useSymbolsInfo();
|
|
18019
18715
|
const accountInfo = useAccountInfo();
|
|
18020
18716
|
const positions3 = usePositions();
|
|
18021
|
-
const
|
|
18717
|
+
const entry = useOrderStore((s) => s.entry);
|
|
18718
|
+
const effectiveMarginMode = options?.initialOrder?.margin_mode ?? entry?.margin_mode ?? MarginMode.CROSS;
|
|
18719
|
+
const symbolLeverage = useLeverageBySymbol(symbol, effectiveMarginMode);
|
|
18022
18720
|
const symbolInfo = symbolConfig[symbol]();
|
|
18023
18721
|
const markPrice = actions.getMarkPriceBySymbol(symbol);
|
|
18024
18722
|
const { orderMetadata } = useOrderlyContext();
|
|
@@ -18040,12 +18738,39 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18040
18738
|
const [doCreateOrder, { isMutating }] = useMutation(
|
|
18041
18739
|
getCreateOrderUrl(formattedOrder)
|
|
18042
18740
|
);
|
|
18043
|
-
const
|
|
18044
|
-
|
|
18045
|
-
|
|
18046
|
-
formattedOrder.reduce_only
|
|
18047
|
-
|
|
18741
|
+
const bestAskBid = askAndBid.current?.[0] || [];
|
|
18742
|
+
const referencePriceFromOrder = bestAskBid.length >= 2 && formattedOrder.order_type && formattedOrder.side ? getOrderReferencePriceFromOrder(formattedOrder, bestAskBid) : null;
|
|
18743
|
+
const maxBuyQtyValue = useMaxQty(symbol, OrderSide.BUY, {
|
|
18744
|
+
reduceOnly: formattedOrder.reduce_only,
|
|
18745
|
+
marginMode: effectiveMarginMode,
|
|
18746
|
+
currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
|
|
18747
|
+
});
|
|
18748
|
+
const maxSellQtyValue = useMaxQty(symbol, OrderSide.SELL, {
|
|
18749
|
+
reduceOnly: formattedOrder.reduce_only,
|
|
18750
|
+
marginMode: effectiveMarginMode,
|
|
18751
|
+
currentOrderReferencePrice: referencePriceFromOrder && referencePriceFromOrder > 0 ? referencePriceFromOrder : void 0
|
|
18752
|
+
});
|
|
18753
|
+
const maxQtyValue = formattedOrder.side === OrderSide.BUY ? maxBuyQtyValue : maxSellQtyValue;
|
|
18048
18754
|
const maxQty = options.maxQty ?? maxQtyValue;
|
|
18755
|
+
const maxQtys = useMemo(
|
|
18756
|
+
() => ({
|
|
18757
|
+
maxBuy: formattedOrder.side === OrderSide.BUY ? (
|
|
18758
|
+
// @ts-ignore
|
|
18759
|
+
options.maxQty ?? maxBuyQtyValue
|
|
18760
|
+
) : maxBuyQtyValue,
|
|
18761
|
+
maxSell: formattedOrder.side === OrderSide.SELL ? (
|
|
18762
|
+
// @ts-ignore
|
|
18763
|
+
options.maxQty ?? maxSellQtyValue
|
|
18764
|
+
) : maxSellQtyValue
|
|
18765
|
+
}),
|
|
18766
|
+
[
|
|
18767
|
+
formattedOrder.side,
|
|
18768
|
+
maxBuyQtyValue,
|
|
18769
|
+
maxSellQtyValue,
|
|
18770
|
+
// @ts-ignore
|
|
18771
|
+
options.maxQty
|
|
18772
|
+
]
|
|
18773
|
+
);
|
|
18049
18774
|
const updateOrderPrice = () => {
|
|
18050
18775
|
const order_type = formattedOrder.order_type;
|
|
18051
18776
|
const order_type_ext = formattedOrder.order_type_ext ?? lastOrderTypeExt.current;
|
|
@@ -18134,6 +18859,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18134
18859
|
};
|
|
18135
18860
|
}, []);
|
|
18136
18861
|
useEffect(() => {
|
|
18862
|
+
if (formattedOrder.symbol !== symbol) {
|
|
18863
|
+
return;
|
|
18864
|
+
}
|
|
18137
18865
|
if ((formattedOrder.order_type === OrderType.MARKET || formattedOrder.order_type === OrderType.STOP_MARKET) && markPrice) {
|
|
18138
18866
|
const baseOn = /* @__PURE__ */ new Set();
|
|
18139
18867
|
if (lastChangedField.current) {
|
|
@@ -18147,7 +18875,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18147
18875
|
}
|
|
18148
18876
|
orderEntryActions.onMarkPriceChange(markPrice, Array.from(baseOn));
|
|
18149
18877
|
}
|
|
18150
|
-
}, [markPrice, formattedOrder.order_type]);
|
|
18878
|
+
}, [markPrice, formattedOrder.order_type, formattedOrder.symbol, symbol]);
|
|
18151
18879
|
const prepareData = useCallback(() => {
|
|
18152
18880
|
return {
|
|
18153
18881
|
markPrice: actions.getMarkPriceBySymbol(symbol),
|
|
@@ -18256,7 +18984,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18256
18984
|
}
|
|
18257
18985
|
);
|
|
18258
18986
|
};
|
|
18259
|
-
const { freeCollateral, totalCollateral } = useCollateral();
|
|
18987
|
+
const { freeCollateral, freeCollateralUSDCOnly, totalCollateral } = useCollateral();
|
|
18260
18988
|
const currentPosition = useMemo(() => {
|
|
18261
18989
|
const rows = positions3 ?? [];
|
|
18262
18990
|
const p = Array.isArray(rows) ? rows.find(
|
|
@@ -18269,6 +18997,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18269
18997
|
if (!markPrice2 || !accountInfo || !symbolInfo) {
|
|
18270
18998
|
return null;
|
|
18271
18999
|
}
|
|
19000
|
+
const sumUnitaryFunding = fundingRates[symbol]?.sum_unitary_funding ?? 0;
|
|
18272
19001
|
const estLiqPrice2 = calcEstLiqPrice(formattedOrder, askAndBid.current[0], {
|
|
18273
19002
|
markPrice: markPrice2,
|
|
18274
19003
|
totalCollateral,
|
|
@@ -18276,7 +19005,8 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18276
19005
|
imr_factor: accountInfo.imr_factor[symbol],
|
|
18277
19006
|
symbol,
|
|
18278
19007
|
positions: positions3,
|
|
18279
|
-
symbolInfo
|
|
19008
|
+
symbolInfo,
|
|
19009
|
+
sumUnitaryFunding
|
|
18280
19010
|
});
|
|
18281
19011
|
return estLiqPrice2;
|
|
18282
19012
|
}, [
|
|
@@ -18286,7 +19016,8 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18286
19016
|
totalCollateral,
|
|
18287
19017
|
symbol,
|
|
18288
19018
|
maxQty,
|
|
18289
|
-
symbolInfo
|
|
19019
|
+
symbolInfo,
|
|
19020
|
+
fundingRates
|
|
18290
19021
|
]);
|
|
18291
19022
|
const estLiqPriceDistance = useMemo(() => {
|
|
18292
19023
|
if (!estLiqPrice) {
|
|
@@ -18409,6 +19140,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18409
19140
|
resetMetaState,
|
|
18410
19141
|
formattedOrder,
|
|
18411
19142
|
maxQty,
|
|
19143
|
+
maxQtys,
|
|
18412
19144
|
estLiqPrice,
|
|
18413
19145
|
estLiqPriceDistance,
|
|
18414
19146
|
currentPosition,
|
|
@@ -18421,7 +19153,7 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18421
19153
|
validator: validateOrder,
|
|
18422
19154
|
validate: validateOrder
|
|
18423
19155
|
},
|
|
18424
|
-
freeCollateral,
|
|
19156
|
+
freeCollateral: effectiveMarginMode === MarginMode.ISOLATED ? freeCollateralUSDCOnly : freeCollateral,
|
|
18425
19157
|
setValue: useMemoizedFn(setValue),
|
|
18426
19158
|
setValues: useMemoizedFn(setValues),
|
|
18427
19159
|
symbolInfo: symbolInfo || EMPTY_OBJECT,
|
|
@@ -18431,93 +19163,6 @@ var useOrderEntry2 = (symbol, options = {}) => {
|
|
|
18431
19163
|
symbolLeverage
|
|
18432
19164
|
};
|
|
18433
19165
|
};
|
|
18434
|
-
var initialOrderState2 = {
|
|
18435
|
-
order_price: "",
|
|
18436
|
-
order_quantity: "",
|
|
18437
|
-
trigger_price: "",
|
|
18438
|
-
tp_trigger_price: "",
|
|
18439
|
-
sl_trigger_price: "",
|
|
18440
|
-
total: "",
|
|
18441
|
-
symbol: ""
|
|
18442
|
-
};
|
|
18443
|
-
var useOrderStore2 = create()(
|
|
18444
|
-
immer((set, get3) => ({
|
|
18445
|
-
entry: {
|
|
18446
|
-
side: OrderSide.BUY,
|
|
18447
|
-
order_type: OrderType.LIMIT,
|
|
18448
|
-
...initialOrderState2
|
|
18449
|
-
},
|
|
18450
|
-
estLeverage: null,
|
|
18451
|
-
estLiquidationPrice: null,
|
|
18452
|
-
errors: {},
|
|
18453
|
-
actions: {
|
|
18454
|
-
hasTP_SL: () => {
|
|
18455
|
-
const order = get3().entry;
|
|
18456
|
-
return typeof order.tp_trigger_price !== "undefined" || typeof order.sl_trigger_price !== "undefined";
|
|
18457
|
-
},
|
|
18458
|
-
updateOrderComputed: (data) => {
|
|
18459
|
-
set(
|
|
18460
|
-
(state) => {
|
|
18461
|
-
state.estLeverage = data.estLeverage;
|
|
18462
|
-
state.estLiquidationPrice = data.estLiquidationPrice;
|
|
18463
|
-
},
|
|
18464
|
-
false
|
|
18465
|
-
// "updateOrderComputed"
|
|
18466
|
-
);
|
|
18467
|
-
},
|
|
18468
|
-
updateOrder: (order) => {
|
|
18469
|
-
set(
|
|
18470
|
-
(state) => {
|
|
18471
|
-
state.entry = {
|
|
18472
|
-
...state.entry,
|
|
18473
|
-
...order
|
|
18474
|
-
};
|
|
18475
|
-
},
|
|
18476
|
-
false
|
|
18477
|
-
// "updateOrder"
|
|
18478
|
-
);
|
|
18479
|
-
},
|
|
18480
|
-
updateOrderByKey: (key, value) => {
|
|
18481
|
-
set(
|
|
18482
|
-
(state) => {
|
|
18483
|
-
state.entry[key] = value;
|
|
18484
|
-
},
|
|
18485
|
-
false
|
|
18486
|
-
// "updateOrderByKey"
|
|
18487
|
-
);
|
|
18488
|
-
},
|
|
18489
|
-
restoreOrder: (order) => {
|
|
18490
|
-
set(
|
|
18491
|
-
(state) => {
|
|
18492
|
-
state.entry = order;
|
|
18493
|
-
},
|
|
18494
|
-
false
|
|
18495
|
-
// "restoreOrder"
|
|
18496
|
-
);
|
|
18497
|
-
},
|
|
18498
|
-
resetOrder: (order) => {
|
|
18499
|
-
set(
|
|
18500
|
-
(state) => {
|
|
18501
|
-
state.entry.order_price = "";
|
|
18502
|
-
state.entry.order_quantity = "";
|
|
18503
|
-
state.entry.trigger_price = "";
|
|
18504
|
-
state.entry.total = "";
|
|
18505
|
-
state.entry.tp_trigger_price = "";
|
|
18506
|
-
state.entry.tp_pnl = "";
|
|
18507
|
-
state.entry.tp_offset = "";
|
|
18508
|
-
state.entry.tp_offset_percentage = "";
|
|
18509
|
-
state.entry.sl_trigger_price = "";
|
|
18510
|
-
state.entry.sl_pnl = "";
|
|
18511
|
-
state.entry.sl_offset = "";
|
|
18512
|
-
state.entry.sl_offset_percentage = "";
|
|
18513
|
-
},
|
|
18514
|
-
true
|
|
18515
|
-
// "resetOrder"
|
|
18516
|
-
);
|
|
18517
|
-
}
|
|
18518
|
-
}
|
|
18519
|
-
}))
|
|
18520
|
-
);
|
|
18521
19166
|
var useOrderEntity = (order, options) => {
|
|
18522
19167
|
const { symbol } = order;
|
|
18523
19168
|
const { maxQty } = options || {};
|
|
@@ -18675,13 +19320,15 @@ var usePositionClose = (options) => {
|
|
|
18675
19320
|
symbol,
|
|
18676
19321
|
order_type: type,
|
|
18677
19322
|
side,
|
|
18678
|
-
reduce_only: true
|
|
19323
|
+
reduce_only: true,
|
|
19324
|
+
// Use position's margin_mode or default to CROSS for backward compatibility
|
|
19325
|
+
margin_mode: position.margin_mode || MarginMode.CROSS
|
|
18679
19326
|
};
|
|
18680
19327
|
if (type === OrderType.LIMIT) {
|
|
18681
19328
|
data.order_price = price;
|
|
18682
19329
|
}
|
|
18683
19330
|
return data;
|
|
18684
|
-
}, [symbol, price, type, quantity]);
|
|
19331
|
+
}, [symbol, price, type, quantity, position.margin_mode]);
|
|
18685
19332
|
const maxQty = useMemo(() => {
|
|
18686
19333
|
if (!position) {
|
|
18687
19334
|
return 0;
|
|
@@ -18883,9 +19530,11 @@ var useTpslPriceChecker = (params) => {
|
|
|
18883
19530
|
prevResultRef.current = currentResult;
|
|
18884
19531
|
return currentResult;
|
|
18885
19532
|
};
|
|
18886
|
-
var useEstLiqPriceBySymbol = (symbol) => {
|
|
19533
|
+
var useEstLiqPriceBySymbol = (symbol, marginMode) => {
|
|
18887
19534
|
const [data] = usePositionStream(symbol);
|
|
18888
|
-
const position = data?.rows?.find(
|
|
19535
|
+
const position = data?.rows?.find(
|
|
19536
|
+
(row) => row.symbol === symbol && row.margin_mode === marginMode
|
|
19537
|
+
);
|
|
18889
19538
|
return useMemo(() => {
|
|
18890
19539
|
return position?.est_liq_price ?? void 0;
|
|
18891
19540
|
}, [position]);
|
|
@@ -18906,7 +19555,63 @@ var useGetEstLiqPrice = (props) => {
|
|
|
18906
19555
|
return estLiqPrice;
|
|
18907
19556
|
}, [estLiqPrice, markPrice, side]);
|
|
18908
19557
|
};
|
|
19558
|
+
var useFeatureFlag = (key) => {
|
|
19559
|
+
const { data: publicFlags, isLoading: publicLoading } = useQuery("/v1/public/feature_flags", {});
|
|
19560
|
+
const publicFlag = useMemo(() => {
|
|
19561
|
+
if (!publicFlags || publicLoading) {
|
|
19562
|
+
return void 0;
|
|
19563
|
+
}
|
|
19564
|
+
return publicFlags.find((flag) => flag.key === key);
|
|
19565
|
+
}, [publicFlags, publicLoading, key]);
|
|
19566
|
+
const shouldQueryPrivate = useMemo(() => {
|
|
19567
|
+
return publicFlag !== void 0;
|
|
19568
|
+
}, [publicFlag]);
|
|
19569
|
+
const { data: privateFlags, isLoading: privateLoading } = usePrivateQuery(shouldQueryPrivate ? "/v1/feature_flags" : null, {});
|
|
19570
|
+
const privateFlag = useMemo(() => {
|
|
19571
|
+
if (!shouldQueryPrivate || !privateFlags || privateLoading) {
|
|
19572
|
+
return void 0;
|
|
19573
|
+
}
|
|
19574
|
+
return privateFlags.find((flag) => flag.key === key);
|
|
19575
|
+
}, [shouldQueryPrivate, privateFlags, privateLoading, key]);
|
|
19576
|
+
return useMemo(() => {
|
|
19577
|
+
if (publicLoading || shouldQueryPrivate && privateLoading) {
|
|
19578
|
+
return {
|
|
19579
|
+
enabled: false,
|
|
19580
|
+
data: void 0
|
|
19581
|
+
};
|
|
19582
|
+
}
|
|
19583
|
+
if (publicFlag === void 0) {
|
|
19584
|
+
return {
|
|
19585
|
+
enabled: true,
|
|
19586
|
+
data: void 0
|
|
19587
|
+
};
|
|
19588
|
+
}
|
|
19589
|
+
if (privateFlag === void 0) {
|
|
19590
|
+
return {
|
|
19591
|
+
enabled: false,
|
|
19592
|
+
data: void 0
|
|
19593
|
+
};
|
|
19594
|
+
}
|
|
19595
|
+
return {
|
|
19596
|
+
enabled: true,
|
|
19597
|
+
data: privateFlag
|
|
19598
|
+
};
|
|
19599
|
+
}, [
|
|
19600
|
+
publicFlag,
|
|
19601
|
+
privateFlag,
|
|
19602
|
+
publicLoading,
|
|
19603
|
+
shouldQueryPrivate,
|
|
19604
|
+
privateLoading,
|
|
19605
|
+
key
|
|
19606
|
+
]);
|
|
19607
|
+
};
|
|
19608
|
+
|
|
19609
|
+
// src/feature-flag/flagKeys.ts
|
|
19610
|
+
var FlagKeys = /* @__PURE__ */ ((FlagKeys2) => {
|
|
19611
|
+
FlagKeys2["IsolatedMargin"] = "isolated-margin";
|
|
19612
|
+
return FlagKeys2;
|
|
19613
|
+
})(FlagKeys || {});
|
|
18909
19614
|
|
|
18910
|
-
export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, ERROR_MSG_CODES, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, ORDERLY_ORDERBOOK_DEPTH_KEY, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, getPriceKey, indexedDBManager, initializeAppDatabase, isCurrentlyClosed, isCurrentlyTrading, noCacheConfig, parseJSON, persistIndexedDB, resetTimestampOffsetState, timestampWaitingMiddleware, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAppStore, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChainInfo, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEstLiqPriceBySymbol, useEventEmitter, useFeeState, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateBySymbol, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetEstLiqPrice, useGetReferralCode, useGetRwaSymbolCloseTimeInterval, useGetRwaSymbolInfo, useGetRwaSymbolOpenStatus, useGetRwaSymbolOpenTimeInterval, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useInitRwaSymbolsRuntime, useInternalTransfer, useKeyStore, useLazyQuery, useLeverage, useLeverageBySymbol, useLocalStorage, useMainTokenStore, useMainnetChainsStore, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxLeverage, useMaxQty, useMaxWithdrawal, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated,
|
|
19615
|
+
export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, ERROR_MSG_CODES, EpochStatus, ExtendedConfigStore, FlagKeys, MaintenanceStatus, MarketsStorageKey, MarketsType, ORDERLY_ORDERBOOK_DEPTH_KEY, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, getPriceKey, indexedDBManager, initializeAppDatabase, isCurrentlyClosed, isCurrentlyTrading, noCacheConfig, parseJSON, persistIndexedDB, resetTimestampOffsetState, timestampWaitingMiddleware, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAppStore, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChainInfo, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEstLiqPriceBySymbol, useEventEmitter, useFeatureFlag, useFeeState, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateBySymbol, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetEstLiqPrice, useGetReferralCode, useGetRwaSymbolCloseTimeInterval, useGetRwaSymbolInfo, useGetRwaSymbolOpenStatus, useGetRwaSymbolOpenTimeInterval, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useInitRwaSymbolsRuntime, useInternalTransfer, useKeyStore, useLazyQuery, useLeverage, useLeverageBySymbol, useLocalStorage, useMainTokenStore, useMainnetChainsStore, useMaintenanceStatus, useMarginModeBySymbol, useMarginModes, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxLeverage, useMaxQty, useMaxWithdrawal, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore, useOrderStream, useOrderbookStream, useOrderlyContext, usePortfolio, usePositionActions, usePositionClose, usePositionStream, usePositions, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useRwaSymbolsInfo, useRwaSymbolsInfoStore, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountAlgoOrderStream, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSwapSupportStore, useSymbolInfo, useSymbolLeverage, useSymbolLeverageMap, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTestTokenStore, useTestnetChainsStore, useTickerStream, useTokenInfo, useTokensInfo, useTpslPriceChecker, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useUpdatedRef, useUserStatistics, useVaultsHistory, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWalletTopic, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
|
|
18911
19616
|
//# sourceMappingURL=index.mjs.map
|
|
18912
19617
|
//# sourceMappingURL=index.mjs.map
|