diff --git a/hooks/useEstimateSwap.ts b/hooks/useEstimateSwap.ts index ab2bf1cc..ff9bafbf 100644 --- a/hooks/useEstimateSwap.ts +++ b/hooks/useEstimateSwap.ts @@ -37,17 +37,18 @@ export const useEstimateSwap = ({ forceUpdate, }); useEffect(() => { - if (dclEstimateResult?.tag && v1EstimateResult?.tag && validator()) { + if ( + dclEstimateResult?.tag && + v1EstimateResult?.tag && + validator() && + !v1Loading && + !dclLoading + ) { getBestEstimateResult(); setEstimateLoading(false); } - if (tokenIn_amount == "0" || !tokenIn_amount) { - setEstimateResult((prev: any) => { - if (prev?.amount_out !== "0" || !prev?.loadingComplete) { - return { ...prev, amount_out: "0", loadingComplete: true }; - } - return prev; - }); + if (!Number(tokenIn_amount || 0)) { + setEstimateLoading(false); } }, [ dclEstimateResult?.tag, @@ -55,9 +56,13 @@ export const useEstimateSwap = ({ dclEstimateResult?.amount_out, v1EstimateResult?.amount_out, tokenIn_amount, + v1Loading, + dclLoading, ]); useEffect(() => { - setEstimateLoading(v1Loading || dclLoading); + if (v1Loading || dclLoading) { + setEstimateLoading(true); + } }, [v1Loading, dclLoading]); function getBestEstimateResult() { const { amount_out: dcl_amount_out } = dclEstimateResult!; @@ -65,10 +70,10 @@ export const useEstimateSwap = ({ console.log(dcl_amount_out, v1_amount_out, "dcl_amount_out, v1_amount_out"); // best is v1 if (new Decimal(v1_amount_out || 0).gt(dcl_amount_out || 0)) { - setEstimateResult({ ...v1EstimateResult, loadingComplete: true }); + setEstimateResult(v1EstimateResult); } else if (new Decimal(dcl_amount_out || 0).gt(v1_amount_out || 0)) { // best is dcl - setEstimateResult({ ...dclEstimateResult, loadingComplete: true }); + setEstimateResult(dclEstimateResult); } } function validator() { diff --git a/hooks/useLiqPrice.ts b/hooks/useLiqPrice.ts index 4fcbb83b..c7bd1183 100644 --- a/hooks/useLiqPrice.ts +++ b/hooks/useLiqPrice.ts @@ -45,36 +45,58 @@ export function useLiqPrice({ const token_c_price = token_c_asset?.price?.usd || 0; const token_p_price = token_p_asset?.price?.usd || 0; const token_d_price = token_d_asset?.price?.usd || 0; - const hp_fee_decimals = get_hp_fee({ + const hp_fee_amount = get_hp_fee({ debt_cap, uahpi: token_d_asset.uahpi, uahpi_at_open, }); const hp_fee = new Decimal(token_d_price).mul( shrinkToken( - hp_fee_decimals, + hp_fee_amount, token_d_asset.metadata.decimals + token_d_asset.config.extra_decimals, ), ); + // (token_c_value + token_p_value) * percent > total_debt + total_hp_fee if (position_type == "Long") { - const p_liq_price = new Decimal(token_d_amount || 0) - .mul(token_d_price) + // c and d are the same token + // const left = new Decimal(token_c_amount || 0) + // .mul(token_c_price) + // .plus(new Decimal(token_p_amount || 0).mul(token_p_price)) + // .mul(safety_buffer); + // const right = new Decimal(token_d_amount || 0).plus(hp_fee_amount || 0).mul(token_c_price); + const liq_price = new Decimal(token_d_amount || 0) .plus(hp_fee) - .div(safety_buffer) - .minus(new Decimal(token_c_amount || 0).mul(token_c_price)) - .div(token_p_amount) + .minus(new Decimal(token_c_amount || 0).mul(safety_buffer)) + .div(new Decimal(token_p_amount || 0).mul(safety_buffer)) .toFixed(); - return p_liq_price; + // const p_liq_price = new Decimal(token_d_amount || 0) + // .mul(token_d_price) + // .plus(hp_fee) + // .div(safety_buffer) + // .minus(new Decimal(token_c_amount || 0).mul(token_c_price)) + // .div(token_p_amount) + // .toFixed(); + return liq_price; } else { - // Short - const d_liq_price = new Decimal(token_c_amount) - .mul(token_c_price) - .plus(new Decimal(token_p_amount).mul(token_p_price)) + // Short c and p are the same token + // const left = new Decimal(token_c_amount || 0) + // .mul(token_c_price) + // .plus(new Decimal(token_p_amount || 0).mul(token_c_price)) + // .mul(safety_buffer); + // const right = new Decimal(token_d_amount || 0).plus(hp_fee_amount || 0).mul(token_d_price); + const liq_price = new Decimal(token_c_amount || 0) + .plus(token_p_amount || 0) .mul(safety_buffer) - .minus(hp_fee) - .div(token_d_amount) + .div(new Decimal(token_d_amount || 0).plus(hp_fee)) .toFixed(); - return d_liq_price; + // const d_liq_price = new Decimal(token_c_amount) + // .mul(token_c_price) + // .plus(new Decimal(token_p_amount).mul(token_p_price)) + // .mul(safety_buffer) + // .minus(hp_fee) + // .div(token_d_amount) + // .toFixed(); + return liq_price; } } diff --git a/interfaces/margin.ts b/interfaces/margin.ts index ae1be4d8..d19c7b8b 100644 --- a/interfaces/margin.ts +++ b/interfaces/margin.ts @@ -42,7 +42,6 @@ export interface IEstimateResult { fee: number; tag: string; from: "v1" | "dcl"; - loadingComplete?: boolean; } export interface IPool { amount_in?: string; diff --git a/screens/Trading/components/ChangeCollateralMobile.tsx b/screens/Trading/components/ChangeCollateralMobile.tsx index c9ec75bc..77bca076 100644 --- a/screens/Trading/components/ChangeCollateralMobile.tsx +++ b/screens/Trading/components/ChangeCollateralMobile.tsx @@ -591,13 +591,13 @@ const ChangeCollateralMobile: FC = ({ open, onClose {+(inputValue || 0) > 0 ? ( <> - ${beautifyPrice(LiqPrice)} + {beautifyPrice(LiqPrice)} -

${beautifyPrice(LiqPriceNew)}

+

{beautifyPrice(LiqPriceNew)}

) : ( -

${beautifyPrice(LiqPrice)}

+

{beautifyPrice(LiqPrice)}

)} @@ -732,13 +732,13 @@ const ChangeCollateralMobile: FC = ({ open, onClose {+(inputValue || 0) > 0 ? ( <> - ${beautifyPrice(LiqPrice)} + {beautifyPrice(LiqPrice)} -

${beautifyPrice(LiqPriceNew)}

+

{beautifyPrice(LiqPriceNew)}

) : ( -

${beautifyPrice(LiqPrice)}

+

{beautifyPrice(LiqPrice)}

)} diff --git a/screens/Trading/components/ConfirmMobile.tsx b/screens/Trading/components/ConfirmMobile.tsx index 2a0efb27..08b261e3 100644 --- a/screens/Trading/components/ConfirmMobile.tsx +++ b/screens/Trading/components/ConfirmMobile.tsx @@ -287,7 +287,7 @@ const ConfirmMobile: React.FC = ({
Liq. Price
-
${beautifyPrice(confirmInfo.LiqPrice)}
+
{beautifyPrice(confirmInfo.LiqPrice)}
{isMinTokenPAmount && ( diff --git a/screens/Trading/components/Table.tsx b/screens/Trading/components/Table.tsx index 89c27b03..285f74bb 100644 --- a/screens/Trading/components/Table.tsx +++ b/screens/Trading/components/Table.tsx @@ -290,7 +290,7 @@ const TradingTable = ({ const sortList = { close_timestamp: "Close time", open_timestamp: "Opening time", - pnl: "PNL & ROE", + pnl: "PNL", }; return (
@@ -339,7 +339,7 @@ const TradingTable = ({ Entry Price Index Price Liq. Price - PNL & ROE + PNL
handleSort("open_ts")} @@ -438,7 +438,7 @@ const TradingTable = ({ Fee handleSortChange("pnl")}>
- PNL & ROE + PNL { return !isMobile ? ( - {`${getSymbolById(assetP.token_id, assetP.metadata?.symbol)}/${getSymbolById( - assetD.token_id, - assetD.metadata?.symbol, - )}`} + {record.trend === "long" + ? `${getSymbolById(assetP.token_id, assetP.metadata?.symbol)}/${getSymbolById( + assetD.token_id, + assetD.metadata?.symbol, + )}` + : `${getSymbolById(assetD.token_id, assetD.metadata?.symbol)}/${getSymbolById( + assetP.token_id, + assetP.metadata?.symbol, + )}`}
{ ), ) : null} + + {record.trend === "long" + ? `${getSymbolById(assetP.token_id, assetP.metadata?.symbol)}` + : `${getSymbolById(assetD.token_id, assetD.metadata?.symbol)}`} + {beautifyPrice( @@ -74,17 +84,11 @@ const HistoryRow = ({ key, index, record, assetP, assetD, assetC }) => { ) : ( "-" )} -

- {getSymbolById(assetC.token_id, assetC.metadata?.symbol)} -

{record.price !== "0" ? {beautifyPrice(Number(record.price))} : "-"} -

- {getSymbolById(assetC.token_id, assetC.metadata?.symbol)} -

@@ -104,9 +108,6 @@ const HistoryRow = ({ key, index, record, assetP, assetD, assetC }) => { {record.pnl !== "0" ? beautifyPrice(Math.abs(record.pnl * record.c_token_price), false, 3, 3) : ""} - {/*

- {getSymbolById(assetC.token_id, assetC.metadata?.symbol)} -

*/}
@@ -194,6 +195,11 @@ const HistoryRow = ({ key, index, record, assetP, assetD, assetC }) => { ), ) : null} + + {record.trend === "long" + ? `${getSymbolById(assetP.token_id, assetP.metadata?.symbol)}` + : `${getSymbolById(assetD.token_id, assetD.metadata?.symbol)}`} +

@@ -267,7 +273,7 @@ const HistoryRow = ({ key, index, record, assetP, assetD, assetC }) => {

{record.close_type}

- PNL & ROE + PNL

0 ? "text-green-150" : record.pnl < 0 ? "text-red-150" : "" diff --git a/screens/Trading/components/Table/PositionRow.tsx b/screens/Trading/components/Table/PositionRow.tsx index 772f3b63..b89987ac 100644 --- a/screens/Trading/components/Table/PositionRow.tsx +++ b/screens/Trading/components/Table/PositionRow.tsx @@ -98,7 +98,7 @@ const PositionRow = ({ const netValue = parseTokenValue(item.token_c_info.balance, decimalsC) * (priceC || 0); const collateral = parseTokenValue(item.token_c_info.balance, decimalsC); - const assetLabel = positionType.label === "Long" ? symbolD : symbolP; + const assetLabel = positionType.label === "Long" ? symbolP : symbolD; const indexPrice = positionType.label === "Long" ? priceP / priceD : priceD / priceP; const openTime = new Date(Number(item.open_ts) / 1e6); const uahpi: any = isMainStream @@ -144,7 +144,10 @@ const PositionRow = ({

-

{beautifyPrice(size)}

+

+ {" "} + {beautifyPrice(size)} {assetLabel} +

({beautifyPrice(sizeValue, true, 3, 3)})
@@ -174,16 +177,12 @@ const PositionRow = ({ ) : ( - )} - {assetLabel}
-
- {beautifyPrice(indexPrice)} - {assetLabel} -
+
{beautifyPrice(indexPrice)}
- ${beautifyPrice(LiqPrice)} + {beautifyPrice(LiqPrice)}

0 ? "text-green-150" : pnl < 0 ? "text-red-150" : "text-gray-400"}`}> {pnl === 0 ? "" : `${pnl > 0 ? `+$` : `-$`}`} @@ -258,7 +257,10 @@ const PositionRow = ({

-

{beautifyPrice(size)}

+

+ {" "} + {beautifyPrice(size)} {assetLabel} +

({beautifyPrice(sizeValue, true, 3, 3)})

Size

@@ -291,9 +293,7 @@ const PositionRow = ({

Entry Price

{entryPrice !== null ? ( - - {beautifyPrice(entryPrice)} {assetLabel} - + {beautifyPrice(entryPrice)} ) : ( - )} @@ -301,20 +301,18 @@ const PositionRow = ({

Index Price

-

- {beautifyPrice(indexPrice)} {assetLabel} -

+

{beautifyPrice(indexPrice)}

Liq. Price

-

${beautifyPrice(LiqPrice)}

+

{beautifyPrice(LiqPrice)}

Opening time

{new Date(openTime).toLocaleString()}

- PNL & ROE{" "} + PNL{" "}

0 ? "text-green-150" : pnl < 0 ? "text-red-150" : "text-gray-400" diff --git a/screens/Trading/components/TradingOperate.tsx b/screens/Trading/components/TradingOperate.tsx index bb3ed4b1..8ef90fcb 100644 --- a/screens/Trading/components/TradingOperate.tsx +++ b/screens/Trading/components/TradingOperate.tsx @@ -71,7 +71,6 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => const [warnTip, setWarnTip] = useState(""); const [LiqPrice, setLiqPrice] = useState(""); const [forceUpdate, setForceUpdate] = useState(0); - const [lastTokenInAmount, setLastTokenInAmount] = useState(0); const customInputRef = useRef(null); const accountId = useAppSelector(getAccountId); const { filteredTokenTypeMap } = useRegisterTokenType(); @@ -129,14 +128,17 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => /** * longInput shortInput deal start * */ + // TODOXX useEffect(() => { const inputUsdCharcate1 = getAssetPrice(ReduxcategoryAssets1); const inputUsdCharcate2 = getAssetPrice(ReduxcategoryAssets2); if (inputUsdCharcate1 && estimateData) { + // out put input updateOutput(activeTab, inputUsdCharcate1); } if (inputUsdCharcate2) { + // swap token in amount updateInputAmounts(activeTab, inputUsdCharcate2, inputUsdCharcate1); } }, [ @@ -145,10 +147,9 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => rangeMount, estimateData, slippageTolerance, - forceUpdate, tokenInAmount, - activeTab, // Add activeTab to dependencies if needed ReduxcategoryAssets1, + ReduxcategoryAssets2, ]); // update liq price for long useDebounce( @@ -156,20 +157,27 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => if (ReduxcategoryAssets2 && ReduxcategoryAssets1 && estimateData) { if (activeTab == "long" && +(longInput || 0) > 0 && (longOutput || 0) > 0) { const safetyBufferFactor = 1 - min_safety_buffer / 10000; - const assetPrice = getAssetPrice(ReduxcategoryAssets2) as any; - const token_c_value = new Decimal(longInput).mul(assetPrice || 0); - const token_d_value = token_c_value.mul(rangeMount || 0); - const liqPriceX = token_d_value - .div(safetyBufferFactor) - .minus(token_c_value) - .div(longOutput) + // const assetPrice = getAssetPrice(ReduxcategoryAssets2) as any; + // const token_c_value = new Decimal(longInput).mul(assetPrice || 0); + // const token_d_value = token_c_value.mul(rangeMount || 0); + const token_c_amount = longInput; + const token_d_amount = new Decimal(token_c_amount || 0).mul(rangeMount || 0); + const token_p_amount = longOutput; + const liq_price = new Decimal(token_d_amount || 0) + .minus(new Decimal(token_c_amount || 0).mul(safetyBufferFactor)) + .div(new Decimal(token_p_amount || 0).mul(safetyBufferFactor)) .toFixed(); - setLiqPrice(liqPriceX || "0"); + // const liqPriceX = token_d_value + // .div(safetyBufferFactor) + // .minus(token_c_value) + // .div(longOutput) + // .toFixed(); + setLiqPrice(liq_price || "0"); } } }, 200, - [activeTab, longOutput, longInput], + [activeTab, estimateData], ); // update liq price for short useDebounce( @@ -182,41 +190,53 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => +(shortOutput || 0) > 0 ) { const safetyBufferFactor = 1 - min_safety_buffer / 10000; - const assetPrice = getAssetPrice(ReduxcategoryAssets2) as any; - const token_c_value = new Decimal(shortInput).mul(assetPrice || 0); - const token_p_value = new Decimal(estimateData.amount_out).mul(assetPrice || 0); - const liqPriceX = new Decimal(token_c_value) - .plus(token_p_value) + // const assetPrice = getAssetPrice(ReduxcategoryAssets2) as any; + // const token_c_value = new Decimal(shortInput).mul(assetPrice || 0); + // const token_p_value = new Decimal(estimateData.amount_out).mul(assetPrice || 0); + const token_c_amount = shortInput; + const token_p_amount = estimateData.amount_out; + const token_d_amount = shortOutput; + + // const liq_price = new Decimal(token_c_amount || 0) + // .plus(token_p_amount || 0) + // .mul(safety_buffer) + // .div(new Decimal(token_d_amount || 0).plus(hp_fee)) + // .toFixed(); + const liq_price = new Decimal(token_c_amount || 0) + .plus(token_p_amount || 0) .mul(safetyBufferFactor) - .div(shortOutput); - setLiqPrice(liqPriceX.toFixed()); + .div(token_d_amount) + .toFixed(); + // const liqPriceX = new Decimal(token_c_value) + // .plus(token_p_value) + // .mul(safetyBufferFactor) + // .div(shortOutput); + setLiqPrice(liq_price || "0"); } } - setForceUpdateLoading(!estimateData?.loadingComplete); }, 200, - [estimateData, activeTab, shortOutput, shortInput], + [estimateData, activeTab], ); - // update price and make refresh icon spin + // force estimating useEffect(() => { const interval = setInterval(() => { - if (tokenInAmount === lastTokenInAmount && longInput) { - setTokenInAmount((prev) => prev); + // TODOXX + if (tokenInAmount) { setForceUpdate((prev) => prev + 1); setForceUpdateLoading(true); - } else { - setLastTokenInAmount(tokenInAmount); } }, 20_000); return () => clearInterval(interval); - }, [tokenInAmount, lastTokenInAmount]); + }, [tokenInAmount]); + // TODOXX // for same input, forceUpdateLoading is true useEffect(() => { if (forceUpdateLoading) { const timer = setTimeout(() => { setForceUpdateLoading(false); - }, 4000); + }, 1000); return () => clearTimeout(timer); } @@ -363,7 +383,6 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => dispatch(setReduxActiveTab(tabString)); setActiveTab(tabString); initCateState(tabString); - setForceUpdate((prev) => prev + 1); }; const getTabClassName = (tabName: string) => { return activeTab === tabName @@ -458,6 +477,7 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => function getAssetPrice(categoryId) { return categoryId ? combinedAssetsData[categoryId["token_id"]]?.price?.usd : 0; } + // TODOXX function updateOutput(tab: string, inputUsdCharcate: number) { /** * @param inputUsdCharcate category1 current price @@ -481,6 +501,7 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => outputUsdSetter(inputUsdCharcate * tokenInAmount); } } + // TODOXX function updateInputAmounts(tab, inputUsdCharcate2, inputUsdCharcate1) { /** * @param inputUsdCharcate2 category2 current price @@ -575,6 +596,7 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => if (!tokenInAmount || forceUpdateLoading) { return; } + // TODOXX setForceUpdate((prev) => prev + 1); setForceUpdateLoading(true); }} @@ -653,7 +675,6 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => tokenList={isMainStream ? categoryAssets2 : categoryAssets2MEME} type="cate2" isMemeCategory={!isMainStream} - setForceUpdate={() => setForceUpdate((prev) => prev + 1)} />

${longInputUsd.toFixed(2)}

@@ -696,7 +717,7 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) =>
Liq. Price
- ${beautifyPrice(LiqPrice)} + {beautifyPrice(LiqPrice)}
Fee
@@ -791,7 +812,6 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) => tokenList={isMainStream ? categoryAssets2 : categoryAssets2MEME} type="cate2" isMemeCategory={!isMainStream} - setForceUpdate={() => setForceUpdate((prev) => prev + 1)} />

${shortInputUsd.toFixed(2)}

@@ -833,7 +853,7 @@ const TradingOperate: React.FC = ({ onMobileClose, id }) =>
Liq. Price
- ${beautifyPrice(LiqPrice)} + {beautifyPrice(LiqPrice)}
Fee
diff --git a/screens/Trading/components/tokenbox.tsx b/screens/Trading/components/tokenbox.tsx index 8e56b74e..fc666082 100644 --- a/screens/Trading/components/tokenbox.tsx +++ b/screens/Trading/components/tokenbox.tsx @@ -22,14 +22,12 @@ interface TradingTokenInter { tokenList: Array; type: string; setMaxInputBanlance?: (key: string) => void; - setForceUpdate?: () => void; isMemeCategory?: boolean; } const TradingToken: React.FC = ({ tokenList, type, setMaxInputBanlance, - setForceUpdate, isMemeCategory, }) => { let timer: NodeJS.Timeout; @@ -86,7 +84,6 @@ const TradingToken: React.FC = ({ } else { console.warn(`Unsupported type: ${type}`); } - setForceUpdate && setForceUpdate(); setShowModal(false); }; diff --git a/screens/Trading/index.tsx b/screens/Trading/index.tsx index ad3dce65..34b73dbd 100644 --- a/screens/Trading/index.tsx +++ b/screens/Trading/index.tsx @@ -1,5 +1,6 @@ import { useEffect, useMemo, useState } from "react"; import { useRouter } from "next/router"; +import Decimal from "decimal.js"; import { useAppDispatch, useAppSelector } from "../../redux/hooks"; import { LayoutBox } from "../../components/LayoutContainer/LayoutContainer"; import { ComeBackIcon, MemeTagIcon, TokenArrow } from "./components/TradingIcon"; @@ -29,6 +30,7 @@ import { getSymbolById } from "../../transformers/nearSymbolTrans"; import { useRegisterTokenType } from "../../hooks/useRegisterTokenType"; const Trading = () => { + const [open, setOpen] = useState(false); const isMobile = isMobileDevice(); const { query } = useRouterQuery(); const accountId = useAccountId(); @@ -176,9 +178,15 @@ const Trading = () => { return () => clearInterval(intervalId); // Cleanup on unmount }, [id]); - - const [open, setOpen] = useState(false); - // + const indexPrice = useMemo(() => { + if (currentTokenCate1?.token_id && currentTokenCate2?.token_id) { + const currentTokenCate1Price = currentTokenCate1?.price?.usd || 0; + const currentTokenCate2Price = currentTokenCate2?.price?.usd || 0; + if (new Decimal(currentTokenCate2Price).gt(0)) { + return new Decimal(currentTokenCate1Price).div(currentTokenCate2Price).toFixed(); + } + } + }, [currentTokenCate1, currentTokenCate2]); return ( {isLoading ? ( @@ -265,7 +273,7 @@ const Trading = () => { )}
- ${beautifyPrice(combinedAssetsData[id]?.price?.usd || 0)} + {beautifyPrice(indexPrice)} {/* total v */}
@@ -307,9 +315,7 @@ const Trading = () => { currentTokenCate1?.metadata?.symbol, )}

-

- ${beautifyPrice(combinedAssetsData[id]?.price?.usd || 0)} -

+

{beautifyPrice(indexPrice)}

{/* cate2 */} diff --git a/utils/beautyNumber.tsx b/utils/beautyNumber.tsx index 413a768a..42feefa9 100644 --- a/utils/beautyNumber.tsx +++ b/utils/beautyNumber.tsx @@ -1,7 +1,7 @@ import { twMerge } from "tailwind-merge"; export const beautifyPrice = ( - num: string | number, + num: string | number | undefined, isDollar: boolean = false, decimalPlaces: number = 5, digitsPlaces: number = 4,