All Downloads are FREE. Search and download functionalities are using the official Maven repository.

info.bitrich.xchangestream.lgo.LgoUserBatchSubscription Maven / Gradle / Ivy

The newest version!
package info.bitrich.xchangestream.lgo;

import static java.util.stream.Collectors.toConcurrentMap;

import com.fasterxml.jackson.databind.ObjectMapper;
import info.bitrich.xchangestream.lgo.domain.LgoBatchOrderEvent;
import info.bitrich.xchangestream.lgo.domain.LgoGroupedUserUpdate;
import info.bitrich.xchangestream.lgo.dto.LgoUserMessage;
import info.bitrich.xchangestream.lgo.dto.LgoUserSnapshot;
import info.bitrich.xchangestream.lgo.dto.LgoUserUpdate;
import info.bitrich.xchangestream.service.netty.StreamingObjectMapperHelper;
import io.reactivex.rxjava3.core.Observable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Collectors;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.Order;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.MarketOrder;

class LgoUserBatchSubscription {

  private final Observable downstream;
  private final LgoStreamingService streamingService;
  private final CurrencyPair currencyPair;

  static LgoUserBatchSubscription create(
      LgoStreamingService streamingService, CurrencyPair currencyPair) {
    return new LgoUserBatchSubscription(streamingService, currencyPair);
  }

  private LgoUserBatchSubscription(
      LgoStreamingService streamingService, CurrencyPair currencyPair) {
    this.streamingService = streamingService;
    this.currencyPair = currencyPair;
    downstream = createSubscription();
  }

  Observable getPublisher() {
    return downstream;
  }

  private Observable createSubscription() {
    final ObjectMapper mapper = StreamingObjectMapperHelper.getObjectMapper();
    return streamingService
        .subscribeChannel(LgoAdapter.channelName("user", currencyPair))
        .map(s -> mapper.treeToValue(s, LgoUserMessage.class))
        .scan(
            new LgoGroupedUserUpdate(),
            (acc, s) -> {
              List events = new ArrayList<>();
              if (s.getType().equals("update")) {
                LgoUserUpdate userUpdate = (LgoUserUpdate) s;
                List updates =
                    updateAllOrders(
                        currencyPair, userUpdate.getOrderEvents(), acc.getAllOpenOrders());
                events.addAll(
                    LgoAdapter.adaptOrderEvent(
                        userUpdate.getOrderEvents(), s.getBatchId(), updates));
                return new LgoGroupedUserUpdate(
                    acc.getAllOpenOrders(), updates, events, s.getBatchId(), s.getType());
              } else {
                Collection allOrders =
                    handleUserSnapshot(currencyPair, (LgoUserSnapshot) s);
                ConcurrentMap ordersById =
                    allOrders.stream().collect(toConcurrentMap(LimitOrder::getId, this::copyOrder));
                return new LgoGroupedUserUpdate(
                    ordersById, new ArrayList<>(allOrders), events, s.getBatchId(), s.getType());
              }
            })
        .skip(1) // skips the first element, for this is the empty accumulator
        .share();
  }

  private List updateAllOrders(
      CurrencyPair currencyPair,
      List orderEvents,
      Map allOpenOrders) {
    return orderEvents.stream()
        .map(orderEvent -> orderEvent.applyOnOrders(currencyPair, allOpenOrders))
        .map(this::copyOrder)
        .collect(Collectors.toList());
  }

  private Collection handleUserSnapshot(CurrencyPair currencyPair, LgoUserSnapshot s) {
    return LgoAdapter.adaptOrdersSnapshot(s.getSnapshotData(), currencyPair);
  }

  private Order copyOrder(Order order) {
    Order copy =
        order instanceof LimitOrder
            ? LimitOrder.Builder.from(order).build()
            : MarketOrder.Builder.from(order).build();
    // because actual released version of xchange-core has buggy Builder.from methods
    copy.setFee(order.getFee());
    copy.setCumulativeAmount(order.getCumulativeAmount());
    // https://github.com/knowm/XChange/pull/3163
    return copy;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy