@orderly.network/hooks 2.5.3 → 2.6.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.mjs CHANGED
@@ -3,13 +3,13 @@ import useSWR__default, { mutate } from 'swr';
3
3
  import * as useSWR from 'swr';
4
4
  export { useSWR as swr };
5
5
  export { unstable_serialize, default as useSWR, useSWRConfig } from 'swr';
6
- import { TesntTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, SDKError, TrackerEventName, AccountStatusEnum, AlgoOrderRootType, OrderStatus, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, ARBITRUM_TESTNET_CHAINID, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_MAINNET_CHAINID, isNativeTokenChecker, ChainNamespace, MaxUint256, DEPOSIT_FEE_RATE, EMPTY_LIST, LedgerWalletKey, SolanaChains, AlgoOrderType, DistributionType, TriggerPriceType } from '@orderly.network/types';
7
- import React, { createContext, useContext, useCallback, useState, useEffect, useMemo, useRef, useId, useLayoutEffect } from 'react';
6
+ import { TesntTokenFallback, ArbitrumSepoliaTokenInfo, SolanaDevnetTokenInfo, OrderType, OrderSide, SDKError, TrackerEventName, AccountStatusEnum, EMPTY_LIST, AlgoOrderType, AlgoOrderRootType, OrderStatus, EMPTY_OBJECT, ArbitrumSepoliaChainInfo, SolanaDevnetChainInfo, ARBITRUM_TESTNET_CHAINID, SOLANA_TESTNET_CHAINID, MONAD_TESTNET_CHAINID, ABSTRACT_TESTNET_CHAINID, BSC_TESTNET_CHAINID, nativeTokenAddress, ChainKey, chainsInfoMap, ARBITRUM_MAINNET_CHAINID, isNativeTokenChecker, ChainNamespace, MaxUint256, ETHEREUM_MAINNET_CHAINID, DEPOSIT_FEE_RATE, LedgerWalletKey, SolanaChains, PositionType, DistributionType, TriggerPriceType } from '@orderly.network/types';
7
+ import React2, { createContext, useContext, useCallback, useState, useEffect, useMemo, useRef, useId, useLayoutEffect } from 'react';
8
8
  import useSWRMutation from 'swr/mutation';
9
+ import { zero, windowGuard, getTimestamp, getGlobalObject, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, camelCaseToUnderscoreCase, removeTrailingZeros, commify, todpIfNeed } from '@orderly.network/utils';
9
10
  import useConstant from 'use-constant';
10
11
  export { default as useConstant } from 'use-constant';
11
- import { SimpleDI, Account, EventEmitter, EVENT_NAMES, DefaultConfigStore, LocalStorageStore } from '@orderly.network/core';
12
- import { zero, windowGuard, getTimestamp, getGlobalObject, Decimal, timeConvertString, isTestnet, getPrecisionByNumber, camelCaseToUnderscoreCase, removeTrailingZeros, commify, todpIfNeed } from '@orderly.network/utils';
12
+ import { SimpleDI, Account, EventEmitter, DefaultConfigStore, EVENT_NAMES, LocalStorageStore } from '@orderly.network/core';
13
13
  import { debounce } from 'lodash';
14
14
  import useSWRInfinite, { unstable_serialize } from 'swr/infinite';
15
15
  import * as amplitude from '@amplitude/analytics-browser';
@@ -17,11 +17,11 @@ import { jsx } from 'react/jsx-runtime';
17
17
  import { DefaultEVMWalletAdapter } from '@orderly.network/default-evm-adapter';
18
18
  import { DefaultSolanaWalletAdapter } from '@orderly.network/default-solana-adapter';
19
19
  import { EthersProvider } from '@orderly.network/web3-provider-ethers';
20
+ import useSWRSubscription from 'swr/subscription';
21
+ import { pathOr, omit, prop, pick, compose, head, mergeDeepRight, min, max, isNil, propOr, path, lensIndex, over } from 'ramda';
20
22
  import { create } from 'zustand';
21
23
  import { immer } from 'zustand/middleware/immer';
22
- import { pathOr, omit, prop, pick, compose, head, mergeDeepRight, min, max, isNil, propOr, path, lensIndex, over } from 'ramda';
23
24
  import { account, order, positions } from '@orderly.network/perp';
24
- import useSWRSubscription from 'swr/subscription';
25
25
  import { useDebouncedCallback, useThrottledCallback } from 'use-debounce';
26
26
  export * from 'use-debounce';
27
27
  import { produce } from 'immer';
@@ -36,13 +36,16 @@ var __export = (target, all) => {
36
36
  // src/version.ts
37
37
  if (typeof window !== "undefined") {
38
38
  window.__ORDERLY_VERSION__ = window.__ORDERLY_VERSION__ || {};
39
- window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.5.3";
39
+ window.__ORDERLY_VERSION__["@orderly.network/hooks"] = "2.6.0";
40
40
  }
41
- var version_default = "2.5.3";
41
+ var version_default = "2.6.0";
42
42
  var fetcher = (url, init2 = {}, queryOptions) => get(url, init2, queryOptions?.formatter);
43
43
  var OrderlyContext = createContext({
44
44
  // configStore: new MemoryConfigStore(),
45
45
  });
46
+ var useOrderlyContext = () => {
47
+ return useContext(OrderlyContext);
48
+ };
46
49
  var OrderlyProvider = OrderlyContext.Provider;
47
50
  function useConfig(key, defaultValue) {
48
51
  const { configStore } = useContext(OrderlyContext);
@@ -120,6 +123,8 @@ var useAccountInstance = () => {
120
123
  });
121
124
  return account9;
122
125
  };
126
+
127
+ // src/useMutation.ts
123
128
  var fetcher2 = (url, options) => {
124
129
  const init2 = {
125
130
  method: options.arg.method,
@@ -131,7 +136,7 @@ var fetcher2 = (url, options) => {
131
136
  init2.body = JSON.stringify(options.arg.data);
132
137
  }
133
138
  if (typeof options.arg.params === "object" && Object.keys(options.arg.params).length) {
134
- let search = new URLSearchParams(options.arg.params);
139
+ const search = new URLSearchParams(options.arg.params);
135
140
  url = `${url}?${search.toString()}`;
136
141
  }
137
142
  return mutate$1(url, init2);
@@ -152,7 +157,7 @@ var useMutation = (url, method = "POST", options) => {
152
157
  const mutation = async (data2, params, options2) => {
153
158
  let newUrl = url;
154
159
  if (typeof params === "object" && Object.keys(params).length) {
155
- let search = new URLSearchParams(params);
160
+ const search = new URLSearchParams(params);
156
161
  newUrl = `${url}?${search.toString()}`;
157
162
  }
158
163
  const payload = {
@@ -175,15 +180,7 @@ var useMutation = (url, method = "POST", options) => {
175
180
  options2
176
181
  );
177
182
  };
178
- return [
179
- mutation,
180
- {
181
- data,
182
- error,
183
- reset,
184
- isMutating
185
- }
186
- ];
183
+ return [useMemoizedFn(mutation), { data, error, reset, isMutating }];
187
184
  };
188
185
  var signatureMiddleware = (useSWRNext) => {
189
186
  const apiBaseUrl = useConfig("apiBaseUrl");
@@ -471,6 +468,53 @@ var useMemoizedFn = (fn) => {
471
468
  }
472
469
  return memoizedFn.current;
473
470
  };
471
+ var useAudioPlayer = (src, options = {}) => {
472
+ const { volume = 1, loop, autoPlay } = options;
473
+ const audioRef = useRef(null);
474
+ const [status, setStatus] = useState("idle");
475
+ const onPlay = () => {
476
+ setStatus("play");
477
+ };
478
+ const onPlaying = () => {
479
+ setStatus("playing");
480
+ };
481
+ const onPause = () => {
482
+ setStatus("paused");
483
+ };
484
+ const onEnded = () => {
485
+ setStatus("ended");
486
+ };
487
+ const onError = () => {
488
+ setStatus("error");
489
+ };
490
+ const element = useMemo(() => {
491
+ return React2.createElement("audio", {
492
+ controls: false,
493
+ ref: audioRef,
494
+ autoPlay,
495
+ src,
496
+ style: { display: "none" },
497
+ onPlay,
498
+ onPlaying,
499
+ onPause,
500
+ onEnded,
501
+ onError
502
+ });
503
+ }, [autoPlay, src, onPlay, onPlaying, onPause, onEnded, onError]);
504
+ useEffect(() => {
505
+ const el = audioRef.current;
506
+ if (!el) {
507
+ return;
508
+ }
509
+ el.loop = loop ?? false;
510
+ el.volume = Math.max(0, Math.min(1, volume));
511
+ return () => {
512
+ audioRef.current?.pause();
513
+ audioRef.current = null;
514
+ };
515
+ }, [loop, volume]);
516
+ return [element, audioRef, status];
517
+ };
474
518
  var usePreLoadData = () => {
475
519
  const [timestampOffsetInitialized, setTimestampOffsetInitialized] = useState(false);
476
520
  const { error: tokenError, data: tokenData } = useQuery(
@@ -705,73 +749,693 @@ var useTrackingInstance = () => {
705
749
  });
706
750
  SimpleDI.registerByName("instance", instance);
707
751
  }
708
- return instance;
709
- });
710
- return trackInstace;
711
- };
712
- var useKeyStore = () => {
713
- const ctx = useContext(OrderlyContext);
714
- return ctx.keyStore;
715
- };
716
- var useSimpleDI = () => {
752
+ return instance;
753
+ });
754
+ return trackInstace;
755
+ };
756
+ var useKeyStore = () => {
757
+ const ctx = useContext(OrderlyContext);
758
+ return ctx.keyStore;
759
+ };
760
+ var useSimpleDI = () => {
761
+ return {
762
+ get: SimpleDI.get,
763
+ // getOr: SimpleDI.getOr<T>(name, SimpleDI.get<T>(name)),
764
+ register: SimpleDI.register
765
+ };
766
+ };
767
+ var WsNetworkStatus = /* @__PURE__ */ ((WsNetworkStatus2) => {
768
+ WsNetworkStatus2["Connected"] = "connected";
769
+ WsNetworkStatus2["Unstable"] = "unstable";
770
+ WsNetworkStatus2["Disconnected"] = "disconnected";
771
+ return WsNetworkStatus2;
772
+ })(WsNetworkStatus || {});
773
+ function useWsStatus() {
774
+ const ws = useWS();
775
+ const [wsStatus, setWsStatus] = useState(
776
+ ws.client.public.readyState ? "connected" /* Connected */ : "disconnected" /* Disconnected */
777
+ );
778
+ const connectCount = useRef(0);
779
+ useEffect(() => {
780
+ ws.on("status:change", (status) => {
781
+ const { type, isPrivate } = status;
782
+ if (!isPrivate) {
783
+ switch (type) {
784
+ case "open":
785
+ connectCount.current = 0;
786
+ setWsStatus("connected" /* Connected */);
787
+ break;
788
+ case "close":
789
+ connectCount.current = 0;
790
+ setWsStatus("disconnected" /* Disconnected */);
791
+ break;
792
+ case "reconnecting":
793
+ connectCount.current++;
794
+ if (connectCount.current >= 3) {
795
+ setWsStatus("unstable" /* Unstable */);
796
+ }
797
+ break;
798
+ }
799
+ }
800
+ });
801
+ return () => {
802
+ ws.off("status:change", () => {
803
+ });
804
+ };
805
+ }, []);
806
+ return wsStatus;
807
+ }
808
+ var StatusContext = createContext({});
809
+ var StatusProvider = (props) => {
810
+ const wsStatus = useWsStatus();
811
+ const memoizedValue = useMemo(() => {
812
+ return { ws: wsStatus };
813
+ }, [wsStatus]);
814
+ return /* @__PURE__ */ jsx(StatusContext.Provider, { value: memoizedValue, children: props.children });
815
+ };
816
+
817
+ // src/constants.ts
818
+ var DEFAULT_TICK_SIZES = {
819
+ PERP_BTC_USDC: "1",
820
+ PERP_ETH_USDC: "0.1",
821
+ PERP_SOL_USDC: "0.01"
822
+ };
823
+ var ProxyConfigStore = class {
824
+ constructor(_originConfigStore) {
825
+ this._originConfigStore = _originConfigStore;
826
+ windowGuard(() => {
827
+ this._proxyConfigStore = window.__ORDERLY_CONFIG_STORE__ || _originConfigStore;
828
+ });
829
+ }
830
+ get(key) {
831
+ const value = this._proxyConfigStore?.get(key);
832
+ if (typeof value === "undefined") {
833
+ return this._originConfigStore.get(key);
834
+ }
835
+ return value;
836
+ }
837
+ getOr(key, defaultValue) {
838
+ return (this._proxyConfigStore ?? this._originConfigStore).getOr(
839
+ key,
840
+ defaultValue
841
+ );
842
+ }
843
+ set(key, value) {
844
+ (this._proxyConfigStore ?? this._originConfigStore).set(key, value);
845
+ }
846
+ clear() {
847
+ throw new SDKError("Method not implemented.");
848
+ }
849
+ getFromOrigin(key) {
850
+ return this._originConfigStore.get(key);
851
+ }
852
+ getOrFromOrigin(key, defaultValue) {
853
+ return this._originConfigStore.getOr(key, defaultValue);
854
+ }
855
+ setToOrigin(key, value) {
856
+ this._originConfigStore.set(key, value);
857
+ }
858
+ clearOrigin() {
859
+ this._originConfigStore.clear();
860
+ }
861
+ };
862
+ var useMarketsStream = () => {
863
+ const ws = useWS();
864
+ const { data: futures } = useQuery(`/v1/public/futures`, {
865
+ revalidateOnFocus: false
866
+ });
867
+ const topic = "tickers";
868
+ const { data: tickers } = useSWRSubscription("tickers", (_, { next }) => {
869
+ const unsubscribe = ws.subscribe(
870
+ // { event: "subscribe", topic: "markprices" },
871
+ topic,
872
+ {
873
+ onMessage: (message) => {
874
+ next(null, message);
875
+ }
876
+ // onUnsubscribe: () => {
877
+ // return "markprices";
878
+ // },
879
+ // onError: (error: any) => {
880
+ //
881
+ // },
882
+ }
883
+ );
884
+ return () => {
885
+ unsubscribe?.();
886
+ };
887
+ });
888
+ const value = useMemo(() => {
889
+ if (!futures)
890
+ return null;
891
+ if (!tickers)
892
+ return futures;
893
+ return futures.map((item) => {
894
+ const ticker = tickers.find(
895
+ (t) => t.symbol === item.symbol
896
+ );
897
+ if (ticker) {
898
+ const data = {
899
+ ...item,
900
+ ["24h_close"]: ticker.close,
901
+ ["24h_open"]: ticker.open,
902
+ /**
903
+ * @deprecated
904
+ * spelling mistake, use 24h_volume to instead, will be remove next version
905
+ */
906
+ ["24h_volumn"]: ticker.volume,
907
+ ["24h_volume"]: ticker.volume,
908
+ ["24h_amount"]: ticker.amount,
909
+ change: 0
910
+ };
911
+ if (ticker.close !== void 0 && ticker.open !== void 0) {
912
+ data["change"] = new Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
913
+ }
914
+ return data;
915
+ }
916
+ return item;
917
+ });
918
+ }, [futures, tickers]);
919
+ return { data: value };
920
+ };
921
+ function createGetter(data, depth = 2) {
922
+ const getValue = (value, defaultValue) => {
923
+ if (defaultValue === void 0) {
924
+ return value;
925
+ }
926
+ return value ?? defaultValue;
927
+ };
928
+ return new Proxy(data || {}, {
929
+ get(target, property, receiver) {
930
+ if (property === "isNil") {
931
+ return isNil(data);
932
+ }
933
+ if (depth === 1) {
934
+ return (defaultValue) => {
935
+ if (!target)
936
+ return defaultValue;
937
+ return getValue(target[property], defaultValue);
938
+ };
939
+ }
940
+ return (key, defaultValue) => {
941
+ if (key) {
942
+ return getValue(target[property]?.[key], defaultValue);
943
+ } else {
944
+ return getValue(target[property], defaultValue);
945
+ }
946
+ };
947
+ }
948
+ });
949
+ }
950
+ var useAppStore = create()(
951
+ immer((set) => ({
952
+ // accountInfo: null,
953
+ portfolio: {
954
+ totalCollateral: zero,
955
+ totalValue: null,
956
+ freeCollateral: zero,
957
+ availableBalance: 0,
958
+ unsettledPnL: 0,
959
+ totalUnrealizedROI: 0
960
+ },
961
+ appState: {
962
+ positionsLoading: false,
963
+ ordersLoading: false,
964
+ fundingRatesLoading: false,
965
+ ready: false
966
+ },
967
+ actions: {
968
+ cleanAll: () => {
969
+ set((state) => {
970
+ state.accountInfo = void 0;
971
+ state.portfolio = {
972
+ totalCollateral: zero,
973
+ totalValue: null,
974
+ freeCollateral: zero,
975
+ availableBalance: 0,
976
+ unsettledPnL: 0,
977
+ totalUnrealizedROI: 0
978
+ };
979
+ }, false);
980
+ },
981
+ setAccountInfo: (accountInfo) => {
982
+ set(
983
+ (state) => {
984
+ state.accountInfo = accountInfo;
985
+ },
986
+ false
987
+ // "setAccountInfo"
988
+ );
989
+ },
990
+ setSymbolsInfo: (symbolsInfo) => {
991
+ set(
992
+ (state) => {
993
+ state.symbolsInfo = symbolsInfo;
994
+ },
995
+ false
996
+ // "setSymbolsInfo"
997
+ );
998
+ },
999
+ setFundingRates: (fundingRates) => {
1000
+ set(
1001
+ (state) => {
1002
+ state.fundingRates = fundingRates;
1003
+ },
1004
+ false
1005
+ // "setFundingRates"
1006
+ );
1007
+ },
1008
+ updateAppStatus: (key, value) => {
1009
+ set(
1010
+ (state) => {
1011
+ state.appState[key] = value;
1012
+ },
1013
+ false
1014
+ // "updateAppStatus"
1015
+ );
1016
+ },
1017
+ updatePortfolio: (key, value) => {
1018
+ set(
1019
+ (state) => {
1020
+ state.portfolio[key] = value;
1021
+ },
1022
+ false
1023
+ // "updatePortfolio"
1024
+ );
1025
+ },
1026
+ batchUpdateForPortfolio: (data) => {
1027
+ set(
1028
+ (state) => {
1029
+ state.portfolio = { ...state.portfolio, ...data };
1030
+ },
1031
+ false
1032
+ // "batchUpdateForPortfolio"
1033
+ );
1034
+ },
1035
+ restoreHolding: (holding) => {
1036
+ set(
1037
+ (state) => {
1038
+ state.portfolio.holding = holding;
1039
+ },
1040
+ false
1041
+ // "updateHolding"
1042
+ );
1043
+ },
1044
+ updateHolding(msg) {
1045
+ set(
1046
+ (state) => {
1047
+ if (state.portfolio.holding && state.portfolio.holding.length) {
1048
+ for (const key in msg) {
1049
+ const holding = state.portfolio.holding.find(
1050
+ (item) => item.token === key
1051
+ );
1052
+ if (holding) {
1053
+ holding.holding = msg[key].holding;
1054
+ holding.frozen = msg[key].frozen;
1055
+ }
1056
+ }
1057
+ }
1058
+ },
1059
+ false
1060
+ // "updateHolding"
1061
+ );
1062
+ }
1063
+ }
1064
+ }))
1065
+ );
1066
+ var useAccountInfo = () => useAppStore((state) => state.accountInfo);
1067
+
1068
+ // src/orderly/useSymbolsInfo.ts
1069
+ var useSymbolsInfo = () => {
1070
+ const symbolsInfo = useAppStore((state) => state.symbolsInfo);
1071
+ return useMemo(() => createGetter({ ...symbolsInfo }), [symbolsInfo]);
1072
+ };
1073
+ var useSymbolsInfoStore = () => {
1074
+ return useAppStore((state) => state.symbolsInfo);
1075
+ };
1076
+
1077
+ // src/orderly/useMarkets.ts
1078
+ var MarketsType = /* @__PURE__ */ ((MarketsType2) => {
1079
+ MarketsType2[MarketsType2["FAVORITES"] = 0] = "FAVORITES";
1080
+ MarketsType2[MarketsType2["RECENT"] = 1] = "RECENT";
1081
+ MarketsType2[MarketsType2["ALL"] = 2] = "ALL";
1082
+ MarketsType2[MarketsType2["NEW_LISTING"] = 3] = "NEW_LISTING";
1083
+ return MarketsType2;
1084
+ })(MarketsType || {});
1085
+ var MarketsStorageKey = "orderly_markets";
1086
+ var DefaultFavoriteTab = { name: "Popular", id: 1 };
1087
+ var useMarketsStore = () => {
1088
+ const { configStore } = useContext(OrderlyContext);
1089
+ const ee = useEventEmitter();
1090
+ const id = useId();
1091
+ const getStore = () => {
1092
+ const store = configStore.get(MarketsStorageKey);
1093
+ return store || getDefaultStoreData();
1094
+ };
1095
+ const getStoreByKey = (key, defaultValue) => {
1096
+ const store = getStore();
1097
+ return store[key] || defaultValue;
1098
+ };
1099
+ const updateStore = (data) => {
1100
+ configStore.set(MarketsStorageKey, {
1101
+ ...getStore(),
1102
+ ...data
1103
+ });
1104
+ };
1105
+ const getFavoriteTabs = () => {
1106
+ return getStoreByKey("favoriteTabs", [{ ...DefaultFavoriteTab }]);
1107
+ };
1108
+ const getSelectedFavoriteTab = () => {
1109
+ return getStoreByKey("selectedFavoriteTab", { ...DefaultFavoriteTab });
1110
+ };
1111
+ const getFavorites = () => {
1112
+ const favs = getStoreByKey("favorites", []);
1113
+ const tabs = getFavoriteTabs();
1114
+ return filterInvalidTabs(favs, tabs);
1115
+ };
1116
+ const getRecent = () => {
1117
+ return getStoreByKey("recent", []);
1118
+ };
1119
+ const getNewListing = () => {
1120
+ return getStoreByKey("newListing", []);
1121
+ };
1122
+ const getTabSort = () => {
1123
+ return getStoreByKey("tabSort", {});
1124
+ };
1125
+ const [favoriteTabs, setFavoriteTabs] = useState(getFavoriteTabs);
1126
+ const [selectedFavoriteTab, setSelectedFavoriteTab] = useState(
1127
+ getSelectedFavoriteTab
1128
+ );
1129
+ const [favorites, setFavorites] = useState(getFavorites);
1130
+ const [recent, setRecent] = useState(getRecent);
1131
+ const [newListing, setNewListing] = useState(getNewListing);
1132
+ const [tabSort, setTabSort] = useState(getTabSort);
1133
+ const updateFavoriteTabs = (tab, operator) => {
1134
+ const tabs = updateTabs(favoriteTabs, tab, operator);
1135
+ setFavoriteTabs(tabs);
1136
+ ee.emit("markets:changed", createEventData(id, "favoriteTabs", tabs));
1137
+ };
1138
+ const updateSelectedFavoriteTab = (tab) => {
1139
+ setSelectedFavoriteTab(tab);
1140
+ ee.emit(
1141
+ "markets:changed",
1142
+ createEventData(id, "lastSelectedFavoriteTab", tab)
1143
+ );
1144
+ };
1145
+ const updateSymbolFavoriteState = (symbol, tab, remove = false) => {
1146
+ const list = updateSymbolFavorite({ favorites, symbol, tab, remove });
1147
+ setFavorites(list);
1148
+ ee.emit("markets:changed", createEventData(id, "favorites", list));
1149
+ };
1150
+ const addToHistory = (symbol) => {
1151
+ const list = addToTop(recent, symbol);
1152
+ setRecent(list);
1153
+ ee.emit("markets:changed", id);
1154
+ ee.emit("markets:changed", createEventData(id, "recent", list));
1155
+ };
1156
+ const pinToTop = (symbol) => {
1157
+ const newList = moveToTop(favorites, symbol);
1158
+ if (newList) {
1159
+ setFavorites(newList);
1160
+ ee.emit("markets:changed", createEventData(id, "favorites", newList));
1161
+ }
1162
+ };
1163
+ const updateTabsSortState = (tabId, sortKey, sortOrder) => {
1164
+ const map = getStoreByKey("tabSort", {});
1165
+ map[tabId] = {
1166
+ sortKey,
1167
+ sortOrder
1168
+ };
1169
+ setTabSort(map);
1170
+ };
1171
+ useEffect(() => {
1172
+ updateStore({
1173
+ favoriteTabs,
1174
+ favorites,
1175
+ recent,
1176
+ newListing,
1177
+ tabSort,
1178
+ selectedFavoriteTab
1179
+ });
1180
+ }, [
1181
+ favoriteTabs,
1182
+ favorites,
1183
+ recent,
1184
+ newListing,
1185
+ tabSort,
1186
+ selectedFavoriteTab
1187
+ ]);
1188
+ useEffect(() => {
1189
+ const event = ({ id: srcId, key, data }) => {
1190
+ if (srcId === id) {
1191
+ return;
1192
+ }
1193
+ if (key === "favoriteTabs") {
1194
+ setFavoriteTabs(data);
1195
+ } else if (key === "lastSelectedFavoriteTab") {
1196
+ setSelectedFavoriteTab(data);
1197
+ } else if (key === "favorites") {
1198
+ setFavorites(data);
1199
+ } else if (key === "recent") {
1200
+ setRecent(data);
1201
+ } else if (key === "newListing") {
1202
+ setNewListing(data);
1203
+ }
1204
+ };
1205
+ ee.on("markets:changed", event);
1206
+ return () => {
1207
+ ee.off("markets:changed", event);
1208
+ };
1209
+ }, [id]);
1210
+ return {
1211
+ favoriteTabs,
1212
+ favorites,
1213
+ recent,
1214
+ newListing,
1215
+ tabSort,
1216
+ selectedFavoriteTab,
1217
+ updateFavorites: setFavorites,
1218
+ updateFavoriteTabs,
1219
+ updateSymbolFavoriteState,
1220
+ pinToTop,
1221
+ addToHistory,
1222
+ updateSelectedFavoriteTab,
1223
+ updateTabsSortState
1224
+ };
1225
+ };
1226
+ var useMarkets = (type = 2 /* ALL */) => {
1227
+ const { data: futures } = useMarketsStream();
1228
+ const symbolsInfo = useSymbolsInfo();
1229
+ const [markets, setMarkets] = useState([]);
1230
+ const store = useMarketsStore();
1231
+ const { favorites, recent, newListing } = store;
1232
+ useEffect(() => {
1233
+ const markets2 = addFieldToMarkets(futures, symbolsInfo);
1234
+ const filterList = filterMarkets({
1235
+ markets: markets2,
1236
+ favorites,
1237
+ recent,
1238
+ newListing,
1239
+ type
1240
+ });
1241
+ setMarkets(filterList);
1242
+ }, [futures, symbolsInfo, favorites, recent, newListing, type]);
1243
+ return [markets, store];
1244
+ };
1245
+ var addFieldToMarkets = (futures, symbolsInfo) => {
1246
+ return (futures || [])?.map((item) => {
1247
+ const info = symbolsInfo[item.symbol];
1248
+ return {
1249
+ ...item,
1250
+ quote_dp: info("quote_dp"),
1251
+ created_time: info("created_time"),
1252
+ leverage: getLeverage(info("base_imr")),
1253
+ openInterest: getOpenInterest(item.open_interest, item.index_price),
1254
+ "8h_funding": get8hFunding(item.est_funding_rate, info("funding_period")),
1255
+ change: get24hChange({
1256
+ change: item.change,
1257
+ close: item["24h_close"],
1258
+ open: item["24h_open"]
1259
+ })
1260
+ };
1261
+ });
1262
+ };
1263
+ var filterMarkets = (params) => {
1264
+ const { markets, favorites, recent, newListing, type } = params;
1265
+ let curData = [];
1266
+ if (type === 2 /* ALL */) {
1267
+ curData = markets;
1268
+ } else if (type === 3 /* NEW_LISTING */) {
1269
+ curData = markets.filter((item) => isNewListing(item.created_time)).sort((a, b) => b.created_time - a.created_time);
1270
+ } else {
1271
+ const storageData = type === 0 /* FAVORITES */ ? favorites : type === 1 /* RECENT */ ? recent : newListing;
1272
+ const keys = storageData.map((item) => item.name);
1273
+ curData = markets?.filter((item) => keys.includes(item.symbol));
1274
+ }
1275
+ const favoriteKeys = favorites.map((item) => item.name);
1276
+ return curData?.map((item) => ({
1277
+ ...item,
1278
+ isFavorite: type === 0 /* FAVORITES */ ? true : favoriteKeys.includes(item.symbol)
1279
+ }));
1280
+ };
1281
+ function isEmpty(value) {
1282
+ return value === void 0 || value === null;
1283
+ }
1284
+ var isNewListing = (createdTime) => {
1285
+ const thirtyDaysInMs = 30 * 24 * 60 * 60 * 1e3;
1286
+ const now = Date.now();
1287
+ return now - createdTime < thirtyDaysInMs;
1288
+ };
1289
+ function get8hFunding(est_funding_rate, funding_period) {
1290
+ let funding8h = 0;
1291
+ if (isEmpty(est_funding_rate)) {
1292
+ return null;
1293
+ }
1294
+ if (funding_period) {
1295
+ funding8h = new Decimal(est_funding_rate || 0).mul(funding_period).div(8).toNumber();
1296
+ }
1297
+ return funding8h;
1298
+ }
1299
+ function get24hChange(params) {
1300
+ const { change, close, open } = params;
1301
+ if (change !== void 0) {
1302
+ return change;
1303
+ }
1304
+ if (!isEmpty(close) && !isEmpty(open)) {
1305
+ if (open === 0) {
1306
+ return 0;
1307
+ }
1308
+ return new Decimal(close).minus(open).div(open).toNumber();
1309
+ }
1310
+ }
1311
+ function getLeverage(base_imr) {
1312
+ return base_imr ? 1 / base_imr : void 0;
1313
+ }
1314
+ function getOpenInterest(open_interest, index_price) {
1315
+ return new Decimal(open_interest || 0).mul(index_price || 0).toNumber();
1316
+ }
1317
+ function getDefaultStoreData() {
1318
+ return {
1319
+ recent: [],
1320
+ favorites: [
1321
+ { name: "PERP_ETH_USDC", tabs: [{ ...DefaultFavoriteTab }] },
1322
+ { name: "PERP_BTC_USDC", tabs: [{ ...DefaultFavoriteTab }] }
1323
+ ],
1324
+ favoriteTabs: [{ ...DefaultFavoriteTab }],
1325
+ selectedFavoriteTab: { ...DefaultFavoriteTab },
1326
+ tabSort: {}
1327
+ };
1328
+ }
1329
+ function filterInvalidTabs(favorites, tabs) {
1330
+ return favorites.map((favorite) => {
1331
+ return {
1332
+ ...favorite,
1333
+ tabs: favorite.tabs.filter(
1334
+ (tab) => !!tabs.find((item) => item.id === tab.id)
1335
+ )
1336
+ };
1337
+ }).filter((item) => !!item.tabs.length);
1338
+ }
1339
+ function updateTabs(favoriteTabs, tab, operator) {
1340
+ if (Array.isArray(tab)) {
1341
+ return tab;
1342
+ }
1343
+ const tabs = [...favoriteTabs];
1344
+ const index = tabs.findIndex((item) => item.id === tab.id);
1345
+ if (operator?.add) {
1346
+ tabs.push(tab);
1347
+ } else if (operator?.update && index !== -1) {
1348
+ tabs[index] = tab;
1349
+ } else if (operator?.delete && index !== -1) {
1350
+ tabs.splice(index, 1);
1351
+ }
1352
+ return tabs;
1353
+ }
1354
+ function addToTop(recent, symbol) {
1355
+ const list = [...recent];
1356
+ const index = list.findIndex((item) => item.name == symbol.symbol);
1357
+ if (index !== -1) {
1358
+ list.splice(index, 1);
1359
+ }
1360
+ list.unshift({ name: symbol.symbol });
1361
+ return list;
1362
+ }
1363
+ function moveToTop(favorites, symbol) {
1364
+ const index = favorites.findIndex((item) => item.name === symbol.symbol);
1365
+ if (index !== -1) {
1366
+ const item = favorites[index];
1367
+ const list = [...favorites];
1368
+ list.splice(index, 1);
1369
+ list.unshift(item);
1370
+ return list;
1371
+ }
1372
+ }
1373
+ function updateSymbolFavorite(params) {
1374
+ const { favorites, symbol, tab, remove = false } = params;
1375
+ const list = [...favorites];
1376
+ const index = list.findIndex((item) => item.name == symbol.symbol);
1377
+ const tabs = Array.isArray(tab) ? tab : [tab];
1378
+ if (index === -1) {
1379
+ if (tabs.length && !remove) {
1380
+ list.unshift({ name: symbol.symbol, tabs });
1381
+ }
1382
+ } else {
1383
+ const favorite = list[index];
1384
+ if (Array.isArray(tab)) {
1385
+ if (!tab.length) {
1386
+ list.splice(index, 1);
1387
+ } else {
1388
+ list[index] = { ...favorite, tabs: tab };
1389
+ }
1390
+ } else {
1391
+ if (remove) {
1392
+ const tabs2 = favorite.tabs.filter((item) => item.id != tab.id);
1393
+ if (!tabs2.length) {
1394
+ list.splice(index, 1);
1395
+ } else {
1396
+ list[index] = { ...favorite, tabs: tabs2 };
1397
+ }
1398
+ } else {
1399
+ list[index] = { ...favorite, tabs: [...favorite.tabs, tab] };
1400
+ }
1401
+ }
1402
+ }
1403
+ return list;
1404
+ }
1405
+ function createEventData(id, key, data) {
717
1406
  return {
718
- get: SimpleDI.get,
719
- // getOr: SimpleDI.getOr<T>(name, SimpleDI.get<T>(name)),
720
- register: SimpleDI.register
1407
+ id,
1408
+ key,
1409
+ data
721
1410
  };
722
- };
723
- var WsNetworkStatus = /* @__PURE__ */ ((WsNetworkStatus2) => {
724
- WsNetworkStatus2["Connected"] = "connected";
725
- WsNetworkStatus2["Unstable"] = "unstable";
726
- WsNetworkStatus2["Disconnected"] = "disconnected";
727
- return WsNetworkStatus2;
728
- })(WsNetworkStatus || {});
729
- function useWsStatus() {
730
- const ws = useWS();
731
- const [wsStatus, setWsStatus] = useState(
732
- ws.client.public.readyState ? "connected" /* Connected */ : "disconnected" /* Disconnected */
733
- );
734
- const connectCount = useRef(0);
735
- useEffect(() => {
736
- ws.on("status:change", (status) => {
737
- const { type, isPrivate } = status;
738
- if (!isPrivate) {
739
- switch (type) {
740
- case "open":
741
- connectCount.current = 0;
742
- setWsStatus("connected" /* Connected */);
743
- break;
744
- case "close":
745
- connectCount.current = 0;
746
- setWsStatus("disconnected" /* Disconnected */);
747
- break;
748
- case "reconnecting":
749
- connectCount.current++;
750
- if (connectCount.current >= 3) {
751
- setWsStatus("unstable" /* Unstable */);
752
- }
753
- break;
754
- }
755
- }
756
- });
757
- return () => {
758
- ws.off("status:change", () => {
759
- });
760
- };
761
- }, []);
762
- return wsStatus;
763
1411
  }
764
- var StatusContext = createContext({});
765
- var StatusProvider = (props) => {
766
- const wsStatus = useWsStatus();
767
- return /* @__PURE__ */ jsx(StatusContext.Provider, { value: { ws: wsStatus }, children: props.children });
768
- };
769
1412
 
770
- // src/constants.ts
771
- var DEFAULT_TICK_SIZES = {
772
- PERP_BTC_USDC: "1",
773
- PERP_ETH_USDC: "0.1",
774
- PERP_SOL_USDC: "0.01"
1413
+ // src/extendedConfigStore.ts
1414
+ var ExtendedConfigStore = class extends DefaultConfigStore {
1415
+ constructor(init2) {
1416
+ super(init2);
1417
+ }
1418
+ get(key) {
1419
+ if (key === MarketsStorageKey) {
1420
+ const jsonStr = localStorage.getItem(MarketsStorageKey);
1421
+ if (!jsonStr) {
1422
+ const oldJsonStr = localStorage.getItem(
1423
+ MarketsStorageKey.replace("orderly_", "")
1424
+ );
1425
+ return oldJsonStr ? JSON.parse(oldJsonStr) : "";
1426
+ }
1427
+ return JSON.parse(jsonStr);
1428
+ }
1429
+ return super.get(key);
1430
+ }
1431
+ set(key, value) {
1432
+ if (key === MarketsStorageKey) {
1433
+ const jsonStr = JSON.stringify(value);
1434
+ localStorage.setItem(MarketsStorageKey, jsonStr);
1435
+ return;
1436
+ }
1437
+ super.set(key, value);
1438
+ }
775
1439
  };
776
1440
  var useWSObserver = (calculatorService) => {
777
1441
  const ws = useWS();
@@ -880,7 +1544,7 @@ var BaseMergeHandler = class {
880
1544
  if (key.startsWith("orders:FILLED") || key.startsWith("orders:REJECTED")) {
881
1545
  return prevData;
882
1546
  }
883
- if (key.startsWith("orders:NEW") || key.startsWith("orders:INCOMPLETE")) {
1547
+ if (key.startsWith("orders:NEW") || key.startsWith("orders:INCOMPLETE") || key.startsWith("algoOrders:INCOMPLETE")) {
884
1548
  return this.remove(prevData);
885
1549
  }
886
1550
  if (key.startsWith("orders:CANCELLED")) {
@@ -892,7 +1556,7 @@ var BaseMergeHandler = class {
892
1556
  return this.update(prevData);
893
1557
  case "FILLED": {
894
1558
  if (this.orderIsExisting(prevData)) {
895
- if (key.startsWith("orders:INCOMPLETE") || key.startsWith("orders:NEW") || // all orders key
1559
+ if (key.startsWith("orders:INCOMPLETE") || key.startsWith("orders:NEW") || key.startsWith("algoOrders:INCOMPLETE") || // all orders key
896
1560
  key.startsWith("orders:")) {
897
1561
  if (this.isFullFilled()) {
898
1562
  return this.remove(prevData);
@@ -900,7 +1564,7 @@ var BaseMergeHandler = class {
900
1564
  return this.update(prevData);
901
1565
  }
902
1566
  } else {
903
- if (key.startsWith("orders:CANCELLED") || key.startsWith("orders:INCOMPLETE") || key.startsWith("orders:NEW")) {
1567
+ if (key.startsWith("orders:CANCELLED") || key.startsWith("orders:INCOMPLETE") || key.startsWith("orders:NEW") || key.startsWith("algoOrders:INCOMPLETE")) {
904
1568
  return prevData;
905
1569
  }
906
1570
  return this.insert(prevData);
@@ -1063,123 +1727,6 @@ var AlgoOrderMergeHandler = class _AlgoOrderMergeHandler extends BaseMergeHandle
1063
1727
  return rootOrder;
1064
1728
  }
1065
1729
  };
1066
- var useAppStore = create()(
1067
- immer((set) => ({
1068
- // accountInfo: null,
1069
- portfolio: {
1070
- totalCollateral: zero,
1071
- totalValue: null,
1072
- freeCollateral: zero,
1073
- availableBalance: 0,
1074
- unsettledPnL: 0,
1075
- totalUnrealizedROI: 0
1076
- },
1077
- appState: {
1078
- positionsLoading: false,
1079
- ordersLoading: false,
1080
- fundingRatesLoading: false,
1081
- ready: false
1082
- },
1083
- actions: {
1084
- cleanAll: () => {
1085
- set((state) => {
1086
- state.accountInfo = void 0;
1087
- state.portfolio = {
1088
- totalCollateral: zero,
1089
- totalValue: null,
1090
- freeCollateral: zero,
1091
- availableBalance: 0,
1092
- unsettledPnL: 0,
1093
- totalUnrealizedROI: 0
1094
- };
1095
- }, false);
1096
- },
1097
- setAccountInfo: (accountInfo) => {
1098
- set(
1099
- (state) => {
1100
- state.accountInfo = accountInfo;
1101
- },
1102
- false
1103
- // "setAccountInfo"
1104
- );
1105
- },
1106
- setSymbolsInfo: (symbolsInfo) => {
1107
- set(
1108
- (state) => {
1109
- state.symbolsInfo = symbolsInfo;
1110
- },
1111
- false
1112
- // "setSymbolsInfo"
1113
- );
1114
- },
1115
- setFundingRates: (fundingRates) => {
1116
- set(
1117
- (state) => {
1118
- state.fundingRates = fundingRates;
1119
- },
1120
- false
1121
- // "setFundingRates"
1122
- );
1123
- },
1124
- updateAppStatus: (key, value) => {
1125
- set(
1126
- (state) => {
1127
- state.appState[key] = value;
1128
- },
1129
- false
1130
- // "updateAppStatus"
1131
- );
1132
- },
1133
- updatePortfolio: (key, value) => {
1134
- set(
1135
- (state) => {
1136
- state.portfolio[key] = value;
1137
- },
1138
- false
1139
- // "updatePortfolio"
1140
- );
1141
- },
1142
- batchUpdateForPortfolio: (data) => {
1143
- set(
1144
- (state) => {
1145
- state.portfolio = { ...state.portfolio, ...data };
1146
- },
1147
- false
1148
- // "batchUpdateForPortfolio"
1149
- );
1150
- },
1151
- restoreHolding: (holding) => {
1152
- set(
1153
- (state) => {
1154
- state.portfolio.holding = holding;
1155
- },
1156
- false
1157
- // "updateHolding"
1158
- );
1159
- },
1160
- updateHolding(msg) {
1161
- set(
1162
- (state) => {
1163
- if (state.portfolio.holding && state.portfolio.holding.length) {
1164
- for (const key in msg) {
1165
- const holding = state.portfolio.holding.find(
1166
- (item) => item.token === key
1167
- );
1168
- if (holding) {
1169
- holding.holding = msg[key].holding;
1170
- holding.frozen = msg[key].frozen;
1171
- }
1172
- }
1173
- }
1174
- },
1175
- false
1176
- // "updateHolding"
1177
- );
1178
- }
1179
- }
1180
- }))
1181
- );
1182
- var useAccountInfo = () => useAppStore((state) => state.accountInfo);
1183
1730
  var useTokensInfoStore = create(
1184
1731
  (set) => ({
1185
1732
  tokensInfo: [],
@@ -1740,48 +2287,19 @@ var PositionCalculator = class extends BaseCalculator {
1740
2287
  if (positions3 && Array.isArray(positions3.rows)) {
1741
2288
  return positions3;
1742
2289
  }
1743
- return this.preprocess(this.getAllPositions(ctx));
1744
- }
1745
- destroy() {
1746
- usePositionStore.getState().actions.closePosition(this.symbol);
1747
- CalculatorContext.instance?.deleteByName(this.name);
1748
- }
1749
- getAllPositions(ctx) {
1750
- return ctx.get((output) => output[AllPositions]) || usePositionStore.getState().positions[AllPositions];
1751
- }
1752
- };
1753
- PositionCalculator.logPosition = (symbol = "all") => {
1754
- return usePositionStore.getState().positions[symbol];
1755
- };
1756
- function createGetter(data, depth = 2) {
1757
- const getValue = (value, defaultValue) => {
1758
- if (defaultValue === void 0) {
1759
- return value;
1760
- }
1761
- return value ?? defaultValue;
1762
- };
1763
- return new Proxy(data || {}, {
1764
- get(target, property, receiver) {
1765
- if (property === "isNil") {
1766
- return isNil(data);
1767
- }
1768
- if (depth === 1) {
1769
- return (defaultValue) => {
1770
- if (!target)
1771
- return defaultValue;
1772
- return getValue(target[property], defaultValue);
1773
- };
1774
- }
1775
- return (key, defaultValue) => {
1776
- if (key) {
1777
- return getValue(target[property]?.[key], defaultValue);
1778
- } else {
1779
- return getValue(target[property], defaultValue);
1780
- }
1781
- };
1782
- }
1783
- });
1784
- }
2290
+ return this.preprocess(this.getAllPositions(ctx));
2291
+ }
2292
+ destroy() {
2293
+ usePositionStore.getState().actions.closePosition(this.symbol);
2294
+ CalculatorContext.instance?.deleteByName(this.name);
2295
+ }
2296
+ getAllPositions(ctx) {
2297
+ return ctx.get((output) => output[AllPositions]) || usePositionStore.getState().positions[AllPositions];
2298
+ }
2299
+ };
2300
+ PositionCalculator.logPosition = (symbol = "all") => {
2301
+ return usePositionStore.getState().positions[symbol];
2302
+ };
1785
2303
  var parseHolding = (holding, indexPrices, tokensInfo) => {
1786
2304
  const nonUSDC = [];
1787
2305
  let USDC_holding = 0;
@@ -2215,13 +2733,6 @@ var useMarkPrice = (symbol) => {
2215
2733
  }, [symbol]);
2216
2734
  return { data: price };
2217
2735
  };
2218
- var useSymbolsInfo = () => {
2219
- const symbolsInfo = useAppStore((state) => state.symbolsInfo);
2220
- return useMemo(() => createGetter({ ...symbolsInfo }), [symbolsInfo]);
2221
- };
2222
- var useSymbolsInfoStore = () => {
2223
- return useAppStore((state) => state.symbolsInfo);
2224
- };
2225
2736
  var useIndexPrice = (symbol) => {
2226
2737
  symbol = symbol.replace("PERP", "SPOT");
2227
2738
  const ws = useWS();
@@ -2619,65 +3130,6 @@ var useAccountInfo2 = () => {
2619
3130
  revalidateOnFocus: false
2620
3131
  });
2621
3132
  };
2622
- var useMarketsStream = () => {
2623
- const ws = useWS();
2624
- const { data: futures } = useQuery(`/v1/public/futures`, {
2625
- revalidateOnFocus: false
2626
- });
2627
- const topic = "tickers";
2628
- const { data: tickers } = useSWRSubscription("tickers", (_, { next }) => {
2629
- const unsubscribe = ws.subscribe(
2630
- // { event: "subscribe", topic: "markprices" },
2631
- topic,
2632
- {
2633
- onMessage: (message) => {
2634
- next(null, message);
2635
- }
2636
- // onUnsubscribe: () => {
2637
- // return "markprices";
2638
- // },
2639
- // onError: (error: any) => {
2640
- //
2641
- // },
2642
- }
2643
- );
2644
- return () => {
2645
- unsubscribe?.();
2646
- };
2647
- });
2648
- const value = useMemo(() => {
2649
- if (!futures)
2650
- return null;
2651
- if (!tickers)
2652
- return futures;
2653
- return futures.map((item) => {
2654
- const ticker = tickers.find(
2655
- (t) => t.symbol === item.symbol
2656
- );
2657
- if (ticker) {
2658
- const data = {
2659
- ...item,
2660
- ["24h_close"]: ticker.close,
2661
- ["24h_open"]: ticker.open,
2662
- /**
2663
- * @deprecated
2664
- * spelling mistake, use 24h_volume to instead, will be remove next version
2665
- */
2666
- ["24h_volumn"]: ticker.volume,
2667
- ["24h_volume"]: ticker.volume,
2668
- ["24h_amount"]: ticker.amount,
2669
- change: 0
2670
- };
2671
- if (ticker.close !== void 0 && ticker.open !== void 0) {
2672
- data["change"] = new Decimal(ticker.close).minus(ticker.open).div(ticker.open).toNumber();
2673
- }
2674
- return data;
2675
- }
2676
- return item;
2677
- });
2678
- }, [futures, tickers]);
2679
- return { data: value };
2680
- };
2681
3133
  var useFundingRates = () => {
2682
3134
  const data = useAppStore((state) => state.fundingRates);
2683
3135
  return createGetter({ ...data });
@@ -2829,11 +3281,11 @@ var useMarket = (type) => {
2829
3281
  const rate = fundingRates[item.symbol];
2830
3282
  const est_funding_rate = rate("est_funding_rate");
2831
3283
  const funding_period = info("funding_period");
2832
- const change = item.change === void 0 ? get24hChange(item["24h_close"], item["24h_open"]) : item.change;
3284
+ const change = item.change === void 0 ? get24hChange2(item["24h_close"], item["24h_open"]) : item.change;
2833
3285
  return {
2834
3286
  ...item,
2835
3287
  change,
2836
- "8h_funding": get8hFunding(est_funding_rate, funding_period),
3288
+ "8h_funding": get8hFunding2(est_funding_rate, funding_period),
2837
3289
  quote_dp: info("quote_dp"),
2838
3290
  created_time: info("created_time"),
2839
3291
  openInterest: new Decimal(open_interest || 0).mul(index_price || 0).toNumber()
@@ -2886,266 +3338,37 @@ var useMarket = (type) => {
2886
3338
  const updateSelectedFavoriteTab = (tab) => {
2887
3339
  updateStore("lastSelectedFavoriteTab", tab);
2888
3340
  };
2889
- const updateTabsSortState = (tabId, sortKey, sortOrder) => {
2890
- const map = getStore("tabSort", {});
2891
- map[tabId] = {
2892
- sortKey,
2893
- sortOrder
2894
- };
2895
- updateStore("tabSort", map);
2896
- setTabSort(map);
2897
- };
2898
- const markets = getData(type);
2899
- return [
2900
- markets || [],
2901
- {
2902
- favoriteTabs,
2903
- favorites,
2904
- recent,
2905
- tabSort,
2906
- addToHistory,
2907
- updateFavorites,
2908
- updateFavoriteTabs,
2909
- updateSymbolFavoriteState,
2910
- pinToTop,
2911
- getLastSelFavTab,
2912
- updateSelectedFavoriteTab,
2913
- updateTabsSortState
2914
- }
2915
- ];
2916
- };
2917
- function get8hFunding(est_funding_rate, funding_period) {
2918
- let funding8h = 0;
2919
- if (est_funding_rate === void 0 || est_funding_rate === null) {
2920
- return null;
2921
- }
2922
- if (funding_period) {
2923
- funding8h = new Decimal(est_funding_rate || 0).mul(funding_period).div(8).toNumber();
2924
- }
2925
- return funding8h;
2926
- }
2927
- function get24hChange(close, open) {
2928
- if (close !== void 0 && open !== void 0) {
2929
- if (open === 0) {
2930
- return 0;
2931
- }
2932
- return new Decimal(close).minus(open).div(open).toNumber();
2933
- }
2934
- }
2935
- var MarketsType = /* @__PURE__ */ ((MarketsType2) => {
2936
- MarketsType2[MarketsType2["FAVORITES"] = 0] = "FAVORITES";
2937
- MarketsType2[MarketsType2["RECENT"] = 1] = "RECENT";
2938
- MarketsType2[MarketsType2["ALL"] = 2] = "ALL";
2939
- MarketsType2[MarketsType2["NEW_LISTING"] = 3] = "NEW_LISTING";
2940
- return MarketsType2;
2941
- })(MarketsType || {});
2942
- var MarketsStorageKey = "orderly_markets";
2943
- var DefaultFavoriteTab = { name: "Popular", id: 1 };
2944
- var useMarketsStore = () => {
2945
- const { configStore } = useContext(OrderlyContext);
2946
- const ee = useEventEmitter();
2947
- const id = useId();
2948
- const getStore = () => {
2949
- const store = configStore.get(MarketsStorageKey);
2950
- return store || getDefaultStoreData();
2951
- };
2952
- const getStoreByKey = (key, defaultValue) => {
2953
- const store = getStore();
2954
- return store[key] || defaultValue;
2955
- };
2956
- const updateStore = (data) => {
2957
- configStore.set(MarketsStorageKey, {
2958
- ...getStore(),
2959
- ...data
2960
- });
2961
- };
2962
- const getFavoriteTabs = () => {
2963
- return getStoreByKey("favoriteTabs", [{ ...DefaultFavoriteTab }]);
2964
- };
2965
- const getSelectedFavoriteTab = () => {
2966
- return getStoreByKey("selectedFavoriteTab", { ...DefaultFavoriteTab });
2967
- };
2968
- const getFavorites = () => {
2969
- const favs = getStoreByKey("favorites", []);
2970
- const tabs = getFavoriteTabs();
2971
- return filterInvalidTabs(favs, tabs);
2972
- };
2973
- const getRecent = () => {
2974
- return getStoreByKey("recent", []);
2975
- };
2976
- const getNewListing = () => {
2977
- return getStoreByKey("newListing", []);
2978
- };
2979
- const getTabSort = () => {
2980
- return getStoreByKey("tabSort", {});
2981
- };
2982
- const [favoriteTabs, setFavoriteTabs] = useState(getFavoriteTabs);
2983
- const [selectedFavoriteTab, setSelectedFavoriteTab] = useState(
2984
- getSelectedFavoriteTab
2985
- );
2986
- const [favorites, setFavorites] = useState(getFavorites);
2987
- const [recent, setRecent] = useState(getRecent);
2988
- const [newListing, setNewListing] = useState(getNewListing);
2989
- const [tabSort, setTabSort] = useState(getTabSort);
2990
- const updateFavoriteTabs = (tab, operator) => {
2991
- const tabs = updateTabs(favoriteTabs, tab, operator);
2992
- setFavoriteTabs(tabs);
2993
- ee.emit("markets:changed", createEventData(id, "favoriteTabs", tabs));
2994
- };
2995
- const updateSelectedFavoriteTab = (tab) => {
2996
- setSelectedFavoriteTab(tab);
2997
- ee.emit(
2998
- "markets:changed",
2999
- createEventData(id, "lastSelectedFavoriteTab", tab)
3000
- );
3001
- };
3002
- const updateSymbolFavoriteState = (symbol, tab, remove = false) => {
3003
- const list = updateSymbolFavorite({ favorites, symbol, tab, remove });
3004
- setFavorites(list);
3005
- ee.emit("markets:changed", createEventData(id, "favorites", list));
3006
- };
3007
- const addToHistory = (symbol) => {
3008
- const list = addToTop(recent, symbol);
3009
- setRecent(list);
3010
- ee.emit("markets:changed", id);
3011
- ee.emit("markets:changed", createEventData(id, "recent", list));
3012
- };
3013
- const pinToTop = (symbol) => {
3014
- const newList = moveToTop(favorites, symbol);
3015
- if (newList) {
3016
- setFavorites(newList);
3017
- ee.emit("markets:changed", createEventData(id, "favorites", newList));
3018
- }
3019
- };
3020
- const updateTabsSortState = (tabId, sortKey, sortOrder) => {
3021
- const map = getStoreByKey("tabSort", {});
3022
- map[tabId] = {
3023
- sortKey,
3024
- sortOrder
3025
- };
3026
- setTabSort(map);
3027
- };
3028
- useEffect(() => {
3029
- updateStore({
3030
- favoriteTabs,
3031
- favorites,
3032
- recent,
3033
- newListing,
3034
- tabSort,
3035
- selectedFavoriteTab
3036
- });
3037
- }, [
3038
- favoriteTabs,
3039
- favorites,
3040
- recent,
3041
- newListing,
3042
- tabSort,
3043
- selectedFavoriteTab
3044
- ]);
3045
- useEffect(() => {
3046
- const event = ({ id: srcId, key, data }) => {
3047
- if (srcId === id) {
3048
- return;
3049
- }
3050
- if (key === "favoriteTabs") {
3051
- setFavoriteTabs(data);
3052
- } else if (key === "lastSelectedFavoriteTab") {
3053
- setSelectedFavoriteTab(data);
3054
- } else if (key === "favorites") {
3055
- setFavorites(data);
3056
- } else if (key === "recent") {
3057
- setRecent(data);
3058
- } else if (key === "newListing") {
3059
- setNewListing(data);
3060
- }
3061
- };
3062
- ee.on("markets:changed", event);
3063
- return () => {
3064
- ee.off("markets:changed", event);
3341
+ const updateTabsSortState = (tabId, sortKey, sortOrder) => {
3342
+ const map = getStore("tabSort", {});
3343
+ map[tabId] = {
3344
+ sortKey,
3345
+ sortOrder
3065
3346
  };
3066
- }, [id]);
3067
- return {
3068
- favoriteTabs,
3069
- favorites,
3070
- recent,
3071
- newListing,
3072
- tabSort,
3073
- selectedFavoriteTab,
3074
- updateFavorites: setFavorites,
3075
- updateFavoriteTabs,
3076
- updateSymbolFavoriteState,
3077
- pinToTop,
3078
- addToHistory,
3079
- updateSelectedFavoriteTab,
3080
- updateTabsSortState
3347
+ updateStore("tabSort", map);
3348
+ setTabSort(map);
3081
3349
  };
3082
- };
3083
- var useMarkets = (type = 2 /* ALL */) => {
3084
- const { data: futures } = useMarketsStream();
3085
- const symbolsInfo = useSymbolsInfo();
3086
- const [markets, setMarkets] = useState([]);
3087
- const store = useMarketsStore();
3088
- const { favorites, recent, newListing } = store;
3089
- useEffect(() => {
3090
- const markets2 = addFieldToMarkets(futures, symbolsInfo);
3091
- const filterList = filterMarkets({
3092
- markets: markets2,
3350
+ const markets = getData(type);
3351
+ return [
3352
+ markets || [],
3353
+ {
3354
+ favoriteTabs,
3093
3355
  favorites,
3094
3356
  recent,
3095
- newListing,
3096
- type
3097
- });
3098
- setMarkets(filterList);
3099
- }, [futures, symbolsInfo, favorites, recent, newListing, type]);
3100
- return [markets, store];
3101
- };
3102
- var addFieldToMarkets = (futures, symbolsInfo) => {
3103
- return (futures || [])?.map((item) => {
3104
- const info = symbolsInfo[item.symbol];
3105
- return {
3106
- ...item,
3107
- quote_dp: info("quote_dp"),
3108
- created_time: info("created_time"),
3109
- leverage: getLeverage(info("base_imr")),
3110
- openInterest: getOpenInterest(item.open_interest, item.index_price),
3111
- "8h_funding": get8hFunding2(item.est_funding_rate, info("funding_period")),
3112
- change: get24hChange2({
3113
- change: item.change,
3114
- close: item["24h_close"],
3115
- open: item["24h_open"]
3116
- })
3117
- };
3118
- });
3119
- };
3120
- var filterMarkets = (params) => {
3121
- const { markets, favorites, recent, newListing, type } = params;
3122
- let curData = [];
3123
- if (type === 2 /* ALL */) {
3124
- curData = markets;
3125
- } else if (type === 3 /* NEW_LISTING */) {
3126
- curData = markets.filter((item) => isNewListing(item.created_time)).sort((a, b) => b.created_time - a.created_time);
3127
- } else {
3128
- const storageData = type === 0 /* FAVORITES */ ? favorites : type === 1 /* RECENT */ ? recent : newListing;
3129
- const keys = storageData.map((item) => item.name);
3130
- curData = markets?.filter((item) => keys.includes(item.symbol));
3131
- }
3132
- const favoriteKeys = favorites.map((item) => item.name);
3133
- return curData?.map((item) => ({
3134
- ...item,
3135
- isFavorite: type === 0 /* FAVORITES */ ? true : favoriteKeys.includes(item.symbol)
3136
- }));
3137
- };
3138
- function isEmpty(value) {
3139
- return value === void 0 || value === null;
3140
- }
3141
- var isNewListing = (createdTime) => {
3142
- const thirtyDaysInMs = 30 * 24 * 60 * 60 * 1e3;
3143
- const now = Date.now();
3144
- return now - createdTime < thirtyDaysInMs;
3357
+ tabSort,
3358
+ addToHistory,
3359
+ updateFavorites,
3360
+ updateFavoriteTabs,
3361
+ updateSymbolFavoriteState,
3362
+ pinToTop,
3363
+ getLastSelFavTab,
3364
+ updateSelectedFavoriteTab,
3365
+ updateTabsSortState
3366
+ }
3367
+ ];
3145
3368
  };
3146
3369
  function get8hFunding2(est_funding_rate, funding_period) {
3147
3370
  let funding8h = 0;
3148
- if (isEmpty(est_funding_rate)) {
3371
+ if (est_funding_rate === void 0 || est_funding_rate === null) {
3149
3372
  return null;
3150
3373
  }
3151
3374
  if (funding_period) {
@@ -3153,119 +3376,14 @@ function get8hFunding2(est_funding_rate, funding_period) {
3153
3376
  }
3154
3377
  return funding8h;
3155
3378
  }
3156
- function get24hChange2(params) {
3157
- const { change, close, open } = params;
3158
- if (change !== void 0) {
3159
- return change;
3160
- }
3161
- if (!isEmpty(close) && !isEmpty(open)) {
3379
+ function get24hChange2(close, open) {
3380
+ if (close !== void 0 && open !== void 0) {
3162
3381
  if (open === 0) {
3163
3382
  return 0;
3164
3383
  }
3165
3384
  return new Decimal(close).minus(open).div(open).toNumber();
3166
3385
  }
3167
3386
  }
3168
- function getLeverage(base_imr) {
3169
- return base_imr ? 1 / base_imr : void 0;
3170
- }
3171
- function getOpenInterest(open_interest, index_price) {
3172
- return new Decimal(open_interest || 0).mul(index_price || 0).toNumber();
3173
- }
3174
- function getDefaultStoreData() {
3175
- return {
3176
- recent: [],
3177
- favorites: [
3178
- { name: "PERP_ETH_USDC", tabs: [{ ...DefaultFavoriteTab }] },
3179
- { name: "PERP_BTC_USDC", tabs: [{ ...DefaultFavoriteTab }] }
3180
- ],
3181
- favoriteTabs: [{ ...DefaultFavoriteTab }],
3182
- selectedFavoriteTab: { ...DefaultFavoriteTab },
3183
- tabSort: {}
3184
- };
3185
- }
3186
- function filterInvalidTabs(favorites, tabs) {
3187
- return favorites.map((favorite) => {
3188
- return {
3189
- ...favorite,
3190
- tabs: favorite.tabs.filter(
3191
- (tab) => !!tabs.find((item) => item.id === tab.id)
3192
- )
3193
- };
3194
- }).filter((item) => !!item.tabs.length);
3195
- }
3196
- function updateTabs(favoriteTabs, tab, operator) {
3197
- if (Array.isArray(tab)) {
3198
- return tab;
3199
- }
3200
- const tabs = [...favoriteTabs];
3201
- const index = tabs.findIndex((item) => item.id === tab.id);
3202
- if (operator?.add) {
3203
- tabs.push(tab);
3204
- } else if (operator?.update && index !== -1) {
3205
- tabs[index] = tab;
3206
- } else if (operator?.delete && index !== -1) {
3207
- tabs.splice(index, 1);
3208
- }
3209
- return tabs;
3210
- }
3211
- function addToTop(recent, symbol) {
3212
- const list = [...recent];
3213
- const index = list.findIndex((item) => item.name == symbol.symbol);
3214
- if (index !== -1) {
3215
- list.splice(index, 1);
3216
- }
3217
- list.unshift({ name: symbol.symbol });
3218
- return list;
3219
- }
3220
- function moveToTop(favorites, symbol) {
3221
- const index = favorites.findIndex((item) => item.name === symbol.symbol);
3222
- if (index !== -1) {
3223
- const item = favorites[index];
3224
- const list = [...favorites];
3225
- list.splice(index, 1);
3226
- list.unshift(item);
3227
- return list;
3228
- }
3229
- }
3230
- function updateSymbolFavorite(params) {
3231
- const { favorites, symbol, tab, remove = false } = params;
3232
- const list = [...favorites];
3233
- const index = list.findIndex((item) => item.name == symbol.symbol);
3234
- const tabs = Array.isArray(tab) ? tab : [tab];
3235
- if (index === -1) {
3236
- if (tabs.length && !remove) {
3237
- list.unshift({ name: symbol.symbol, tabs });
3238
- }
3239
- } else {
3240
- const favorite = list[index];
3241
- if (Array.isArray(tab)) {
3242
- if (!tab.length) {
3243
- list.splice(index, 1);
3244
- } else {
3245
- list[index] = { ...favorite, tabs: tab };
3246
- }
3247
- } else {
3248
- if (remove) {
3249
- const tabs2 = favorite.tabs.filter((item) => item.id != tab.id);
3250
- if (!tabs2.length) {
3251
- list.splice(index, 1);
3252
- } else {
3253
- list[index] = { ...favorite, tabs: tabs2 };
3254
- }
3255
- } else {
3256
- list[index] = { ...favorite, tabs: [...favorite.tabs, tab] };
3257
- }
3258
- }
3259
- }
3260
- return list;
3261
- }
3262
- function createEventData(id, key, data) {
3263
- return {
3264
- id,
3265
- key,
3266
- data
3267
- };
3268
- }
3269
3387
 
3270
3388
  // src/orderly/useMarkPricesStream.ts
3271
3389
  var useMarkPricesStream = () => {
@@ -3473,8 +3591,9 @@ var useFundingDetails = (symbol) => {
3473
3591
  });
3474
3592
  };
3475
3593
  var calculatePositiveRate = (periodData, period) => {
3476
- if (!periodData || !period)
3594
+ if (!periodData || !period) {
3477
3595
  return 0;
3596
+ }
3478
3597
  const daysMap = {
3479
3598
  "1d": 1,
3480
3599
  "3d": 3,
@@ -3492,8 +3611,9 @@ var useFundingRateHistory = () => {
3492
3611
  );
3493
3612
  const getPositiveRates = useCallback(
3494
3613
  (data, period) => {
3495
- if (!data?.length)
3614
+ if (!data?.length) {
3496
3615
  return {};
3616
+ }
3497
3617
  return data.reduce(
3498
3618
  (acc, item) => {
3499
3619
  acc[item.symbol] = calculatePositiveRate(
@@ -3508,17 +3628,11 @@ var useFundingRateHistory = () => {
3508
3628
  []
3509
3629
  );
3510
3630
  return {
3511
- data: historyData ?? [],
3631
+ data: historyData ?? EMPTY_LIST,
3512
3632
  isLoading,
3513
3633
  getPositiveRates
3514
3634
  };
3515
3635
  };
3516
- var findTPSLFromOrders = (orders, symbol) => {
3517
- const order = findPositionTPSLFromOrders(orders, symbol);
3518
- if (!order)
3519
- return;
3520
- return findTPSLFromOrder(order);
3521
- };
3522
3636
  var findTPSLFromOrder = (order) => {
3523
3637
  let tp_trigger_price;
3524
3638
  let sl_trigger_price;
@@ -3539,10 +3653,51 @@ var findTPSLFromOrder = (order) => {
3539
3653
  sl_trigger_price
3540
3654
  };
3541
3655
  };
3656
+ var findTPSLOrderPriceFromOrder = (order) => {
3657
+ let tp_order_price;
3658
+ let sl_order_price;
3659
+ const tpOrder = order?.child_orders?.find(
3660
+ (order2) => order2.algo_type === AlgoOrderType.TAKE_PROFIT
3661
+ );
3662
+ const slOrder = order?.child_orders?.find(
3663
+ (order2) => order2.algo_type === AlgoOrderType.STOP_LOSS
3664
+ );
3665
+ if (tpOrder) {
3666
+ if (tpOrder.trigger_price) {
3667
+ if (tpOrder.price) {
3668
+ tp_order_price = tpOrder.price;
3669
+ } else {
3670
+ tp_order_price = OrderType.MARKET;
3671
+ }
3672
+ }
3673
+ }
3674
+ if (slOrder) {
3675
+ if (slOrder.trigger_price) {
3676
+ if (slOrder.price) {
3677
+ sl_order_price = slOrder.price;
3678
+ } else {
3679
+ sl_order_price = OrderType.MARKET;
3680
+ }
3681
+ }
3682
+ }
3683
+ return {
3684
+ tp_order_price,
3685
+ sl_order_price
3686
+ };
3687
+ };
3542
3688
  var findPositionTPSLFromOrders = (orders, symbol) => {
3543
- return orders?.find((order) => {
3689
+ const fullPositionOrder = orders?.find((order) => {
3544
3690
  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);
3545
3691
  });
3692
+ const partialPositionOrders = orders?.filter((order) => {
3693
+ 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);
3694
+ }).sort((a, b) => {
3695
+ return b.created_time - a.created_time;
3696
+ });
3697
+ return {
3698
+ fullPositionOrder,
3699
+ partialPositionOrders
3700
+ };
3546
3701
  };
3547
3702
 
3548
3703
  // src/orderly/usePositionStream/usePositionStream.ts
@@ -3636,16 +3791,27 @@ var usePositionStream = (symbol = "all", options) => {
3636
3791
  }
3637
3792
  if (Array.isArray(tpslOrders) && tpslOrders.length) {
3638
3793
  rows = rows.map((item) => {
3639
- const related_order = findPositionTPSLFromOrders(
3640
- tpslOrders,
3641
- item.symbol
3642
- );
3643
- const tp_sl_pricer = !!related_order ? findTPSLFromOrder(related_order) : void 0;
3794
+ const { fullPositionOrder, partialPositionOrders } = findPositionTPSLFromOrders(tpslOrders, item.symbol);
3795
+ const full_tp_sl = fullPositionOrder ? findTPSLFromOrder(fullPositionOrder) : void 0;
3796
+ const partialPossitionOrder = partialPositionOrders && partialPositionOrders.length ? partialPositionOrders[0] : void 0;
3797
+ const partial_tp_sl = partialPossitionOrder ? findTPSLFromOrder(partialPossitionOrder) : void 0;
3644
3798
  return {
3645
3799
  ...item,
3646
- tp_trigger_price: tp_sl_pricer?.tp_trigger_price,
3647
- sl_trigger_price: tp_sl_pricer?.sl_trigger_price,
3648
- algo_order: related_order
3800
+ // tp_trigger_price: tp_sl_pricer?.tp_trigger_price,
3801
+ // sl_trigger_price: tp_sl_pricer?.sl_trigger_price,
3802
+ // algo_order: related_order,
3803
+ full_tp_sl: {
3804
+ tp_trigger_price: full_tp_sl?.tp_trigger_price,
3805
+ sl_trigger_price: full_tp_sl?.sl_trigger_price,
3806
+ algo_order: fullPositionOrder
3807
+ },
3808
+ partial_tp_sl: {
3809
+ order_num: partialPositionOrders?.length ?? 0,
3810
+ tp_trigger_price: partial_tp_sl?.tp_trigger_price,
3811
+ sl_trigger_price: partial_tp_sl?.sl_trigger_price,
3812
+ algo_order: partialPossitionOrder
3813
+ // algo_order: partialPositionOrders,
3814
+ }
3649
3815
  };
3650
3816
  });
3651
3817
  }
@@ -3658,7 +3824,7 @@ var usePositionStream = (symbol = "all", options) => {
3658
3824
  {
3659
3825
  rows,
3660
3826
  // rows: formattedPositions[0],
3661
- aggregated: formattedPositions?.[1] ?? {},
3827
+ aggregated: formattedPositions?.[1] ?? EMPTY_OBJECT,
3662
3828
  totalCollateral,
3663
3829
  totalValue,
3664
3830
  totalUnrealizedROI
@@ -3683,6 +3849,12 @@ pathOr(0, [
3683
3849
  "aggregated",
3684
3850
  "unsettledPnL"
3685
3851
  ]);
3852
+ var DataCenterContext = createContext({});
3853
+ var useDataCenterContext = () => {
3854
+ return useContext(DataCenterContext);
3855
+ };
3856
+
3857
+ // src/orderly/useOrderStream/useOrderStream.ts
3686
3858
  var useOrderStream = (params, options) => {
3687
3859
  const {
3688
3860
  status,
@@ -3832,6 +4004,15 @@ var useOrderStream = (params, options) => {
3832
4004
  doCancelAllAlgoOrders(null, { algo_type: "STOP" })
3833
4005
  ]);
3834
4006
  }, [normalOrdersResponse.data, algoOrdersResponse.data]);
4007
+ const cancelPostionOrdersByTypes = useCallback(
4008
+ (symbol2, types) => {
4009
+ return doCancelAllAlgoOrders(null, {
4010
+ symbol: symbol2,
4011
+ algo_type: types
4012
+ });
4013
+ },
4014
+ [algoOrdersResponse.data]
4015
+ );
3835
4016
  const cancelAllTPSLOrders = useCallback(() => {
3836
4017
  return cancelAlgoOrdersByTypes([
3837
4018
  AlgoOrderRootType.POSITIONAL_TP_SL,
@@ -3951,6 +4132,7 @@ var useOrderStream = (params, options) => {
3951
4132
  cancelAlgoOrder,
3952
4133
  cancelTPSLChildOrder,
3953
4134
  updateTPSLOrder,
4135
+ cancelPostionOrdersByTypes,
3954
4136
  meta,
3955
4137
  errors: {
3956
4138
  cancelOrder: cancelOrderError,
@@ -4132,7 +4314,7 @@ var useMarginRatio = () => {
4132
4314
  return account.totalMarginRatio({
4133
4315
  totalCollateral,
4134
4316
  markPrices,
4135
- positions: rows ?? []
4317
+ positions: rows ?? EMPTY_LIST
4136
4318
  });
4137
4319
  }, [rows, markPrices, totalCollateral]);
4138
4320
  const currentLeverage = useMemo(() => {
@@ -4781,16 +4963,29 @@ var useDeposit = (options) => {
4781
4963
  const fetchBalanceHandler = useCallback(
4782
4964
  async (address, decimals) => {
4783
4965
  let balance2;
4784
- if (address && isNativeTokenChecker(address)) {
4785
- balance2 = await account9.assetsManager.getNativeBalance({
4786
- decimals
4787
- });
4788
- } else {
4789
- balance2 = await account9.assetsManager.getBalance(address, { decimals });
4966
+ try {
4967
+ if (address && isNativeTokenChecker(address)) {
4968
+ balance2 = await account9.assetsManager.getNativeBalance({
4969
+ decimals
4970
+ });
4971
+ } else {
4972
+ balance2 = await account9.assetsManager.getBalance(address, {
4973
+ decimals
4974
+ });
4975
+ }
4976
+ } catch (err) {
4977
+ if (ignoreBalanceError({
4978
+ token: options.srcToken,
4979
+ chainNamespace: account9.walletAdapter?.chainNamespace,
4980
+ err
4981
+ })) {
4982
+ return "0";
4983
+ }
4984
+ throw err;
4790
4985
  }
4791
4986
  return balance2;
4792
4987
  },
4793
- []
4988
+ [options.srcToken, account9]
4794
4989
  );
4795
4990
  const fetchBalances = useCallback(async (tokens) => {
4796
4991
  const tasks = [];
@@ -4943,15 +5138,62 @@ var useDeposit = (options) => {
4943
5138
  quantity,
4944
5139
  isNativeToken
4945
5140
  ]);
5141
+ const checkIfChainTokenNeedRestApprove = useCallback(
5142
+ (chainId, token) => {
5143
+ if (chainId !== ETHEREUM_MAINNET_CHAINID) {
5144
+ return false;
5145
+ }
5146
+ if (token !== "USDT") {
5147
+ return false;
5148
+ }
5149
+ return true;
5150
+ },
5151
+ []
5152
+ );
5153
+ const resetApprove = useCallback(
5154
+ async (tokenAddress, decimal, vaultAddress2) => {
5155
+ const result = await account9.assetsManager.approve({
5156
+ address: tokenAddress,
5157
+ amount: "0",
5158
+ vaultAddress: vaultAddress2,
5159
+ decimals: decimal
5160
+ });
5161
+ const txResult = await account9.walletAdapter?.pollTransactionReceiptWithBackoff(
5162
+ result.hash
5163
+ );
5164
+ if (txResult && txResult.status === 1) {
5165
+ account9.assetsManager.getAllowance({
5166
+ address: tokenAddress,
5167
+ decimals: decimal,
5168
+ vaultAddress: vaultAddress2
5169
+ }).then((allowance2) => {
5170
+ setAllowance(allowance2);
5171
+ });
5172
+ }
5173
+ },
5174
+ []
5175
+ );
4946
5176
  const approve = useCallback(
4947
5177
  async (amount) => {
4948
5178
  if (!options.address) {
4949
5179
  throw new Error("address is required");
4950
5180
  }
5181
+ let isSetMaxValue = false;
5182
+ if (checkIfChainTokenNeedRestApprove(options.srcChainId, options.srcToken)) {
5183
+ isSetMaxValue = true;
5184
+ if (allowance && new Decimal(allowance).gt(0)) {
5185
+ await resetApprove(
5186
+ options.address,
5187
+ options.decimals,
5188
+ vaultAddress
5189
+ );
5190
+ }
5191
+ }
4951
5192
  return account9.assetsManager.approve({
4952
5193
  address: options.address,
4953
5194
  amount,
4954
5195
  vaultAddress,
5196
+ isSetMaxValue,
4955
5197
  decimals: options.decimals
4956
5198
  }).then((result) => {
4957
5199
  return updateAllowanceWhenTxSuccess(result.hash);
@@ -4959,10 +5201,15 @@ var useDeposit = (options) => {
4959
5201
  },
4960
5202
  [
4961
5203
  account9,
5204
+ options.srcChainId,
5205
+ options.srcToken,
5206
+ allowance,
4962
5207
  options.address,
4963
5208
  options.decimals,
4964
5209
  vaultAddress,
4965
- updateAllowanceWhenTxSuccess
5210
+ updateAllowanceWhenTxSuccess,
5211
+ checkIfChainTokenNeedRestApprove,
5212
+ resetApprove
4966
5213
  ]
4967
5214
  );
4968
5215
  const deposit = useCallback(async () => {
@@ -5096,6 +5343,10 @@ var useDeposit = (options) => {
5096
5343
  setQuantity
5097
5344
  };
5098
5345
  };
5346
+ function ignoreBalanceError(options) {
5347
+ const { token, chainNamespace, err } = options;
5348
+ return chainNamespace === ChainNamespace.solana && token === "USDC" && err?.name === "TokenAccountNotFoundError";
5349
+ }
5099
5350
 
5100
5351
  // src/orderly/useConvert.ts
5101
5352
  var useConvert = (options) => {
@@ -5140,45 +5391,34 @@ var useSubAccountMutation = (url, method = "POST", options) => {
5140
5391
  fetcher3,
5141
5392
  restOptions
5142
5393
  );
5143
- const mutation = useCallback(
5144
- async (data2, params, options2) => {
5145
- const { accountId: _accountId, ...restOptions2 } = options2 || {};
5146
- let newUrl = url;
5147
- if (typeof params === "object" && Object.keys(params).length) {
5148
- const search = new URLSearchParams(params);
5149
- newUrl = `${url}?${search.toString()}`;
5150
- }
5151
- const payload = {
5152
- method,
5153
- url: newUrl,
5154
- data: data2
5155
- };
5156
- const signer = account9.signer;
5157
- const signature = await signer.sign(payload, getTimestamp());
5158
- return trigger(
5159
- {
5160
- data: data2,
5161
- params,
5162
- method,
5163
- signature: {
5164
- ...signature,
5165
- "orderly-account-id": accountId || _accountId || account9.accountId
5166
- }
5167
- },
5168
- restOptions2
5169
- );
5170
- },
5171
- [trigger, account9, accountId]
5172
- );
5173
- return [
5174
- mutation,
5175
- {
5176
- data,
5177
- error,
5178
- reset,
5179
- isMutating
5394
+ const mutation = async (data2, params, options2) => {
5395
+ const { accountId: _accountId, ...restOptions2 } = options2 || {};
5396
+ let newUrl = url;
5397
+ if (typeof params === "object" && Object.keys(params).length) {
5398
+ const search = new URLSearchParams(params);
5399
+ newUrl = `${url}?${search.toString()}`;
5180
5400
  }
5181
- ];
5401
+ const payload = {
5402
+ method,
5403
+ url: newUrl,
5404
+ data: data2
5405
+ };
5406
+ const signer = account9.signer;
5407
+ const signature = await signer.sign(payload, getTimestamp());
5408
+ return trigger(
5409
+ {
5410
+ data: data2,
5411
+ params,
5412
+ method,
5413
+ signature: {
5414
+ ...signature,
5415
+ "orderly-account-id": accountId || _accountId || account9.accountId
5416
+ }
5417
+ },
5418
+ restOptions2
5419
+ );
5420
+ };
5421
+ return [useMemoizedFn(mutation), { data, error, reset, isMutating }];
5182
5422
  };
5183
5423
 
5184
5424
  // src/orderly/useTransfer.ts
@@ -5423,10 +5663,14 @@ var OrderValidation = class {
5423
5663
  return "TP price";
5424
5664
  case "sl_trigger_price":
5425
5665
  return "SL price";
5426
- case "max_price":
5427
- return "Upper price";
5428
- case "min_price":
5429
- return "Lower price";
5666
+ case "tp_order_price":
5667
+ return "TP order price";
5668
+ case "sl_order_price":
5669
+ return "SL order price";
5670
+ case "start_price":
5671
+ return "Start price";
5672
+ case "end_price":
5673
+ return "End price";
5430
5674
  case "total_orders":
5431
5675
  return "Total orders";
5432
5676
  case "skew":
@@ -5441,6 +5685,18 @@ var OrderValidation = class {
5441
5685
  message: `${this.getLabel(key)} is required`
5442
5686
  };
5443
5687
  }
5688
+ static priceErrorMin(key) {
5689
+ return {
5690
+ type: "priceErrorMin",
5691
+ message: `Your ${this.getLabel(key)} should be set lower than your order price.`
5692
+ };
5693
+ }
5694
+ static priceErrorMax(key) {
5695
+ return {
5696
+ type: "priceErrorMax",
5697
+ message: `Your ${this.getLabel(key)} should be set higher than your order price.`
5698
+ };
5699
+ }
5444
5700
  static min(key, value) {
5445
5701
  return {
5446
5702
  type: "min",
@@ -5556,36 +5812,57 @@ var BaseOrderCreator = class {
5556
5812
  get type() {
5557
5813
  return this.orderType;
5558
5814
  }
5815
+ getChildOrderType(positionType, orderPrice) {
5816
+ if (positionType === PositionType.FULL) {
5817
+ return OrderType.CLOSE_POSITION;
5818
+ }
5819
+ let type = OrderType.MARKET;
5820
+ if (orderPrice) {
5821
+ type = OrderType.LIMIT;
5822
+ }
5823
+ return type;
5824
+ }
5559
5825
  parseBracketOrder(data) {
5560
5826
  const orders = [];
5561
5827
  const side = data.side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
5828
+ const algoType = data.position_type === PositionType.PARTIAL ? AlgoOrderRootType.TP_SL : AlgoOrderRootType.POSITIONAL_TP_SL;
5562
5829
  if (!!data.tp_trigger_price) {
5563
5830
  const tp_trigger_price = data.tp_trigger_price;
5564
- orders.push({
5831
+ const orderItem = {
5565
5832
  algo_type: AlgoOrderType.TAKE_PROFIT,
5566
5833
  side,
5567
- type: OrderType.CLOSE_POSITION,
5834
+ // TODO need confirm child order type
5835
+ type: this.getChildOrderType(data.position_type, data.tp_order_price),
5568
5836
  trigger_price: tp_trigger_price,
5569
5837
  symbol: data.symbol,
5570
5838
  reduce_only: true
5571
- });
5839
+ };
5840
+ if (data.tp_order_price) {
5841
+ orderItem.price = data.tp_order_price;
5842
+ }
5843
+ orders.push(orderItem);
5572
5844
  }
5573
5845
  if (!!data.sl_trigger_price) {
5574
5846
  const sl_trigger_price = data.sl_trigger_price;
5575
- orders.push({
5847
+ const orderItem = {
5576
5848
  algo_type: AlgoOrderType.STOP_LOSS,
5577
5849
  side,
5578
- type: OrderType.CLOSE_POSITION,
5850
+ // TODO need confirm child order type
5851
+ type: this.getChildOrderType(data.position_type, data.sl_order_price),
5579
5852
  trigger_price: sl_trigger_price,
5580
5853
  symbol: data.symbol,
5581
5854
  reduce_only: true
5582
- });
5855
+ };
5856
+ if (data.sl_order_price) {
5857
+ orderItem.price = data.sl_order_price;
5858
+ }
5859
+ orders.push(orderItem);
5583
5860
  }
5584
5861
  if (!orders.length)
5585
5862
  return null;
5586
5863
  return {
5587
5864
  symbol: data.symbol,
5588
- algo_type: AlgoOrderRootType.POSITIONAL_TP_SL,
5865
+ algo_type: algoType,
5589
5866
  child_orders: orders
5590
5867
  };
5591
5868
  }
@@ -5770,15 +6047,75 @@ var LimitOrderCreator = class extends BaseOrderCreator {
5770
6047
  });
5771
6048
  }
5772
6049
  };
6050
+ function getOrderPrice(order, askAndBid) {
6051
+ const orderPrice = Number(order.order_price);
6052
+ if (order.order_type === OrderType.MARKET || order.order_type === OrderType.STOP_MARKET) {
6053
+ if (order.side === OrderSide.BUY) {
6054
+ return askAndBid[0];
6055
+ } else {
6056
+ return askAndBid[1];
6057
+ }
6058
+ } else {
6059
+ if (order.side === OrderSide.BUY) {
6060
+ if (orderPrice >= askAndBid[0]) {
6061
+ return askAndBid[0];
6062
+ } else {
6063
+ return orderPrice;
6064
+ }
6065
+ } else {
6066
+ if (orderPrice <= askAndBid[1]) {
6067
+ return askAndBid[1];
6068
+ } else {
6069
+ return orderPrice;
6070
+ }
6071
+ }
6072
+ }
6073
+ }
6074
+ function getPriceRange(inputs) {
6075
+ const { basePrice, side, symbolInfo } = inputs;
6076
+ const { price_range, price_scope, quote_min, quote_max } = symbolInfo;
6077
+ const maxPriceNumber = order.maxPrice(basePrice, price_range);
6078
+ const minPriceNumber = order.minPrice(basePrice, price_range);
6079
+ const scopePriceNumber = order.scopePrice(basePrice, price_scope, side);
6080
+ const priceRange = side === OrderSide.BUY ? {
6081
+ min: scopePriceNumber,
6082
+ max: maxPriceNumber
6083
+ } : {
6084
+ min: minPriceNumber,
6085
+ max: scopePriceNumber
6086
+ };
6087
+ const minPrice3 = Math.max(quote_min, priceRange?.min);
6088
+ const maxPrice3 = Math.min(quote_max, priceRange?.max);
6089
+ return {
6090
+ minPrice: minPrice3,
6091
+ maxPrice: maxPrice3
6092
+ };
6093
+ }
6094
+
6095
+ // src/services/orderCreator/baseBracketOrderCreator.ts
6096
+ var formatPrice = (price, quote_dp) => {
6097
+ return new Decimal(price).toDecimalPlaces(quote_dp).toNumber();
6098
+ };
5773
6099
  async function bracketOrderValidator(values2, config) {
5774
6100
  const result = /* @__PURE__ */ Object.create(null);
5775
6101
  await Promise.resolve();
5776
- const { tp_trigger_price, sl_trigger_price, side } = values2;
6102
+ const {
6103
+ tp_enable,
6104
+ tp_trigger_price,
6105
+ tp_order_price,
6106
+ tp_order_type,
6107
+ sl_trigger_price,
6108
+ sl_enable,
6109
+ sl_order_price,
6110
+ sl_order_type,
6111
+ side
6112
+ } = values2;
5777
6113
  const qty = Number(values2.quantity);
5778
6114
  const maxQty = config.maxQty;
5779
6115
  const type = values2.order_type;
5780
- const { quote_max, quote_min, price_scope, quote_dp } = config.symbol ?? {};
6116
+ const { quote_max, quote_min, quote_dp } = config.symbol ?? {};
5781
6117
  const mark_price = type === OrderType.MARKET ? config.markPrice : values2.order_price ? Number(values2.order_price) : void 0;
6118
+ const tpslSide = side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
5782
6119
  if (!isNaN(qty) && qty > maxQty) {
5783
6120
  result.quantity = OrderValidation.max("quantity", config.maxQty);
5784
6121
  }
@@ -5788,58 +6125,156 @@ async function bracketOrderValidator(values2, config) {
5788
6125
  if (Number(sl_trigger_price) < 0) {
5789
6126
  result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
5790
6127
  }
6128
+ if (tp_enable && !tp_trigger_price) {
6129
+ result.tp_trigger_price = OrderValidation.required("tp_trigger_price");
6130
+ }
6131
+ if (sl_enable && !sl_trigger_price) {
6132
+ result.sl_trigger_price = OrderValidation.required("sl_trigger_price");
6133
+ }
6134
+ if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
6135
+ result.tp_order_price = OrderValidation.required("tp_order_price");
6136
+ }
6137
+ if (sl_order_type === OrderType.LIMIT && !sl_order_price) {
6138
+ result.sl_order_price = OrderValidation.required("sl_order_price");
6139
+ }
5791
6140
  if (side === OrderSide.BUY && mark_price) {
5792
- const slTriggerPriceScope = new Decimal(mark_price * (1 - price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5793
- if (!!sl_trigger_price && Number(sl_trigger_price) < slTriggerPriceScope) {
6141
+ if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5794
6142
  result.sl_trigger_price = OrderValidation.min(
5795
6143
  "sl_trigger_price",
5796
- slTriggerPriceScope
6144
+ formatPrice(quote_min, quote_dp)
6145
+ );
6146
+ }
6147
+ if (!!sl_trigger_price && Number(sl_trigger_price) > mark_price) {
6148
+ result.sl_trigger_price = OrderValidation.max(
6149
+ "sl_trigger_price",
6150
+ formatPrice(mark_price, quote_dp)
5797
6151
  );
5798
6152
  }
5799
6153
  if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
5800
6154
  result.tp_trigger_price = OrderValidation.min(
5801
6155
  "tp_trigger_price",
5802
- mark_price
6156
+ formatPrice(mark_price, quote_dp)
5803
6157
  );
5804
6158
  }
5805
6159
  if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5806
6160
  result.tp_trigger_price = OrderValidation.max(
5807
6161
  "tp_trigger_price",
5808
- quote_max
6162
+ formatPrice(quote_max, quote_dp)
5809
6163
  );
5810
6164
  }
5811
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5812
- result.sl_trigger_price = OrderValidation.min(
5813
- "sl_trigger_price",
5814
- quote_min
5815
- );
6165
+ if (sl_trigger_price && sl_order_price) {
6166
+ const priceRange = getPriceRange({
6167
+ side: tpslSide,
6168
+ basePrice: Number(sl_trigger_price),
6169
+ symbolInfo: config.symbol
6170
+ });
6171
+ if (Number(sl_order_price) < priceRange.minPrice) {
6172
+ result.sl_order_price = OrderValidation.min(
6173
+ "sl_order_price",
6174
+ formatPrice(priceRange.minPrice, quote_dp)
6175
+ );
6176
+ }
6177
+ if (Number(sl_order_price) > priceRange.maxPrice) {
6178
+ result.sl_order_price = OrderValidation.max(
6179
+ "sl_order_price",
6180
+ formatPrice(priceRange.maxPrice, quote_dp)
6181
+ );
6182
+ }
6183
+ if (Number(sl_trigger_price) < Number(sl_order_price)) {
6184
+ result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
6185
+ }
6186
+ }
6187
+ if (tp_trigger_price && tp_order_price) {
6188
+ const priceRange = getPriceRange({
6189
+ side: tpslSide,
6190
+ basePrice: Number(tp_trigger_price),
6191
+ symbolInfo: config.symbol
6192
+ });
6193
+ if (Number(tp_order_price) > priceRange.maxPrice) {
6194
+ result.tp_order_price = OrderValidation.max(
6195
+ "tp_order_price",
6196
+ formatPrice(priceRange.maxPrice, quote_dp)
6197
+ );
6198
+ }
6199
+ if (Number(tp_order_price) < priceRange.minPrice) {
6200
+ result.tp_order_price = OrderValidation.min(
6201
+ "tp_order_price",
6202
+ formatPrice(priceRange.minPrice, quote_dp)
6203
+ );
6204
+ }
6205
+ if (Number(tp_trigger_price) > Number(tp_order_price)) {
6206
+ result.tp_trigger_price = OrderValidation.priceErrorMin("tp_trigger_price");
6207
+ }
5816
6208
  }
5817
6209
  }
5818
6210
  if (side === OrderSide.SELL && mark_price) {
5819
- const slTriggerPriceScope = new Decimal(mark_price * (1 + price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
5820
- if (!!sl_trigger_price && Number(sl_trigger_price) > slTriggerPriceScope) {
6211
+ if (!!sl_trigger_price && Number(sl_trigger_price) > quote_max) {
5821
6212
  result.sl_trigger_price = OrderValidation.max(
5822
6213
  "sl_trigger_price",
5823
- slTriggerPriceScope
6214
+ formatPrice(quote_max, quote_dp)
6215
+ );
6216
+ }
6217
+ if (!!sl_trigger_price && Number(sl_trigger_price) < mark_price) {
6218
+ result.sl_trigger_price = OrderValidation.min(
6219
+ "sl_trigger_price",
6220
+ formatPrice(mark_price, quote_dp)
5824
6221
  );
5825
6222
  }
5826
6223
  if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
5827
6224
  result.tp_trigger_price = OrderValidation.max(
5828
6225
  "tp_trigger_price",
5829
- mark_price
6226
+ formatPrice(mark_price, quote_dp)
5830
6227
  );
5831
6228
  }
5832
- if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
5833
- result.tp_trigger_price = OrderValidation.max(
6229
+ if (!!tp_trigger_price && Number(tp_trigger_price) < quote_min) {
6230
+ result.tp_trigger_price = OrderValidation.min(
5834
6231
  "tp_trigger_price",
5835
- quote_max
6232
+ formatPrice(quote_min, quote_dp)
5836
6233
  );
5837
6234
  }
5838
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
5839
- result.sl_trigger_price = OrderValidation.min(
5840
- "sl_trigger_price",
5841
- quote_min
5842
- );
6235
+ if (sl_trigger_price && sl_order_price) {
6236
+ const priceRange = getPriceRange({
6237
+ side: tpslSide,
6238
+ basePrice: Number(sl_trigger_price),
6239
+ symbolInfo: config.symbol
6240
+ });
6241
+ if (Number(sl_order_price) < priceRange.minPrice) {
6242
+ result.sl_order_price = OrderValidation.min(
6243
+ "sl_order_price",
6244
+ formatPrice(priceRange.minPrice, quote_dp)
6245
+ );
6246
+ }
6247
+ if (Number(sl_order_price) > priceRange.maxPrice) {
6248
+ result.sl_order_price = OrderValidation.max(
6249
+ "sl_order_price",
6250
+ formatPrice(priceRange.maxPrice, quote_dp)
6251
+ );
6252
+ }
6253
+ if (Number(sl_trigger_price) > Number(sl_order_price)) {
6254
+ result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
6255
+ }
6256
+ }
6257
+ if (tp_trigger_price && tp_order_price) {
6258
+ const priceRange = getPriceRange({
6259
+ side: tpslSide,
6260
+ basePrice: Number(tp_trigger_price),
6261
+ symbolInfo: config.symbol
6262
+ });
6263
+ if (Number(tp_order_price) < priceRange.minPrice) {
6264
+ result.tp_order_price = OrderValidation.min(
6265
+ "tp_order_price",
6266
+ formatPrice(priceRange.minPrice, quote_dp)
6267
+ );
6268
+ }
6269
+ if (Number(tp_order_price) > priceRange.maxPrice) {
6270
+ result.tp_order_price = OrderValidation.max(
6271
+ "tp_order_price",
6272
+ formatPrice(priceRange.maxPrice, quote_dp)
6273
+ );
6274
+ }
6275
+ if (Number(tp_trigger_price) < Number(tp_order_price)) {
6276
+ result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
6277
+ }
5843
6278
  }
5844
6279
  }
5845
6280
  return Object.keys(result).length > 0 ? result : null;
@@ -5916,233 +6351,78 @@ var BracketMarketOrderCreator = class extends MarketOrderCreator {
5916
6351
  return { ...value, ...bracketData };
5917
6352
  }
5918
6353
  };
5919
-
5920
- // src/services/orderCreator/fokCreator.ts
5921
- var FOKOrderCreator = class extends LimitOrderCreator {
5922
- };
5923
-
5924
- // src/services/orderCreator/generalCreator.ts
5925
- var GeneralOrderCreator = class extends BaseOrderCreator {
5926
- create(data) {
5927
- return {
5928
- ...this.baseOrder(data),
5929
- order_price: data.order_price,
5930
- order_quantity: data.order_quantity
5931
- };
5932
- }
5933
- validate(values2, configs) {
5934
- return super.baseValidate(values2, configs);
5935
- }
5936
- };
5937
-
5938
- // src/services/orderCreator/iocCreator.ts
5939
- var IOCOrderCreator = class extends LimitOrderCreator {
5940
- };
5941
-
5942
- // src/services/orderCreator/postOnlyCreator.ts
5943
- var PostOnlyOrderCreator = class extends LimitOrderCreator {
5944
- };
5945
- var getCreateOrderUrl = (order) => {
5946
- const isAlgoOrder = order?.order_type === OrderType.STOP_LIMIT || order?.order_type === OrderType.STOP_MARKET || order?.order_type === OrderType.CLOSE_POSITION || order.algo_type && order.algo_type === AlgoOrderRootType.BRACKET || isBracketOrder(order);
5947
- if (order.order_type === OrderType.SCALED) {
5948
- return "/v1/batch-order";
5949
- }
5950
- return isAlgoOrder ? "/v1/algo/order" : "/v1/order";
5951
- };
5952
- var getOrderCreator = (order) => {
5953
- let type;
5954
- if (isBracketOrder(order)) {
5955
- type = `${AlgoOrderRootType.BRACKET}:${order.order_type}`;
5956
- } else if (order.order_type === OrderType.LIMIT) {
5957
- type = order.order_type_ext || order.order_type;
5958
- } else {
5959
- type = order.order_type;
5960
- }
5961
- return OrderFactory.create(type);
5962
- };
5963
- var tpslFields = [
5964
- "tp_trigger_price",
5965
- "sl_trigger_price",
5966
- "tp_pnl",
5967
- "sl_pnl",
5968
- "tp_offset",
5969
- "sl_offset",
5970
- "tp_offset_percentage",
5971
- "sl_offset_percentage"
5972
- ];
5973
- var isBracketOrder = (order) => {
5974
- return !!order.tp_trigger_price || !!order.sl_trigger_price;
5975
- };
5976
- var hasTPSL = (order) => {
5977
- return tpslFields.some((field) => !!order[field]);
5978
- };
5979
- function getOrderPrice(order, askAndBid) {
5980
- const orderPrice = Number(order.order_price);
5981
- if (order.order_type === OrderType.MARKET || order.order_type === OrderType.STOP_MARKET) {
5982
- if (order.side === OrderSide.BUY) {
5983
- return askAndBid[0];
5984
- } else {
5985
- return askAndBid[1];
5986
- }
5987
- } else {
5988
- if (order.side === OrderSide.BUY) {
5989
- if (orderPrice >= askAndBid[0]) {
5990
- return askAndBid[0];
5991
- } else {
5992
- return orderPrice;
5993
- }
5994
- } else {
5995
- if (orderPrice <= askAndBid[1]) {
5996
- return askAndBid[1];
5997
- } else {
5998
- return orderPrice;
5999
- }
6000
- }
6001
- }
6002
- }
6003
- var getPriceAndQty = (order, symbolInfo, askAndBid) => {
6004
- let quantity = Number(order.order_quantity);
6005
- const orderPrice = Number(order.order_price);
6006
- if (isNaN(quantity) || quantity <= 0) {
6007
- return null;
6008
- }
6009
- if (askAndBid.length === 0) {
6010
- return null;
6011
- }
6012
- if ((order.order_type === OrderType.LIMIT || order.order_type === OrderType.STOP_LIMIT) && isNaN(orderPrice)) {
6013
- return null;
6014
- }
6015
- let price;
6016
- if (order.order_type === OrderType.SCALED) {
6017
- price = calcScaledOrderAvgOrderPrice(order, symbolInfo, askAndBid);
6018
- const orders = calcScaledOrderBatchBody(order, symbolInfo);
6019
- const sumQtys = orders.reduce((acc, order2) => {
6020
- return acc.plus(new Decimal(order2.order_quantity));
6021
- }, zero);
6022
- quantity = sumQtys.todp(symbolInfo.base_dp).toNumber();
6023
- if (!quantity || isNaN(quantity)) {
6024
- return null;
6025
- }
6026
- } else {
6027
- price = getOrderPrice(order, askAndBid);
6028
- }
6029
- if (!price || isNaN(price)) {
6030
- return null;
6354
+
6355
+ // src/services/orderCreator/fokCreator.ts
6356
+ var FOKOrderCreator = class extends LimitOrderCreator {
6357
+ };
6358
+
6359
+ // src/services/orderCreator/generalCreator.ts
6360
+ var GeneralOrderCreator = class extends BaseOrderCreator {
6361
+ create(data) {
6362
+ return {
6363
+ ...this.baseOrder(data),
6364
+ order_price: data.order_price,
6365
+ order_quantity: data.order_quantity
6366
+ };
6031
6367
  }
6032
- if (order.side === OrderSide.SELL) {
6033
- quantity = -quantity;
6368
+ validate(values2, configs) {
6369
+ return super.baseValidate(values2, configs);
6034
6370
  }
6035
- return { price, quantity };
6036
6371
  };
6037
- var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
6038
- const { symbolInfo } = inputs;
6039
- const result = getPriceAndQty(order$1, symbolInfo, askAndBid);
6040
- if (!result)
6041
- return null;
6042
- const { price, quantity } = result;
6043
- if (!price || !quantity)
6044
- return null;
6045
- const {
6046
- symbol,
6047
- imr_factor,
6048
- markPrice,
6049
- totalCollateral,
6050
- futures_taker_fee_rate,
6051
- positions: positions3
6052
- } = inputs;
6053
- const orderFee = order.orderFee({
6054
- qty: quantity,
6055
- price,
6056
- futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
6057
- });
6058
- const liqPrice = order.estLiqPrice({
6059
- markPrice,
6060
- baseIMR: symbolInfo.base_imr,
6061
- baseMMR: symbolInfo.base_mmr,
6062
- totalCollateral,
6063
- positions: positions3 == null ? [] : positions3,
6064
- IMR_Factor: imr_factor,
6065
- orderFee,
6066
- newOrder: {
6067
- qty: quantity,
6068
- price,
6069
- symbol
6070
- }
6071
- });
6072
- if (liqPrice <= 0)
6073
- return null;
6074
- return liqPrice;
6372
+
6373
+ // src/services/orderCreator/iocCreator.ts
6374
+ var IOCOrderCreator = class extends LimitOrderCreator {
6075
6375
  };
6076
- var calcEstLeverage = (order$1, askAndBid, inputs) => {
6077
- const { totalCollateral, positions: positions3, symbol, symbolInfo } = inputs;
6078
- const result = getPriceAndQty(order$1, symbolInfo, askAndBid);
6079
- if (!result)
6080
- return null;
6081
- const { price, quantity } = result;
6082
- if (!price || !quantity)
6083
- return null;
6084
- return order.estLeverage({
6085
- totalCollateral,
6086
- positions: positions3,
6087
- newOrder: {
6088
- symbol,
6089
- qty: result.quantity,
6090
- price: result.price
6091
- }
6092
- });
6376
+
6377
+ // src/services/orderCreator/postOnlyCreator.ts
6378
+ var PostOnlyOrderCreator = class extends LimitOrderCreator {
6093
6379
  };
6094
- function isBBOOrder(options) {
6095
- const { order_type, order_type_ext } = options;
6096
- return order_type === OrderType.LIMIT && [OrderType.ASK, OrderType.BID].includes(order_type_ext);
6097
- }
6098
6380
  function calcScaledOrderPrices(inputs) {
6099
- const { min_price, max_price, total_orders, quote_dp } = inputs;
6100
- if (!min_price || !max_price || !total_orders) {
6101
- return [];
6102
- }
6103
- const minPrice3 = new Decimal(min_price);
6104
- const maxPrice3 = new Decimal(max_price);
6381
+ const { start_price, end_price, total_orders, quote_dp } = inputs;
6382
+ const startPrice = new Decimal(start_price);
6383
+ const endPrice = new Decimal(end_price);
6105
6384
  const totalOrders = Number(total_orders);
6106
- const priceStep = maxPrice3.minus(minPrice3).div(totalOrders - 1);
6385
+ const priceStep = endPrice.minus(startPrice).div(totalOrders - 1);
6107
6386
  const prices = [];
6108
6387
  for (let i = 0; i < totalOrders; i++) {
6109
- prices[i] = minPrice3.plus(priceStep.mul(i)).todp(quote_dp).toString();
6388
+ prices[i] = startPrice.plus(priceStep.mul(i)).todp(quote_dp).toString();
6110
6389
  }
6111
6390
  return prices;
6112
6391
  }
6113
6392
  function getScaledOrderSkew(inputs) {
6114
6393
  const { skew, distribution_type, total_orders } = inputs;
6115
6394
  if (distribution_type === DistributionType.FLAT) {
6116
- return 1;
6395
+ return new Decimal(1);
6117
6396
  } else if (distribution_type === DistributionType.ASCENDING) {
6118
- return total_orders;
6397
+ return new Decimal(total_orders);
6119
6398
  } else if (distribution_type === DistributionType.DESCENDING) {
6120
- return 1 / total_orders;
6399
+ return new Decimal(1).div(total_orders);
6121
6400
  }
6122
- return skew;
6401
+ return new Decimal(skew);
6123
6402
  }
6124
6403
  function calcScaledOrderWeights(inputs) {
6125
6404
  const { total_orders, distribution_type, skew } = inputs;
6126
6405
  const weights = [];
6127
- if (!total_orders || !distribution_type || distribution_type === DistributionType.CUSTOM && (!skew || skew <= 0 || skew > 100)) {
6406
+ if (isInvalidTotalOrders(total_orders) || isInvalidSkew(skew, distribution_type)) {
6128
6407
  return {
6129
6408
  weights: [],
6130
- sumWeights: 0,
6131
- minWeight: 0
6409
+ sumWeights: zero,
6410
+ minWeight: zero
6132
6411
  };
6133
6412
  }
6134
6413
  const totalOrders = Number(total_orders);
6135
- const skewNum = getScaledOrderSkew({
6414
+ const _skew = getScaledOrderSkew({
6136
6415
  skew,
6137
6416
  distribution_type,
6138
- total_orders: totalOrders
6417
+ total_orders
6139
6418
  });
6419
+ const slope = _skew.minus(1).div(totalOrders - 1);
6140
6420
  for (let i = 0; i < totalOrders; i++) {
6141
- weights[i] = 1 + (skewNum - 1) * i / (totalOrders - 1);
6421
+ weights[i] = new Decimal(1).plus(slope.mul(i));
6142
6422
  }
6143
- const sumWeights = weights.reduce((acc, cur) => acc + cur, 0);
6423
+ const sumWeights = weights.reduce((acc, cur) => acc.plus(cur), zero);
6144
6424
  const minWeight = weights.reduce(
6145
- (min3, current) => current < min3 ? current : min3,
6425
+ (min3, current) => current.lt(min3) ? current : min3,
6146
6426
  weights?.[0]
6147
6427
  );
6148
6428
  return {
@@ -6153,23 +6433,21 @@ function calcScaledOrderWeights(inputs) {
6153
6433
  }
6154
6434
  function calcScaledOrderQtys(inputs) {
6155
6435
  const {
6156
- order_quantity = 0,
6157
- total_orders = 0,
6436
+ order_quantity,
6437
+ total_orders,
6158
6438
  distribution_type,
6159
6439
  skew,
6160
6440
  base_dp,
6161
6441
  base_tick
6162
6442
  } = inputs;
6163
6443
  const qtys = [];
6164
- if (!order_quantity || !total_orders) {
6165
- return [];
6166
- }
6444
+ const totalOrders = Number(total_orders);
6167
6445
  const { weights, sumWeights } = calcScaledOrderWeights({
6168
6446
  total_orders,
6169
6447
  distribution_type,
6170
6448
  skew
6171
6449
  });
6172
- for (let i = 0; i < total_orders; i++) {
6450
+ for (let i = 0; i < totalOrders; i++) {
6173
6451
  let qty = new Decimal(order_quantity).mul(weights[i]).div(sumWeights);
6174
6452
  if (base_tick > 1) {
6175
6453
  qty = qty.div(base_tick).todp(0, Decimal.ROUND_DOWN).mul(base_tick);
@@ -6181,7 +6459,7 @@ function calcScaledOrderQtys(inputs) {
6181
6459
  return qtys;
6182
6460
  }
6183
6461
  function calcScaledOrderBatchBody(order, symbolInfo) {
6184
- if (!validateScaledOrderInput(order)) {
6462
+ if (isInvalidScaledOrderInput(order)) {
6185
6463
  return [];
6186
6464
  }
6187
6465
  try {
@@ -6190,8 +6468,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
6190
6468
  symbol,
6191
6469
  side,
6192
6470
  order_quantity,
6193
- min_price,
6194
- max_price,
6471
+ start_price,
6472
+ end_price,
6195
6473
  total_orders,
6196
6474
  distribution_type,
6197
6475
  skew,
@@ -6199,13 +6477,12 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
6199
6477
  visible_quantity
6200
6478
  } = order;
6201
6479
  const prices = calcScaledOrderPrices({
6202
- min_price,
6203
- max_price,
6480
+ start_price,
6481
+ end_price,
6204
6482
  total_orders,
6205
6483
  quote_dp
6206
6484
  });
6207
6485
  const qtys = calcScaledOrderQtys({
6208
- side,
6209
6486
  order_quantity,
6210
6487
  total_orders,
6211
6488
  distribution_type,
@@ -6236,8 +6513,8 @@ function calcScaledOrderBatchBody(order, symbolInfo) {
6236
6513
  return [];
6237
6514
  }
6238
6515
  }
6239
- function calcScaledOrderAvgOrderPrice(order, symbolInfo, askAndBid) {
6240
- if (!validateScaledOrderInput(order)) {
6516
+ function calcScaledOrderAvgPrice(order, symbolInfo, askAndBid) {
6517
+ if (isInvalidScaledOrderInput(order)) {
6241
6518
  return null;
6242
6519
  }
6243
6520
  try {
@@ -6254,20 +6531,6 @@ function calcScaledOrderAvgOrderPrice(order, symbolInfo, askAndBid) {
6254
6531
  return null;
6255
6532
  }
6256
6533
  }
6257
- function validateScaledOrderInput(order) {
6258
- const {
6259
- min_price,
6260
- max_price,
6261
- order_quantity,
6262
- total_orders,
6263
- distribution_type,
6264
- skew
6265
- } = order;
6266
- if (!min_price || !max_price || !order_quantity || !total_orders || !distribution_type || distribution_type === DistributionType.CUSTOM && (!skew || skew <= 0 || skew > 100) || total_orders < 2 || total_orders > 20) {
6267
- return false;
6268
- }
6269
- return true;
6270
- }
6271
6534
  function calcScaledOrderMinTotalAmount(order, symbolInfo, askAndBid) {
6272
6535
  try {
6273
6536
  const minTotalAmount_baseMin = calcScaledOrderMinTotalAmountByBaseMin(
@@ -6292,7 +6555,7 @@ function calcScaledOrderMinTotalAmountByBaseMin(order, symbolInfo) {
6292
6555
  distribution_type,
6293
6556
  skew
6294
6557
  });
6295
- const minTotalAmount = new Decimal(base_min).mul(new Decimal(sumWeights).div(minWeight)).todp(base_dp, Decimal.ROUND_UP).toNumber();
6558
+ const minTotalAmount = new Decimal(base_min).mul(sumWeights.div(minWeight)).todp(base_dp, Decimal.ROUND_UP).toNumber();
6296
6559
  return minTotalAmount;
6297
6560
  }
6298
6561
  function calcScaledOrderMinTotalAmountByMinNotional(order, symbolInfo, askAndBid) {
@@ -6314,6 +6577,25 @@ function calcScaledOrderMinTotalAmountByMinNotional(order, symbolInfo, askAndBid
6314
6577
  );
6315
6578
  return max_minQty.todp(base_dp, Decimal.ROUND_UP).toNumber();
6316
6579
  }
6580
+ function isInvalidSkew(skew, distribution_type) {
6581
+ const skewNum = Number(skew);
6582
+ return !distribution_type || distribution_type === DistributionType.CUSTOM && (!skew || skewNum <= 0 || skewNum > 100);
6583
+ }
6584
+ function isInvalidTotalOrders(total_orders) {
6585
+ const totalOrders = Number(total_orders);
6586
+ return !total_orders || totalOrders < 2 || totalOrders > 20;
6587
+ }
6588
+ function isInvalidScaledOrderInput(order) {
6589
+ const {
6590
+ start_price,
6591
+ end_price,
6592
+ order_quantity,
6593
+ total_orders,
6594
+ distribution_type,
6595
+ skew
6596
+ } = order;
6597
+ return !start_price || !end_price || !order_quantity || isInvalidTotalOrders(total_orders) || isInvalidSkew(skew, distribution_type);
6598
+ }
6317
6599
 
6318
6600
  // src/services/orderCreator/scaledOrderCreator.ts
6319
6601
  var ScaledOrderCreator = class extends BaseOrderCreator {
@@ -6347,64 +6629,11 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
6347
6629
  order
6348
6630
  );
6349
6631
  }
6350
- validatePrice(values2, config) {
6351
- const errors = {};
6352
- const { side, min_price, max_price } = values2;
6353
- const { price_range, price_scope, quote_max, quote_min, quote_dp } = config.symbol;
6354
- const maxPriceNumber = order.maxPrice(config.markPrice, price_range);
6355
- const minPriceNumber = order.minPrice(config.markPrice, price_range);
6356
- const scopePriceNumber = order.scopePrice(
6357
- config.markPrice,
6358
- price_scope,
6359
- side
6360
- );
6361
- const priceRange = side === OrderSide.BUY ? {
6362
- min: scopePriceNumber,
6363
- max: maxPriceNumber
6364
- } : {
6365
- min: minPriceNumber,
6366
- max: scopePriceNumber
6367
- };
6368
- const minPrice3 = Number(min_price || 0);
6369
- const maxPrice3 = Number(max_price || 0);
6370
- if (!min_price) {
6371
- errors.min_price = OrderValidation.required("min_price");
6372
- } else {
6373
- if (minPrice3 < priceRange?.min) {
6374
- errors.min_price = OrderValidation.min(
6375
- "min_price",
6376
- new Decimal(priceRange.min).todp(quote_dp).toString()
6377
- );
6378
- } else if (minPrice3 < quote_min) {
6379
- errors.min_price = OrderValidation.min("min_price", quote_min);
6380
- } else if (minPrice3 > maxPrice3) {
6381
- errors.min_price = OrderValidation.max("min_price", max_price);
6382
- }
6383
- }
6384
- if (!max_price) {
6385
- errors.max_price = OrderValidation.required("max_price");
6386
- } else {
6387
- if (maxPrice3 < priceRange?.min) {
6388
- errors.max_price = OrderValidation.min(
6389
- "max_price",
6390
- new Decimal(priceRange.min).todp(quote_dp).toString()
6391
- );
6392
- } else if (maxPrice3 > priceRange?.max) {
6393
- errors.max_price = OrderValidation.max(
6394
- "max_price",
6395
- new Decimal(priceRange.max).todp(quote_dp).toString()
6396
- );
6397
- } else if (maxPrice3 > quote_max) {
6398
- errors.max_price = OrderValidation.max("max_price", quote_max);
6399
- }
6400
- }
6401
- return errors;
6402
- }
6403
6632
  async validate(values2, config) {
6404
- const { base_dp } = config.symbol;
6405
- const { maxQty, askAndBid } = config;
6406
- const { order_quantity, total_orders, distribution_type, skew } = values2;
6407
- const errors = this.validatePrice(values2, config);
6633
+ const { maxQty, askAndBid, markPrice, symbol } = config;
6634
+ const { base_dp, quote_dp } = config.symbol;
6635
+ const { order_quantity, total, total_orders, distribution_type, skew } = values2;
6636
+ const errors = validatePrice(values2, config);
6408
6637
  if (!total_orders) {
6409
6638
  errors.total_orders = OrderValidation.required("total_orders");
6410
6639
  } else {
@@ -6434,10 +6663,14 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
6434
6663
  "order_quantity",
6435
6664
  new Decimal(maxQty).todp(base_dp).toString()
6436
6665
  );
6666
+ errors.total = OrderValidation.max(
6667
+ "total",
6668
+ new Decimal(maxQty).mul(markPrice).todp(quote_dp).toString()
6669
+ );
6437
6670
  } else if (!errors.skew && !errors.total_orders) {
6438
6671
  const minTotalAmount = calcScaledOrderMinTotalAmount(
6439
6672
  values2,
6440
- config.symbol,
6673
+ symbol,
6441
6674
  askAndBid
6442
6675
  );
6443
6676
  if (minTotalAmount && qty.lt(minTotalAmount)) {
@@ -6445,12 +6678,49 @@ var ScaledOrderCreator = class extends BaseOrderCreator {
6445
6678
  "order_quantity",
6446
6679
  minTotalAmount
6447
6680
  );
6681
+ errors.total = OrderValidation.min(
6682
+ "total",
6683
+ new Decimal(minTotalAmount).mul(markPrice).todp(quote_dp).toString()
6684
+ );
6448
6685
  }
6449
6686
  }
6450
6687
  }
6688
+ if (!total) {
6689
+ errors.total = OrderValidation.required("total");
6690
+ }
6451
6691
  return errors;
6452
6692
  }
6453
6693
  };
6694
+ function validatePrice(values2, config) {
6695
+ const errors = {};
6696
+ const { start_price, end_price } = values2;
6697
+ const { quote_dp } = config.symbol;
6698
+ if (!config.markPrice) {
6699
+ return errors;
6700
+ }
6701
+ const { minPrice: minPrice3, maxPrice: maxPrice3 } = getPriceRange({
6702
+ side: values2.side,
6703
+ basePrice: config.markPrice,
6704
+ symbolInfo: config.symbol
6705
+ });
6706
+ const comparePrice = (key, value) => {
6707
+ const price = new Decimal(value || 0);
6708
+ if (price.lt(minPrice3)) {
6709
+ errors[key] = OrderValidation.min(
6710
+ key,
6711
+ new Decimal(minPrice3).todp(quote_dp).toString()
6712
+ );
6713
+ } else if (price.gt(maxPrice3)) {
6714
+ errors[key] = OrderValidation.max(
6715
+ key,
6716
+ new Decimal(maxPrice3).todp(quote_dp).toString()
6717
+ );
6718
+ }
6719
+ };
6720
+ comparePrice("start_price", start_price);
6721
+ comparePrice("end_price", end_price);
6722
+ return errors;
6723
+ }
6454
6724
  var { maxPrice: maxPrice2, minPrice: minPrice2, scopePrice: scopePrice2 } = order;
6455
6725
  var StopLimitOrderCreator = class extends BaseOrderCreator {
6456
6726
  constructor() {
@@ -6587,6 +6857,9 @@ var StopMarketOrderCreator = class extends BaseOrderCreator {
6587
6857
  });
6588
6858
  }
6589
6859
  };
6860
+ var formatPrice2 = (price, quote_dp) => {
6861
+ return new Decimal(price).toDecimalPlaces(quote_dp).toNumber();
6862
+ };
6590
6863
  var BaseAlgoOrderCreator = class {
6591
6864
  /**
6592
6865
  * base validate
@@ -6594,7 +6867,17 @@ var BaseAlgoOrderCreator = class {
6594
6867
  validate(values2, config) {
6595
6868
  const result = /* @__PURE__ */ Object.create(null);
6596
6869
  return Promise.resolve().then(() => {
6597
- const { tp_trigger_price, sl_trigger_price, side } = values2;
6870
+ const {
6871
+ tp_trigger_price,
6872
+ sl_trigger_price,
6873
+ side,
6874
+ tp_enable,
6875
+ sl_enable,
6876
+ tp_order_type,
6877
+ sl_order_type,
6878
+ tp_order_price,
6879
+ sl_order_price
6880
+ } = values2;
6598
6881
  const qty = Number(values2.quantity);
6599
6882
  const maxQty = config.maxQty;
6600
6883
  const orderType = values2.order_type;
@@ -6618,77 +6901,166 @@ var BaseAlgoOrderCreator = class {
6618
6901
  if (Number(sl_trigger_price) < 0) {
6619
6902
  result.sl_trigger_price = OrderValidation.min("sl_trigger_price", 0);
6620
6903
  }
6904
+ if (tp_enable && !tp_trigger_price) {
6905
+ result.tp_trigger_price = OrderValidation.required("tp_trigger_price");
6906
+ }
6907
+ if (sl_enable && !sl_trigger_price) {
6908
+ result.sl_trigger_price = OrderValidation.required("sl_trigger_price");
6909
+ }
6910
+ if (tp_order_type === OrderType.LIMIT && !tp_order_price) {
6911
+ result.tp_order_price = OrderValidation.required("tp_order_price");
6912
+ }
6913
+ if (sl_order_type === OrderType.LIMIT && !sl_order_price) {
6914
+ result.sl_order_price = OrderValidation.required("sl_order_price");
6915
+ }
6621
6916
  const mark_price = orderType === OrderType.MARKET || orderType == null ? config.markPrice : values2.order_price ? Number(values2.order_price) : void 0;
6917
+ const tpslSide = side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
6622
6918
  if (side === OrderSide.BUY && mark_price) {
6623
- const slTriggerPriceScope = new Decimal(mark_price * (1 - price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
6624
- if (!!sl_trigger_price && Number(sl_trigger_price) < slTriggerPriceScope) {
6919
+ if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
6625
6920
  result.sl_trigger_price = OrderValidation.min(
6626
6921
  "sl_trigger_price",
6627
- slTriggerPriceScope
6922
+ formatPrice2(quote_min, quote_dp)
6628
6923
  );
6629
6924
  }
6630
- if (!!sl_trigger_price && Number(sl_trigger_price) > config.markPrice) {
6925
+ if (!!sl_trigger_price && Number(sl_trigger_price) > mark_price) {
6631
6926
  result.sl_trigger_price = OrderValidation.max(
6632
6927
  "sl_trigger_price",
6633
- config.markPrice
6928
+ formatPrice2(mark_price, quote_dp)
6634
6929
  );
6635
6930
  }
6636
- if (!!tp_trigger_price && Number(tp_trigger_price) <= config.markPrice) {
6931
+ if (!!tp_trigger_price && Number(tp_trigger_price) <= mark_price) {
6637
6932
  result.tp_trigger_price = OrderValidation.min(
6638
6933
  "tp_trigger_price",
6639
- config.markPrice
6934
+ formatPrice2(mark_price, quote_dp)
6640
6935
  );
6641
6936
  }
6642
6937
  if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
6643
6938
  result.tp_trigger_price = OrderValidation.max(
6644
6939
  "tp_trigger_price",
6645
- quote_max
6940
+ formatPrice2(quote_max, quote_dp)
6646
6941
  );
6647
6942
  }
6648
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
6649
- result.sl_trigger_price = OrderValidation.min(
6650
- "sl_trigger_price",
6651
- quote_min
6652
- );
6943
+ if (sl_trigger_price && sl_order_price) {
6944
+ const slOrderPriceRange = getPriceRange({
6945
+ side: tpslSide,
6946
+ basePrice: Number(sl_trigger_price),
6947
+ symbolInfo: config.symbol
6948
+ });
6949
+ if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
6950
+ result.sl_order_price = OrderValidation.min(
6951
+ "sl_order_price",
6952
+ formatPrice2(slOrderPriceRange.minPrice, quote_dp)
6953
+ );
6954
+ }
6955
+ if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
6956
+ result.sl_order_price = OrderValidation.max(
6957
+ "sl_order_price",
6958
+ formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
6959
+ );
6960
+ }
6961
+ if (Number(sl_trigger_price) < Number(sl_order_price)) {
6962
+ result.sl_trigger_price = OrderValidation.priceErrorMax("sl_trigger_price");
6963
+ }
6964
+ }
6965
+ if (tp_trigger_price && tp_order_price) {
6966
+ const tpOrderPriceRange = getPriceRange({
6967
+ side: tpslSide,
6968
+ basePrice: Number(tp_trigger_price),
6969
+ symbolInfo: config.symbol
6970
+ });
6971
+ if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
6972
+ result.tp_order_price = OrderValidation.max(
6973
+ "tp_order_price",
6974
+ formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
6975
+ );
6976
+ }
6977
+ if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
6978
+ result.tp_order_price = OrderValidation.min(
6979
+ "tp_order_price",
6980
+ formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
6981
+ );
6982
+ }
6983
+ if (Number(tp_trigger_price) > Number(tp_order_price)) {
6984
+ result.tp_trigger_price = OrderValidation.priceErrorMin("tp_trigger_price");
6985
+ }
6653
6986
  }
6654
6987
  }
6655
6988
  if (side === OrderSide.SELL && mark_price) {
6656
- const slTriggerPriceScope = new Decimal(mark_price * (1 + price_scope)).toDecimalPlaces(quote_dp, Decimal.ROUND_DOWN).toNumber();
6657
- if (!!sl_trigger_price && Number(sl_trigger_price) > slTriggerPriceScope) {
6989
+ if (!!sl_trigger_price && Number(sl_trigger_price) > quote_max) {
6658
6990
  result.sl_trigger_price = OrderValidation.max(
6659
6991
  "sl_trigger_price",
6660
- slTriggerPriceScope
6992
+ formatPrice2(quote_max, quote_dp)
6661
6993
  );
6662
6994
  }
6663
- if (!!sl_trigger_price && Number(sl_trigger_price) < config.markPrice) {
6995
+ if (!!sl_trigger_price && Number(sl_trigger_price) < mark_price) {
6664
6996
  result.sl_trigger_price = OrderValidation.min(
6665
6997
  "sl_trigger_price",
6666
- config.markPrice
6998
+ formatPrice2(mark_price, quote_dp)
6667
6999
  );
6668
7000
  }
6669
- if (!!tp_trigger_price && Number(tp_trigger_price) >= config.markPrice) {
7001
+ if (!!tp_trigger_price && Number(tp_trigger_price) >= mark_price) {
6670
7002
  result.tp_trigger_price = OrderValidation.max(
6671
7003
  "tp_trigger_price",
6672
- config.markPrice
7004
+ formatPrice2(mark_price, quote_dp)
6673
7005
  );
6674
7006
  }
6675
- if (!!tp_trigger_price && Number(tp_trigger_price) > quote_max) {
6676
- result.tp_trigger_price = OrderValidation.max(
7007
+ if (!!tp_trigger_price && Number(tp_trigger_price) < quote_min) {
7008
+ result.tp_trigger_price = OrderValidation.min(
6677
7009
  "tp_trigger_price",
6678
- quote_max
7010
+ formatPrice2(quote_min, quote_dp)
6679
7011
  );
6680
7012
  }
6681
- if (!!sl_trigger_price && Number(sl_trigger_price) < quote_min) {
6682
- result.sl_trigger_price = OrderValidation.min(
6683
- "sl_trigger_price",
6684
- quote_min
6685
- );
7013
+ if (sl_trigger_price && sl_order_price) {
7014
+ const slOrderPriceRange = getPriceRange({
7015
+ side: tpslSide,
7016
+ basePrice: Number(sl_trigger_price),
7017
+ symbolInfo: config.symbol
7018
+ });
7019
+ if (Number(sl_order_price) < slOrderPriceRange.minPrice) {
7020
+ result.sl_order_price = OrderValidation.min(
7021
+ "sl_order_price",
7022
+ formatPrice2(slOrderPriceRange.minPrice, quote_dp)
7023
+ );
7024
+ }
7025
+ if (Number(sl_order_price) > slOrderPriceRange.maxPrice) {
7026
+ result.sl_order_price = OrderValidation.max(
7027
+ "sl_order_price",
7028
+ formatPrice2(slOrderPriceRange.maxPrice, quote_dp)
7029
+ );
7030
+ }
7031
+ if (Number(sl_trigger_price) > Number(sl_order_price)) {
7032
+ result.sl_trigger_price = OrderValidation.priceErrorMin("sl_trigger_price");
7033
+ }
7034
+ }
7035
+ if (tp_trigger_price && tp_order_price) {
7036
+ const tpOrderPriceRange = getPriceRange({
7037
+ side: tpslSide,
7038
+ basePrice: Number(tp_trigger_price),
7039
+ symbolInfo: config.symbol
7040
+ });
7041
+ if (Number(tp_order_price) < tpOrderPriceRange.minPrice) {
7042
+ result.tp_order_price = OrderValidation.min(
7043
+ "tp_order_price",
7044
+ formatPrice2(tpOrderPriceRange.minPrice, quote_dp)
7045
+ );
7046
+ }
7047
+ if (Number(tp_order_price) > tpOrderPriceRange.maxPrice) {
7048
+ result.tp_order_price = OrderValidation.max(
7049
+ "tp_order_price",
7050
+ formatPrice2(tpOrderPriceRange.maxPrice, quote_dp)
7051
+ );
7052
+ }
7053
+ if (Number(tp_trigger_price) < Number(tp_order_price)) {
7054
+ result.tp_trigger_price = OrderValidation.priceErrorMax("tp_trigger_price");
7055
+ }
6686
7056
  }
6687
7057
  }
6688
7058
  return Object.keys(result).length > 0 ? result : null;
6689
7059
  });
6690
7060
  }
6691
7061
  };
7062
+
7063
+ // src/services/orderCreator/tpslOrderCreator.ts
6692
7064
  var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
6693
7065
  constructor() {
6694
7066
  super(...arguments);
@@ -6697,29 +7069,39 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
6697
7069
  create(values2, config) {
6698
7070
  const side = values2.side === OrderSide.BUY ? OrderSide.SELL : OrderSide.BUY;
6699
7071
  const child_orders = [];
6700
- if (typeof values2.tp_trigger_price !== "undefined") {
7072
+ if (values2.tp_trigger_price) {
6701
7073
  const tp_trigger_price = !!values2.tp_trigger_price ? new Decimal(values2.tp_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.tp_trigger_price;
6702
- child_orders.push({
7074
+ const orderItem = {
6703
7075
  algo_type: AlgoOrderType.TAKE_PROFIT,
6704
7076
  reduce_only: true,
6705
7077
  side,
6706
7078
  type: OrderType.MARKET,
6707
- trigger_price: tp_trigger_price,
7079
+ trigger_price: new Decimal(tp_trigger_price).toNumber(),
6708
7080
  symbol: values2.symbol,
6709
7081
  is_activated: !!values2.tp_trigger_price
6710
- });
7082
+ };
7083
+ if (values2.tp_order_price) {
7084
+ orderItem.price = new Decimal(values2.tp_order_price).toNumber();
7085
+ orderItem.type = OrderType.LIMIT;
7086
+ }
7087
+ child_orders.push(orderItem);
6711
7088
  }
6712
- if (typeof values2.sl_trigger_price !== "undefined") {
7089
+ if (values2.sl_trigger_price) {
6713
7090
  const sl_trigger_price = !!values2.sl_trigger_price ? new Decimal(values2.sl_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.sl_trigger_price;
6714
- child_orders.push({
7091
+ const orderItem = {
6715
7092
  algo_type: AlgoOrderType.STOP_LOSS,
6716
7093
  reduce_only: true,
6717
7094
  side,
6718
7095
  type: OrderType.MARKET,
6719
- trigger_price: sl_trigger_price,
7096
+ trigger_price: new Decimal(sl_trigger_price).toNumber(),
6720
7097
  symbol: values2.symbol,
6721
7098
  is_activated: !!values2.sl_trigger_price
6722
- });
7099
+ };
7100
+ if (values2.sl_order_price) {
7101
+ orderItem.price = new Decimal(values2.sl_order_price).toNumber();
7102
+ orderItem.type = OrderType.LIMIT;
7103
+ }
7104
+ child_orders.push(orderItem);
6723
7105
  }
6724
7106
  return {
6725
7107
  algo_type: AlgoOrderRootType.TP_SL,
@@ -6735,7 +7117,7 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
6735
7117
  const newData = [];
6736
7118
  const needUpdateQty = values2.quantity !== oldValue.quantity;
6737
7119
  data.child_orders.forEach((order) => {
6738
- let _order = /* @__PURE__ */ Object.create(null);
7120
+ const _order = /* @__PURE__ */ Object.create(null);
6739
7121
  if (needUpdateQty) {
6740
7122
  _order["quantity"] = data.quantity;
6741
7123
  }
@@ -6745,24 +7127,31 @@ var TPSLOrderCreator = class extends BaseAlgoOrderCreator {
6745
7127
  if (oldOrder) {
6746
7128
  if (!order.is_activated) {
6747
7129
  _order["is_activated"] = false;
6748
- } else if (oldOrder.trigger_price !== order.trigger_price) {
6749
- _order["trigger_price"] = order.trigger_price;
6750
- }
6751
- if (Object.keys(_order).length > 0) {
6752
- _order["order_id"] = Number(oldOrder.algo_order_id);
6753
- newData.push(_order);
7130
+ } else {
7131
+ if (oldOrder.trigger_price !== order.trigger_price) {
7132
+ _order["trigger_price"] = order.trigger_price;
7133
+ }
7134
+ if (oldOrder.price !== order.price && order.type === OrderType.LIMIT) {
7135
+ _order["price"] = order.price;
7136
+ }
6754
7137
  }
7138
+ _order["order_id"] = Number(oldOrder.algo_order_id);
7139
+ newData.push(_order);
6755
7140
  }
6756
7141
  });
6757
- if (needUpdateQty && newData.length < 2) {
7142
+ if (newData.length < 2) {
6758
7143
  const missingOrders = oldValue.child_orders.filter(
6759
7144
  (order) => order.algo_order_id !== newData[0].order_id
6760
7145
  );
6761
7146
  if (missingOrders.length) {
6762
- newData.push({
6763
- quantity: Number(data.quantity),
7147
+ const _data = {
7148
+ is_activated: false,
6764
7149
  order_id: missingOrders[0].algo_order_id
6765
- });
7150
+ };
7151
+ if (needUpdateQty) {
7152
+ _data.quantity = Number(data.quantity);
7153
+ }
7154
+ newData.push(_data);
6766
7155
  }
6767
7156
  }
6768
7157
  return [
@@ -6783,32 +7172,42 @@ var TPSLPositionOrderCreator = class extends BaseAlgoOrderCreator {
6783
7172
  const child_orders = [];
6784
7173
  if (typeof values2.tp_trigger_price !== "undefined") {
6785
7174
  const tp_trigger_price = !!values2.tp_trigger_price ? new Decimal(values2.tp_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.tp_trigger_price;
6786
- child_orders.push({
7175
+ const childOrderItem = {
6787
7176
  algo_type: AlgoOrderType.TAKE_PROFIT,
6788
7177
  reduce_only: true,
6789
7178
  side,
6790
- type: OrderType.CLOSE_POSITION,
7179
+ type: values2.tp_order_price ? OrderType.LIMIT : OrderType.CLOSE_POSITION,
6791
7180
  trigger_price: tp_trigger_price,
6792
7181
  trigger_price_type: TriggerPriceType.MARK_PRICE,
6793
7182
  symbol: values2.symbol,
6794
7183
  is_activated: !!values2.tp_trigger_price
6795
- });
7184
+ };
7185
+ if (values2.tp_order_price) {
7186
+ childOrderItem.type = OrderType.LIMIT;
7187
+ childOrderItem.price = new Decimal(values2.tp_order_price).todp(config.symbol.quote_dp).toNumber();
7188
+ }
7189
+ child_orders.push(childOrderItem);
6796
7190
  }
6797
7191
  if (typeof values2.sl_trigger_price !== "undefined") {
6798
7192
  const sl_trigger_price = !!values2.sl_trigger_price ? new Decimal(values2.sl_trigger_price).todp(config.symbol.quote_dp).toNumber() : values2.sl_trigger_price;
6799
- child_orders.push({
7193
+ const childOrderItem = {
6800
7194
  algo_type: AlgoOrderType.STOP_LOSS,
6801
7195
  reduce_only: true,
6802
7196
  side,
6803
- type: OrderType.CLOSE_POSITION,
7197
+ type: values2.sl_order_price ? OrderType.LIMIT : OrderType.CLOSE_POSITION,
6804
7198
  trigger_price: sl_trigger_price,
6805
7199
  trigger_price_type: TriggerPriceType.MARK_PRICE,
6806
7200
  symbol: values2.symbol,
6807
7201
  is_activated: !!values2.sl_trigger_price
6808
- });
7202
+ };
7203
+ if (values2.sl_order_price) {
7204
+ childOrderItem.type = OrderType.LIMIT;
7205
+ childOrderItem.price = new Decimal(values2.sl_order_price).todp(config.symbol.quote_dp).toNumber();
7206
+ }
7207
+ child_orders.push(childOrderItem);
6809
7208
  }
6810
7209
  return {
6811
- algo_type: AlgoOrderRootType.POSITIONAL_TP_SL,
7210
+ algo_type: values2.position_type === PositionType.FULL ? AlgoOrderRootType.POSITIONAL_TP_SL : AlgoOrderRootType.TP_SL,
6812
7211
  trigger_price_type: TriggerPriceType.MARK_PRICE,
6813
7212
  // reduce_only: true,
6814
7213
  symbol: values2.symbol,
@@ -7340,7 +7739,7 @@ function useSubAccountMaxWithdrawal(options) {
7340
7739
  return maxAmount;
7341
7740
  }
7342
7741
  function offsetToPrice(inputs) {
7343
- const { offset, entryPrice, orderType, orderSide } = inputs;
7742
+ const { qty, offset, entryPrice, orderType, orderSide } = inputs;
7344
7743
  if (!offset)
7345
7744
  return;
7346
7745
  if (orderSide === OrderSide.BUY) {
@@ -7378,7 +7777,7 @@ function priceToOffset(inputs, options = {}) {
7378
7777
  return decimal.abs().toNumber();
7379
7778
  }
7380
7779
  function offsetPercentageToPrice(inputs) {
7381
- const { percentage, entryPrice, orderType, orderSide } = inputs;
7780
+ const { qty, percentage, entryPrice, orderType, orderSide } = inputs;
7382
7781
  if (!percentage)
7383
7782
  return;
7384
7783
  if (orderSide === OrderSide.BUY) {
@@ -7458,7 +7857,7 @@ function priceToPnl(inputs, options = {}) {
7458
7857
  );
7459
7858
  }
7460
7859
  if (symbol) {
7461
- return decimal.todp(2, Decimal.ROUND_DOWN).toNumber();
7860
+ return decimal.todp(2, Decimal.ROUND_UP).toNumber();
7462
7861
  }
7463
7862
  return decimal.toNumber();
7464
7863
  }
@@ -7469,78 +7868,153 @@ function calcTPSL_ROI(inputs) {
7469
7868
  return "0";
7470
7869
  return new Decimal(inputs.pnl).div(new Decimal(qtyNum).abs().mul(new Decimal(priceNum))).toString();
7471
7870
  }
7871
+ function checkTPSLOrderTypeIsMarket(key, values2) {
7872
+ const keyPrefix = key.slice(0, 3);
7873
+ const orderTypeKey = `${keyPrefix}order_type`;
7874
+ return values2[orderTypeKey] ? values2[orderTypeKey] === OrderType.MARKET : true;
7875
+ }
7472
7876
  function tpslCalculateHelper(key, inputs, options = {}) {
7473
7877
  const { symbol } = options;
7474
- if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage") {
7878
+ if (key !== "quantity" && key !== "tp_trigger_price" && key !== "sl_trigger_price" && key !== "tp_pnl" && key !== "sl_pnl" && key !== "tp_offset" && key !== "sl_offset" && key !== "tp_offset_percentage" && key !== "sl_offset_percentage" && key !== "tp_order_price" && key !== "sl_order_price" && key !== "tp_order_type" && key !== "sl_order_type" && key !== "tp_enable" && key !== "sl_enable") {
7475
7879
  return {
7476
7880
  [key]: inputs.value
7477
7881
  };
7478
7882
  }
7479
7883
  const orderType = key.startsWith("tp_") ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS;
7480
7884
  const keyPrefix = key.slice(0, 3);
7481
- let qty = Number(key === "quantity" ? inputs.value : inputs.qty);
7885
+ const qty = Number(key === "quantity" ? inputs.value : inputs.qty);
7482
7886
  if (qty === 0 && (key === "tp_pnl" || key === "sl_pnl" || key === "tp_trigger_price" || key === "sl_trigger_price")) {
7483
7887
  return {
7484
- [`${keyPrefix}trigger_price`]: "",
7888
+ // [`${keyPrefix}trigger_price`]: "",
7889
+ // [`${keyPrefix}order_price`]: "",
7485
7890
  // [`${keyPrefix}offset`]: "",
7486
7891
  // [`${keyPrefix}offset_percentage`]: "",
7487
7892
  [`${keyPrefix}pnl`]: "",
7488
7893
  [key]: inputs.value
7489
7894
  };
7490
7895
  }
7491
- let trigger_price, offset, offset_percentage, pnl;
7896
+ let trigger_price, offset, offset_percentage, pnl, order_price, tpsl_order_type = inputs.values[`${keyPrefix}order_type`] ?? OrderType.MARKET;
7492
7897
  const entryPrice = new Decimal(inputs.entryPrice).todp(options.symbol?.quote_dp ?? 2, Decimal.ROUND_UP).toNumber();
7493
7898
  switch (key) {
7494
7899
  case "tp_trigger_price":
7495
7900
  case "sl_trigger_price": {
7496
7901
  trigger_price = inputs.value;
7497
- if (inputs.value === "") {
7498
- return {
7499
- [`${keyPrefix}trigger_price`]: trigger_price,
7500
- [`${keyPrefix}offset`]: "",
7501
- [`${keyPrefix}offset_percentage`]: "",
7502
- [`${keyPrefix}pnl`]: "",
7503
- [`${keyPrefix}ROI`]: ""
7504
- };
7902
+ if (checkTPSLOrderTypeIsMarket(key, inputs.values)) {
7903
+ if (inputs.value === "") {
7904
+ return {
7905
+ [`${keyPrefix}trigger_price`]: trigger_price,
7906
+ [`${keyPrefix}offset`]: "",
7907
+ [`${keyPrefix}offset_percentage`]: "",
7908
+ [`${keyPrefix}pnl`]: "",
7909
+ [`${keyPrefix}ROI`]: ""
7910
+ };
7911
+ }
7912
+ } else {
7913
+ order_price = inputs.values[`${keyPrefix}order_price`] ?? "";
7505
7914
  }
7506
7915
  break;
7507
7916
  }
7917
+ case "tp_enable":
7918
+ case "sl_enable": {
7919
+ return {
7920
+ [`${keyPrefix}enable`]: inputs.value,
7921
+ [`${keyPrefix}order_type`]: OrderType.MARKET,
7922
+ [`${keyPrefix}trigger_price`]: "",
7923
+ [`${keyPrefix}order_price`]: "",
7924
+ [`${keyPrefix}offset`]: "",
7925
+ [`${keyPrefix}offset_percentage`]: "",
7926
+ [`${keyPrefix}pnl`]: "",
7927
+ [`${keyPrefix}ROI`]: ""
7928
+ };
7929
+ }
7508
7930
  case "tp_pnl":
7509
7931
  case "sl_pnl": {
7510
7932
  pnl = inputs.value;
7511
- trigger_price = pnlToPrice({
7512
- qty,
7513
- pnl: Number(inputs.value),
7514
- entryPrice,
7515
- orderSide: inputs.orderSide,
7516
- orderType
7517
- });
7933
+ if (!checkTPSLOrderTypeIsMarket(key, inputs.values)) {
7934
+ order_price = pnlToPrice({
7935
+ qty,
7936
+ pnl: Number(inputs.value),
7937
+ entryPrice,
7938
+ orderSide: inputs.orderSide,
7939
+ orderType
7940
+ });
7941
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? order_price;
7942
+ } else {
7943
+ trigger_price = pnlToPrice({
7944
+ qty,
7945
+ pnl: Number(inputs.value),
7946
+ entryPrice,
7947
+ orderSide: inputs.orderSide,
7948
+ orderType
7949
+ });
7950
+ }
7518
7951
  break;
7519
7952
  }
7520
7953
  case "tp_offset":
7521
7954
  case "sl_offset": {
7522
7955
  offset = inputs.value;
7523
- trigger_price = offsetToPrice({
7524
- offset: Number(inputs.value),
7525
- entryPrice,
7526
- orderSide: inputs.orderSide,
7527
- orderType: key === "tp_offset" ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS
7528
- });
7956
+ if (!checkTPSLOrderTypeIsMarket(key, inputs.values)) {
7957
+ order_price = offsetToPrice({
7958
+ qty,
7959
+ offset: Number(inputs.value),
7960
+ entryPrice,
7961
+ orderSide: inputs.orderSide,
7962
+ orderType: key === "tp_offset" ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS
7963
+ });
7964
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? order_price;
7965
+ } else {
7966
+ trigger_price = offsetToPrice({
7967
+ qty,
7968
+ offset: Number(inputs.value),
7969
+ entryPrice,
7970
+ orderSide: inputs.orderSide,
7971
+ orderType: key === "tp_offset" ? AlgoOrderType.TAKE_PROFIT : AlgoOrderType.STOP_LOSS
7972
+ });
7973
+ }
7974
+ break;
7975
+ }
7976
+ case "tp_order_price":
7977
+ case "sl_order_price": {
7978
+ order_price = inputs.value;
7979
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? order_price;
7980
+ break;
7981
+ }
7982
+ case "tp_order_type":
7983
+ case "sl_order_type": {
7984
+ tpsl_order_type = inputs.value;
7985
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? "";
7986
+ if (tpsl_order_type === OrderType.MARKET) {
7987
+ order_price = "";
7988
+ } else {
7989
+ order_price = trigger_price;
7990
+ }
7529
7991
  break;
7530
7992
  }
7531
7993
  case "tp_offset_percentage":
7532
7994
  case "sl_offset_percentage": {
7533
7995
  offset_percentage = inputs.value;
7534
- trigger_price = offsetPercentageToPrice({
7535
- percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
7536
- entryPrice,
7537
- orderSide: inputs.orderSide,
7538
- orderType
7539
- });
7996
+ if (!checkTPSLOrderTypeIsMarket(key, inputs.values)) {
7997
+ order_price = offsetPercentageToPrice({
7998
+ qty,
7999
+ percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
8000
+ entryPrice,
8001
+ orderSide: inputs.orderSide,
8002
+ orderType
8003
+ });
8004
+ trigger_price = inputs.values[`${keyPrefix}trigger_price`] ?? order_price;
8005
+ } else {
8006
+ trigger_price = offsetPercentageToPrice({
8007
+ qty,
8008
+ percentage: Number(`${inputs.value}`.replace(/\.0{0,2}$/, "")),
8009
+ entryPrice,
8010
+ orderSide: inputs.orderSide,
8011
+ orderType
8012
+ });
8013
+ }
7540
8014
  break;
7541
8015
  }
7542
8016
  }
7543
- if (!trigger_price)
8017
+ if (!trigger_price && checkTPSLOrderTypeIsMarket(key, inputs.values)) {
7544
8018
  return {
7545
8019
  [`${keyPrefix}trigger_price`]: "",
7546
8020
  [`${keyPrefix}offset`]: "",
@@ -7549,36 +8023,47 @@ function tpslCalculateHelper(key, inputs, options = {}) {
7549
8023
  [`${keyPrefix}ROI`]: "",
7550
8024
  [key]: inputs.value
7551
8025
  };
7552
- return {
7553
- [`${keyPrefix}trigger_price`]: todpIfNeed(
7554
- trigger_price,
7555
- symbol?.quote_dp ?? 2
7556
- ),
7557
- [`${keyPrefix}offset`]: offset ?? priceToOffset(
8026
+ }
8027
+ let calcPrice = trigger_price;
8028
+ if (tpsl_order_type && tpsl_order_type === OrderType.LIMIT) {
8029
+ calcPrice = order_price;
8030
+ } else if (!checkTPSLOrderTypeIsMarket(key, inputs.values)) {
8031
+ calcPrice = order_price;
8032
+ }
8033
+ if (calcPrice) {
8034
+ pnl = pnl ?? priceToPnl(
7558
8035
  {
7559
- price: Number(trigger_price),
8036
+ qty,
8037
+ price: Number(calcPrice),
7560
8038
  entryPrice,
7561
8039
  orderSide: inputs.orderSide,
7562
8040
  orderType
7563
8041
  },
7564
8042
  options
7565
- ),
7566
- [`${keyPrefix}offset_percentage`]: offset_percentage ?? priceToOffsetPercentage({
7567
- price: Number(trigger_price),
7568
- entryPrice,
7569
- orderSide: inputs.orderSide,
7570
- orderType
7571
- }),
7572
- [`${keyPrefix}pnl`]: pnl ?? priceToPnl(
8043
+ );
8044
+ offset = offset ?? priceToOffset(
7573
8045
  {
7574
- qty,
7575
- price: Number(trigger_price),
8046
+ price: Number(calcPrice),
7576
8047
  entryPrice,
7577
8048
  orderSide: inputs.orderSide,
7578
8049
  orderType
7579
8050
  },
7580
8051
  options
7581
- )
8052
+ );
8053
+ offset_percentage = offset_percentage ?? priceToOffsetPercentage({
8054
+ price: Number(calcPrice),
8055
+ entryPrice,
8056
+ orderSide: inputs.orderSide,
8057
+ orderType
8058
+ });
8059
+ }
8060
+ return {
8061
+ [`${keyPrefix}trigger_price`]: trigger_price ? todpIfNeed(trigger_price, symbol?.quote_dp ?? 2) : "",
8062
+ [`${keyPrefix}order_type`]: tpsl_order_type ?? OrderType.MARKET,
8063
+ [`${keyPrefix}order_price`]: order_price ? todpIfNeed(order_price, symbol?.quote_dp ?? 2) : "",
8064
+ [`${keyPrefix}offset`]: offset ?? "",
8065
+ [`${keyPrefix}offset_percentage`]: offset_percentage ?? "",
8066
+ [`${keyPrefix}pnl`]: pnl ?? ""
7582
8067
  // [`${keyPrefix}ROI`]: calcROI({
7583
8068
  // pnl: Number(pnl ?? 0),
7584
8069
  // qty,
@@ -7588,16 +8073,45 @@ function tpslCalculateHelper(key, inputs, options = {}) {
7588
8073
  }
7589
8074
 
7590
8075
  // src/orderly/useTakeProfitAndStopLoss/useTPSL.ts
8076
+ var checkIsEnableTpSL = (order) => {
8077
+ const result = {
8078
+ tp_enable: true,
8079
+ sl_enable: true
8080
+ };
8081
+ if (!order) {
8082
+ return result;
8083
+ }
8084
+ const tp = order.child_orders.find(
8085
+ (o) => o.algo_type === AlgoOrderType.TAKE_PROFIT && o.is_activated
8086
+ );
8087
+ const sl = order.child_orders.find(
8088
+ (o) => o.algo_type === AlgoOrderType.STOP_LOSS && o.is_activated
8089
+ );
8090
+ if (!tp) {
8091
+ result.tp_enable = false;
8092
+ }
8093
+ if (!sl) {
8094
+ result.sl_enable = false;
8095
+ }
8096
+ return result;
8097
+ };
7591
8098
  var useTaskProfitAndStopLossInternal = (position, options) => {
7592
8099
  const isEditing = typeof options?.isEditing !== "undefined" ? options.isEditing : !!options?.defaultOrder;
7593
8100
  const [order, setOrder] = useState({
7594
8101
  algo_order_id: options?.defaultOrder?.algo_order_id,
7595
8102
  symbol: position.symbol,
7596
8103
  side: Number(position.position_qty) > 0 ? OrderSide.BUY : OrderSide.SELL,
7597
- quantity: isEditing ? options?.defaultOrder?.quantity === 0 ? Math.abs(position.position_qty) : options?.defaultOrder?.quantity : "",
8104
+ quantity: isEditing ? options?.defaultOrder?.quantity === 0 ? Math.abs(position.position_qty) : options?.defaultOrder?.quantity : options?.positionType === PositionType.FULL ? Math.abs(position.position_qty) : 0,
8105
+ // quantity:
8106
+ // options?.positionType === PositionType.PARTIAL
8107
+ // ? 0
8108
+ // : Math.abs(position.position_qty),
7598
8109
  // quantity:
7599
8110
  // options?.defaultOrder?.quantity || Math.abs(position.position_qty),
7600
- algo_type: options?.defaultOrder?.algo_type
8111
+ algo_type: options?.defaultOrder?.algo_type,
8112
+ tp_enable: isEditing ? checkIsEnableTpSL(options?.defaultOrder).tp_enable : options?.tpslEnable?.tp_enable,
8113
+ sl_enable: isEditing ? checkIsEnableTpSL(options?.defaultOrder).sl_enable : options?.tpslEnable?.sl_enable,
8114
+ position_type: options?.positionType
7601
8115
  });
7602
8116
  const symbolInfo = useSymbolsInfo()[position.symbol]();
7603
8117
  const { data: markPrice } = useMarkPrice(order.symbol);
@@ -7609,16 +8123,23 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
7609
8123
  if (!isEditing || !options?.defaultOrder)
7610
8124
  return;
7611
8125
  const trigger_prices = findTPSLFromOrder(options.defaultOrder);
8126
+ const order2 = {};
7612
8127
  if (trigger_prices.tp_trigger_price) {
7613
- setOrderValue("tp_trigger_price", trigger_prices.tp_trigger_price, {
7614
- ignoreValidate: true
7615
- });
8128
+ order2.tp_trigger_price = trigger_prices.tp_trigger_price;
7616
8129
  }
7617
8130
  if (trigger_prices.sl_trigger_price) {
7618
- setOrderValue("sl_trigger_price", trigger_prices.sl_trigger_price, {
7619
- ignoreValidate: true
7620
- });
8131
+ order2.sl_trigger_price = trigger_prices.sl_trigger_price;
8132
+ }
8133
+ const order_prices = findTPSLOrderPriceFromOrder(options.defaultOrder);
8134
+ if (order_prices.tp_order_price && order_prices.tp_order_price !== OrderType.MARKET) {
8135
+ order2.tp_order_type = OrderType.LIMIT;
8136
+ order2.tp_order_price = order_prices.tp_order_price;
7621
8137
  }
8138
+ if (order_prices.sl_order_price && order_prices.sl_order_price !== OrderType.MARKET) {
8139
+ order2.sl_order_type = OrderType.LIMIT;
8140
+ order2.sl_order_price = order_prices.sl_order_price;
8141
+ }
8142
+ setValues(order2);
7622
8143
  }, []);
7623
8144
  const _setOrderValue = (key, value, options2) => {
7624
8145
  setOrder((prev) => {
@@ -7629,7 +8150,8 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
7629
8150
  value,
7630
8151
  entryPrice: position.average_open_price,
7631
8152
  qty: side === OrderSide.BUY ? Number(prev.quantity) : -Number(prev.quantity),
7632
- orderSide: side
8153
+ orderSide: side,
8154
+ values: prev
7633
8155
  },
7634
8156
  {
7635
8157
  symbol: symbolInfo
@@ -7650,11 +8172,21 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
7650
8172
  ignoreValidate: true
7651
8173
  });
7652
8174
  }
8175
+ if (typeof order.sl_order_price !== "undefined") {
8176
+ _setOrderValue("sl_order_price", order.sl_order_price, {
8177
+ ignoreValidate: true
8178
+ });
8179
+ }
7653
8180
  if (typeof order.tp_trigger_price !== "undefined") {
7654
8181
  _setOrderValue("tp_trigger_price", order.tp_trigger_price, {
7655
8182
  ignoreValidate: true
7656
8183
  });
7657
8184
  }
8185
+ if (typeof order.tp_order_price !== "undefined") {
8186
+ _setOrderValue("tp_order_price", order.tp_order_price, {
8187
+ ignoreValidate: true
8188
+ });
8189
+ }
7658
8190
  _setOrderValue(key, value, options2);
7659
8191
  return;
7660
8192
  }
@@ -7669,6 +8201,9 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
7669
8201
  requestAnimationFrame(() => {
7670
8202
  if (order.ignoreValidate)
7671
8203
  return;
8204
+ if (!order.quantity) {
8205
+ return;
8206
+ }
7672
8207
  const orderCreator = getOrderCreator2();
7673
8208
  orderCreator.validate(order, valueConfig).then((errors2) => {
7674
8209
  setErrors(errors2);
@@ -7715,7 +8250,7 @@ var useTaskProfitAndStopLossInternal = (position, options) => {
7715
8250
  return OrderFactory.create(AlgoOrderRootType.TP_SL);
7716
8251
  }
7717
8252
  return OrderFactory.create(
7718
- compare() ? AlgoOrderRootType.POSITIONAL_TP_SL : AlgoOrderRootType.TP_SL
8253
+ options?.positionType === PositionType.FULL ? AlgoOrderRootType.POSITIONAL_TP_SL : AlgoOrderRootType.TP_SL
7719
8254
  );
7720
8255
  };
7721
8256
  const submit = async (params) => {
@@ -7953,7 +8488,7 @@ var useStatisticsDaily = (params, options) => {
7953
8488
  return { vol: vol.toNumber(), pnl: pnl.toNumber(), roi: roi.toNumber() };
7954
8489
  }, [data]);
7955
8490
  return [
7956
- data || [],
8491
+ data || EMPTY_LIST,
7957
8492
  {
7958
8493
  aggregateValue
7959
8494
  }
@@ -8043,7 +8578,7 @@ var useDistributionHistory = (parmas) => {
8043
8578
  var useTransferHistory = (parmas) => {
8044
8579
  const { dataRange, page, size, side, fromId, toId, main_sub_only } = parmas;
8045
8580
  const infos = useSymbolsInfo();
8046
- const memoizedQueryKey = React.useMemo(() => {
8581
+ const memoizedQueryKey = React2.useMemo(() => {
8047
8582
  const search = new URLSearchParams();
8048
8583
  search.set("page", page.toString());
8049
8584
  search.set("size", size.toString());
@@ -8066,7 +8601,7 @@ var useTransferHistory = (parmas) => {
8066
8601
  errorRetryCount: 3
8067
8602
  }
8068
8603
  );
8069
- const parsedData = React.useMemo(() => {
8604
+ const parsedData = React2.useMemo(() => {
8070
8605
  if (!Array.isArray(data?.rows) || !data?.rows.length || infos.isNil) {
8071
8606
  return [];
8072
8607
  }
@@ -8385,6 +8920,12 @@ var useMarketStore = create(
8385
8920
  }
8386
8921
  })
8387
8922
  );
8923
+ var useMarketList = () => {
8924
+ return useMarketStore((state) => state.market);
8925
+ };
8926
+ var useMarketMap = () => {
8927
+ return useMarketStore((state) => state.marketMap);
8928
+ };
8388
8929
 
8389
8930
  // src/orderly/usePublicDataObserver.ts
8390
8931
  var publicQueryOptions = {
@@ -8398,7 +8939,7 @@ var usePublicDataObserver = () => {
8398
8939
  );
8399
8940
  const { updateMarket } = useMarketStore((state) => state.actions);
8400
8941
  const setTokensInfo = useTokensInfoStore((state) => state.setTokensInfo);
8401
- const { dataAdapter } = useContext(OrderlyContext);
8942
+ const { dataAdapter } = useOrderlyContext();
8402
8943
  const resolveList = typeof dataAdapter?.symbolList === "function" ? dataAdapter.symbolList : (oriVal) => oriVal;
8403
8944
  useQuery(`/v1/public/info`, {
8404
8945
  ...publicQueryOptions,
@@ -8480,10 +9021,6 @@ function getEstFundingRate(data) {
8480
9021
  }
8481
9022
  return est_funding_rate;
8482
9023
  }
8483
- var DataCenterContext = createContext(
8484
- {}
8485
- );
8486
- var useDataCenterContext = () => useContext(DataCenterContext);
8487
9024
  var DataCenterProvider = ({
8488
9025
  children
8489
9026
  }) => {
@@ -8497,94 +9034,26 @@ var DataCenterProvider = ({
8497
9034
  return getKeyHandlerMapRef.current;
8498
9035
  }
8499
9036
  });
9037
+ const memoizedValue = useMemo(() => {
9038
+ return {
9039
+ registerKeyHandler: (key, fun) => {
9040
+ getKeyHandlerMapRef.current.set(key, fun);
9041
+ },
9042
+ unregisterKeyHandler: (key) => {
9043
+ getKeyHandlerMapRef.current.delete(key);
9044
+ }
9045
+ };
9046
+ }, [getKeyHandlerMapRef.current]);
8500
9047
  if (error) {
8501
9048
  return /* @__PURE__ */ jsx("div", { children: "Data load failed" });
8502
9049
  }
8503
9050
  if (!done) {
8504
9051
  return null;
8505
9052
  }
8506
- return /* @__PURE__ */ jsx(
8507
- DataCenterContext.Provider,
8508
- {
8509
- value: {
8510
- registerKeyHandler: (key, fun) => {
8511
- getKeyHandlerMapRef.current.set(key, fun);
8512
- },
8513
- unregisterKeyHandler: (key) => {
8514
- getKeyHandlerMapRef.current.delete(key);
8515
- }
8516
- },
8517
- children
8518
- }
8519
- );
8520
- };
8521
- var ProxyConfigStore = class {
8522
- constructor(_originConfigStore) {
8523
- this._originConfigStore = _originConfigStore;
8524
- windowGuard(() => {
8525
- this._proxyConfigStore = window.__ORDERLY_CONFIG_STORE__ || _originConfigStore;
8526
- });
8527
- }
8528
- get(key) {
8529
- const value = this._proxyConfigStore?.get(key);
8530
- if (typeof value === "undefined") {
8531
- return this._originConfigStore.get(key);
8532
- }
8533
- return value;
8534
- }
8535
- getOr(key, defaultValue) {
8536
- return (this._proxyConfigStore ?? this._originConfigStore).getOr(
8537
- key,
8538
- defaultValue
8539
- );
8540
- }
8541
- set(key, value) {
8542
- (this._proxyConfigStore ?? this._originConfigStore).set(key, value);
8543
- }
8544
- clear() {
8545
- throw new SDKError("Method not implemented.");
8546
- }
8547
- getFromOrigin(key) {
8548
- return this._originConfigStore.get(key);
8549
- }
8550
- getOrFromOrigin(key, defaultValue) {
8551
- return this._originConfigStore.getOr(key, defaultValue);
8552
- }
8553
- setToOrigin(key, value) {
8554
- this._originConfigStore.set(key, value);
8555
- }
8556
- clearOrigin() {
8557
- this._originConfigStore.clear();
8558
- }
8559
- };
8560
- var ExtendedConfigStore = class extends DefaultConfigStore {
8561
- constructor(init2) {
8562
- super(init2);
8563
- }
8564
- get(key) {
8565
- if (key === MarketsStorageKey) {
8566
- const jsonStr = localStorage.getItem(MarketsStorageKey);
8567
- if (!jsonStr) {
8568
- const oldJsonStr = localStorage.getItem(
8569
- MarketsStorageKey.replace("orderly_", "")
8570
- );
8571
- return oldJsonStr ? JSON.parse(oldJsonStr) : "";
8572
- }
8573
- return JSON.parse(jsonStr);
8574
- }
8575
- return super.get(key);
8576
- }
8577
- set(key, value) {
8578
- if (key === MarketsStorageKey) {
8579
- const jsonStr = JSON.stringify(value);
8580
- localStorage.setItem(MarketsStorageKey, jsonStr);
8581
- return;
8582
- }
8583
- super.set(key, value);
8584
- }
9053
+ return /* @__PURE__ */ jsx(DataCenterContext.Provider, { value: memoizedValue, children });
8585
9054
  };
8586
9055
  var OrderlyConfigProvider = (props) => {
8587
- const [account9, setAccount] = React.useState(null);
9056
+ const [account9, setAccount] = React2.useState(null);
8588
9057
  const {
8589
9058
  configStore,
8590
9059
  keyStore,
@@ -8598,7 +9067,8 @@ var OrderlyConfigProvider = (props) => {
8598
9067
  customChains,
8599
9068
  enableSwapDeposit = false,
8600
9069
  chainTransformer,
8601
- dataAdapter
9070
+ dataAdapter,
9071
+ notification
8602
9072
  } = props;
8603
9073
  if (typeof configStore !== "undefined" && !configStore.get("brokerId")) {
8604
9074
  throw new SDKError(
@@ -8660,7 +9130,8 @@ var OrderlyConfigProvider = (props) => {
8660
9130
  enableSwapDeposit,
8661
9131
  defaultOrderbookTickSizes,
8662
9132
  chainTransformer,
8663
- dataAdapter
9133
+ dataAdapter,
9134
+ notification
8664
9135
  };
8665
9136
  }, [
8666
9137
  innerConfigStore,
@@ -8672,6 +9143,7 @@ var OrderlyConfigProvider = (props) => {
8672
9143
  enableSwapDeposit,
8673
9144
  defaultOrderbookTickSizes,
8674
9145
  dataAdapter,
9146
+ notification,
8675
9147
  chainTransformer
8676
9148
  ]);
8677
9149
  if (!account9) {
@@ -8724,7 +9196,6 @@ function orderTypeHandle(inputs) {
8724
9196
  if (value === OrderType.MARKET || value === OrderType.LIMIT) {
8725
9197
  values2.trigger_price = void 0;
8726
9198
  }
8727
- if (value === OrderType.MARKET || value === OrderType.STOP_MARKET) ;
8728
9199
  return [values2, input, value, markPrice, config];
8729
9200
  }
8730
9201
  function orderEntityFormatHandle(baseTick, quoteTick) {
@@ -8785,8 +9256,7 @@ function quantityInputHandle(inputs) {
8785
9256
  const price = markPrice;
8786
9257
  values2.order_price = "";
8787
9258
  values2.total = quantity.mul(price).todp(2).toString();
8788
- }
8789
- if (values2.order_type === OrderType.LIMIT || values2.order_type === OrderType.STOP_LIMIT) {
9259
+ } else if (values2.order_type === OrderType.LIMIT || values2.order_type === OrderType.STOP_LIMIT) {
8790
9260
  if (values2.order_price) {
8791
9261
  const price = Number(values2.order_price);
8792
9262
  const total = quantity.mul(price);
@@ -8794,6 +9264,8 @@ function quantityInputHandle(inputs) {
8794
9264
  } else {
8795
9265
  values2.total = "";
8796
9266
  }
9267
+ } else if (values2.order_type === OrderType.SCALED && markPrice) {
9268
+ values2.total = quantity.mul(markPrice).todp(config.quote_dp).toString();
8797
9269
  }
8798
9270
  return [
8799
9271
  {
@@ -8852,8 +9324,9 @@ function tpslInputHandle(inputs) {
8852
9324
  entryPrice: price,
8853
9325
  // order price or mark price
8854
9326
  qty: values2.side === OrderSide.BUY ? Number(values2.order_quantity) : Number(values2.order_quantity) * -1,
8855
- orderSide: values2.side
9327
+ orderSide: values2.side,
8856
9328
  // values: newValues,
9329
+ values: values2
8857
9330
  },
8858
9331
  {
8859
9332
  symbol: config
@@ -8877,6 +9350,7 @@ var getCalculateHandler = (fieldName) => {
8877
9350
  case "total": {
8878
9351
  return totalInputHandle;
8879
9352
  }
9353
+ case "tp_enable":
8880
9354
  case "tp_pnl":
8881
9355
  case "sl_pnl":
8882
9356
  case "tp_trigger_price":
@@ -8885,6 +9359,11 @@ var getCalculateHandler = (fieldName) => {
8885
9359
  case "sl_offset":
8886
9360
  case "tp_offset_percentage":
8887
9361
  case "sl_offset_percentage":
9362
+ case "tp_order_price":
9363
+ case "tp_order_type":
9364
+ case "sl_enable":
9365
+ case "sl_order_type":
9366
+ case "sl_order_price":
8888
9367
  return tpslInputHandle;
8889
9368
  default:
8890
9369
  return otherInputHandle;
@@ -10045,7 +10524,7 @@ __export(utils_exports, {
10045
10524
  fetcher: () => fetcher,
10046
10525
  findPositionTPSLFromOrders: () => findPositionTPSLFromOrders,
10047
10526
  findTPSLFromOrder: () => findTPSLFromOrder,
10048
- findTPSLFromOrders: () => findTPSLFromOrders,
10527
+ findTPSLOrderPriceFromOrder: () => findTPSLOrderPriceFromOrder,
10049
10528
  formatNumber: () => formatNumber,
10050
10529
  getPositionBySymbol: () => getPositionBySymbol,
10051
10530
  priceToPnl: () => priceToPnl
@@ -10410,9 +10889,9 @@ var useReferralInfo = () => {
10410
10889
  []
10411
10890
  );
10412
10891
  const getFirstRefCode = useCallback(() => {
10413
- if (!data?.referrer_info.referral_codes)
10892
+ if (!data?.referrer_info?.referral_codes)
10414
10893
  return void 0;
10415
- const referralCodes = [...data?.referrer_info.referral_codes];
10894
+ const referralCodes = [...data?.referrer_info?.referral_codes];
10416
10895
  const pinedItems = [];
10417
10896
  for (let i = 0; i < pinCodes.length; i++) {
10418
10897
  const code = pinCodes[i];
@@ -15626,21 +16105,155 @@ function getQueryParamsFromObject(obj) {
15626
16105
  }
15627
16106
  return queryParams.toString();
15628
16107
  }
16108
+ var getCreateOrderUrl = (order) => {
16109
+ const isAlgoOrder = order?.order_type === OrderType.STOP_LIMIT || order?.order_type === OrderType.STOP_MARKET || order?.order_type === OrderType.CLOSE_POSITION || order.algo_type && order.algo_type === AlgoOrderRootType.BRACKET || isBracketOrder(order);
16110
+ if (order.order_type === OrderType.SCALED) {
16111
+ return "/v1/batch-order";
16112
+ }
16113
+ return isAlgoOrder ? "/v1/algo/order" : "/v1/order";
16114
+ };
16115
+ var getOrderCreator = (order) => {
16116
+ let type;
16117
+ if (isBracketOrder(order)) {
16118
+ type = `${AlgoOrderRootType.BRACKET}:${order.order_type}`;
16119
+ } else if (order.order_type === OrderType.LIMIT) {
16120
+ type = order.order_type_ext || order.order_type;
16121
+ } else {
16122
+ type = order.order_type;
16123
+ }
16124
+ return OrderFactory.create(type);
16125
+ };
16126
+ var tpslFields = [
16127
+ "tp_trigger_price",
16128
+ "sl_trigger_price",
16129
+ "tp_pnl",
16130
+ "sl_pnl",
16131
+ "tp_offset",
16132
+ "sl_offset",
16133
+ "tp_offset_percentage",
16134
+ "sl_offset_percentage"
16135
+ ];
16136
+ var isBracketOrder = (order) => {
16137
+ if (order.sl_enable || order.tp_enable) {
16138
+ return true;
16139
+ }
16140
+ return !!order.tp_trigger_price || !!order.sl_trigger_price;
16141
+ };
16142
+ var hasTPSL = (order) => {
16143
+ return tpslFields.some((field) => !!order[field]);
16144
+ };
16145
+ var getPriceAndQty = (order, symbolInfo, askAndBid) => {
16146
+ let quantity = Number(order.order_quantity);
16147
+ const orderPrice = Number(order.order_price);
16148
+ if (isNaN(quantity) || quantity <= 0) {
16149
+ return null;
16150
+ }
16151
+ if (askAndBid.length === 0) {
16152
+ return null;
16153
+ }
16154
+ if ((order.order_type === OrderType.LIMIT || order.order_type === OrderType.STOP_LIMIT) && isNaN(orderPrice)) {
16155
+ return null;
16156
+ }
16157
+ let price;
16158
+ if (order.order_type === OrderType.SCALED) {
16159
+ price = calcScaledOrderAvgPrice(order, symbolInfo, askAndBid);
16160
+ const orders = calcScaledOrderBatchBody(order, symbolInfo);
16161
+ const sumQtys = orders.reduce((acc, order2) => {
16162
+ return acc.plus(new Decimal(order2.order_quantity));
16163
+ }, zero);
16164
+ quantity = sumQtys.todp(symbolInfo.base_dp).toNumber();
16165
+ if (!quantity || isNaN(quantity)) {
16166
+ return null;
16167
+ }
16168
+ } else {
16169
+ price = getOrderPrice(order, askAndBid);
16170
+ }
16171
+ if (!price || isNaN(price)) {
16172
+ return null;
16173
+ }
16174
+ if (order.side === OrderSide.SELL) {
16175
+ quantity = -quantity;
16176
+ }
16177
+ return { price, quantity };
16178
+ };
16179
+ var calcEstLiqPrice = (order$1, askAndBid, inputs) => {
16180
+ const { symbolInfo } = inputs;
16181
+ const result = getPriceAndQty(order$1, symbolInfo, askAndBid);
16182
+ if (!result)
16183
+ return null;
16184
+ const { price, quantity } = result;
16185
+ if (!price || !quantity)
16186
+ return null;
16187
+ const {
16188
+ symbol,
16189
+ imr_factor,
16190
+ markPrice,
16191
+ totalCollateral,
16192
+ futures_taker_fee_rate,
16193
+ positions: positions3
16194
+ } = inputs;
16195
+ const orderFee = order.orderFee({
16196
+ qty: quantity,
16197
+ price,
16198
+ futuresTakeFeeRate: Number(futures_taker_fee_rate) / 1e4
16199
+ });
16200
+ const liqPrice = order.estLiqPrice({
16201
+ markPrice,
16202
+ baseIMR: symbolInfo.base_imr,
16203
+ baseMMR: symbolInfo.base_mmr,
16204
+ totalCollateral,
16205
+ positions: positions3 == null ? [] : positions3,
16206
+ IMR_Factor: imr_factor,
16207
+ orderFee,
16208
+ newOrder: {
16209
+ qty: quantity,
16210
+ price,
16211
+ symbol
16212
+ }
16213
+ });
16214
+ if (liqPrice <= 0)
16215
+ return null;
16216
+ return liqPrice;
16217
+ };
16218
+ var calcEstLeverage = (order$1, askAndBid, inputs) => {
16219
+ const { totalCollateral, positions: positions3, symbol, symbolInfo } = inputs;
16220
+ const result = getPriceAndQty(order$1, symbolInfo, askAndBid);
16221
+ if (!result)
16222
+ return null;
16223
+ const { price, quantity } = result;
16224
+ if (!price || !quantity)
16225
+ return null;
16226
+ return order.estLeverage({
16227
+ totalCollateral,
16228
+ positions: positions3,
16229
+ newOrder: {
16230
+ symbol,
16231
+ qty: result.quantity,
16232
+ price: result.price
16233
+ }
16234
+ });
16235
+ };
16236
+ function isBBOOrder(options) {
16237
+ const { order_type, order_type_ext } = options;
16238
+ return order_type === OrderType.LIMIT && [OrderType.ASK, OrderType.BID].includes(order_type_ext);
16239
+ }
15629
16240
  var initialOrderState = {
15630
16241
  order_price: "",
15631
16242
  order_quantity: "",
15632
16243
  trigger_price: "",
15633
16244
  tp_trigger_price: "",
15634
16245
  sl_trigger_price: "",
16246
+ tp_order_type: OrderType.MARKET,
15635
16247
  tp_pnl: "",
15636
16248
  sl_pnl: "",
15637
16249
  tp_offset_percentage: "",
15638
16250
  sl_offset_percentage: "",
15639
16251
  tp_offset: "",
15640
16252
  sl_offset: "",
16253
+ sl_order_type: OrderType.MARKET,
15641
16254
  total: "",
15642
- min_price: "",
15643
- max_price: "",
16255
+ start_price: "",
16256
+ end_price: "",
15644
16257
  totalOrders: "",
15645
16258
  distribution_type: "",
15646
16259
  skew: ""
@@ -16304,9 +16917,9 @@ var useOrderEntry2 = (symbol, options = {}) => {
16304
16917
  validate: validateOrder
16305
16918
  },
16306
16919
  freeCollateral,
16307
- setValue,
16308
- setValues,
16309
- symbolInfo: symbolInfo || {},
16920
+ setValue: useMemoizedFn(setValue),
16921
+ setValues: useMemoizedFn(setValues),
16922
+ symbolInfo: symbolInfo || EMPTY_OBJECT,
16310
16923
  metaState: meta,
16311
16924
  isMutating,
16312
16925
  markPrice
@@ -16639,6 +17252,6 @@ var usePositionClose = (options) => {
16639
17252
  };
16640
17253
  };
16641
17254
 
16642
- export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusContext, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, getMinNotional, parseJSON, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAssetsHistory, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEventEmitter, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetReferralCode, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useKeyStore, useLazyQuery, useLeverage, useLocalStorage, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxQty, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore2 as useOrderStore, useOrderStream, useOrderbookStream, usePositionActions, usePositionClose, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTickerStream, useTokenInfo, useTokensInfo, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useUpdatedRef, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWalletTopic, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
17255
+ export { DefaultLayoutConfig, DistributionId, ENVType2 as ENVType, EpochStatus, ExtendedConfigStore, MaintenanceStatus, MarketsStorageKey, MarketsType, OrderlyConfigProvider, OrderlyContext, OrderlyProvider, StatusProvider, TWType, WalletConnectorContext, WsNetworkStatus, checkNotional, cleanStringStyle, fetcher, findPositionTPSLFromOrders, findTPSLFromOrder, findTPSLOrderPriceFromOrder, getMinNotional, parseJSON, useAccount, useAccountInfo2 as useAccountInfo, useAccountInstance, useAccountRewardsHistory, useAllBrokers, useApiKeyManager, useAssetsHistory, useAudioPlayer, useBalanceSubscription, useBalanceTopic, useBoolean, useChain, useChains, useCheckReferralCode, useCollateral, useCommission, useComputedLTV, useConfig, useConvert, useCurEpochEstimate, useDaily, useDeposit, useDistribution, useDistributionHistory, useEpochInfo, useEventEmitter, useFundingDetails, useFundingFeeHistory, useFundingRate, useFundingRateHistory, useFundingRates, useFundingRatesStore, useGetClaimed, useGetEnv, useGetReferralCode, useHoldingStream, useIndexPrice, useIndexPricesStream, useInfiniteQuery, useKeyStore, useLazyQuery, useLeverage, useLocalStorage, useMaintenanceStatus, useMarginRatio, useMarkPrice, useMarkPriceBySymbol, useMarkPricesStream, useMarket, useMarketList, useMarketMap, useMarketTradeStream, useMarkets, useMarketsStore, useMarketsStream, useMaxQty, useMediaQuery, useMemoizedFn, useMutation, useNetworkInfo, useOdosQuote, useOrderEntity, useOrderEntry2 as useOrderEntry, useOrderEntry as useOrderEntry_deprecated, useOrderStore2 as useOrderStore, useOrderStream, useOrderbookStream, useOrderlyContext, usePositionActions, usePositionClose, usePositionStream, usePoster, usePreLoadData, usePrivateDataObserver, usePrivateInfiniteQuery, usePrivateQuery, useQuery, useRefereeHistory, useRefereeInfo, useRefereeRebateSummary, useReferralInfo, useReferralRebateSummary, useRestrictedInfo, useSessionStorage, useSettleSubscription, useSimpleDI, useStatisticsDaily, useStorageChain, useStorageLedgerAddress, useSubAccountDataObserver, useSubAccountMaxWithdrawal, useSubAccountMutation, useSubAccountQuery, useSubAccountWS, useSymbolLeverage, useSymbolPriceRange, useSymbolsInfo, useSymbolsInfoStore, useTPSLOrder, useTickerStream, useTokenInfo, useTokensInfo, useTrack, useTrackingInstance, useTradingRewardsStatus, useTransfer, useTransferHistory, useUpdatedRef, useWS, useWalletConnector, useWalletRewardsHistory, useWalletSubscription, useWalletTopic, useWithdraw, useWsStatus, utils_exports as utils, version_default as version };
16643
17256
  //# sourceMappingURL=out.js.map
16644
17257
  //# sourceMappingURL=index.mjs.map