Update Order Lines for Advanced Order Types

Added ability to visualize advanced order types in the trading view chart.

Also fixed the calculateMarketPrice bug that was not setting advanced limit orders to the limit price.
This commit is contained in:
impossiblepairs 2021-10-16 11:49:57 -07:00
parent 3b5c84bcc4
commit 504613aa07
2 changed files with 124 additions and 72 deletions

View File

@ -16,6 +16,7 @@ import { PerpOrder, PerpMarket } from '@blockworks-foundation/mango-client'
import { notify } from '../../utils/notifications'
import { sleep, formatUsdValue } from '../../utils'
import useInterval from '../../hooks/useInterval'
import { PerpTriggerOrder } from '../../@types/types'
// This is a basic example of how to create a TV widget
// You can add more feature such as storing charts in localStorage
@ -150,7 +151,7 @@ const TVChartContainer = () => {
const handleCancelOrder = async (
order: Order | PerpOrder,
order: Order | PerpOrder | PerpTriggerOrder,
market: Market | PerpMarket
) => {
const wallet = useMangoStore.getState().wallet.current
@ -158,7 +159,7 @@ const TVChartContainer = () => {
useMangoStore.getState().selectedMangoGroup.current
const selectedMangoAccount =
useMangoStore.getState().selectedMangoAccount.current
const mangoClient = useMangoStore.getState().connection.client
let txid
try {
if (!selectedMangoGroup || !selectedMangoAccount) return
@ -171,14 +172,24 @@ const TVChartContainer = () => {
order as Order
)
} else if (market instanceof PerpMarket) {
if (order.perpTrigger?.clientOrderId ) {
txid = await mangoClient.removeAdvancedOrder(
selectedMangoGroup,
selectedMangoAccount,
wallet,
(order as PerpTriggerOrder).orderId
)
} else {
txid = await mangoClient.cancelPerpOrder(
selectedMangoGroup,
selectedMangoAccount,
wallet,
market,
order as PerpOrder
order as PerpOrder,
false
)
}
}
notify({ title: 'Successfully cancelled order', txid })
toggleOrderInProgress(false)
} catch (e) {
@ -188,17 +199,16 @@ const TVChartContainer = () => {
txid: e.txid,
type: 'error',
})
return false
console.log('error', `${e}`)
} finally {
sleep(500).then(() => {
actions.fetchMangoAccounts()
actions.updateOpenOrders()
actions.reloadMangoAccount()
actions.reloadOrders()
toggleOrderInProgress(false)
toggleMoveInProgress(false)
})
}
}
const handleModifyOrder = async (
order: Order | PerpOrder,
market: Market | PerpMarket,
@ -265,8 +275,8 @@ const TVChartContainer = () => {
togglePriceReset(true)
} finally {
sleep(1000).then(() => {
actions.fetchMangoAccounts()
actions.updateOpenOrders()
actions.fetchAllMangoAccounts()
actions.reloadOrders()
toggleOrderInProgress(false)
toggleMoveInProgress(false)
})
@ -283,6 +293,7 @@ const TVChartContainer = () => {
toggleOrderInProgress(true)
const currentOrderPrice = order.price
const updatedOrderPrice = this.getPrice()
if (!order.perpTrigger?.clientOrderId) {
if (
(order.side === 'buy' &&
updatedOrderPrice > 1.05 * selectedMarketPrice) ||
@ -312,11 +323,11 @@ const TVChartContainer = () => {
body: `Would you like to change your order from a
${order.size} ${market.config.baseSymbol} ${
order.side
} at ${formatUsdValue(currentOrderPrice)}
} at $${currentOrderPrice}
to a
${order.size} ${market.config.baseSymbol} LIMIT ${
order.side
} at ${formatUsdValue(updatedOrderPrice)}?
} at $${updatedOrderPrice}?
`,
callback: (res) => {
if (res) {
@ -329,6 +340,18 @@ const TVChartContainer = () => {
},
})
}
} else {
tvWidgetRef.current.showNoticeDialog({
title: 'Advanced Order Type',
body:
'Advanced order types in the chart window may only be cancelled. If new conditions are required, please cancel this order and use the Advanced Trade Form.',
callback: () => {
this.setPrice(currentOrderPrice)
toggleMoveInProgress(false)
toggleOrderInProgress(false)
},
})
}
})
.onCancel(function () {
toggleOrderInProgress(true)
@ -337,7 +360,7 @@ const TVChartContainer = () => {
body: `Would you like to cancel your order for
${order.size} ${market.config.baseSymbol} ${
order.side
} at ${formatUsdValue(order.price)}
} at $${order.price}
`,
callback: (res) => {
if (res) {
@ -348,21 +371,46 @@ const TVChartContainer = () => {
},
})
})
.setText(`${order.side.toUpperCase()} ${market.config.baseSymbol}`)
.setBodyBorderColor(order.side == 'buy' ? '#AFD803' : '#E54033')
.setBodyBackgroundColor('#000000')
.setBodyTextColor('#F2C94C')
.setLineLength(3)
.setLineColor(order.side == 'buy' ? '#AFD803' : '#E54033')
.setQuantity(order.size)
.setTooltip(`Order #: ${order.orderId}`)
.setQuantityBorderColor(order.side == 'buy' ? '#AFD803' : '#E54033')
.setQuantityBackgroundColor('#000000')
.setQuantityTextColor('#F2C94C')
.setCancelButtonBorderColor(order.side == 'buy' ? '#AFD803' : '#E54033')
.setCancelButtonBackgroundColor('#000000')
.setCancelButtonIconColor('#F2C94C')
.setPrice(order.price)
.setQuantity(order.size)
.setText(getLineText(order, market))
.setTooltip(order.perpTrigger?.clientOrderId ? `${order.orderType} Order #: ${order.orderId}` : `Order #: ${order.orderId}`)
.setBodyTextColor(theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C')
.setQuantityTextColor(theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C')
.setCancelButtonIconColor(theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C')
.setBodyBorderColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
.setQuantityBorderColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
.setCancelButtonBorderColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
.setBodyBackgroundColor(theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832')
.setQuantityBackgroundColor(theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832')
.setCancelButtonBackgroundColor(theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832')
.setBodyFont('Lato, sans-serif')
.setQuantityFont('Lato, sans-serif')
.setLineColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
.setLineLength(3)
.setLineWidth(2)
.setLineStyle(1)
}
function getLineText(order, market) {
if (order.perpTrigger?.clientOrderId) {
if (order.side === 'buy') {
if (order.perpTrigger.triggerCondition === 'above') {
return (order.orderType === 'market' ? `Stop Loss ` : `Stop Limit `) + `(${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} $${Number(order.perpTrigger.triggerPrice)}`
} else {
return `Take Profit (${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} $${Number(order.perpTrigger.triggerPrice)}`
}
} else {
if (order.perpTrigger.triggerCondition === 'below') {
return (order.orderType === 'market' ? `Stop Loss ` : `Stop Limit `) + `(${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} $${Number(order.perpTrigger.triggerPrice)}`
} else {
return `Take Profit (${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} $${Number(order.perpTrigger.triggerPrice)}`
}
}
} else {
return `${order.side} ${market.config.baseSymbol}`.toUpperCase()
}
}

View File

@ -108,8 +108,12 @@ export function calculateTradePrice(
if (tradeType === 'Market') {
return calculateMarketPrice(orderBook, baseSize, side)
} else if (TRIGGER_ORDER_TYPES.includes(tradeType)) {
if( tradeType === 'Take Profit Limit' || tradeType === 'Stop Limit' ) {
return Number(price)
} else {
return Number(triggerPrice)
}
}
return Number(price)
}