add recent trade volume alert
This commit is contained in:
parent
5732910003
commit
bf626cc8ef
|
@ -1,5 +1,13 @@
|
|||
const Label = ({ text, optional }: { text: string; optional?: boolean }) => (
|
||||
<p className="mb-2 text-left text-sm text-th-fgd-3">
|
||||
const Label = ({
|
||||
text,
|
||||
optional,
|
||||
className,
|
||||
}: {
|
||||
text: string
|
||||
optional?: boolean
|
||||
className?: string
|
||||
}) => (
|
||||
<p className={`mb-2 text-left text-sm text-th-fgd-3 ${className}`}>
|
||||
{text}{' '}
|
||||
{optional ? (
|
||||
<span className="ml-1 text-xs text-th-fgd-4">(Optional)</span>
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
import { ModalProps } from '../../types/modal'
|
||||
import Modal from '../shared/Modal'
|
||||
import Button, { LinkButton } from '../shared/Button'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
import { SOUND_SETTINGS_KEY, TRADE_VOLUME_ALERT_KEY } from 'utils/constants'
|
||||
import Label from '@components/forms/Label'
|
||||
import { useState } from 'react'
|
||||
import Switch from '@components/forms/Switch'
|
||||
import { INITIAL_SOUND_SETTINGS } from '@components/settings/SoundSettings'
|
||||
import NumberFormat, { NumberFormatValues } from 'react-number-format'
|
||||
import { Howl } from 'howler'
|
||||
import { PlayIcon } from '@heroicons/react/20/solid'
|
||||
|
||||
const volumeAlertSound = new Howl({
|
||||
src: ['/sounds/trade-buy.mp3'],
|
||||
volume: 0.8,
|
||||
})
|
||||
|
||||
export const DEFAULT_VOLUME_ALERT_SETTINGS = { seconds: 30, value: 10000 }
|
||||
|
||||
const INPUT_CLASSES =
|
||||
'h-12 w-full rounded-md border border-th-input-border bg-th-input-bkg px-3 font-mono text-base text-th-fgd-1 focus:border-th-input-border-hover focus:outline-none md:hover:border-th-input-border-hover'
|
||||
|
||||
const TradeVolumeAlertModal = ({ isOpen, onClose }: ModalProps) => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
const [soundSettings, setSoundSettings] = useLocalStorageState(
|
||||
SOUND_SETTINGS_KEY,
|
||||
INITIAL_SOUND_SETTINGS
|
||||
)
|
||||
const [alertSettings, setAlertSettings] = useLocalStorageState(
|
||||
TRADE_VOLUME_ALERT_KEY,
|
||||
DEFAULT_VOLUME_ALERT_SETTINGS
|
||||
)
|
||||
const [formValues, setFormValues] = useState(alertSettings)
|
||||
|
||||
const handleSave = () => {
|
||||
setAlertSettings(formValues)
|
||||
onClose()
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose}>
|
||||
<h2 className="mb-2">{t('trade:volume-alert')}</h2>
|
||||
<p className="mb-2">{t('trade:volume-alert-desc')}</p>
|
||||
<LinkButton
|
||||
className="mb-4 flex w-full items-center justify-center"
|
||||
onClick={() => volumeAlertSound.play()}
|
||||
>
|
||||
<PlayIcon className="mr-1.5 h-4 w-4" />
|
||||
<span>{t('trade:preview-sound')}</span>
|
||||
</LinkButton>
|
||||
<div className="flex items-center justify-between rounded-md bg-th-bkg-3 p-3">
|
||||
<p>{t('trade:activate-volume-alert')}</p>
|
||||
<Switch
|
||||
className="text-th-fgd-3"
|
||||
checked={soundSettings['recent-trades']}
|
||||
onChange={() =>
|
||||
setSoundSettings({
|
||||
...soundSettings,
|
||||
'recent-trades': !soundSettings['recent-trades'],
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
{soundSettings['recent-trades'] ? (
|
||||
<>
|
||||
<div className="my-4">
|
||||
<Label text={t('trade:interval-seconds')} />
|
||||
<NumberFormat
|
||||
name="seconds"
|
||||
id="seconds"
|
||||
inputMode="numeric"
|
||||
thousandSeparator=","
|
||||
allowNegative={false}
|
||||
decimalScale={0}
|
||||
isNumericString={true}
|
||||
className={INPUT_CLASSES}
|
||||
placeholder="e.g. 30"
|
||||
value={formValues.seconds}
|
||||
onValueChange={(e: NumberFormatValues) =>
|
||||
setFormValues({
|
||||
...formValues,
|
||||
seconds: e.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<Label text={t('trade:notional-volume')} />
|
||||
<NumberFormat
|
||||
name="value"
|
||||
id="value"
|
||||
inputMode="numeric"
|
||||
thousandSeparator=","
|
||||
allowNegative={false}
|
||||
isNumericString={true}
|
||||
className={INPUT_CLASSES}
|
||||
placeholder="e.g. 10,000"
|
||||
value={formValues.value}
|
||||
onValueChange={(e: NumberFormatValues) =>
|
||||
setFormValues({
|
||||
...formValues,
|
||||
value: e.value,
|
||||
})
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
className="w-full"
|
||||
disabled={!formValues.seconds || !formValues.value}
|
||||
onClick={handleSave}
|
||||
size="large"
|
||||
>
|
||||
{t('save')}
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
</Modal>
|
||||
)
|
||||
}
|
||||
|
||||
export default TradeVolumeAlertModal
|
|
@ -41,13 +41,13 @@ const SoundSettings = () => {
|
|||
onChange={() => handleToggleSoundSetting('all')}
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between border-t border-th-bkg-3 p-4">
|
||||
{/* <div className="flex items-center justify-between border-t border-th-bkg-3 p-4">
|
||||
<p>{t('settings:recent-trades')}</p>
|
||||
<Switch
|
||||
checked={soundSettings['recent-trades']}
|
||||
onChange={() => handleToggleSoundSetting('recent-trades')}
|
||||
/>
|
||||
</div>
|
||||
</div> */}
|
||||
<div className="flex items-center justify-between border-t border-th-bkg-3 p-4">
|
||||
<p>{t('settings:swap-success')}</p>
|
||||
<Switch
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import useInterval from '@components/shared/useInterval'
|
||||
import mangoStore from '@store/mangoStore'
|
||||
import { useEffect, useMemo } from 'react'
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { floorToDecimal, getDecimalCount } from 'utils/numbers'
|
||||
import Decimal from 'decimal.js'
|
||||
import { ChartTradeType } from 'types'
|
||||
|
@ -9,54 +9,62 @@ import useSelectedMarket from 'hooks/useSelectedMarket'
|
|||
import { Howl } from 'howler'
|
||||
import { IconButton } from '@components/shared/Button'
|
||||
import useLocalStorageState from 'hooks/useLocalStorageState'
|
||||
import { SOUND_SETTINGS_KEY } from 'utils/constants'
|
||||
import { SpeakerWaveIcon, SpeakerXMarkIcon } from '@heroicons/react/20/solid'
|
||||
import { SOUND_SETTINGS_KEY, TRADE_VOLUME_ALERT_KEY } from 'utils/constants'
|
||||
import { BellAlertIcon, BellSlashIcon } from '@heroicons/react/20/solid'
|
||||
import Tooltip from '@components/shared/Tooltip'
|
||||
import { INITIAL_SOUND_SETTINGS } from '@components/settings/SoundSettings'
|
||||
import usePrevious from '@components/shared/usePrevious'
|
||||
import TradeVolumeAlertModal, {
|
||||
DEFAULT_VOLUME_ALERT_SETTINGS,
|
||||
} from '@components/modals/TradeVolumeAlertModal'
|
||||
|
||||
const buySound = new Howl({
|
||||
const volumeAlertSound = new Howl({
|
||||
src: ['/sounds/trade-buy.mp3'],
|
||||
volume: 0.5,
|
||||
})
|
||||
const sellSound = new Howl({
|
||||
src: ['/sounds/trade-sell.mp3'],
|
||||
volume: 0.5,
|
||||
volume: 0.8,
|
||||
})
|
||||
|
||||
const RecentTrades = () => {
|
||||
const { t } = useTranslation(['common', 'trade'])
|
||||
const fills = mangoStore((s) => s.selectedMarket.fills)
|
||||
const [soundSettings, setSoundSettings] = useLocalStorageState(
|
||||
const [latestFillId, setLatestFillId] = useState('')
|
||||
const [soundSettings] = useLocalStorageState(
|
||||
SOUND_SETTINGS_KEY,
|
||||
INITIAL_SOUND_SETTINGS
|
||||
)
|
||||
const previousFills = usePrevious(fills)
|
||||
|
||||
useEffect(() => {
|
||||
if (!soundSettings['recent-trades']) return
|
||||
if (fills.length && previousFills && previousFills.length) {
|
||||
const latestFill: ChartTradeType = fills[0]
|
||||
const previousFill: ChartTradeType = previousFills[0]
|
||||
if (previousFill.orderId.toString() !== latestFill.orderId.toString()) {
|
||||
const side =
|
||||
latestFill.side || (latestFill.takerSide === 1 ? 'bid' : 'ask')
|
||||
if (['buy', 'bid'].includes(side)) {
|
||||
buySound.play()
|
||||
} else {
|
||||
sellSound.play()
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [fills, previousFills, soundSettings])
|
||||
const [alertSettings] = useLocalStorageState(
|
||||
TRADE_VOLUME_ALERT_KEY,
|
||||
DEFAULT_VOLUME_ALERT_SETTINGS
|
||||
)
|
||||
const [showVolumeAlertModal, setShowVolumeAlertModal] = useState(false)
|
||||
|
||||
const {
|
||||
selectedMarket,
|
||||
serumOrPerpMarket: market,
|
||||
baseSymbol,
|
||||
quoteBank,
|
||||
quoteSymbol,
|
||||
} = useSelectedMarket()
|
||||
|
||||
useEffect(() => {
|
||||
if (!fills.length) return
|
||||
if (!latestFillId) {
|
||||
setLatestFillId(fills[0].orderId.toString())
|
||||
}
|
||||
}, [fills])
|
||||
|
||||
useInterval(() => {
|
||||
if (!soundSettings['recent-trades'] || !quoteBank) return
|
||||
setLatestFillId(fills[0].orderId.toString())
|
||||
const fillsLimitIndex = fills.findIndex(
|
||||
(f) => f.orderId.toString() === latestFillId
|
||||
)
|
||||
const newFillsVolumeValue = fills
|
||||
.slice(0, fillsLimitIndex)
|
||||
.reduce((a, c) => a + c.size * c.price, 0)
|
||||
if (newFillsVolumeValue * quoteBank.uiPrice > Number(alertSettings.value)) {
|
||||
volumeAlertSound.play()
|
||||
}
|
||||
}, alertSettings.seconds * 1000)
|
||||
|
||||
// const fetchRecentTrades = useCallback(async () => {
|
||||
// if (!market) return
|
||||
|
||||
|
@ -113,107 +121,110 @@ const RecentTrades = () => {
|
|||
}, [fills])
|
||||
|
||||
return (
|
||||
<div className="thin-scroll h-full overflow-y-scroll">
|
||||
<div className="flex items-center justify-between border-b border-th-bkg-3 py-1 px-2">
|
||||
<Tooltip content={t('trade:trade-sounds-tooltip')} delay={250}>
|
||||
<IconButton
|
||||
onClick={() =>
|
||||
setSoundSettings({
|
||||
...soundSettings,
|
||||
'recent-trades': !soundSettings['recent-trades'],
|
||||
})
|
||||
}
|
||||
size="small"
|
||||
hideBg
|
||||
>
|
||||
{soundSettings['recent-trades'] ? (
|
||||
<SpeakerWaveIcon className="h-4 w-4 text-th-fgd-3" />
|
||||
) : (
|
||||
<SpeakerXMarkIcon className="h-4 w-4 text-th-fgd-3" />
|
||||
)}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<span className="text-xs text-th-fgd-4">
|
||||
{t('trade:buys')}:{' '}
|
||||
<span className="font-mono text-th-up">
|
||||
{(buyRatio * 100).toFixed(1)}%
|
||||
<>
|
||||
<div className="thin-scroll h-full overflow-y-scroll">
|
||||
<div className="flex items-center justify-between border-b border-th-bkg-3 py-1 px-2">
|
||||
<Tooltip content={t('trade:tooltip-volume-alert')} delay={250}>
|
||||
<IconButton
|
||||
onClick={() => setShowVolumeAlertModal(true)}
|
||||
size="small"
|
||||
hideBg
|
||||
>
|
||||
{soundSettings['recent-trades'] ? (
|
||||
<BellAlertIcon className="h-4 w-4 text-th-fgd-3" />
|
||||
) : (
|
||||
<BellSlashIcon className="h-4 w-4 text-th-fgd-3" />
|
||||
)}
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<span className="text-xs text-th-fgd-4">
|
||||
{t('trade:buys')}:{' '}
|
||||
<span className="font-mono text-th-up">
|
||||
{(buyRatio * 100).toFixed(1)}%
|
||||
</span>
|
||||
<span className="px-2">|</span>
|
||||
{t('trade:sells')}:{' '}
|
||||
<span className="font-mono text-th-down">
|
||||
{(sellRatio * 100).toFixed(1)}%
|
||||
</span>
|
||||
</span>
|
||||
<span className="px-2">|</span>
|
||||
{t('trade:sells')}:{' '}
|
||||
<span className="font-mono text-th-down">
|
||||
{(sellRatio * 100).toFixed(1)}%
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div className="px-2">
|
||||
<table className="min-w-full">
|
||||
<thead>
|
||||
<tr className="text-right text-xxs text-th-fgd-4">
|
||||
<th className="py-2 font-normal">{`${t(
|
||||
'price'
|
||||
)} (${quoteSymbol})`}</th>
|
||||
<th className="py-2 font-normal">
|
||||
{t('trade:size')} ({baseSymbol})
|
||||
</th>
|
||||
<th className="py-2 font-normal">{t('time')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{!!fills.length &&
|
||||
fills.map((trade: ChartTradeType, i: number) => {
|
||||
const side =
|
||||
trade.side || (trade.takerSide === 1 ? 'bid' : 'ask')
|
||||
</div>
|
||||
<div className="px-2">
|
||||
<table className="min-w-full">
|
||||
<thead>
|
||||
<tr className="text-right text-xxs text-th-fgd-4">
|
||||
<th className="py-2 font-normal">{`${t(
|
||||
'price'
|
||||
)} (${quoteSymbol})`}</th>
|
||||
<th className="py-2 font-normal">
|
||||
{t('trade:size')} ({baseSymbol})
|
||||
</th>
|
||||
<th className="py-2 font-normal">{t('time')}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{!!fills.length &&
|
||||
fills.map((trade: ChartTradeType, i: number) => {
|
||||
const side =
|
||||
trade.side || (trade.takerSide === 1 ? 'bid' : 'ask')
|
||||
|
||||
// const price =
|
||||
// typeof trade.price === 'number'
|
||||
// ? trade.price
|
||||
// : trade.price.toNumber()
|
||||
const formattedPrice = market?.tickSize
|
||||
? floorToDecimal(
|
||||
trade.price,
|
||||
getDecimalCount(market.tickSize)
|
||||
)
|
||||
: new Decimal(trade?.price || 0)
|
||||
|
||||
// const size = trade?.quantity?.toNumber() || trade?.size
|
||||
const formattedSize =
|
||||
market?.minOrderSize && trade.size
|
||||
// const price =
|
||||
// typeof trade.price === 'number'
|
||||
// ? trade.price
|
||||
// : trade.price.toNumber()
|
||||
const formattedPrice = market?.tickSize
|
||||
? floorToDecimal(
|
||||
trade.size,
|
||||
getDecimalCount(market.minOrderSize)
|
||||
trade.price,
|
||||
getDecimalCount(market.tickSize)
|
||||
)
|
||||
: new Decimal(trade.size || 0)
|
||||
: new Decimal(trade?.price || 0)
|
||||
|
||||
return (
|
||||
<tr className="font-mono text-xs" key={i}>
|
||||
<td
|
||||
className={`pb-1.5 text-right ${
|
||||
['buy', 'bid'].includes(side)
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
{formattedPrice.toFixed()}
|
||||
</td>
|
||||
<td className="pb-1.5 text-right">
|
||||
{formattedSize.toFixed()}
|
||||
</td>
|
||||
<td className="pb-1.5 text-right text-th-fgd-4">
|
||||
{trade.time
|
||||
? new Date(trade.time).toLocaleTimeString()
|
||||
: trade.timestamp
|
||||
? new Date(
|
||||
trade.timestamp.toNumber()
|
||||
).toLocaleTimeString()
|
||||
: '-'}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
// const size = trade?.quantity?.toNumber() || trade?.size
|
||||
const formattedSize =
|
||||
market?.minOrderSize && trade.size
|
||||
? floorToDecimal(
|
||||
trade.size,
|
||||
getDecimalCount(market.minOrderSize)
|
||||
)
|
||||
: new Decimal(trade.size || 0)
|
||||
|
||||
return (
|
||||
<tr className="font-mono text-xs" key={i}>
|
||||
<td
|
||||
className={`pb-1.5 text-right ${
|
||||
['buy', 'bid'].includes(side)
|
||||
? 'text-th-up'
|
||||
: 'text-th-down'
|
||||
}`}
|
||||
>
|
||||
{formattedPrice.toFixed()}
|
||||
</td>
|
||||
<td className="pb-1.5 text-right">
|
||||
{formattedSize.toFixed()}
|
||||
</td>
|
||||
<td className="pb-1.5 text-right text-th-fgd-4">
|
||||
{trade.time
|
||||
? new Date(trade.time).toLocaleTimeString()
|
||||
: trade.timestamp
|
||||
? new Date(
|
||||
trade.timestamp.toNumber()
|
||||
).toLocaleTimeString()
|
||||
: '-'}
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{showVolumeAlertModal ? (
|
||||
<TradeVolumeAlertModal
|
||||
isOpen={showVolumeAlertModal}
|
||||
onClose={() => setShowVolumeAlertModal(false)}
|
||||
/>
|
||||
) : null}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
|
@ -16,6 +17,7 @@
|
|||
"hourly-funding": "Hourly Funding",
|
||||
"in-orders": "In Orders",
|
||||
"instantaneous-funding": "Instantaneous Funding",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"limit-price": "Limit Price",
|
||||
"margin": "Margin",
|
||||
"no-balances": "No balances",
|
||||
|
@ -23,6 +25,7 @@
|
|||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
|
@ -32,6 +35,7 @@
|
|||
"post": "Post",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"preview-sound": "Preview Sound",
|
||||
"quote": "Quote",
|
||||
"sells": "Sells",
|
||||
"settle-funds": "Settle Funds",
|
||||
|
@ -45,7 +49,9 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"trades": "Trades",
|
||||
"unsettled": "Unsettled"
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
|
@ -16,6 +17,7 @@
|
|||
"hourly-funding": "Hourly Funding",
|
||||
"in-orders": "In Orders",
|
||||
"instantaneous-funding": "Instantaneous Funding",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"limit-price": "Limit Price",
|
||||
"margin": "Margin",
|
||||
"no-balances": "No balances",
|
||||
|
@ -23,6 +25,7 @@
|
|||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
|
@ -32,6 +35,7 @@
|
|||
"post": "Post",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"preview-sound": "Preview Sound",
|
||||
"quote": "Quote",
|
||||
"sells": "Sells",
|
||||
"settle-funds": "Settle Funds",
|
||||
|
@ -45,7 +49,9 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"trades": "Trades",
|
||||
"unsettled": "Unsettled"
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
|
@ -16,6 +17,7 @@
|
|||
"hourly-funding": "Hourly Funding",
|
||||
"in-orders": "In Orders",
|
||||
"instantaneous-funding": "Instantaneous Funding",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"limit-price": "Limit Price",
|
||||
"margin": "Margin",
|
||||
"no-balances": "No balances",
|
||||
|
@ -23,6 +25,7 @@
|
|||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
|
@ -32,6 +35,7 @@
|
|||
"post": "Post",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"preview-sound": "Preview Sound",
|
||||
"quote": "Quote",
|
||||
"sells": "Sells",
|
||||
"settle-funds": "Settle Funds",
|
||||
|
@ -45,7 +49,9 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"trades": "Trades",
|
||||
"unsettled": "Unsettled"
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
|
@ -16,6 +17,7 @@
|
|||
"hourly-funding": "Hourly Funding",
|
||||
"in-orders": "In Orders",
|
||||
"instantaneous-funding": "Instantaneous Funding",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"limit-price": "Limit Price",
|
||||
"margin": "Margin",
|
||||
"no-balances": "No balances",
|
||||
|
@ -23,6 +25,7 @@
|
|||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
|
@ -32,6 +35,7 @@
|
|||
"post": "Post",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"preview-sound": "Preview Sound",
|
||||
"quote": "Quote",
|
||||
"sells": "Sells",
|
||||
"settle-funds": "Settle Funds",
|
||||
|
@ -45,7 +49,9 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"trades": "Trades",
|
||||
"unsettled": "Unsettled"
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"activate-volume-alert": "Activate Volume Alert",
|
||||
"amount": "Amount",
|
||||
"base": "Base",
|
||||
"book": "Book",
|
||||
|
@ -16,6 +17,7 @@
|
|||
"hourly-funding": "Hourly Funding",
|
||||
"in-orders": "In Orders",
|
||||
"instantaneous-funding": "Instantaneous Funding",
|
||||
"interval-seconds": "Interval (seconds)",
|
||||
"limit-price": "Limit Price",
|
||||
"margin": "Margin",
|
||||
"no-balances": "No balances",
|
||||
|
@ -23,6 +25,7 @@
|
|||
"no-positions": "No perp positions",
|
||||
"no-unsettled": "No unsettled funds",
|
||||
"notional": "Notional",
|
||||
"notional-volume": "Notional Volume ($)",
|
||||
"open-interest": "Open Interest",
|
||||
"oracle-price": "Oracle Price",
|
||||
"order-error": "Failed to place order",
|
||||
|
@ -32,6 +35,7 @@
|
|||
"post": "Post",
|
||||
"place-order": "Place {{side}} Order",
|
||||
"placing-order": "Placing Order",
|
||||
"preview-sound": "Preview Sound",
|
||||
"quote": "Quote",
|
||||
"sells": "Sells",
|
||||
"settle-funds": "Settle Funds",
|
||||
|
@ -45,7 +49,9 @@
|
|||
"tooltip-ioc": "Immediate-Or-Cancel (IOC) orders are guaranteed to be the taker and must be executed immediately. Any portion of the order that can't be filled immediately will be cancelled",
|
||||
"tooltip-post": "Post orders are guaranteed to be the maker or they will be canceled",
|
||||
"tooltip-slippage": "An estimate of the difference between the current price and the price your trade will be executed at",
|
||||
"trade-sounds-tooltip": "Play a sound alert for every new trade",
|
||||
"tooltip-volume-alert": "Volume Alert Settings",
|
||||
"trades": "Trades",
|
||||
"unsettled": "Unsettled"
|
||||
"unsettled": "Unsettled",
|
||||
"volume-alert": "Volume Alert",
|
||||
"volume-alert-desc": "Play a sound whenever volume exceeds your alert threshold"
|
||||
}
|
|
@ -65,3 +65,5 @@ export const MIN_SOL_BALANCE = 0.001
|
|||
export const ACCOUNT_ACTION_MODAL_HEIGHT = '506px'
|
||||
|
||||
export const ACCOUNT_ACTION_MODAL_INNER_HEIGHT = '444px'
|
||||
|
||||
export const TRADE_VOLUME_ALERT_KEY = 'tradeVolumeAlert-0.1'
|
||||
|
|
Loading…
Reference in New Issue