fasenderos / nodejs-order-book

Ultra-fast Node.js Order Book written in TypeScript for high-frequency trading (HFT) :rocket::rocket:
https://github.com/fasenderos/nodejs-order-book
MIT License
146 stars 35 forks source link

How to lock user balance on market order #242

Closed ohari5336 closed 1 year ago

ohari5336 commented 1 year ago

Hello, please help me with this scenario Pair Matic/USD wallet balance of user1 is 10 USD wallet balance of user2 is 5 USD

User1 want to sell 10 Matic at price of 1 USD User2 place a MARKET order to buy 10 Matic but he use has balance of 5 USD.

How to stop this order and process according to wallet balance

fasenderos commented 1 year ago

Hi, before sending an order to the orderbook your application have to check if the user can send an order, next decrease the balance as per the order size, execute the order and if something goes wrong or the order is not fully executed increase again the balance (pseudo code):

function userCanTrade(user, order) {
  return user.isActive && user.availableBalance >= order.size
}

function setAvailableBalance(user, newBalance) {
  return this.userService.updateById(user.id, {availableBalance: newBalance})
}

function async createOrder(user, order) {
  try {
    let orderExecuted;
    let updatedUser;
    if (userCanTrade(user)) {
      // Decrease available balance
      updatedUser = await setAvailableBalance(user, user.availableBalance - order.size);
      orderExecuted = lob.market(order.side, order.size)
      if (orderExecuted.quantityLeft > 0) {
        // Increase available balance for the quantity not executed
        await setAvailableBalance(updatedUser, updatedUser.availableBalance + response.quantityLeft);
      }
    } else {
     throw new Error('Something wrong')
    }
  } catch((e) => {
    console.error(e.message)
    if (!orderExecuted && updatedUser) {
      // User balance has been updated but the order has not been executed
      // so we restore the original balance
       await setAvailableBalance(user, user.availableBalance);
    }
  }
}
ohari5336 commented 1 year ago

When user 2 add order of buy 10 matic according my given situation, and according your code it's lock user matic how it's possible.

In real scenario user 2 usd lock but without price how i do this (in buy order every time amount multiply by size), and also my situation user have nor enough balance soo if your order matching engine match this with 2-3 buy orders then how i rollback this because user don't have enough balance in his account

fasenderos commented 1 year ago

Yes of course was a pseudo code for the sake of example. The responsibility of the orderbook is to matching orders. Every other aspect (user can trade?? user has enough money?? current price?? persist order on DB??) must be managed by the application by reading every response of the order book and updating the state accordingly

So in a real exchange you keep track of the market price for several reasons, say to show data in a graph or execute some cron job at specific price etc. and in order to not degrading the orderbook performance you can't call it every time to known the current price, so you have to keep track of the current price in a separate service (like redis and persist as a timeseries on DB every minute for the OHLC chart) by updating it at every order that move the price.

fasenderos commented 1 year ago

Closed for inactivity. Reopen if you need more help.