content: package com.github.misterchangray.service.common;
  
  
  import com.github.misterchangray.libs.binance.api.client.BinanceApiClientFactory;
  import com.github.misterchangray.libs.binance.api.client.BinanceApiRestClient;
  import com.github.misterchangray.libs.binance.api.client.domain.market.OrderBook;
  import com.github.misterchangray.libs.binance.api.client.domain.market.OrderBookEntry;
  
  import java.math.BigDecimal;
  import java.util.*;
  
  /**
   * Illustrates how to use the depthSpot event stream to create a local cache of bids/asks for a symbol.
   */
  public class BiAnDepthCache {
  
      private static final String BIDS  = "BIDS";
      private static final String ASKS  = "ASKS";
  
      private long lastUpdateId;
  
      private Map<String, NavigableMap<BigDecimal, BigDecimal>> depthCache;
  
      public BiAnDepthCache(String symbol) {
          initializeDepthCache(symbol);
      }
  
      /**
       * Initializes the depthSpot cache by using the REST API.
       */
      private void initializeDepthCache(String symbol) {
          BinanceApiClientFactory factory = BinanceApiClientFactory.newInstance();
          BinanceApiRestClient client = factory.newRestClient();
          OrderBook orderBook = client.getOrderBook(symbol.toUpperCase(), 10);
  
          this.depthCache = new HashMap<>();
          this.lastUpdateId = orderBook.getLastUpdateId();
  
          NavigableMap<BigDecimal, BigDecimal> asks = new TreeMap<>(Comparator.reverseOrder());
          for (OrderBookEntry ask : orderBook.getAsks()) {
              asks.put(new BigDecimal(ask.getPrice()), new BigDecimal(ask.getQty()));
          }
          depthCache.put(ASKS, asks);
  
          NavigableMap<BigDecimal, BigDecimal> bids = new TreeMap<>(Comparator.reverseOrder());
          for (OrderBookEntry bid : orderBook.getBids()) {
              bids.put(new BigDecimal(bid.getPrice()), new BigDecimal(bid.getQty()));
          }
          depthCache.put(BIDS, bids);
      }
  
  
  
      /**
       * Updates an order book (bids or asks) with a delta received from the server.
       *
       * Whenever the qty specified is ZERO, it means the price should was removed from the order book.
       */
      public void updateOrderBook(NavigableMap<BigDecimal, BigDecimal> lastOrderBookEntries, List<OrderBookEntry> orderBookDeltas) {
          for (OrderBookEntry orderBookDelta : orderBookDeltas) {
              BigDecimal price = new BigDecimal(orderBookDelta.getPrice());
              BigDecimal qty = new BigDecimal(orderBookDelta.getQty());
              if (qty.compareTo(BigDecimal.ZERO) == 0) {
                  // qty=0 means remove this level
                  lastOrderBookEntries.remove(price);
              } else {
                  lastOrderBookEntries.put(price, qty);
              }
          }
      }
  
      public NavigableMap<BigDecimal, BigDecimal> getAsks() {
          return depthCache.get(ASKS);
      }
  
      public NavigableMap<BigDecimal, BigDecimal> getBids() {
          return depthCache.get(BIDS);
      }
  
      /**
       * @return the best ask in the order book
       */
      public Map.Entry<BigDecimal, BigDecimal> getBestAsk() {
          return getAsks().lastEntry();
      }
  
      /**
       * @return the best bid in the order book
       */
      public Map.Entry<BigDecimal, BigDecimal> getBestBid() {
          return getBids().firstEntry();
      }
  
      /**
       * @return a depthSpot cache, containing two keys (ASKs and BIDs), and for each, an ordered list of book entries.
       */
      public Map<String, NavigableMap<BigDecimal, BigDecimal>> getDepthCache() {
          return depthCache;
      }
  
  
  }