0

我编写了一个从 Web 套接字接收数据的小应用程序,我将其存储在静态 ConcurrentSkipListMap 中。应用程序最初创建一个新线程,它在循环调用 ConcurrentSkipListMap.firstKey() 时无限运行。一段时间后,即使 ConcurrentSkipListMap 包含数据,此调用也会引发 NoSuchElementException。 catch 块中的断点 我的应用程序示例:

我有包含 websocket 实现和 NavigableMap init 的缓存器类:

package solvethat.net.triobot.Example;

import com.binance.api.client.BinanceApiCallback;
import com.binance.api.client.BinanceApiClientFactory;
import com.binance.api.client.domain.event.DepthEvent;
import com.binance.api.client.domain.market.OrderBook;
import com.binance.api.client.domain.market.OrderBookEntry;

import java.math.BigDecimal;
import java.util.Comparator;
import java.util.List;
import java.util.NavigableMap;
import java.util.concurrent.ConcurrentSkipListMap;

public class AskCacher {

private long updateId;
private final BinanceApiClientFactory factory;

public AskCacher() {
    factory = BinanceApiClientFactory.newInstance();
    initAsks();
    runWebsocket();
}

/**
 * Init data getting order book snapshot
 */
private void initAsks() {
    try {
        OrderBook orderBook = factory.newRestClient().getOrderBook("btcusdt".toUpperCase(), 10);
        updateId = orderBook.getLastUpdateId();
        NavigableMap<Double, Double> asks = new ConcurrentSkipListMap<>(Comparator.naturalOrder());
        for (OrderBookEntry ask : orderBook.getAsks()) {
            asks.put(Double.parseDouble(ask.getPrice()), Double.parseDouble(ask.getQty()));
        }
        StaticData.ask = asks;
    } catch (Exception e) {
        System.err.println(e.getMessage());
    }
}

private void runWebsocket() {
    factory.newWebSocketClient().onDepthEvent("btcusdt", new BinanceApiCallback<>() {
        /**
         * Set ask price and call analysis method
         */
        @Override
        public void onResponse(DepthEvent depthEvent) {
            if (depthEvent.getFinalUpdateId() > updateId) {
                updateId = depthEvent.getFinalUpdateId();
                updateOrderBook(depthEvent.getAsks());
            }
        }

        /**
         * Just print err message
         */
        @Override
        public void onFailure(final Throwable cause) {
            System.err.println(cause.getMessage());
        }
    });
}

/**
 * Updates an order book (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.
 */
private void updateOrderBook(List<OrderBookEntry> orderBookDeltas) {
    for (OrderBookEntry orderBookDelta : orderBookDeltas) {
        Double price = Double.parseDouble(orderBookDelta.getPrice());
        BigDecimal qty = new BigDecimal(orderBookDelta.getQty());
        if (qty.compareTo(BigDecimal.ZERO) == 0) {
            // qty=0 means remove this level
            StaticData.ask.remove(price);
        } else {
            StaticData.ask.put(price, Double.parseDouble(orderBookDelta.getQty()));
        }
    }

    // Print best ask to see if cacher is alive
    System.out.println("btc-usdt best ask: " + StaticData.ask.firstKey());

    // Edit map length
    if (StaticData.ask.size() > 10) {
        StaticData.ask.tailMap((Double) StaticData.ask.keySet().toArray()[10], true).clear();
    }
}}

然后无限循环:

package solvethat.net.triobot.Example;
public class InfiniteLoop {

public void loopProcess() {
    Analyzer analyzer = new Analyzer();
    while (true) {
        analyzer.analyze(StaticData.ask.firstEntry());
    }
}}

和分析器类:

package solvethat.net.triobot.Example;

import java.util.Map;

public class Analyzer {

    public void analyze(Map.Entry<Double, Double> entry) {

        StaticData.AnalyzeObject analyzeObject = new StaticData.AnalyzeObject();
        analyzeObject.setBestAsk(entry.getKey());

        if (analyzeObject.getBestAsk() > 50000) {
            System.out.println("It is a good price!!");
        }
    }

}

静态数据模型:

package solvethat.net.triobot.Example;

import java.util.NavigableMap;

public class StaticData {
    public static NavigableMap<Double, Double> ask;

    public static class AnalyzeObject {

        double bestAsk;

        public double getBestAsk() {
            return bestAsk;
        }

        public void setBestAsk(double bestAsk) {
            this.bestAsk = bestAsk;
        }
    }
}

主类例如运行:

package solvethat.net.triobot.Example;

public class Main {
    public static void main(String[] arguments) {
        new AskCacher();
        new Thread(new InfiniteLoop()::loopProcess).start();
    }
}

该示例仅显示了应用程序的组成方式,但我无法使用它来引发错误,但我将我的 repo 公开: https ://github.com/Sick-E/TrioBot

谁能帮帮我吗?谢谢你。托马斯

4

1 回答 1

0

你可以用类似的东西替换你的代码(不需要异常处理)

Optional.ofNullable(trio.getThirdPair().getBids().firstEntry())
  .map(Map.Entry::getKey)
  .ifPresent(trio.getTrioAnalysis()::setBidThird);
于 2021-08-20T15:33:34.560 回答