123 lines
4.3 KiB
JavaScript
123 lines
4.3 KiB
JavaScript
import {orderFilled, orderStatuses, vaultOpenOrders, vaultRecentlyClosedOrders} from "./cache.js"
|
|
import {sql} from "./db.js";
|
|
|
|
|
|
export function sendVaultOrders( socket, chainId, vault ) {
|
|
Promise.all([
|
|
vaultOpenOrders.get(chainId, vault, '[]'),
|
|
vaultRecentlyClosedOrders.get(chainId, vault, '[]'),
|
|
archivedOrders(chainId, vault),
|
|
]).then(async (got)=>{
|
|
const [openIndexes, closedIndexes, recents] = got
|
|
const statuses = {}
|
|
// noinspection JSCheckFunctionSignatures
|
|
const indexes = [...JSON.parse(openIndexes), ...JSON.parse(closedIndexes)]
|
|
const proms = []
|
|
if( openIndexes !== null ) {
|
|
for (const orderIndex of indexes) {
|
|
// there is a race condition here since we need multiple queries to get the complete order status,
|
|
// so we check for nulls and exclude such an order, since it was deleted and no longer active.
|
|
proms.push(orderStatus(chainId, vault, orderIndex).then((status)=>{
|
|
if (status !== null)
|
|
statuses[orderIndex] = status
|
|
}))
|
|
}
|
|
}
|
|
for( let [orderIndex, status] of recents ) {
|
|
if( !(orderIndex in statuses) ) {
|
|
// only write the database version if there's no open order in the memcache
|
|
const orderKey = `${vault}|${orderIndex}`
|
|
proms.push(fillOrderStatus(chainId, orderKey, status))
|
|
statuses[orderIndex] = status
|
|
}
|
|
}
|
|
await Promise.all(proms)
|
|
const result = []
|
|
for(const index of Object.keys(statuses))
|
|
result.push([parseInt(index), statuses[index]])
|
|
socket.emit('os', chainId, vault, result)
|
|
})
|
|
}
|
|
|
|
export function unsubVaultOrders( socket, chainId, vault ) {
|
|
console.log('todo: unsubVaultOrders') // todo
|
|
}
|
|
|
|
export async function orderStatus( chainId, vault, orderIndex ) {
|
|
const orderKey = `${vault}|${orderIndex}`
|
|
let status = await orderStatuses.get(chainId, orderKey)
|
|
if( status === null ) {
|
|
console.warn(`Could not find order status for ${chainId}|${vault}|${orderIndex}`)
|
|
}
|
|
else {
|
|
status = JSON.parse(status)
|
|
await fillOrderStatus(chainId, orderKey, status)
|
|
}
|
|
return status
|
|
}
|
|
|
|
async function fillOrderStatus(chainId, orderKey, status ) {
|
|
const fills = await orderFilled.get(chainId, orderKey)
|
|
if (fills !== null)
|
|
applyFillsServer(status, JSON.parse(fills))
|
|
}
|
|
|
|
export async function archivedOrders(chainId, vault, limit=100 ) {
|
|
const query = await sql(
|
|
`select oi.order_index, sd.value
|
|
from seriesdict sd,
|
|
orderindex oi
|
|
where oi.chain = ${chainId}
|
|
and oi.vault = '${vault}'
|
|
and sd.series = 'o'
|
|
and sd.key = concat('${vault}', '|', to_char(oi.order_index, 'FM9999999999999999999'))
|
|
order by oi.order_index desc
|
|
limit ${limit}`
|
|
)
|
|
const result = []
|
|
for( const {order_index, value} of query.rows)
|
|
result.push([order_index,JSON.parse(value)])
|
|
return result
|
|
}
|
|
|
|
export function applyFillsServer(orderStatus, orderFills) {
|
|
// class ElaboratedTrancheStatus:
|
|
// filledIn: int
|
|
// filledOut: int
|
|
// activationTime: int
|
|
// startTime: int
|
|
// endTime: int
|
|
// fills: list[Fill]
|
|
//
|
|
// class Fill:
|
|
// tx: str
|
|
// time: int
|
|
// filledIn: int
|
|
// filledOut: int
|
|
// fee: int
|
|
|
|
// console.log('apply fills OrderStatus', orderStatus)
|
|
// console.log('apply fills orderFills', orderFills)
|
|
const trancheStatus = orderStatus[9]
|
|
let orderIn = 0n
|
|
let orderOut = 0n
|
|
for (const i in orderFills) {
|
|
let filledIn = 0n
|
|
let filledOut = 0n
|
|
const [activationTime, fills] = orderFills[i];
|
|
for (const fill of fills) {
|
|
filledIn += BigInt(fill[2])
|
|
filledOut += BigInt(fill[3])
|
|
}
|
|
const old = trancheStatus[i]
|
|
const startTime = old[3]
|
|
const endTime = old[4]
|
|
trancheStatus[i] = [filledIn.toString(), filledOut.toString(), activationTime, startTime, endTime, fills]
|
|
orderIn += filledIn
|
|
orderOut += filledOut
|
|
}
|
|
orderStatus[7] = orderIn.toString()
|
|
orderStatus[8] = orderOut.toString()
|
|
// console.log('apply fills final', orderStatus, orderStatus[1][8])
|
|
}
|