Example #1
0
  private void executeBuying(ExecuteBuyOrderCommand buyCommand) {
    OrderBook orderBook = orderBookRepository.load(buyCommand.getOrderBookId());

    // buying price >= current buying price
    if (orderBook.getHighestBuyPrice().compareTo(buyCommand.getItemPrice()) >= 0) {
      return;
    }

    // refresh current buy price
    orderBook.resetHighestBuyPrice(buyCommand.getOrderId().toString(), buyCommand.getItemPrice());

    // buying price >= than the current highest selling  price
    logger.info("Executing Buying order {}", buyCommand);

    boolean done = true;
    do {
      final List<Order> sellOrders =
          orderExecutorHelper.findAscPendingOrdersByPriceTime(
              buyCommand.getPlaceDate(),
              buyCommand.getItemPrice(),
              buyCommand.getOrderBookId(),
              100);

      // no selling order matched
      if (isEmpty(sellOrders)) {
        return;
      }

      for (Order sellOrder : sellOrders) {
        // should not happen here, coz the repo does not return the right result
        if (sellOrder.getItemPrice().compareTo(buyCommand.getItemPrice()) > 0) {
          logger.warn(
              "Strange here, why sell orders from repo have price greater than current buy price!");
          break;
        }

        final Order buyOrder = orderExecutorHelper.findBuyOrder(buyCommand.getOrderId());

        BigMoney matchedTradePrice = sellOrder.getItemPrice();
        BigMoney matchedTradeAmount =
            min(sellOrder.getItemRemaining(), buyOrder.getItemRemaining());

        final BigMoney executedMoney =
            convertTo(matchedTradeAmount, matchedTradePrice).toBigMoney();

        BigMoney buyCommission =
            orderExecutorHelper.calcExecutedBuyCommission(
                buyOrder, matchedTradePrice, matchedTradeAmount);
        BigMoney sellCommission =
            orderExecutorHelper.calcExecutedSellCommission(
                sellOrder, matchedTradePrice, matchedTradeAmount);

        if (logger.isDebugEnabled()) {
          logger.debug(
              "Executing orders with amount {}, price {}, buy commission {}, sell commission {}, total money {}: highest buying order {}, lowest selling order {}",
              matchedTradeAmount,
              matchedTradePrice,
              buyCommission,
              sellCommission,
              executedMoney,
              sellOrder,
              buyOrder);
          orderBook.executeBuying(
              matchedTradeAmount,
              matchedTradePrice,
              executedMoney,
              buyOrder.getPrimaryKey(),
              sellOrder.getPrimaryKey(),
              buyCommission,
              sellCommission,
              buyOrder.getTransactionId(),
              sellOrder.getTransactionId(),
              buyOrder.getPortfolioId(),
              sellOrder.getPortfolioId(),
              buyCommand.getPlaceDate());
        }

        orderExecutorHelper.recordTraded(
            buyOrder,
            sellOrder,
            buyCommission,
            sellCommission,
            matchedTradeAmount,
            matchedTradeAmount,
            buyCommand.getPlaceDate());

        if (buyOrder.getItemRemaining().toMoney(RoundingMode.HALF_EVEN).isNegativeOrZero()) {
          done = true;
          break;
        }
      }
    } while (!done);

    orderExecutorHelper.refresh(orderBook);
  }