@orderly.network/ui-positions 2.8.5-alpha.0 → 2.8.6-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +76 -1
- package/dist/index.d.ts +76 -1
- package/dist/index.js +601 -103
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +517 -25
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -13
package/dist/index.mjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { registerSimpleDialog, Flex, Text, CloseIcon, Button, ThrottledButton, useScreen, Grid, Statistic, ExclamationFillIcon, modal, Tooltip, DataTable, cn, ListView, SimpleSheet,
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { registerSimpleDialog, useModal, SimpleDialog, Flex, Text, toast, Badge, Divider, CloseIcon, Button, ThrottledButton, useScreen, ArrowDownShortIcon, ArrowUpShortIcon, Grid, Statistic, ExclamationFillIcon, modal, Tooltip, DataTable, cn, ListView, SimpleSheet, usePagination, DataFilter, formatAddress, Box, HoverCard, ArrowLeftRightIcon, capitalizeFirstLetter, ShareIcon, EditIcon, Input, inputFormatter, Select, PopoverRoot, PopoverTrigger, PopoverContent, Slider } from '@orderly.network/ui';
|
|
2
|
+
import React2, { createContext, useMemo, useCallback, useContext, useState, useEffect, useRef } from 'react';
|
|
3
|
+
import { i18n, useTranslation } from '@orderly.network/i18n';
|
|
4
|
+
import { OrderSide, OrderType, EMPTY_LIST, AccountStatusEnum, TrackerEventName, PositionType, AlgoOrderType } from '@orderly.network/types';
|
|
5
5
|
import { commifyOptional, Decimal, formatNum, getTimestamp, commify } from '@orderly.network/utils';
|
|
6
|
-
import {
|
|
7
|
-
import { usePrivateInfiniteQuery, useBoolean, useSessionStorage, useAccount, usePrivateQuery, useTrack, usePositionStream,
|
|
6
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
+
import { useSymbolsInfo, useMarkPrice, useMaxQty, useSubAccountMutation, useLocalStorage, usePrivateInfiniteQuery, useBoolean, useSessionStorage, useAccount, usePrivateQuery, useTrack, usePositionStream, usePositionClose, useSWR, fetcher, useGetRwaSymbolOpenStatus, useTpslPriceChecker, useConfig, useReferralInfo, useAccountInfo, useLeverageBySymbol, utils, useMaxLeverage } from '@orderly.network/hooks';
|
|
8
8
|
import { produce } from 'immer';
|
|
9
9
|
import { positions, account } from '@orderly.network/perp';
|
|
10
10
|
import { useDataTap, useOrderEntryFormErrorMsg } from '@orderly.network/react-app';
|
|
11
11
|
import { AuthGuardDataTable } from '@orderly.network/ui-connector';
|
|
12
12
|
import { SymbolLeverageDialogId, SymbolLeverageSheetId } from '@orderly.network/ui-leverage';
|
|
13
13
|
import { SharePnLDialogId, SharePnLBottomSheetId } from '@orderly.network/ui-share';
|
|
14
|
-
import { TPSLSheetId, TPSLDialogId, TPSLDetailSheetId, TPSLDetailDialogId } from '@orderly.network/ui-tpsl';
|
|
14
|
+
import { CloseToLiqPriceIcon, TPSLSheetId, TPSLDialogId, TPSLDetailSheetId, TPSLDetailDialogId } from '@orderly.network/ui-tpsl';
|
|
15
15
|
import { subDays, differenceInDays } from 'date-fns';
|
|
16
16
|
|
|
17
17
|
// src/index.ts
|
|
@@ -870,6 +870,404 @@ function useSort(initialSort, onSortChange) {
|
|
|
870
870
|
getSortedList
|
|
871
871
|
};
|
|
872
872
|
}
|
|
873
|
+
var OrderInfoCard = ({
|
|
874
|
+
title,
|
|
875
|
+
side,
|
|
876
|
+
leverage,
|
|
877
|
+
qty,
|
|
878
|
+
baseDp,
|
|
879
|
+
estLiqPrice,
|
|
880
|
+
className
|
|
881
|
+
}) => {
|
|
882
|
+
const { t } = useTranslation();
|
|
883
|
+
return /* @__PURE__ */ jsxs(
|
|
884
|
+
Flex,
|
|
885
|
+
{
|
|
886
|
+
direction: "column",
|
|
887
|
+
gap: 3,
|
|
888
|
+
itemAlign: "start",
|
|
889
|
+
className: `oui-bg-base-6 oui-rounded-lg oui-p-3 oui-w-full oui-font-weight-semibold ${className || ""}`,
|
|
890
|
+
children: [
|
|
891
|
+
/* @__PURE__ */ jsxs(Flex, { justify: "between", itemAlign: "center", gap: 2, children: [
|
|
892
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", weight: "semibold", intensity: 98, children: title }),
|
|
893
|
+
/* @__PURE__ */ jsxs(Flex, { itemAlign: "center", gap: 1, children: [
|
|
894
|
+
/* @__PURE__ */ jsx(Badge, { color: side === OrderSide.SELL ? "sell" : "buy", size: "xs", children: side === OrderSide.SELL ? t("common.sell") : t("common.buy") }),
|
|
895
|
+
/* @__PURE__ */ jsxs(Badge, { color: "neutral", size: "xs", children: [
|
|
896
|
+
leverage,
|
|
897
|
+
"X"
|
|
898
|
+
] })
|
|
899
|
+
] })
|
|
900
|
+
] }),
|
|
901
|
+
/* @__PURE__ */ jsxs(
|
|
902
|
+
Flex,
|
|
903
|
+
{
|
|
904
|
+
direction: "column",
|
|
905
|
+
justify: "between",
|
|
906
|
+
itemAlign: "center",
|
|
907
|
+
width: "100%",
|
|
908
|
+
children: [
|
|
909
|
+
/* @__PURE__ */ jsxs(
|
|
910
|
+
Flex,
|
|
911
|
+
{
|
|
912
|
+
direction: "row",
|
|
913
|
+
justify: "between",
|
|
914
|
+
itemAlign: "center",
|
|
915
|
+
width: "100%",
|
|
916
|
+
gap: 1,
|
|
917
|
+
children: [
|
|
918
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("common.qty") }),
|
|
919
|
+
/* @__PURE__ */ jsx(Text.numeral, { dp: baseDp, size: "sm", color: "danger", padding: false, children: qty })
|
|
920
|
+
]
|
|
921
|
+
}
|
|
922
|
+
),
|
|
923
|
+
/* @__PURE__ */ jsxs(
|
|
924
|
+
Flex,
|
|
925
|
+
{
|
|
926
|
+
direction: "row",
|
|
927
|
+
justify: "between",
|
|
928
|
+
itemAlign: "center",
|
|
929
|
+
width: "100%",
|
|
930
|
+
gap: 1,
|
|
931
|
+
children: [
|
|
932
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("common.price") }),
|
|
933
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", weight: "semibold", children: t("common.market") })
|
|
934
|
+
]
|
|
935
|
+
}
|
|
936
|
+
),
|
|
937
|
+
estLiqPrice && /* @__PURE__ */ jsxs(
|
|
938
|
+
Flex,
|
|
939
|
+
{
|
|
940
|
+
direction: "row",
|
|
941
|
+
justify: "between",
|
|
942
|
+
itemAlign: "center",
|
|
943
|
+
width: "100%",
|
|
944
|
+
gap: 1,
|
|
945
|
+
children: [
|
|
946
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("orderEntry.estLiqPrice") }),
|
|
947
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", weight: "semibold", children: estLiqPrice })
|
|
948
|
+
]
|
|
949
|
+
}
|
|
950
|
+
)
|
|
951
|
+
]
|
|
952
|
+
}
|
|
953
|
+
)
|
|
954
|
+
]
|
|
955
|
+
}
|
|
956
|
+
);
|
|
957
|
+
};
|
|
958
|
+
var ReversePosition = (props) => {
|
|
959
|
+
const { displayInfo, className, style, onConfirm, onCancel } = props;
|
|
960
|
+
const { t } = useTranslation();
|
|
961
|
+
if (!displayInfo) {
|
|
962
|
+
return null;
|
|
963
|
+
}
|
|
964
|
+
const {
|
|
965
|
+
symbol,
|
|
966
|
+
base,
|
|
967
|
+
quote,
|
|
968
|
+
baseDp,
|
|
969
|
+
quoteDp,
|
|
970
|
+
positionQty,
|
|
971
|
+
reverseQty,
|
|
972
|
+
markPrice,
|
|
973
|
+
leverage,
|
|
974
|
+
isLong
|
|
975
|
+
} = displayInfo;
|
|
976
|
+
const closeSide = !isLong ? OrderSide.SELL : OrderSide.BUY;
|
|
977
|
+
const openSide = isLong ? OrderSide.SELL : OrderSide.BUY;
|
|
978
|
+
const closeAction = isLong ? t("positions.reverse.marketCloseLong") : t("positions.reverse.marketCloseShort");
|
|
979
|
+
const openAction = openSide === OrderSide.BUY ? t("positions.reverse.marketOpenLong") : t("positions.reverse.marketOpenShort");
|
|
980
|
+
const reverseTo = isLong ? t("positions.reverse.reverseToShort") : t("positions.reverse.reverseToLong");
|
|
981
|
+
const reverseToIcon = isLong ? /* @__PURE__ */ jsx(ArrowDownShortIcon, { size: 16, color: "danger", opacity: 1 }) : /* @__PURE__ */ jsx(ArrowUpShortIcon, { size: 16, color: "success", opacity: 1 });
|
|
982
|
+
const priceLabel = /* @__PURE__ */ jsxs(Flex, { itemAlign: "center", gap: 1, children: [
|
|
983
|
+
/* @__PURE__ */ jsx(Text.numeral, { dp: quoteDp, size: "sm", intensity: 80, children: markPrice }),
|
|
984
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", intensity: 36, children: quote })
|
|
985
|
+
] });
|
|
986
|
+
return /* @__PURE__ */ jsxs(
|
|
987
|
+
Flex,
|
|
988
|
+
{
|
|
989
|
+
direction: "column",
|
|
990
|
+
className,
|
|
991
|
+
style,
|
|
992
|
+
gap: 4,
|
|
993
|
+
width: "100%",
|
|
994
|
+
children: [
|
|
995
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 2, width: "100%", children: [
|
|
996
|
+
/* @__PURE__ */ jsxs(Flex, { justify: "between", itemAlign: "center", width: "100%", children: [
|
|
997
|
+
/* @__PURE__ */ jsx(
|
|
998
|
+
Text.formatted,
|
|
999
|
+
{
|
|
1000
|
+
size: "base",
|
|
1001
|
+
weight: "semibold",
|
|
1002
|
+
rule: "symbol",
|
|
1003
|
+
formatString: "base-type",
|
|
1004
|
+
intensity: 98,
|
|
1005
|
+
showIcon: true,
|
|
1006
|
+
children: symbol
|
|
1007
|
+
}
|
|
1008
|
+
),
|
|
1009
|
+
/* @__PURE__ */ jsx(Badge, { color: isLong ? "sell" : "buy", size: "xs", children: reverseTo })
|
|
1010
|
+
] }),
|
|
1011
|
+
/* @__PURE__ */ jsxs(Flex, { justify: "between", itemAlign: "center", width: "100%", children: [
|
|
1012
|
+
/* @__PURE__ */ jsx(Text, { size: "sm", intensity: 54, children: t("common.markPrice") }),
|
|
1013
|
+
priceLabel
|
|
1014
|
+
] })
|
|
1015
|
+
] }),
|
|
1016
|
+
/* @__PURE__ */ jsx(Divider, { intensity: 4, className: "oui-w-full" }),
|
|
1017
|
+
/* @__PURE__ */ jsx(
|
|
1018
|
+
OrderInfoCard,
|
|
1019
|
+
{
|
|
1020
|
+
title: closeAction,
|
|
1021
|
+
side: closeSide,
|
|
1022
|
+
leverage,
|
|
1023
|
+
qty: positionQty,
|
|
1024
|
+
baseDp
|
|
1025
|
+
}
|
|
1026
|
+
),
|
|
1027
|
+
/* @__PURE__ */ jsxs(Flex, { direction: "row", itemAlign: "center", width: "100%", children: [
|
|
1028
|
+
/* @__PURE__ */ jsx(Divider, { intensity: 8, className: "oui-w-full" }),
|
|
1029
|
+
/* @__PURE__ */ jsxs(Flex, { className: "oui-px-4 oui-py-[3px] oui-border oui-border-base-contrast-12 oui-rounded-full oui-shrink-0", children: [
|
|
1030
|
+
reverseToIcon,
|
|
1031
|
+
/* @__PURE__ */ jsx(Text, { size: "2xs", color: isLong ? "danger" : "success", children: reverseTo })
|
|
1032
|
+
] }),
|
|
1033
|
+
/* @__PURE__ */ jsx(Divider, { intensity: 8, className: "oui-w-full" })
|
|
1034
|
+
] }),
|
|
1035
|
+
/* @__PURE__ */ jsx(
|
|
1036
|
+
OrderInfoCard,
|
|
1037
|
+
{
|
|
1038
|
+
title: openAction,
|
|
1039
|
+
side: openSide,
|
|
1040
|
+
leverage,
|
|
1041
|
+
qty: reverseQty,
|
|
1042
|
+
baseDp
|
|
1043
|
+
}
|
|
1044
|
+
),
|
|
1045
|
+
/* @__PURE__ */ jsx(Text, { size: "2xs", color: "warning", weight: "semibold", children: t("positions.reverse.description") })
|
|
1046
|
+
]
|
|
1047
|
+
}
|
|
1048
|
+
);
|
|
1049
|
+
};
|
|
1050
|
+
var useReversePositionEnabled = () => {
|
|
1051
|
+
const { isMobile, isDesktop } = useScreen();
|
|
1052
|
+
const [desktopEnabled, setDesktopEnabled] = useLocalStorage(
|
|
1053
|
+
"orderly_reverse_position_enabled_desktop",
|
|
1054
|
+
true
|
|
1055
|
+
);
|
|
1056
|
+
const [mobileEnabled, setMobileEnabled] = useLocalStorage(
|
|
1057
|
+
"orderly_reverse_position_enabled_mobile",
|
|
1058
|
+
false
|
|
1059
|
+
);
|
|
1060
|
+
const isEnabled = useMemo(() => {
|
|
1061
|
+
if (isMobile) {
|
|
1062
|
+
return mobileEnabled;
|
|
1063
|
+
}
|
|
1064
|
+
if (isDesktop) {
|
|
1065
|
+
return desktopEnabled;
|
|
1066
|
+
}
|
|
1067
|
+
return false;
|
|
1068
|
+
}, [isMobile, isDesktop, desktopEnabled, mobileEnabled]);
|
|
1069
|
+
const setEnabled = useCallback(
|
|
1070
|
+
(enabled) => {
|
|
1071
|
+
if (isMobile) {
|
|
1072
|
+
setMobileEnabled(enabled);
|
|
1073
|
+
} else if (isDesktop) {
|
|
1074
|
+
setDesktopEnabled(enabled);
|
|
1075
|
+
}
|
|
1076
|
+
},
|
|
1077
|
+
[isMobile, isDesktop, setMobileEnabled, setDesktopEnabled]
|
|
1078
|
+
);
|
|
1079
|
+
return {
|
|
1080
|
+
isEnabled,
|
|
1081
|
+
setEnabled
|
|
1082
|
+
};
|
|
1083
|
+
};
|
|
1084
|
+
var useReversePositionScript = (options) => {
|
|
1085
|
+
const { position, onSuccess, onError } = options || {};
|
|
1086
|
+
const { t } = useTranslation();
|
|
1087
|
+
const { isEnabled, setEnabled } = useReversePositionEnabled();
|
|
1088
|
+
const symbolsInfo = useSymbolsInfo();
|
|
1089
|
+
const symbol = position?.symbol || "";
|
|
1090
|
+
const { data: symbolMarketPrice } = useMarkPrice(symbol);
|
|
1091
|
+
const symbolInfo = symbolsInfo?.[symbol];
|
|
1092
|
+
const positionQty = useMemo(() => {
|
|
1093
|
+
if (!position)
|
|
1094
|
+
return 0;
|
|
1095
|
+
return Math.abs(position.position_qty);
|
|
1096
|
+
}, [position]);
|
|
1097
|
+
const isLong = useMemo(() => {
|
|
1098
|
+
if (!position)
|
|
1099
|
+
return false;
|
|
1100
|
+
return position.position_qty > 0;
|
|
1101
|
+
}, [position]);
|
|
1102
|
+
const oppositeSide = useMemo(() => {
|
|
1103
|
+
return isLong ? OrderSide.SELL : OrderSide.BUY;
|
|
1104
|
+
}, [isLong]);
|
|
1105
|
+
const maxOpenQty = useMaxQty(symbol, oppositeSide, false);
|
|
1106
|
+
const reverseQty = useMemo(() => {
|
|
1107
|
+
if (!position)
|
|
1108
|
+
return 0;
|
|
1109
|
+
const desiredQty = positionQty;
|
|
1110
|
+
if (desiredQty > maxOpenQty && maxOpenQty > 0) {
|
|
1111
|
+
return maxOpenQty;
|
|
1112
|
+
}
|
|
1113
|
+
return desiredQty;
|
|
1114
|
+
}, [positionQty, maxOpenQty]);
|
|
1115
|
+
const [doCreateOrder, { isMutating }] = useSubAccountMutation(
|
|
1116
|
+
"/v1/order",
|
|
1117
|
+
"POST",
|
|
1118
|
+
{
|
|
1119
|
+
accountId: position?.account_id
|
|
1120
|
+
}
|
|
1121
|
+
);
|
|
1122
|
+
const reversePosition = useCallback(async () => {
|
|
1123
|
+
if (!position || positionQty === 0) {
|
|
1124
|
+
toast.error("No position to reverse");
|
|
1125
|
+
return false;
|
|
1126
|
+
}
|
|
1127
|
+
try {
|
|
1128
|
+
const closeSide = isLong ? OrderSide.SELL : OrderSide.BUY;
|
|
1129
|
+
const closeOrder = await doCreateOrder({
|
|
1130
|
+
symbol: position.symbol,
|
|
1131
|
+
order_type: OrderType.MARKET,
|
|
1132
|
+
side: closeSide,
|
|
1133
|
+
order_quantity: new Decimal(positionQty).toString(),
|
|
1134
|
+
reduce_only: true
|
|
1135
|
+
});
|
|
1136
|
+
const openSide = isLong ? OrderSide.SELL : OrderSide.BUY;
|
|
1137
|
+
const openOrder = await doCreateOrder({
|
|
1138
|
+
symbol: position.symbol,
|
|
1139
|
+
order_type: OrderType.MARKET,
|
|
1140
|
+
side: openSide,
|
|
1141
|
+
order_quantity: new Decimal(reverseQty).toString(),
|
|
1142
|
+
reduce_only: false
|
|
1143
|
+
});
|
|
1144
|
+
if (!openOrder.success) {
|
|
1145
|
+
throw new Error(
|
|
1146
|
+
openOrder.message || "Failed to open opposite position"
|
|
1147
|
+
);
|
|
1148
|
+
}
|
|
1149
|
+
onSuccess?.();
|
|
1150
|
+
return true;
|
|
1151
|
+
} catch (error) {
|
|
1152
|
+
onError?.(error);
|
|
1153
|
+
return false;
|
|
1154
|
+
}
|
|
1155
|
+
}, [position, positionQty, reverseQty, isLong, doCreateOrder, t, onSuccess]);
|
|
1156
|
+
const displayInfo = useMemo(() => {
|
|
1157
|
+
if (!position || !symbolInfo) {
|
|
1158
|
+
return null;
|
|
1159
|
+
}
|
|
1160
|
+
const base = symbolInfo("base");
|
|
1161
|
+
const quote = symbolInfo("quote");
|
|
1162
|
+
const baseDp = symbolInfo("base_dp");
|
|
1163
|
+
const quoteDp = symbolInfo("quote_dp");
|
|
1164
|
+
const leverage = position.leverage || 1;
|
|
1165
|
+
return {
|
|
1166
|
+
symbol: position.symbol,
|
|
1167
|
+
base,
|
|
1168
|
+
quote,
|
|
1169
|
+
baseDp,
|
|
1170
|
+
quoteDp,
|
|
1171
|
+
positionQty: new Decimal(positionQty).todp(baseDp).toString(),
|
|
1172
|
+
reverseQty: new Decimal(reverseQty).todp(baseDp).toString(),
|
|
1173
|
+
markPrice: symbolMarketPrice ? new Decimal(symbolMarketPrice).todp(quoteDp).toString() : "--",
|
|
1174
|
+
leverage,
|
|
1175
|
+
isLong
|
|
1176
|
+
};
|
|
1177
|
+
}, [
|
|
1178
|
+
position,
|
|
1179
|
+
symbolMarketPrice,
|
|
1180
|
+
symbolInfo,
|
|
1181
|
+
positionQty,
|
|
1182
|
+
reverseQty,
|
|
1183
|
+
isLong
|
|
1184
|
+
]);
|
|
1185
|
+
return {
|
|
1186
|
+
isEnabled,
|
|
1187
|
+
setEnabled,
|
|
1188
|
+
reversePosition,
|
|
1189
|
+
isReversing: isMutating,
|
|
1190
|
+
displayInfo,
|
|
1191
|
+
positionQty,
|
|
1192
|
+
reverseQty,
|
|
1193
|
+
isLong
|
|
1194
|
+
};
|
|
1195
|
+
};
|
|
1196
|
+
var ReversePositionWidget = (props) => {
|
|
1197
|
+
const { position, close, resolve, reject } = props;
|
|
1198
|
+
const { t } = useTranslation();
|
|
1199
|
+
const { visible, hide, onOpenChange } = useModal();
|
|
1200
|
+
const state = useReversePositionScript({
|
|
1201
|
+
position,
|
|
1202
|
+
onSuccess: () => {
|
|
1203
|
+
resolve?.(true);
|
|
1204
|
+
hide();
|
|
1205
|
+
},
|
|
1206
|
+
onError: (error) => {
|
|
1207
|
+
reject?.(error);
|
|
1208
|
+
hide();
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
const actions = useMemo(() => {
|
|
1212
|
+
return {
|
|
1213
|
+
primary: {
|
|
1214
|
+
label: t("common.confirm"),
|
|
1215
|
+
onClick: async () => {
|
|
1216
|
+
try {
|
|
1217
|
+
const result = await state.reversePosition();
|
|
1218
|
+
if (result) {
|
|
1219
|
+
resolve?.(true);
|
|
1220
|
+
hide();
|
|
1221
|
+
return true;
|
|
1222
|
+
} else {
|
|
1223
|
+
reject?.(false);
|
|
1224
|
+
return false;
|
|
1225
|
+
}
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
reject?.(error);
|
|
1228
|
+
throw error;
|
|
1229
|
+
}
|
|
1230
|
+
},
|
|
1231
|
+
loading: state.isReversing,
|
|
1232
|
+
disabled: state.isReversing || !state.displayInfo
|
|
1233
|
+
},
|
|
1234
|
+
secondary: {
|
|
1235
|
+
label: t("common.cancel"),
|
|
1236
|
+
onClick: async () => {
|
|
1237
|
+
reject?.("cancel");
|
|
1238
|
+
hide();
|
|
1239
|
+
return false;
|
|
1240
|
+
}
|
|
1241
|
+
}
|
|
1242
|
+
};
|
|
1243
|
+
}, [state, t, resolve, reject, hide]);
|
|
1244
|
+
return /* @__PURE__ */ jsx(
|
|
1245
|
+
SimpleDialog,
|
|
1246
|
+
{
|
|
1247
|
+
open: visible,
|
|
1248
|
+
onOpenChange,
|
|
1249
|
+
size: "sm",
|
|
1250
|
+
title: i18n.t("positions.reverse.title"),
|
|
1251
|
+
classNames: {
|
|
1252
|
+
content: "oui-border oui-border-line-6"
|
|
1253
|
+
},
|
|
1254
|
+
actions,
|
|
1255
|
+
children: /* @__PURE__ */ jsx(ReversePosition, { ...state })
|
|
1256
|
+
}
|
|
1257
|
+
);
|
|
1258
|
+
};
|
|
1259
|
+
var ReversePositionDialogId = "ReversePositionDialogId";
|
|
1260
|
+
registerSimpleDialog(
|
|
1261
|
+
ReversePositionDialogId,
|
|
1262
|
+
ReversePositionWidget,
|
|
1263
|
+
{
|
|
1264
|
+
size: "sm",
|
|
1265
|
+
classNames: {
|
|
1266
|
+
content: "oui-border oui-border-line-6"
|
|
1267
|
+
},
|
|
1268
|
+
title: () => i18n.t("positions.reverse.title")
|
|
1269
|
+
}
|
|
1270
|
+
);
|
|
873
1271
|
var PositionsTabName = /* @__PURE__ */ ((PositionsTabName2) => {
|
|
874
1272
|
PositionsTabName2["Positions"] = "positions";
|
|
875
1273
|
PositionsTabName2["PositionHistory"] = "positionHistory";
|
|
@@ -911,6 +1309,7 @@ var usePositionsScript = (props) => {
|
|
|
911
1309
|
// Default to true for backward compatibility
|
|
912
1310
|
} = props;
|
|
913
1311
|
const { pagination, setPage } = usePagination({ pageSize: 50 });
|
|
1312
|
+
const { isEnabled: positionReverse } = useReversePositionEnabled();
|
|
914
1313
|
const { tabSort, onTabSort } = useTabSort({
|
|
915
1314
|
storageKey: TRADING_POSITIONS_SORT_STORAGE_KEY
|
|
916
1315
|
});
|
|
@@ -918,7 +1317,7 @@ var usePositionsScript = (props) => {
|
|
|
918
1317
|
enableSortingStorage ? tabSort?.["positions" /* Positions */] : void 0,
|
|
919
1318
|
enableSortingStorage ? onTabSort("positions" /* Positions */) : void 0
|
|
920
1319
|
);
|
|
921
|
-
|
|
1320
|
+
React2.useEffect(() => {
|
|
922
1321
|
setPage(1);
|
|
923
1322
|
}, [symbol]);
|
|
924
1323
|
const [data, , { isLoading }] = usePositionStream(symbol, {
|
|
@@ -937,6 +1336,7 @@ var usePositionsScript = (props) => {
|
|
|
937
1336
|
onSymbolChange,
|
|
938
1337
|
pagination,
|
|
939
1338
|
onSort,
|
|
1339
|
+
positionReverse,
|
|
940
1340
|
initialSort: enableSortingStorage ? tabSort?.["positions" /* Positions */] : void 0
|
|
941
1341
|
};
|
|
942
1342
|
};
|
|
@@ -1693,9 +2093,20 @@ var PartialTPSL = (props) => {
|
|
|
1693
2093
|
slTriggerPrice,
|
|
1694
2094
|
direction = "column"
|
|
1695
2095
|
} = props;
|
|
1696
|
-
const {
|
|
2096
|
+
const {
|
|
2097
|
+
partialTPSLOrder: order,
|
|
2098
|
+
quoteDp,
|
|
2099
|
+
baseDp,
|
|
2100
|
+
position
|
|
2101
|
+
} = usePositionsRowContext();
|
|
1697
2102
|
const symbolInfo = useSymbolsInfo();
|
|
1698
2103
|
const { t } = useTranslation();
|
|
2104
|
+
const side = position.position_qty > 0 ? OrderSide.BUY : OrderSide.SELL;
|
|
2105
|
+
const slPriceError = useTpslPriceChecker({
|
|
2106
|
+
slPrice: slTriggerPrice?.toString() ?? void 0,
|
|
2107
|
+
liqPrice: position.est_liq_price ?? null,
|
|
2108
|
+
side
|
|
2109
|
+
});
|
|
1699
2110
|
const child = useMemo(() => {
|
|
1700
2111
|
const children = [];
|
|
1701
2112
|
if (!order?.symbol)
|
|
@@ -1728,6 +2139,7 @@ var PartialTPSL = (props) => {
|
|
|
1728
2139
|
rule: "price",
|
|
1729
2140
|
dp: symbolInfo[order.symbol]("quote_dp", 2),
|
|
1730
2141
|
prefix: /* @__PURE__ */ jsx(Text, { intensity: 54, children: `${t("tpsl.sl")} - ` }),
|
|
2142
|
+
suffix: /* @__PURE__ */ jsx(CloseToLiqPriceIcon, { slPriceError }),
|
|
1731
2143
|
children: slTriggerPrice
|
|
1732
2144
|
},
|
|
1733
2145
|
"sl"
|
|
@@ -1740,7 +2152,7 @@ var PartialTPSL = (props) => {
|
|
|
1740
2152
|
children.splice(1, 0, /* @__PURE__ */ jsx(Text, { children: "/" }, "split"));
|
|
1741
2153
|
}
|
|
1742
2154
|
return children;
|
|
1743
|
-
}, [tpTriggerPrice, slTriggerPrice, order?.symbol, t]);
|
|
2155
|
+
}, [tpTriggerPrice, slTriggerPrice, order?.symbol, t, slPriceError]);
|
|
1744
2156
|
const hasTPSL = Array.isArray(child) ? !!child.length : !child;
|
|
1745
2157
|
return /* @__PURE__ */ jsxs(Flex, { className: "oui-gap-[6px]", children: [
|
|
1746
2158
|
/* @__PURE__ */ jsx(
|
|
@@ -1763,6 +2175,29 @@ var PartialTPSL = (props) => {
|
|
|
1763
2175
|
] })
|
|
1764
2176
|
] });
|
|
1765
2177
|
};
|
|
2178
|
+
var ReversePositionButton = (props) => {
|
|
2179
|
+
const { position } = props;
|
|
2180
|
+
return /* @__PURE__ */ jsx(
|
|
2181
|
+
"div",
|
|
2182
|
+
{
|
|
2183
|
+
className: "",
|
|
2184
|
+
style: { transform: "rotate(90deg)" },
|
|
2185
|
+
onClick: () => {
|
|
2186
|
+
modal.show(ReversePositionDialogId, {
|
|
2187
|
+
position
|
|
2188
|
+
});
|
|
2189
|
+
},
|
|
2190
|
+
children: /* @__PURE__ */ jsx(
|
|
2191
|
+
ArrowLeftRightIcon,
|
|
2192
|
+
{
|
|
2193
|
+
size: 15,
|
|
2194
|
+
opacity: 1,
|
|
2195
|
+
className: "oui-cursor-pointer oui-text-base-contrast-54 hover:oui-text-base-contrast-80"
|
|
2196
|
+
}
|
|
2197
|
+
)
|
|
2198
|
+
}
|
|
2199
|
+
);
|
|
2200
|
+
};
|
|
1766
2201
|
var ShareButton = (props) => {
|
|
1767
2202
|
if (!props.sharePnLConfig) {
|
|
1768
2203
|
return null;
|
|
@@ -1863,6 +2298,12 @@ var ShareButtonWidget = (props) => {
|
|
|
1863
2298
|
var TriggerPrice = (props) => {
|
|
1864
2299
|
const { stopLossPrice, takeProfitPrice } = props;
|
|
1865
2300
|
const { tpslOrder, position } = usePositionsRowContext();
|
|
2301
|
+
const side = position.position_qty > 0 ? OrderSide.BUY : OrderSide.SELL;
|
|
2302
|
+
const slPriceError = useTpslPriceChecker({
|
|
2303
|
+
slPrice: stopLossPrice?.toString() ?? void 0,
|
|
2304
|
+
liqPrice: position.est_liq_price ?? null,
|
|
2305
|
+
side
|
|
2306
|
+
});
|
|
1866
2307
|
return /* @__PURE__ */ jsx(
|
|
1867
2308
|
TPSLTriggerPrice,
|
|
1868
2309
|
{
|
|
@@ -1871,6 +2312,7 @@ var TriggerPrice = (props) => {
|
|
|
1871
2312
|
direction: "column",
|
|
1872
2313
|
order: tpslOrder,
|
|
1873
2314
|
position,
|
|
2315
|
+
slPriceError,
|
|
1874
2316
|
tooltip: true
|
|
1875
2317
|
}
|
|
1876
2318
|
);
|
|
@@ -1993,7 +2435,8 @@ var TPSLTriggerPrice = (props) => {
|
|
|
1993
2435
|
rule: "price",
|
|
1994
2436
|
dp: symbolInfo[order.symbol]("quote_dp", 2),
|
|
1995
2437
|
children: props.stopLossPrice,
|
|
1996
|
-
prefix: !props.takeProfitPrice || direction === "column" ? /* @__PURE__ */ jsx(Text, { intensity: 54, children: `${t("tpsl.sl")} - ` }) : ""
|
|
2438
|
+
prefix: !props.takeProfitPrice || direction === "column" ? /* @__PURE__ */ jsx(Text, { intensity: 54, children: `${t("tpsl.sl")} - ` }) : "",
|
|
2439
|
+
suffix: /* @__PURE__ */ jsx(CloseToLiqPriceIcon, { slPriceError: props.slPriceError })
|
|
1997
2440
|
},
|
|
1998
2441
|
"sl"
|
|
1999
2442
|
)
|
|
@@ -2005,7 +2448,13 @@ var TPSLTriggerPrice = (props) => {
|
|
|
2005
2448
|
children.splice(1, 0, /* @__PURE__ */ jsx(Text, { children: "/" }, "split"));
|
|
2006
2449
|
}
|
|
2007
2450
|
return children;
|
|
2008
|
-
}, [
|
|
2451
|
+
}, [
|
|
2452
|
+
props.takeProfitPrice,
|
|
2453
|
+
props.stopLossPrice,
|
|
2454
|
+
order?.symbol,
|
|
2455
|
+
t,
|
|
2456
|
+
props.slPriceError
|
|
2457
|
+
]);
|
|
2009
2458
|
const content = /* @__PURE__ */ jsx(
|
|
2010
2459
|
"div",
|
|
2011
2460
|
{
|
|
@@ -2140,7 +2589,12 @@ var UnselIcon = () => {
|
|
|
2140
2589
|
);
|
|
2141
2590
|
};
|
|
2142
2591
|
var useColumn = (config) => {
|
|
2143
|
-
const {
|
|
2592
|
+
const {
|
|
2593
|
+
pnlNotionalDecimalPrecision,
|
|
2594
|
+
sharePnLConfig,
|
|
2595
|
+
onSymbolChange,
|
|
2596
|
+
positionReverse
|
|
2597
|
+
} = config;
|
|
2144
2598
|
const { t } = useTranslation();
|
|
2145
2599
|
useRef(Date.now().toString());
|
|
2146
2600
|
const column = useMemo(
|
|
@@ -2411,14 +2865,17 @@ var useColumn = (config) => {
|
|
|
2411
2865
|
title: null,
|
|
2412
2866
|
dataIndex: "close_position",
|
|
2413
2867
|
align: "right",
|
|
2414
|
-
width: 70,
|
|
2868
|
+
width: positionReverse ? 100 : 70,
|
|
2415
2869
|
fixed: "right",
|
|
2416
|
-
render() {
|
|
2417
|
-
return /* @__PURE__ */
|
|
2870
|
+
render(_, record) {
|
|
2871
|
+
return /* @__PURE__ */ jsxs(Flex, { gapX: 2, justify: "end", children: [
|
|
2872
|
+
/* @__PURE__ */ jsx(ClosePositionWidget, {}),
|
|
2873
|
+
positionReverse && /* @__PURE__ */ jsx(ReversePositionButton, { position: record })
|
|
2874
|
+
] });
|
|
2418
2875
|
}
|
|
2419
2876
|
}
|
|
2420
2877
|
],
|
|
2421
|
-
[pnlNotionalDecimalPrecision, sharePnLConfig, t]
|
|
2878
|
+
[pnlNotionalDecimalPrecision, sharePnLConfig, t, positionReverse]
|
|
2422
2879
|
);
|
|
2423
2880
|
return column;
|
|
2424
2881
|
};
|
|
@@ -2598,13 +3055,32 @@ var LiqPrice = (props) => {
|
|
|
2598
3055
|
var TPSLPrice = (props) => {
|
|
2599
3056
|
const { item } = props;
|
|
2600
3057
|
const { t } = useTranslation();
|
|
3058
|
+
const slPriceError = useTpslPriceChecker({
|
|
3059
|
+
slPrice: item.full_tp_sl?.sl_trigger_price?.toString() ?? void 0,
|
|
3060
|
+
liqPrice: item.est_liq_price ?? null,
|
|
3061
|
+
side: item.position_qty > 0 ? OrderSide.BUY : OrderSide.SELL
|
|
3062
|
+
});
|
|
3063
|
+
const partialSlPriceError = useTpslPriceChecker({
|
|
3064
|
+
slPrice: item.partial_tp_sl?.sl_trigger_price?.toString() ?? void 0,
|
|
3065
|
+
liqPrice: item.est_liq_price ?? null,
|
|
3066
|
+
side: item.position_qty > 0 ? OrderSide.BUY : OrderSide.SELL
|
|
3067
|
+
});
|
|
2601
3068
|
const fullTPSL = useMemo(() => {
|
|
2602
3069
|
if (item.full_tp_sl?.tp_trigger_price == null && item.full_tp_sl?.sl_trigger_price == null)
|
|
2603
3070
|
return /* @__PURE__ */ jsx(AddIcon, { positionType: PositionType.FULL });
|
|
2604
3071
|
return /* @__PURE__ */ jsxs(Flex, { className: "oui-gap-[2px]", children: [
|
|
2605
3072
|
item.full_tp_sl?.tp_trigger_price && /* @__PURE__ */ jsx(Text.numeral, { color: "buy", children: item.full_tp_sl.tp_trigger_price }),
|
|
2606
3073
|
item.full_tp_sl?.sl_trigger_price && "/",
|
|
2607
|
-
item.full_tp_sl?.sl_trigger_price && /* @__PURE__ */ jsx(
|
|
3074
|
+
item.full_tp_sl?.sl_trigger_price && /* @__PURE__ */ jsx(
|
|
3075
|
+
Text.numeral,
|
|
3076
|
+
{
|
|
3077
|
+
as: "div",
|
|
3078
|
+
color: "sell",
|
|
3079
|
+
suffix: /* @__PURE__ */ jsx(CloseToLiqPriceIcon, { slPriceError }),
|
|
3080
|
+
className: "oui-flex oui-items-center",
|
|
3081
|
+
children: item.full_tp_sl.sl_trigger_price
|
|
3082
|
+
}
|
|
3083
|
+
),
|
|
2608
3084
|
/* @__PURE__ */ jsx(TPSLEditIcon, {})
|
|
2609
3085
|
] });
|
|
2610
3086
|
}, [item.full_tp_sl]);
|
|
@@ -2614,7 +3090,16 @@ var TPSLPrice = (props) => {
|
|
|
2614
3090
|
return /* @__PURE__ */ jsxs(Flex, { className: "oui-gap-[2px]", itemAlign: "center", children: [
|
|
2615
3091
|
item.partial_tp_sl?.tp_trigger_price && /* @__PURE__ */ jsx(Text.numeral, { color: "buy", children: item.partial_tp_sl.tp_trigger_price }),
|
|
2616
3092
|
item.partial_tp_sl?.sl_trigger_price && "/",
|
|
2617
|
-
item.partial_tp_sl?.sl_trigger_price && /* @__PURE__ */ jsx(
|
|
3093
|
+
item.partial_tp_sl?.sl_trigger_price && /* @__PURE__ */ jsx(
|
|
3094
|
+
Text.numeral,
|
|
3095
|
+
{
|
|
3096
|
+
as: "div",
|
|
3097
|
+
color: "sell",
|
|
3098
|
+
suffix: /* @__PURE__ */ jsx(CloseToLiqPriceIcon, { slPriceError: partialSlPriceError }),
|
|
3099
|
+
className: "oui-flex oui-items-center",
|
|
3100
|
+
children: item.partial_tp_sl.sl_trigger_price
|
|
3101
|
+
}
|
|
3102
|
+
),
|
|
2618
3103
|
/* @__PURE__ */ jsx(Text, { children: `(${item.partial_tp_sl?.order_num})` }),
|
|
2619
3104
|
/* @__PURE__ */ jsx(TPSLEditIcon, {})
|
|
2620
3105
|
] });
|
|
@@ -2685,7 +3170,10 @@ var PositionCell = (props) => {
|
|
|
2685
3170
|
/* @__PURE__ */ jsx(Divider, { intensity: 6, className: "oui-w-full" }),
|
|
2686
3171
|
body,
|
|
2687
3172
|
/* @__PURE__ */ jsx(TPSLPrice, { ...rest }),
|
|
2688
|
-
|
|
3173
|
+
/* @__PURE__ */ jsxs(Flex, { justify: "between", width: "100%", gap: 2, children: [
|
|
3174
|
+
buttons,
|
|
3175
|
+
props.positionReverse && /* @__PURE__ */ jsx(ReversePositionButton, { position: props.item })
|
|
3176
|
+
] })
|
|
2689
3177
|
]
|
|
2690
3178
|
}
|
|
2691
3179
|
);
|
|
@@ -2852,12 +3340,14 @@ var Positions = (props) => {
|
|
|
2852
3340
|
pagination,
|
|
2853
3341
|
isLoading,
|
|
2854
3342
|
dataSource,
|
|
2855
|
-
onSymbolChange
|
|
3343
|
+
onSymbolChange,
|
|
3344
|
+
positionReverse
|
|
2856
3345
|
} = props;
|
|
2857
3346
|
const columns = useColumn({
|
|
2858
3347
|
pnlNotionalDecimalPrecision,
|
|
2859
3348
|
sharePnLConfig,
|
|
2860
|
-
onSymbolChange
|
|
3349
|
+
onSymbolChange,
|
|
3350
|
+
positionReverse
|
|
2861
3351
|
});
|
|
2862
3352
|
return /* @__PURE__ */ jsx(
|
|
2863
3353
|
AuthGuardDataTable,
|
|
@@ -2890,7 +3380,8 @@ var MobilePositions = (props) => {
|
|
|
2890
3380
|
pnlNotionalDecimalPrecision,
|
|
2891
3381
|
sharePnLConfig,
|
|
2892
3382
|
dataSource,
|
|
2893
|
-
onSymbolChange
|
|
3383
|
+
onSymbolChange,
|
|
3384
|
+
positionReverse
|
|
2894
3385
|
} = props;
|
|
2895
3386
|
return /* @__PURE__ */ jsx(
|
|
2896
3387
|
ListView,
|
|
@@ -2905,7 +3396,8 @@ var MobilePositions = (props) => {
|
|
|
2905
3396
|
index,
|
|
2906
3397
|
pnlNotionalDecimalPrecision,
|
|
2907
3398
|
sharePnLConfig,
|
|
2908
|
-
onSymbolChange
|
|
3399
|
+
onSymbolChange,
|
|
3400
|
+
positionReverse
|
|
2909
3401
|
}
|
|
2910
3402
|
) }) })
|
|
2911
3403
|
}
|
|
@@ -4833,6 +5325,6 @@ registerSimpleDialog(MarketCloseConfirmID, MarketCloseConfirm, {
|
|
|
4833
5325
|
closable: false
|
|
4834
5326
|
});
|
|
4835
5327
|
|
|
4836
|
-
export { CloseAllPositions, CloseAllPositionsWidget, CombinePositionsWidget, FundingFeeButton, FundingFeeHistoryUI, Liquidation, LiquidationWidget, MarketCloseConfirmID, MobileLiquidation, MobileLiquidationWidget, MobilePositionHistory, MobilePositionHistoryWidget, MobilePositionsWidget, PositionHistory, PositionHistoryWidget, PositionsTabName, PositionsWidget, sortList, useCloseAllPositionsScript, useLiquidationScript, usePositionHistoryScript, usePositionsRowContext, useSort, useTabSort };
|
|
5328
|
+
export { CloseAllPositions, CloseAllPositionsWidget, CombinePositionsWidget, FundingFeeButton, FundingFeeHistoryUI, Liquidation, LiquidationWidget, MarketCloseConfirmID, MobileLiquidation, MobileLiquidationWidget, MobilePositionHistory, MobilePositionHistoryWidget, MobilePositionsWidget, OrderInfoCard, PositionHistory, PositionHistoryWidget, PositionsTabName, PositionsWidget, ReversePosition, ReversePositionDialogId, ReversePositionWidget, sortList, useCloseAllPositionsScript, useLiquidationScript, usePositionHistoryScript, usePositionsRowContext, useReversePositionEnabled, useReversePositionScript, useSort, useTabSort };
|
|
4837
5329
|
//# sourceMappingURL=out.js.map
|
|
4838
5330
|
//# sourceMappingURL=index.mjs.map
|