feat(deal-ticket): enhance for fee discounts (#5353)
This commit is contained in:
parent
7588d0cd11
commit
a2b9b0da05
@ -77,12 +77,10 @@ export const DealTicketFeeDetails = ({
|
|||||||
label={
|
label={
|
||||||
<>
|
<>
|
||||||
{t('Fees')}
|
{t('Fees')}
|
||||||
{totalDiscountFactor ? (
|
{totalDiscountFactor !== '0' ? (
|
||||||
<Pill size="xxs" intent={Intent.Info} className="ml-1">
|
<Pill size="xxs" intent={Intent.Info} className="ml-1">
|
||||||
-
|
|
||||||
{formatNumberPercentage(
|
{formatNumberPercentage(
|
||||||
new BigNumber(totalDiscountFactor).multipliedBy(100),
|
new BigNumber(totalDiscountFactor).multipliedBy(100)
|
||||||
2
|
|
||||||
)}
|
)}
|
||||||
</Pill>
|
</Pill>
|
||||||
) : null}
|
) : null}
|
||||||
@ -105,10 +103,7 @@ export const DealTicketFeeDetails = ({
|
|||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
<FeesBreakdown
|
<FeesBreakdown
|
||||||
totalFeeAmount={feeEstimate?.totalFeeAmount}
|
feeEstimate={feeEstimate}
|
||||||
referralDiscountFactor={feeEstimate?.referralDiscountFactor}
|
|
||||||
volumeDiscountFactor={feeEstimate?.volumeDiscountFactor}
|
|
||||||
fees={feeEstimate?.fees}
|
|
||||||
feeFactors={market.fees.factors}
|
feeFactors={market.fees.factors}
|
||||||
symbol={assetSymbol}
|
symbol={assetSymbol}
|
||||||
decimals={assetDecimals}
|
decimals={assetDecimals}
|
||||||
|
@ -6,16 +6,19 @@ describe('getDiscountedFee', () => {
|
|||||||
discountedFee: '100',
|
discountedFee: '100',
|
||||||
volumeDiscount: '0',
|
volumeDiscount: '0',
|
||||||
referralDiscount: '0',
|
referralDiscount: '0',
|
||||||
|
totalDiscount: '0',
|
||||||
});
|
});
|
||||||
expect(getDiscountedFee('100', undefined, '0.1')).toEqual({
|
expect(getDiscountedFee('100', undefined, '0.1')).toEqual({
|
||||||
discountedFee: '90',
|
discountedFee: '90',
|
||||||
volumeDiscount: '10',
|
volumeDiscount: '10',
|
||||||
referralDiscount: '0',
|
referralDiscount: '0',
|
||||||
|
totalDiscount: '10',
|
||||||
});
|
});
|
||||||
expect(getDiscountedFee('100', '0.1', undefined)).toEqual({
|
expect(getDiscountedFee('100', '0.1', undefined)).toEqual({
|
||||||
discountedFee: '90',
|
discountedFee: '90',
|
||||||
volumeDiscount: '0',
|
volumeDiscount: '0',
|
||||||
referralDiscount: '10',
|
referralDiscount: '10',
|
||||||
|
totalDiscount: '10',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -24,6 +27,7 @@ describe('getDiscountedFee', () => {
|
|||||||
discountedFee: '',
|
discountedFee: '',
|
||||||
volumeDiscount: '0',
|
volumeDiscount: '0',
|
||||||
referralDiscount: '0',
|
referralDiscount: '0',
|
||||||
|
totalDiscount: '0',
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -35,7 +39,7 @@ describe('getTotalDiscountFactor', () => {
|
|||||||
volumeDiscountFactor: '0',
|
volumeDiscountFactor: '0',
|
||||||
referralDiscountFactor: '0',
|
referralDiscountFactor: '0',
|
||||||
})
|
})
|
||||||
).toEqual(0);
|
).toEqual('0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns volumeDiscountFactor if referralDiscountFactor is 0', () => {
|
it('returns volumeDiscountFactor if referralDiscountFactor is 0', () => {
|
||||||
@ -44,7 +48,7 @@ describe('getTotalDiscountFactor', () => {
|
|||||||
volumeDiscountFactor: '0.1',
|
volumeDiscountFactor: '0.1',
|
||||||
referralDiscountFactor: '0',
|
referralDiscountFactor: '0',
|
||||||
})
|
})
|
||||||
).toEqual(0.1);
|
).toEqual('-0.1');
|
||||||
});
|
});
|
||||||
it('returns referralDiscountFactor if volumeDiscountFactor is 0', () => {
|
it('returns referralDiscountFactor if volumeDiscountFactor is 0', () => {
|
||||||
expect(
|
expect(
|
||||||
@ -52,7 +56,7 @@ describe('getTotalDiscountFactor', () => {
|
|||||||
volumeDiscountFactor: '0',
|
volumeDiscountFactor: '0',
|
||||||
referralDiscountFactor: '0.1',
|
referralDiscountFactor: '0.1',
|
||||||
})
|
})
|
||||||
).toEqual(0.1);
|
).toEqual('-0.1');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('calculates discount using referralDiscountFactor and volumeDiscountFactor', () => {
|
it('calculates discount using referralDiscountFactor and volumeDiscountFactor', () => {
|
||||||
@ -61,6 +65,6 @@ describe('getTotalDiscountFactor', () => {
|
|||||||
volumeDiscountFactor: '0.2',
|
volumeDiscountFactor: '0.2',
|
||||||
referralDiscountFactor: '0.1',
|
referralDiscountFactor: '0.1',
|
||||||
})
|
})
|
||||||
).toBeCloseTo(0.28);
|
).toBe('-0.28');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -15,6 +15,7 @@ export const getDiscountedFee = (
|
|||||||
discountedFee: feeAmount,
|
discountedFee: feeAmount,
|
||||||
volumeDiscount: '0',
|
volumeDiscount: '0',
|
||||||
referralDiscount: '0',
|
referralDiscount: '0',
|
||||||
|
totalDiscount: '0',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const referralDiscount = new BigNumber(referralDiscountFactor || '0')
|
const referralDiscount = new BigNumber(referralDiscountFactor || '0')
|
||||||
@ -23,12 +24,14 @@ export const getDiscountedFee = (
|
|||||||
const volumeDiscount = new BigNumber(volumeDiscountFactor || '0')
|
const volumeDiscount = new BigNumber(volumeDiscountFactor || '0')
|
||||||
.multipliedBy((BigInt(feeAmount) - BigInt(referralDiscount)).toString())
|
.multipliedBy((BigInt(feeAmount) - BigInt(referralDiscount)).toString())
|
||||||
.toFixed(0, BigNumber.ROUND_FLOOR);
|
.toFixed(0, BigNumber.ROUND_FLOOR);
|
||||||
|
const totalDiscount = (
|
||||||
|
BigInt(referralDiscount) + BigInt(volumeDiscount)
|
||||||
|
).toString();
|
||||||
const discountedFee = (
|
const discountedFee = (
|
||||||
BigInt(feeAmount || '0') -
|
BigInt(feeAmount || '0') - BigInt(totalDiscount)
|
||||||
BigInt(referralDiscount) -
|
|
||||||
BigInt(volumeDiscount)
|
|
||||||
).toString();
|
).toString();
|
||||||
return {
|
return {
|
||||||
|
totalDiscount,
|
||||||
referralDiscount,
|
referralDiscount,
|
||||||
volumeDiscount,
|
volumeDiscount,
|
||||||
discountedFee,
|
discountedFee,
|
||||||
@ -39,16 +42,28 @@ export const getTotalDiscountFactor = (feeEstimate?: {
|
|||||||
volumeDiscountFactor?: string;
|
volumeDiscountFactor?: string;
|
||||||
referralDiscountFactor?: string;
|
referralDiscountFactor?: string;
|
||||||
}) => {
|
}) => {
|
||||||
if (!feeEstimate) {
|
if (
|
||||||
return 0;
|
!feeEstimate ||
|
||||||
|
(feeEstimate.referralDiscountFactor === '0' &&
|
||||||
|
feeEstimate.volumeDiscountFactor === '0')
|
||||||
|
) {
|
||||||
|
return '0';
|
||||||
}
|
}
|
||||||
const volumeFactor = Number(feeEstimate?.volumeDiscountFactor) || 0;
|
const volumeFactor = new BigNumber(
|
||||||
const referralFactor = Number(feeEstimate?.referralDiscountFactor) || 0;
|
feeEstimate?.volumeDiscountFactor || 0
|
||||||
if (!volumeFactor) {
|
).minus(1);
|
||||||
return referralFactor;
|
const referralFactor = new BigNumber(
|
||||||
|
feeEstimate?.referralDiscountFactor || 0
|
||||||
|
).minus(1);
|
||||||
|
if (volumeFactor.isZero()) {
|
||||||
|
return feeEstimate.referralDiscountFactor
|
||||||
|
? `-${feeEstimate.referralDiscountFactor}`
|
||||||
|
: '0';
|
||||||
}
|
}
|
||||||
if (!referralFactor) {
|
if (referralFactor.isZero()) {
|
||||||
return volumeFactor;
|
return feeEstimate.volumeDiscountFactor
|
||||||
|
? `-${feeEstimate.volumeDiscountFactor}`
|
||||||
|
: '0';
|
||||||
}
|
}
|
||||||
return 1 - (1 - volumeFactor) * (1 - referralFactor);
|
return volumeFactor.multipliedBy(referralFactor).minus(1).toString();
|
||||||
};
|
};
|
||||||
|
@ -14,13 +14,16 @@ describe('FeesBreakdown', () => {
|
|||||||
liquidityFee: '100',
|
liquidityFee: '100',
|
||||||
};
|
};
|
||||||
const props = {
|
const props = {
|
||||||
totalFeeAmount: '100',
|
|
||||||
fees,
|
|
||||||
feeFactors,
|
feeFactors,
|
||||||
symbol: 'USD',
|
symbol: 'USD',
|
||||||
decimals: 2,
|
decimals: 2,
|
||||||
referralDiscountFactor: '0.01',
|
|
||||||
volumeDiscountFactor: '0.01',
|
feeEstimate: {
|
||||||
|
referralDiscountFactor: '0.01',
|
||||||
|
volumeDiscountFactor: '0.01',
|
||||||
|
totalFeeAmount: '100',
|
||||||
|
fees,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
render(<FeesBreakdown {...props} />);
|
render(<FeesBreakdown {...props} />);
|
||||||
expect(screen.getByText('Maker fee').nextElementSibling).toHaveTextContent(
|
expect(screen.getByText('Maker fee').nextElementSibling).toHaveTextContent(
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
import { sumFeesFactors } from '@vegaprotocol/markets';
|
import { sumFeesFactors } from '@vegaprotocol/markets';
|
||||||
import type { TradeFee, FeeFactors } from '@vegaprotocol/types';
|
import type { FeeFactors } from '@vegaprotocol/types';
|
||||||
import {
|
import {
|
||||||
addDecimalsFormatNumber,
|
addDecimalsFormatNumber,
|
||||||
formatNumberPercentage,
|
formatNumberPercentage,
|
||||||
} from '@vegaprotocol/utils';
|
} from '@vegaprotocol/utils';
|
||||||
import BigNumber from 'bignumber.js';
|
import BigNumber from 'bignumber.js';
|
||||||
import { getDiscountedFee } from '../discounts';
|
import { getDiscountedFee, getTotalDiscountFactor } from '../discounts';
|
||||||
import { useT } from '../../use-t';
|
import { useT } from '../../use-t';
|
||||||
|
import { type useEstimateFees } from '../../hooks/use-estimate-fees';
|
||||||
|
|
||||||
const formatValue = (
|
const formatValue = (
|
||||||
value: string | number | null | undefined,
|
value: string | number | null | undefined,
|
||||||
@ -24,18 +25,16 @@ const FeesBreakdownItem = ({
|
|||||||
decimals,
|
decimals,
|
||||||
}: {
|
}: {
|
||||||
label: string;
|
label: string;
|
||||||
factor?: string;
|
factor?: string | number;
|
||||||
value: string;
|
value: string;
|
||||||
symbol?: string;
|
symbol?: string;
|
||||||
decimals: number;
|
decimals: number;
|
||||||
}) => (
|
}) => (
|
||||||
<>
|
<>
|
||||||
<dt className="col-span-2">{label}</dt>
|
<dt className="col-span-2">{label}</dt>
|
||||||
{factor && (
|
<dd className="text-right col-span-1">
|
||||||
<dd className="text-right col-span-1">
|
{factor ? formatNumberPercentage(new BigNumber(factor).times(100)) : ''}
|
||||||
{formatNumberPercentage(new BigNumber(factor).times(100))}
|
</dd>
|
||||||
</dd>
|
|
||||||
)}
|
|
||||||
<dd className="text-right col-span-3">
|
<dd className="text-right col-span-3">
|
||||||
{formatValue(value, decimals)} {symbol || ''}
|
{formatValue(value, decimals)} {symbol || ''}
|
||||||
</dd>
|
</dd>
|
||||||
@ -43,59 +42,35 @@ const FeesBreakdownItem = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const FeesBreakdown = ({
|
export const FeesBreakdown = ({
|
||||||
totalFeeAmount,
|
feeEstimate,
|
||||||
fees,
|
|
||||||
feeFactors,
|
feeFactors,
|
||||||
symbol,
|
symbol,
|
||||||
decimals,
|
decimals,
|
||||||
referralDiscountFactor,
|
|
||||||
volumeDiscountFactor,
|
|
||||||
}: {
|
}: {
|
||||||
totalFeeAmount?: string;
|
feeEstimate: ReturnType<typeof useEstimateFees>;
|
||||||
fees?: TradeFee;
|
|
||||||
feeFactors?: FeeFactors;
|
feeFactors?: FeeFactors;
|
||||||
symbol?: string;
|
symbol?: string;
|
||||||
decimals: number;
|
decimals: number;
|
||||||
referralDiscountFactor?: string;
|
|
||||||
volumeDiscountFactor?: string;
|
|
||||||
}) => {
|
}) => {
|
||||||
const t = useT();
|
const t = useT();
|
||||||
|
const { fees, totalFeeAmount, referralDiscountFactor, volumeDiscountFactor } =
|
||||||
|
feeEstimate || {};
|
||||||
if (!fees || !totalFeeAmount || totalFeeAmount === '0') return null;
|
if (!fees || !totalFeeAmount || totalFeeAmount === '0') return null;
|
||||||
|
|
||||||
const { discountedFee: discountedInfrastructureFee } = getDiscountedFee(
|
const totalDiscountFactor = getTotalDiscountFactor(feeEstimate);
|
||||||
fees.infrastructureFee,
|
const { discountedFee: discountedTotalFeeAmount, totalDiscount } =
|
||||||
referralDiscountFactor,
|
getDiscountedFee(
|
||||||
volumeDiscountFactor
|
totalFeeAmount,
|
||||||
);
|
referralDiscountFactor,
|
||||||
|
volumeDiscountFactor
|
||||||
const { discountedFee: discountedLiquidityFee } = getDiscountedFee(
|
);
|
||||||
fees.liquidityFee,
|
|
||||||
referralDiscountFactor,
|
|
||||||
volumeDiscountFactor
|
|
||||||
);
|
|
||||||
|
|
||||||
const { discountedFee: discountedMakerFee } = getDiscountedFee(
|
|
||||||
fees.makerFee,
|
|
||||||
referralDiscountFactor,
|
|
||||||
volumeDiscountFactor
|
|
||||||
);
|
|
||||||
|
|
||||||
const {
|
|
||||||
discountedFee: discountedTotalFeeAmount,
|
|
||||||
volumeDiscount,
|
|
||||||
referralDiscount,
|
|
||||||
} = getDiscountedFee(
|
|
||||||
totalFeeAmount,
|
|
||||||
referralDiscountFactor,
|
|
||||||
volumeDiscountFactor
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<dl className="grid grid-cols-6">
|
<dl className="grid grid-cols-6">
|
||||||
<FeesBreakdownItem
|
<FeesBreakdownItem
|
||||||
label={t('Infrastructure fee')}
|
label={t('Infrastructure fee')}
|
||||||
factor={feeFactors?.infrastructureFee}
|
factor={feeFactors?.infrastructureFee}
|
||||||
value={discountedInfrastructureFee}
|
value={fees.infrastructureFee}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
decimals={decimals}
|
decimals={decimals}
|
||||||
/>
|
/>
|
||||||
@ -103,7 +78,7 @@ export const FeesBreakdown = ({
|
|||||||
<FeesBreakdownItem
|
<FeesBreakdownItem
|
||||||
label={t('Liquidity fee')}
|
label={t('Liquidity fee')}
|
||||||
factor={feeFactors?.liquidityFee}
|
factor={feeFactors?.liquidityFee}
|
||||||
value={discountedLiquidityFee}
|
value={fees.liquidityFee}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
decimals={decimals}
|
decimals={decimals}
|
||||||
/>
|
/>
|
||||||
@ -111,35 +86,50 @@ export const FeesBreakdown = ({
|
|||||||
<FeesBreakdownItem
|
<FeesBreakdownItem
|
||||||
label={t('Maker fee')}
|
label={t('Maker fee')}
|
||||||
factor={feeFactors?.makerFee}
|
factor={feeFactors?.makerFee}
|
||||||
value={discountedMakerFee}
|
value={fees.makerFee}
|
||||||
symbol={symbol}
|
symbol={symbol}
|
||||||
decimals={decimals}
|
decimals={decimals}
|
||||||
/>
|
/>
|
||||||
{volumeDiscountFactor && volumeDiscount !== '0' && (
|
{totalDiscount && totalDiscount !== '0' ? (
|
||||||
<FeesBreakdownItem
|
<>
|
||||||
label={t('Volume discount')}
|
<FeesBreakdownItem
|
||||||
factor={volumeDiscountFactor}
|
label={t('Subtotal')}
|
||||||
value={volumeDiscount}
|
value={totalFeeAmount}
|
||||||
symbol={symbol}
|
factor={
|
||||||
decimals={decimals}
|
feeFactors ? sumFeesFactors(feeFactors)?.toString() : undefined
|
||||||
/>
|
}
|
||||||
|
symbol={symbol}
|
||||||
|
decimals={decimals}
|
||||||
|
/>
|
||||||
|
<div className="col-span-6 mt-2"></div>
|
||||||
|
<FeesBreakdownItem
|
||||||
|
label={t('Discount')}
|
||||||
|
factor={totalDiscountFactor}
|
||||||
|
value={`-${totalDiscount}`}
|
||||||
|
symbol={symbol}
|
||||||
|
decimals={decimals}
|
||||||
|
/>
|
||||||
|
<FeesBreakdownItem
|
||||||
|
label={t('Total')}
|
||||||
|
value={discountedTotalFeeAmount}
|
||||||
|
symbol={symbol}
|
||||||
|
decimals={decimals}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div className="col-span-6 mt-2"></div>
|
||||||
|
<FeesBreakdownItem
|
||||||
|
label={t('Total')}
|
||||||
|
factor={
|
||||||
|
feeFactors ? sumFeesFactors(feeFactors)?.toString() : undefined
|
||||||
|
}
|
||||||
|
value={totalFeeAmount}
|
||||||
|
symbol={symbol}
|
||||||
|
decimals={decimals}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
{referralDiscountFactor && referralDiscount !== '0' && (
|
|
||||||
<FeesBreakdownItem
|
|
||||||
label={t('Referral discount')}
|
|
||||||
factor={referralDiscountFactor}
|
|
||||||
value={referralDiscount}
|
|
||||||
symbol={symbol}
|
|
||||||
decimals={decimals}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<FeesBreakdownItem
|
|
||||||
label={t('Total fees')}
|
|
||||||
factor={feeFactors ? sumFeesFactors(feeFactors)?.toString() : undefined}
|
|
||||||
value={discountedTotalFeeAmount}
|
|
||||||
symbol={symbol}
|
|
||||||
decimals={decimals}
|
|
||||||
/>
|
|
||||||
</dl>
|
</dl>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT": "To cover the required margin, this amount will be drawn from your general ({{assetSymbol}}) account.",
|
"DEDUCTION_FROM_COLLATERAL_TOOLTIP_TEXT": "To cover the required margin, this amount will be drawn from your general ({{assetSymbol}}) account.",
|
||||||
"Deposit {{assetSymbol}}": "Deposit {{assetSymbol}}",
|
"Deposit {{assetSymbol}}": "Deposit {{assetSymbol}}",
|
||||||
"Devnet": "Devnet",
|
"Devnet": "Devnet",
|
||||||
|
"Discount": "Discount",
|
||||||
"EST_TOTAL_MARGIN_TOOLTIP_TEXT": "Estimated total margin that will cover open positions, active orders and this order.",
|
"EST_TOTAL_MARGIN_TOOLTIP_TEXT": "Estimated total margin that will cover open positions, active orders and this order.",
|
||||||
"Est. uncrossing price": "Est. uncrossing price",
|
"Est. uncrossing price": "Est. uncrossing price",
|
||||||
"Est. uncrossing vol": "Est. uncrossing vol",
|
"Est. uncrossing vol": "Est. uncrossing vol",
|
||||||
@ -78,6 +79,7 @@
|
|||||||
"Size": "Size",
|
"Size": "Size",
|
||||||
"Size cannot be lower than {{sizeStep}}": "Size cannot be lower than {{sizeStep}}",
|
"Size cannot be lower than {{sizeStep}}": "Size cannot be lower than {{sizeStep}}",
|
||||||
"sizeAtPrice-market": "market",
|
"sizeAtPrice-market": "market",
|
||||||
|
"Subtotal": "Subtotal",
|
||||||
"Stagnet": "Stagnet",
|
"Stagnet": "Stagnet",
|
||||||
"Stop": "Stop",
|
"Stop": "Stop",
|
||||||
"Stop Limit": "Stop Limit",
|
"Stop Limit": "Stop Limit",
|
||||||
@ -104,7 +106,7 @@
|
|||||||
"Time in force": "Time in force",
|
"Time in force": "Time in force",
|
||||||
"TIME_IN_FORCE_SELECTOR_LIQUIDITY_MONITORING_AUCTION": "This market is in auction until it reaches <0>sufficient liquidity</0>. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.",
|
"TIME_IN_FORCE_SELECTOR_LIQUIDITY_MONITORING_AUCTION": "This market is in auction until it reaches <0>sufficient liquidity</0>. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.",
|
||||||
"TIME_IN_FORCE_SELECTOR_PRICE_MONITORING_AUCTION": "This market is in auction due to <0>high price volatility</0>. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.",
|
"TIME_IN_FORCE_SELECTOR_PRICE_MONITORING_AUCTION": "This market is in auction due to <0>high price volatility</0>. Until the auction ends, you can only place GFA, GTT, or GTC limit orders.",
|
||||||
"Total fees": "Total fees",
|
"Total": "Total",
|
||||||
"Total margin available": "Total margin available",
|
"Total margin available": "Total margin available",
|
||||||
"TOTAL_MARGIN_AVAILABLE": "Total margin available = general {{assetSymbol}} balance ({{generalAccountBalance}} {{assetSymbol}}) + margin balance ({{marginAccountBalance}} {{assetSymbol}}) - maintenance level ({{marginMaintenance}} {{assetSymbol}}).",
|
"TOTAL_MARGIN_AVAILABLE": "Total margin available = general {{assetSymbol}} balance ({{generalAccountBalance}} {{assetSymbol}}) + margin balance ({{marginAccountBalance}} {{assetSymbol}}) - maintenance level ({{marginMaintenance}} {{assetSymbol}}).",
|
||||||
"Trading terminated": "Trading terminated",
|
"Trading terminated": "Trading terminated",
|
||||||
|
Loading…
Reference in New Issue
Block a user