Giter Club home page Giter Club logo

bitfinex-v2-wss-api-java's Introduction

Hi there πŸ‘‹

Website ReserchGate Google Scholar LinkedIn Mail

I am Jan, a software developer and computer scientist with a focus on distributed databases and distributed systems.

  • ⛁ I’m currently working on BBoxDB - a distributed key-bounding-box-value database for multi-dimensional data implemented from scratch.

  • πŸ”­ In addition, I work actively on PostgreSQL Lock Tracer - a tool collection to gain deep insights into PostgreSQL's locking activities and troubleshoot performance-related issues.

  • 🌍 You can find more about my and my projects on my website

  • πŸ“« How to reach me: [email protected]

  • ⚑ Fun fact: My first installed Linux Distribution was a SuSE 6.1 (Kernel 2.2.6) in 1999, and my first computer was a Pentium 1 with 100 MHz and 16 MB RAM running Windows 95.

πŸ“ Latest Blog posts

βœ… Statistics

bitfinex-v2-wss-api-java's People

Contributors

alexkarezin avatar barrymac avatar bluedarkgreen avatar bvolpato avatar dependabot-preview[bot] avatar dependabot-support avatar dependabot[bot] avatar flexz9 avatar geekhare avatar hansblafoo avatar hdgh0g avatar hhanh00 avatar ilyagalahov avatar jnidzwetzki avatar khaes-kth avatar leonemagevski avatar mironbalcerzak avatar nschmid avatar rubenfanjulestrada avatar wgolyakov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

bitfinex-v2-wss-api-java's Issues

missing mappings

Greets,
Following currency mappings are missing:

ABS:ETH
ABS:USD
ATM:ETH
AUC:ETH
BNT:ETH
CBT:ETH
CND:ETH
CTX:ETH
DAD:BTC
DAD:ETH
DTA:ETH
ESS:ETH
FSN:ETH
HOT:ETH
IQX:USD
KNC:ETH
KNC:USD
LYM:ETH
LYM:USD
MAN:ETH
MAN:USD
MKR:ETH
MKR:USD
NCA:ETH
ORS:ETH
ORS:USD
POA:ETH
POY:ETH
POY:USD
SEE:BTC
SEE:ETH
SEN:ETH
UTK:ETH
UTK:USD
VEE:ETH
VEN:ETH
VEN:USD
WPR:ETH
XRA:ETH
XRA:USD
ZCN:ETH
ZIL:ETH
ZIL:USD

PS.Wouldn't it be better to refactor BitfinexCurrencyPair and dynamically build it? (maybe "register" method -- there's a REST API that could populate it: https://api.bitfinex.com/v1/symbols_details)

Great job on the lib - thank you big time :)

mb

EXAMPLES.md not up-to-date

Seems like the EXAMPLES.md is not up-to-date.

Following method in Connecting and authorizing does not exist:
BitfinexWebsocketClient client = BitfinexClientFactory.newSingleClient(config);

Following method in Connection Features does not exist:
final SequenceNumberAuditor sequenceNumberAuditor = bitfinexClient.getSequenceNumberAuditor();

I haven't checked the EXAMPLES.md for other errors, but I would appreciate it if you could have a look at it :)

new symbols length >6

After today's update, Bitfinex add two new lines with strange symbols in the list of Symbols.
https://api.bitfinex.com/v1/symbols_details
{"pair":"btcf0:ustf0","price_precision":5,"initial_margin":"1.0","minimum_margin":"0.5","maximum_order_size":"100.0","minimum_order_size":"0.001","expiration":"NA","margin":false},{"pair":"ethf0:ustf0","price_precision":5,"initial_margin":"1.0","minimum_margin":"0.5","maximum_order_size":"1000.0","minimum_order_size":"0.001","expiration":"NA","margin":false}

That have more then six chars and it let the failure:
Exception in thread "main" com.github.jnidzwetzki.bitfinex.v2.exception.BitfinexClientException: The currency pair is not 6 chars long: btcf0:ustf0
at com.github.jnidzwetzki.bitfinex.v2.entity.currency.BitfinexCurrencyPair.registerDefaults(BitfinexCurrencyPair.java:62)

It can be solved with replace registerDefaults() in BitfinexCurrencyPair.java:

` public static void registerDefaults() throws BitfinexClientException {

	try {
		final URL url = new URL(SYMBOL_URL);
		final String symbolJson = Resources.toString(url, Charsets.UTF_8);
		final JSONArray jsonArray = new JSONArray(symbolJson);

		for(int i = 0; i < jsonArray.length(); i++) {
			final JSONObject currency = jsonArray.getJSONObject(i);
			final String pair = currency.getString("pair");

// if(pair.length() != 6) {
// throw new BitfinexClientException("The currency pair is not 6 chars long: " + pair);
// }

			if(pair.length() == 6) {
				final double minOrderSize = currency.getDouble("minimum_order_size");
				final String currency1 = pair.substring(0, 3).toUpperCase();
				final String currency2 = pair.substring(3, 6).toUpperCase();
				register(currency1, currency2, minOrderSize);
			}
		}

	} catch (IOException e) {
		throw new BitfinexClientException(e);
	} 
}`

RCL_ETH does not seem to be available

In the most recent version 0.6.0, there is a new BitfinexCurrencyPair RCL_ETH. According to the responses from Bitfinex, this symbol does not seem to exist. I assume a typo that it actually means RLC_ETH, which already exists in the enum.

Exception while is converting Json.NULL to BigDecimal

Hi jnidzwetzki!

I found out an issue which appears from time to time in my console:
OnError called org.json.JSONException: JSONArray[5] could not convert to BigDecimal

It is happening in PositionHandler.handlePositionCallback method. the line is:
position.setMarginFundingType(positions.getBigDecimal(5));
It happens cause this value might be null and positions.getBigDecimal() is trying to convert JSONObject.NULL to BigDecimal.

Proposed change to handle this properly:
private void handlePositionCallback(final BitfinexApiBroker bitfinexApiBroker, final JSONArray positions) {
		final String currencyString = positions.getString(0);
		BitfinexCurrencyPair currency = BitfinexCurrencyPair.fromSymbolString(currencyString);
		final Position position = new Position(currency);
		position.setStatus(positions.getString(1));
		position.setAmount(getBigDecimalOrNull(positions, 2));
		position.setBasePrice(getBigDecimalOrNull(positions, 3));
		position.setMarginFunding(getBigDecimalOrNull(positions, 4));
		position.setMarginFundingType(getBigDecimalOrNull(positions, 5));
		position.setPl(positions.optBigDecimal(6, BigDecimal.valueOf(-1)));
		position.setPlPercent(positions.optBigDecimal(7, BigDecimal.valueOf(-1)));
		position.setPriceLiquidation(positions.optBigDecimal(8, BigDecimal.valueOf(-1)));
		position.setLeverage(positions.optBigDecimal(9, BigDecimal.valueOf(-1)));
		bitfinexApiBroker.getPositionManager().updatePosition(position);
	}

	private BigDecimal getBigDecimalOrNull(JSONArray positions, int index) {
		return !positions.get(index).equals(JSONObject.NULL) ? positions.getBigDecimal(index) : null;
	}

Errors with derivatives

In BitfinexPair.java, something like below for the derivatives
@Override public String toBitfinexString() { if(!currency2.equals("USTF0")){ return "t" + currency1 + currency2; }else{ return "t" + currency1 + ":" + currency2; } }

Compound order status parse exception

Hi Jan!

Got complicated order status response: INSUFFICIENT BALANCE (G1) was: ACTIVE (note:POSCLOSE), PARTIALLY FILLED @ 0.008049(-0.41291886).
Looks like it should be converted to PARTIALLY FILLED status, however there is a ExchangeOrderState.fromString method which tries to parse text to the status. I guess it should be parsed something like this:

public static ExchangeOrderState fromString(final String string) {
		
		Objects.requireNonNull(string);
		
		for (ExchangeOrderState state : ExchangeOrderState.values()) {
			if (string.startsWith(state.getBitfinexString())) {
				return state;
			}
		}

		if(string.contains("PARTIALLY FILLED")){
			return ExchangeOrderState.STATE_PARTIALLY_FILLED;
		}
		
		throw new IllegalArgumentException("Unable to find order type for: " + string);
	}

Response I got:

Got order callback [0,"oc",[11291120775,null,null,"tNEOBTC",1524661302976,1524661303001,0,-0.41291886,"MARKET",null,null,null,0,"INSUFFICIENT BALANCE (G1) was: ACTIVE (note:POSCLOSE), PARTIALLY FILLED @ 0.008049(-0.41291886)",null,null,0,0.008049,null,null,null,null,null,0,0,0,null,null,"",null,null,null]]
2018-04-25 16:01:43 - OnError called java.lang.IllegalArgumentException: Unable to find order type for: INSUFFICIENT BALANCE (G1) was: ACTIVE (note:POSCLOSE), PARTIALLY FILLED @ 0.008049(-0.41291886)
	at com.github.jnidzwetzki.bitfinex.v2.entity.ExchangeOrderState.fromString(ExchangeOrderState.java:51)
	at com.github.jnidzwetzki.bitfinex.v2.callback.api.OrderHandler.handleOrderCallback(OrderHandler.java:99)
	at com.github.jnidzwetzki.bitfinex.v2.callback.api.OrderHandler.handleChannelData(OrderHandler.java:55)

Each ExecutedTrades appears two times

If you register for listening for ExecutedTrades updates (see https://github.com/jnidzwetzki/bitfinex-v2-wss-api-java/blob/master/EXAMPLES.md), each trade appears exactly two times. Using the Websocket Playground, you'll notice that one trade is received with a "te" field and one with a "tu" field.
According to Bitfinex, the "te" message should appear first whereas the "tu" message should include the tradeID. As both messages seem to include the tradeID, one of the messages doesn't need to be broadcasted and hand over to the callbacks. Naturally, the callback listeners could handle this as well but as I see no advantage in listening for the same message two times, I would recommend to filter one message inside the API.

Callback order EXCHANGE_MARKET amount bought

Hello,

How can you see the amount of bought currency when an order is finished?
I'm doing a callback, but im not feeling it to try things out to figure out what everything is at this moment.

Like I want to buy BTC, I have 50$, how would you buy BTC, and knowing in the callback how much you bought?

ClientGroupId in BitfinexNewOrder should be Long instead of Integer

I'm getting following number format exception (input can't be parsed to Integer):

2019-02-07 14:59:26.546 ERROR 16221 --- [us-jdk-client-2] c.g.j.b.v2.SimpleBitfinexApiBroker : OnError called java.lang.NumberFormatException: For input string: "1569445422239" at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) at java.lang.Integer.parseInt(Integer.java:583) at java.lang.Integer.parseInt(Integer.java:615) at com.github.jnidzwetzki.bitfinex.v2.callback.channel.account.info.OrderHandler.jsonToBitfinexSubmittedOrder(OrderHandler.java:95) at com.github.jnidzwetzki.bitfinex.v2.callback.channel.account.info.OrderHandler.handleChannelData(OrderHandler.java:74) at com.github.jnidzwetzki.bitfinex.v2.callback.channel.AccountInfoHandler.handleChannelData(AccountInfoHandler.java:108) at com.github.jnidzwetzki.bitfinex.v2.SimpleBitfinexApiBroker.handleChannelCallback(SimpleBitfinexApiBroker.java:591) at com.github.jnidzwetzki.bitfinex.v2.SimpleBitfinexApiBroker.websocketCallback(SimpleBitfinexApiBroker.java:524) at com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.onMessage(WebsocketClientEndpoint.java:117)

I guess, the clientGroupId in BitfinexNewOrder should be a Long instead.

Issue while parsing NULL in Order NotificationHandler

Hi Jan!

There is one more similar to submitted before issue :

Channel callback. Got message {}[0,"n",[1523930407542,"on-req",null,null,[null,null,1523930407442000,null,null,null,0.0001,null,"LIMIT",null,null,null,null,null,null,null,6800,null,null,null,null,null,null,0,0,null,null,null,null,null,null,null],null,"ERROR","amount: invalid"]]
2018-04-17 10:00:07 - Got Error message: [0,"n",[1523930407542,"on-req",null,null,[null,null,1523930407442000,null,null,null,0.0001,null,"LIMIT",null,null,null,null,null,null,null,6800,null,null,null,null,null,null,0,0,null,null,null,null,null,null,null],null,"ERROR","amount: invalid"]]
2018-04-17 10:00:07 - OnError called org.json.JSONException: JSONArray[3] not a string.
	at org.json.JSONArray.getString(JSONArray.java:450)
	at com.github.jnidzwetzki.bitfinex.v2.callback.api.NotificationHandler.handleErrorNotification(NotificationHandler.java:74)

Wallet getBalanceAvailable is returning null value

hello, I used the following piece of code for getting the available amount for a currency

for (final BitfinexWallet wallet : bitfinexWebsocketClient.getWalletManager().getWallets()) {
            if (wallet.getCurrency().equals(currency.getCurrency2())) {
                logger.info(wallet.toString());
                return wallet.getBalanceAvailable();
            }
        }

but the return value is null while getBalance() is returning 2327.6672216

[walletType=EXCHANGE, currency=USD, balance=2327.6672216, unsettledInterest=0, balanceAvailable=null]

thank you in advance

does not working walletTable

System.out.println(bitfinexClient.getWalletManager().getWalletTable().get("exchange", "USD"));
always return null

working this
System.out.println(bitfinexClient.getWalletManager().getWalletTable().get(Type.EXCHANGE, "USD"));

Handshake Error

In the BitfinexApiBroker connect method, I'm getting a Handshake Error on the line:

websocketEndpoint.connect();

Anyone else getting the same error? Everything was running perfectly until about 1 hour ago and I haven't been able to connect since then.

create() method in BitfinexOrderBuilder does not accept BigDecimal

The static create() method in BitfinexOrderBuilder requires the amount to be given as double. Since the reminder is using BigDecimals, we might lose precision here if the conversion into double is necessary. Since the BitfinexOrderBuilder processes with BigDecimals internally (see the private constructor), it makes sense to change the amount parameter type to BigDecimal as well.

Connection failed

Hello. Can anyone help pls. I 've tried to run simple example

BitfinexApiBroker bitfinexApiBroker = new BitfinexApiBroker();
        try {
            System.out.println("create connection");
            bitfinexApiBroker.connect();
        } catch (APIException e) {
            LOG.error("getBitfinexResultMap",e);
        }

But i get this error:

ERROR Bitfinex [Bitfinex.java:27] getBitfinexResultMap
com.github.jnidzwetzki.bitfinex.v2.entity.APIException: javax.websocket.DeploymentException: Connection failed.
at com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker.connect(BitfinexApiBroker.java:338)
at exchange.bitfinex.Bitfinex.getBitfinexResultMap(Bitfinex.java:25)
at exchange.Exchange.main(Exchange.java:46)
Caused by: javax.websocket.DeploymentException: Connection failed.
at org.glassfish.tyrus.container.jdk.client.JdkClientContainer$1.call(JdkClientContainer.java:200)
at org.glassfish.tyrus.container.jdk.client.JdkClientContainer$1.call(JdkClientContainer.java:126)
at org.glassfish.tyrus.container.jdk.client.JdkClientContainer.openClientSocket(JdkClientContainer.java:205)
at org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:668)
at org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:717)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:871)
at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:516)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:378)
at com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.connect(WebsocketClientEndpoint.java:87)
at com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker.connect(BitfinexApiBroker.java:329)
... 2 common frames omitted
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Handshaker.checkThrown(Handshaker.java:1529)
at sun.security.ssl.SSLEngineImpl.checkTaskThrown(SSLEngineImpl.java:535)
at sun.security.ssl.SSLEngineImpl.writeAppRecord(SSLEngineImpl.java:1214)
at sun.security.ssl.SSLEngineImpl.wrap(SSLEngineImpl.java:1186)
at javax.net.ssl.SSLEngine.wrap(SSLEngine.java:469)
at org.glassfish.tyrus.container.jdk.client.SslFilter.doHandshakeStep(SslFilter.java:478)
at org.glassfish.tyrus.container.jdk.client.SslFilter.processRead(SslFilter.java:363)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:134)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:136)
at org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:299)
at org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:283)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:281)
at sun.nio.ch.WindowsAsynchronousSocketChannelImpl$ReadTask.completed(WindowsAsynchronousSocketChannelImpl.java:579)
at sun.nio.ch.Iocp$EventHandlerTask.run(Iocp.java:397)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1728)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:330)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:322)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1614)
at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:216)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:1052)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:992)
at sun.security.ssl.Handshaker$1.run(Handshaker.java:989)
at java.security.AccessController.doPrivileged(Native Method)
at sun.security.ssl.Handshaker$DelegatedTask.run(Handshaker.java:1467)
at org.glassfish.tyrus.container.jdk.client.SslFilter.doHandshakeStep(SslFilter.java:553)
... 13 common frames omitted
Caused by: java.security.cert.CertificateException: No name matching api.bitfinex.com found
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:231)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1601)
... 20 common frames omitted
ERROR BitfinexApiBroker [WebsocketClientEndpoint.java:122] Unable to send message, user session is null

What i did wrong?

Fields of ExecutedTrade won't set correctly

If you take the example for listening for executed trades update as shown as in https://github.com/jnidzwetzki/bitfinex-v2-wss-api-java/blob/master/EXAMPLES.md you will get the following output in the System.out.format command which calls ExecutedTrade.toString()

Got executed trade (ExecutedTrade [timestamp=191469397, amount=1518128553252, price=0.00449071, rate=8161.9, period=0]) for symbol (BitfinexExecutedTradeSymbol [bitfinexCurrencyPair=BTC_USD])

Obviously, the timestamp, amount, price and rate values are not correct but shifted by one position. The timestamp value shown above (191469397) is likely an ID, the amount value shown is actually the timestamp, the price value is actually the amount and the rate value is actually the price. Thus, there seems to be a parsing error in the JSON response.

New release

Any chance of releasing the lib with fix: implemented "BU" websocket event.
Current version is not that usable with tons of errors in logs nowadays.

Question for Margin available

Hi. I cant figure out how to get 'margin available'. I've succesfully received my wallet data. Unfortunately it shows -1 in each field "balance available". Example: [walletType=margin, curreny=USD, balance=1800.03706837, unsettledInterest=0.0, balanceAvailable=-1.0], Could you please provide me with guidance how to resolve this issue? It seems that this field is hardcoded

Connection state specific handlers introduced, externalize reconnection if needed

Hi Jan,
Been a while - hope you are doing all fine.

In this PR i've introduced 3 handlers that were missing.

  • onConnectionSuccess()
  • onConnectionFailure()
  • onDisconnection()

Possible problem might arise if user decides mixing logic with onConnectionStateChange(value)... but we cannot do much against "stupid"... :))

The main purpose of this PR is to externalize manual reconnection - for this reason I've introduced a flag BitfinexWebsocketConfiguration#autoReconnect which defaults to true.

have a good day,

  • mb

Can't connect

Hello,

I have just tried your library and here is what I get at connection (both authenticated or not).

11:28:51.990 [main] DEBUG com.github.jnidzwetzki.bitfinex.v2.SequenceNumberAuditor - Resetting sequence auditor
11:28:52.376 [Grizzly-worker(1)] INFO com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker - Closing websocket: CloseReason[1000,Closing]
11:28:52.377 [main] ERROR test.BitfinexWebSocketClient2 - Could not connect to Bitfinex API
com.github.jnidzwetzki.bitfinex.v2.entity.APIException: javax.websocket.DeploymentException: Handshake error.
at com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker.connect(BitfinexApiBroker.java:330)
at test.BitfinexWebSocketClient2.start(BitfinexWebSocketClient2.java:46)
at test.BitfinexWebSocketClient2.main(BitfinexWebSocketClient2.java:78)
Caused by: javax.websocket.DeploymentException: Handshake error.
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:285)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:172)
at com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.connect(WebsocketClientEndpoint.java:87)
at com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker.connect(BitfinexApiBroker.java:321)
... 2 common frames omitted
Caused by: org.glassfish.tyrus.websockets.HandshakeException: Response code was not 101: 400
at org.glassfish.tyrus.websockets.HandShake.validateServerResponse(HandShake.java:314)
at org.glassfish.tyrus.websockets.draft06.HandShake06.validateServerResponse(HandShake06.java:98)
at org.glassfish.tyrus.container.grizzly.WebSocketFilter.handleClientHandShake(WebSocketFilter.java:368)
at org.glassfish.tyrus.container.grizzly.WebSocketFilter.handleHandshake(WebSocketFilter.java:353)
at org.glassfish.tyrus.container.grizzly.WebSocketFilter.handleRead(WebSocketFilter.java:274)
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:837)
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
at java.lang.Thread.run(Thread.java:748)
null

Is this a known problem?

I tried to connect using code with native java calls (not using this library), and it worked.

Handshake Error since schedule maintenance on Jan 07

Ever since the scheduled maintenance I've been getting this. However, I've confirmed that the websocket endpoint being used, "wss://api.bitfinex.com/ws/2", is still valid, by checking on https://www.websocket.org/echo.html, so there's some other issue at play.

Caused by: java.lang.RuntimeException: com.github.jnidzwetzki.bitfinex.v2.entity.APIException: javax.websocket.DeploymentException: Handshake error.
... 6 more
Caused by: com.github.jnidzwetzki.bitfinex.v2.entity.APIException: javax.websocket.DeploymentException: Handshake error.
at com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker.connect(BitfinexApiBroker.java:320)
... 6 more
Caused by: javax.websocket.DeploymentException: Handshake error.
at org.glassfish.tyrus.client.ClientManager$3$1.run(ClientManager.java:679)
at org.glassfish.tyrus.client.ClientManager$3.run(ClientManager.java:717)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:514)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at org.glassfish.tyrus.client.ClientManager$SameThreadExecutorService.execute(ClientManager.java:871)
at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:118)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:516)
at org.glassfish.tyrus.client.ClientManager.connectToServer(ClientManager.java:378)
at com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.connect(WebsocketClientEndpoint.java:87)
at com.github.jnidzwetzki.bitfinex.v2.BitfinexApiBroker.connect(BitfinexApiBroker.java:311)
... 8 more
Caused by: org.glassfish.tyrus.core.HandshakeException: Response code was not 101: 520.
at org.glassfish.tyrus.client.TyrusClientEngine.processResponse(TyrusClientEngine.java:320)
at org.glassfish.tyrus.container.jdk.client.ClientFilter.processRead(ClientFilter.java:190)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:134)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:136)
at org.glassfish.tyrus.container.jdk.client.SslFilter.handleRead(SslFilter.java:406)
at org.glassfish.tyrus.container.jdk.client.SslFilter.processRead(SslFilter.java:368)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:134)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:136)
at org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:299)
at org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:283)
at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
at java.base/sun.nio.ch.Invoker$2.run(Invoker.java:219)
at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.base/java.lang.Thread.run(Thread.java:844)

Missing precision due to floating-point arithmetic

I noticed it several times that rounding issues occur, e.g. while multiplying prices and amounts, which is caused by the limited precision even of double variables. These issues can cause trouble in working with Bitfinex as little rounding problems may lead to an exceeding of available balances and so on.

These problems are caused by the fact that all objects holding numerical values like prices, rates or amounts are using double values. In order to avoid this, the internal representation should be changed to BigDecimal which enables exact representation of numbers and thus exact calculations. However, this also requires that all processing steps like message parsing, value storage, message creation and internal processing must be done with BigDecimal without any intermediate conversion to a floating-point value like double.

Change from float to double in Trade class

In the Trade class there are several attributes which use float as data type: execPrice, orderPrice, execAmount and fee. A problem with that is that while dealing with crypto currencies, we often have to work with very little numbers or long floating point values. The usage of float introduces notable inaccuracy as it is not possible to represent the floating point values sent from Bitfinex exactly. Thus, I recommend to switch to double for these attributes in order to reduce the inaccuracy.

":" in pair name

The point is the length of the array, which is incorrect because of the colon.

For example, an attempt to use such a pair causes errors "BTCF0:USTF0".

Error in method BitfinexCandlestickSymbol.fromBitfinexString(String symbol)

log

21:25:36.697 [ tyrus-jdk-client-3] ERROR com.github.jnidzwetzki.bitfinex.v2.SimpleBitfinexApiBroker - OnError called java.lang.IllegalArgumentException: Unable to parse: trade:1m:tBTCF0:USTF0
at com.github.jnidzwetzki.bitfinex.v2.symbol.BitfinexCandlestickSymbol.fromBitfinexString(BitfinexCandlestickSymbol.java:70)
at com.github.jnidzwetzki.bitfinex.v2.callback.command.SubscribedCallback.handleCandlesCallback(SubscribedCallback.java:89)
at com.github.jnidzwetzki.bitfinex.v2.callback.command.SubscribedCallback.handleChannelData(SubscribedCallback.java:56)
at com.github.jnidzwetzki.bitfinex.v2.SimpleBitfinexApiBroker.handleCommandCallback(SimpleBitfinexApiBroker.java:552)
at com.github.jnidzwetzki.bitfinex.v2.SimpleBitfinexApiBroker.websocketCallback(SimpleBitfinexApiBroker.java:530)
at com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.onMessage(WebsocketClientEndpoint.java:117)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.glassfish.tyrus.core.AnnotatedEndpoint.callMethod(AnnotatedEndpoint.java:552)
at org.glassfish.tyrus.core.AnnotatedEndpoint.access$100(AnnotatedEndpoint.java:65)
at org.glassfish.tyrus.core.AnnotatedEndpoint$WholeHandler$1.onMessage(AnnotatedEndpoint.java:651)
at org.glassfish.tyrus.core.TyrusSession.notifyMessageHandlers(TyrusSession.java:559)
at org.glassfish.tyrus.core.TyrusEndpointWrapper.onMessage(TyrusEndpointWrapper.java:855)
at org.glassfish.tyrus.core.TyrusWebSocket.onMessage(TyrusWebSocket.java:196)
at org.glassfish.tyrus.core.frame.TextFrame.respond(TextFrame.java:115)
at org.glassfish.tyrus.core.ProtocolHandler.process(ProtocolHandler.java:819)
at org.glassfish.tyrus.client.TyrusClientEngine$TyrusReadHandler.handle(TyrusClientEngine.java:724)
at org.glassfish.tyrus.container.jdk.client.ClientFilter.processRead(ClientFilter.java:204)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:111)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:113)
at org.glassfish.tyrus.container.jdk.client.SslFilter.handleRead(SslFilter.java:383)
at org.glassfish.tyrus.container.jdk.client.SslFilter.processRead(SslFilter.java:345)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:111)
at org.glassfish.tyrus.container.jdk.client.Filter.onRead(Filter.java:113)
at org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:294)
at org.glassfish.tyrus.container.jdk.client.TransportFilter$4.completed(TransportFilter.java:278)
at java.base/sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:127)
at java.base/sun.nio.ch.Invoker$2.run(Invoker.java:219)
at java.base/sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
at java.base/java.lang.Thread.run(Thread.java:832)



21:25:36.712 [ tyrus-jdk-client-3] ERROR com.github.jnidzwetzki.bitfinex.v2.SimpleBitfinexApiBroker - Unable to determine symbol for channel 76046 / data is [76046,[[1611771900000,30243,30220,30281,30220,13.79159809],

Issue with order amount after BigDecimal migration

Hi Jan!

This guy is critical:
When I submit an order I get this error:
Got Error message: [0,"n",[1523955674172,"on-req",null,null,[null,null,1523955674030000,null,null,null,-5.95861881,null,"LIMIT",null,null,null,null,null,null,null,68.856,null,null,null,null,null,null,0,0,null,null,null,null,null,null,null],null,"ERROR","amount: invalid"]]

Then I put a break point into BitfinexApiBroker.sendCommand() after final String generation. And I got this record:
[0,"on", null, {"symbol":"tBTCUSD","amount":0.01,"hidden":0,"price":6800,"type":"LIMIT","cid":1523967707187000}]

Then I rolled back to version 0.6.1 and got message at the same breakPoint:
[0,"on", null, {"symbol":"tBTCUSD","amount":"0.01","hidden":0,"price":"6800.0","type":"LIMIT","cid":1523968320583000}]

Looks like amount now serialized in another way cause now it is BigDecimal

Order update functionality

Hi Jan!

Just a quick question. I was trying to update submitted order and as I can see method updateOrder in OrderManager class just add an order to internal order list, however does not send any request with update to Bitfinex using client as it is implemented in placeOrder or cancelOrder methods:
client.sendCommand(orderNewCommand);
Am I right? If no, could you point me to the update order functionality

spring boot application does not deploy on JBoss if I add bitfinex-v2-wss-api dependency to the pom file. (UT003024: Web socket deployment failed. java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>())

Hello,

when i try to deploy the application on JBoss (18.0.1) server this message is displayed in the logs and deployment stops:

[2019-12-05 01:28:56,415] Artifact test-spring-jboss:war exploded: Artifact is being deployed, please wait...
01:28:56,701 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-1) WFLYSRV0027: Starting deployment of "test-spring-jboss-1.0-SNAPSHOT" (runtime-name: "test-spring-jboss-1.0-SNAPSHOT.war")
01:29:02,275 WARN  [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletServerHttpResponse$ResponseAsyncListener due to an exception (enable DEBUG log level to see the cause)
01:29:02,276 WARN  [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletHttpHandlerAdapter$HandlerResultAsyncListener due to an exception (enable DEBUG log level to see the cause)
01:29:02,277 WARN  [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component org.springframework.http.server.ServletServerHttpAsyncRequestControl due to an exception (enable DEBUG log level to see the cause)
01:29:02,278 WARN  [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component org.springframework.web.context.request.async.StandardServletAsyncWebRequest due to an exception (enable DEBUG log level to see the cause)
01:29:02,282 WARN  [org.jboss.as.ee] (MSC service thread 1-7) WFLYEE0007: Not installing optional component org.springframework.http.server.reactive.ServletServerHttpRequest$RequestAsyncListener due to an exception (enable DEBUG log level to see the cause)
01:29:02,343 INFO  [io.undertow.websockets.jsr] (ServerService Thread Pool -- 142) UT026004: Adding annotated client endpoint class com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint
01:29:02,344 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 142) MSC000001: Failed to start service jboss.deployment.unit."test-spring-jboss-1.0-SNAPSHOT.war".undertow-deployment: org.jboss.msc.service.StartException in service jboss.deployment.unit."test-spring-jboss-1.0-SNAPSHOT.war".undertow-deployment: java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:81)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
	at org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:1982)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1486)
	at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1377)
	at java.lang.Thread.run(Thread.java:745)
	at org.jboss.threads.JBossThread.run(JBossThread.java:485)
Caused by: java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
	at io.undertow.websockets.jsr.Bootstrap.handleDeployment(Bootstrap.java:93)
	at io.undertow.servlet.core.DeploymentManagerImpl.handleExtensions(DeploymentManagerImpl.java:279)
	at io.undertow.servlet.core.DeploymentManagerImpl.deploy(DeploymentManagerImpl.java:155)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentService.startContext(UndertowDeploymentService.java:96)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentService$1.run(UndertowDeploymentService.java:78)
	... 9 more
Caused by: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
	at io.undertow.websockets.jsr.ServerWebSocketContainer.addEndpointInternal(ServerWebSocketContainer.java:700)
	at io.undertow.websockets.jsr.ServerWebSocketContainer.addEndpoint(ServerWebSocketContainer.java:622)
	at io.undertow.websockets.jsr.Bootstrap.handleDeployment(Bootstrap.java:87)
	... 13 more
Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()
	at org.jboss.as.ee.component.ReflectiveClassIntrospector.createFactory(ReflectiveClassIntrospector.java:59)
	at org.jboss.as.ee.component.ComponentRegistry.createInstanceFactory(ComponentRegistry.java:76)
	at org.wildfly.extension.undertow.deployment.UndertowDeploymentInfoService$ComponentClassIntrospector.createInstanceFactory(UndertowDeploymentInfoService.java:1290)
	at io.undertow.websockets.jsr.ServerWebSocketContainer.addEndpointInternal(ServerWebSocketContainer.java:694)
	... 15 more
Caused by: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()
	at java.lang.Class.getConstructor0(Class.java:3082)
	at java.lang.Class.getDeclaredConstructor(Class.java:2178)
	at org.jboss.as.ee.component.ReflectiveClassIntrospector.createFactory(ReflectiveClassIntrospector.java:57)
	... 18 more

01:29:02,347 ERROR [org.jboss.as.controller.management-operation] (management-handler-thread - 4) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "test-spring-jboss-1.0-SNAPSHOT")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"test-spring-jboss-1.0-SNAPSHOT.war\".undertow-deployment" => "java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()
    Caused by: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()"}}
01:29:02,348 ERROR [org.jboss.as.server] (management-handler-thread - 4) WFLYSRV0021: Deploy of deployment "test-spring-jboss-1.0-SNAPSHOT.war" was rolled back with the following failure message: 
{"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"test-spring-jboss-1.0-SNAPSHOT.war\".undertow-deployment" => "java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()
    Caused by: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()"}}
01:29:02,463 INFO  [org.jboss.as.server.deployment] (MSC service thread 1-8) WFLYSRV0028: Stopped deployment test-spring-jboss-1.0-SNAPSHOT (runtime-name: test-spring-jboss-1.0-SNAPSHOT.war) in 115ms
[2019-12-05 01:29:02,563] Artifact test-spring-jboss:war exploded: Error during artifact deployment. See server log for details.
[2019-12-05 01:29:02,563] Artifact test-spring-jboss:war exploded: java.lang.Exception: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"test-spring-jboss-1.0-SNAPSHOT.war\".undertow-deployment" => "java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: java.lang.RuntimeException: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: javax.websocket.DeploymentException: UT003024: Web socket deployment failed
    Caused by: java.lang.RuntimeException: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()
    Caused by: java.lang.NoSuchMethodException: com.github.jnidzwetzki.bitfinex.v2.WebsocketClientEndpoint.<init>()"}}

POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>test-spring-jboss</groupId>
    <artifactId>test-spring-jboss</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.1.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>


    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.github.jnidzwetzki</groupId>
            <artifactId>bitfinex-v2-wss-api</artifactId>
            <version>0.7.5</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

SpringBootDemoApplication.java

@SpringBootApplication
public class SpringBootDemoApplication extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder){
        return builder.sources(SpringBootDemoApplication.class);
    }
    public static void main(String[] args){
        SpringApplication.run(SpringBootDemoApplication.class, args);
    }
}

Please help,

Thanks

Handle loan messages

Add a 'do nothing' handler for loan messages until the funding part of the API is implemented.

Callback for error messages

At the moment, all channel related errors are only logged in AccountInfoHandler:111. There should be a callback to receive all errors as a string or a JSON message..

Don't recieve ticker information for all pairs

Hello!First of all thanks for great library.
I have some issue.
I need subscribe three callback(order book,trades and current ticker information) for every pair on exchange.
I create single BitfinexWebsocketClient instance for it.

BitfinexWebsocketClient client= BitfinexClientFactory.newPooledClient(config,249);
client.connect();
 BitfinexCurrencyPair.registerDefaults()

Next i subscribe all pairs

Collection<BitfinexCurrencyPair> symbols = BitfinexCurrencyPair.values();
        ExecutorService service = Executors.newFixedThreadPool(symbols.size()+1);
        final QuoteManager quoteManager = client.getQuoteManager();
        final BiConsumer<BitfinexTickerSymbol, BitfinexTick> volCallback = getTickCallback();

        for (BitfinexCurrencyPair pair:symbols) {
            service.submit(() -> {
                BitfinexTickerSymbol symbol = BitfinexTickerSymbol.fromBitfinexString(pair.toBitfinexString());
                quoteManager.registerTickCallback(symbol, volCallback);
                quoteManager.subscribeTicker(symbol);
                return "true";
            });
        }

The same code i write for order book and executed trades.
But i don't recieve information for some pairs like tBTCUSD or tETHUSD, although almost all work correctly.
Is any idea what i'm doing wrong?Thanks in advance

Is it possible to use this library in Android projects?

I have imported the lib into my Android project with the following gradle commands:

implementation 'com.github.jnidzwetzki:bitfinex-v2-wss-api:0.6.9'
annotationProcessor 'org.apache.logging.log4j:log4j-core:2.11.1'

Added Java 8 and multidex support

multiDexEnabled true
compileOptions {
     sourceCompatibility JavaVersion.VERSION_1_8
     targetCompatibility JavaVersion.VERSION_1_8
}

When I build the project I get the following errors:

Exception in thread "main" java.lang.IllegalArgumentException: Type without superclass: module-info
    at com.google.common.base.Preconditions.checkArgument(Preconditions.java:191)
    at com.google.devtools.build.android.desugar.DefaultMethodClassFixer.visit(DefaultMethodClassFixer.java:80)
    at org.objectweb.asm.ClassVisitor.visit(ClassVisitor.java:113)
    at com.google.devtools.build.android.desugar.InterfaceDesugaring.visit(InterfaceDesugaring.java:97)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:621)
    at org.objectweb.asm.ClassReader.accept(ClassReader.java:500)
    at com.google.devtools.build.android.desugar.Desugar.desugarClassesInInput(Desugar.java:477)
    at com.google.devtools.build.android.desugar.Desugar.desugarOneInput(Desugar.java:361)
    at com.google.devtools.build.android.desugar.Desugar.desugar(Desugar.java:314)
    at com.google.devtools.build.android.desugar.Desugar.main(Desugar.java:711)

:app:transformClassesWithDesugarForDebug FAILED
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:transformClassesWithDesugarForDebug'.
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:100)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:70)
	at org.gradle.api.internal.tasks.execution.OutputDirectoryCreatingTaskExecuter.execute(OutputDirectoryCreatingTaskExecuter.java:51)
	at org.gradle.api.internal.tasks.execution.SkipUpToDateTaskExecuter.execute(SkipUpToDateTaskExecuter.java:62)
	at org.gradle.api.internal.tasks.execution.ResolveTaskOutputCachingStateExecuter.execute(ResolveTaskOutputCachingStateExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ValidatingTaskExecuter.execute(ValidatingTaskExecuter.java:60)
	at org.gradle.api.internal.tasks.execution.SkipEmptySourceFilesTaskExecuter.execute(SkipEmptySourceFilesTaskExecuter.java:97)
	at org.gradle.api.internal.tasks.execution.CleanupStaleOutputsExecuter.execute(CleanupStaleOutputsExecuter.java:87)
	at org.gradle.api.internal.tasks.execution.ResolveTaskArtifactStateTaskExecuter.execute(ResolveTaskArtifactStateTaskExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:52)
	at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:54)
	at org.gradle.api.internal.tasks.execution.ExecuteAtMostOnceTaskExecuter.execute(ExecuteAtMostOnceTaskExecuter.java:43)
	at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:34)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker$1.run(DefaultTaskGraphExecuter.java:248)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:241)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter$EventFiringTaskWorker.execute(DefaultTaskGraphExecuter.java:230)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.processTask(DefaultTaskPlanExecutor.java:123)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.access$200(DefaultTaskPlanExecutor.java:79)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:104)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker$1.execute(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.execute(DefaultTaskExecutionPlan.java:626)
	at org.gradle.execution.taskgraph.DefaultTaskExecutionPlan.executeWithTask(DefaultTaskExecutionPlan.java:581)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor$TaskExecutorWorker.run(DefaultTaskPlanExecutor.java:98)
	at org.gradle.execution.taskgraph.DefaultTaskPlanExecutor.process(DefaultTaskPlanExecutor.java:59)
	at org.gradle.execution.taskgraph.DefaultTaskGraphExecuter.execute(DefaultTaskGraphExecuter.java:128)
	at org.gradle.execution.SelectedTaskExecutionAction.execute(SelectedTaskExecutionAction.java:37)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
	at org.gradle.execution.DefaultBuildExecuter.access$000(DefaultBuildExecuter.java:23)
	at org.gradle.execution.DefaultBuildExecuter$1.proceed(DefaultBuildExecuter.java:43)
	at org.gradle.execution.DryRunBuildExecutionAction.execute(DryRunBuildExecutionAction.java:46)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:37)
	at org.gradle.execution.DefaultBuildExecuter.execute(DefaultBuildExecuter.java:30)
	at org.gradle.initialization.DefaultGradleLauncher$ExecuteTasks.run(DefaultGradleLauncher.java:314)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.initialization.DefaultGradleLauncher.runTasks(DefaultGradleLauncher.java:204)
	at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:134)
	at org.gradle.initialization.DefaultGradleLauncher.executeTasks(DefaultGradleLauncher.java:109)
	at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:78)
	at org.gradle.internal.invocation.GradleBuildController$1.call(GradleBuildController.java:75)
	at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:152)
	at org.gradle.internal.invocation.GradleBuildController.doBuild(GradleBuildController.java:100)
	at org.gradle.internal.invocation.GradleBuildController.run(GradleBuildController.java:75)
	at org.gradle.tooling.internal.provider.runner.BuildModelActionRunner.run(BuildModelActionRunner.java:53)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
	at org.gradle.tooling.internal.provider.ValidatingBuildActionRunner.run(ValidatingBuildActionRunner.java:32)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner$1.run(RunAsBuildOperationBuildActionRunner.java:43)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.launcher.exec.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
	at org.gradle.tooling.internal.provider.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:51)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:47)
	at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:30)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:39)
	at org.gradle.launcher.exec.BuildTreeScopeBuildActionExecuter.execute(BuildTreeScopeBuildActionExecuter.java:25)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:80)
	at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:53)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:57)
	at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:32)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:36)
	at org.gradle.tooling.internal.provider.GradleThreadBuildActionExecuter.execute(GradleThreadBuildActionExecuter.java:25)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:43)
	at org.gradle.tooling.internal.provider.ParallelismConfigurationBuildActionExecuter.execute(ParallelismConfigurationBuildActionExecuter.java:29)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:69)
	at org.gradle.tooling.internal.provider.StartParamsValidatingActionExecuter.execute(StartParamsValidatingActionExecuter.java:30)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:59)
	at org.gradle.tooling.internal.provider.SessionFailureReportingActionExecuter.execute(SessionFailureReportingActionExecuter.java:44)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:45)
	at org.gradle.tooling.internal.provider.SetupLoggingActionExecuter.execute(SetupLoggingActionExecuter.java:30)
	at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
	at org.gradle.util.Swapper.swap(Swapper.java:38)
	at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:62)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:82)
	at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
	at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:122)
	at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
	at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:295)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
	at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: com.android.build.api.transform.TransformException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException
	at com.android.builder.profile.Recorder$Block.handleException(Recorder.java:55)
	at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:104)
	at com.android.build.gradle.internal.pipeline.TransformTask.transform(TransformTask.java:212)
	at sun.reflect.GeneratedMethodAccessor114.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
	at org.gradle.api.internal.project.taskfactory.IncrementalTaskAction.doExecute(IncrementalTaskAction.java:46)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
	at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter$1.run(ExecuteActionsTaskExecuter.java:121)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:336)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor$RunnableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:328)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:199)
	at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeAction(ExecuteActionsTaskExecuter.java:110)
	at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeActions(ExecuteActionsTaskExecuter.java:92)
	... 107 more
Caused by: com.android.build.api.transform.TransformException: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException
	at com.android.build.gradle.internal.transforms.DesugarTransform.transform(DesugarTransform.java:292)
	at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:221)
	at com.android.build.gradle.internal.pipeline.TransformTask$2.call(TransformTask.java:217)
	at com.android.builder.profile.ThreadRecorder.record(ThreadRecorder.java:102)
	... 122 more
Caused by: java.lang.IllegalArgumentException: java.lang.IllegalArgumentException
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:593)
	at java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:677)
	at java.util.concurrent.ForkJoinTask.join(ForkJoinTask.java:720)
	at com.android.ide.common.internal.WaitableExecutor.waitForTasksWithQuickFail(WaitableExecutor.java:146)
	at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.getInitalGraphData(DesugarIncrementalTransformHelper.java:162)
	at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.lambda$makeDesugaringGraph$2(DesugarIncrementalTransformHelper.java:134)
	at com.android.builder.desugaring.DesugaringGraphs.forVariant(DesugaringGraphs.java:50)
	at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.makeDesugaringGraph(DesugarIncrementalTransformHelper.java:132)
	at com.google.common.base.Suppliers$NonSerializableMemoizingSupplier.get(Suppliers.java:160)
	at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.getAdditionalPaths(DesugarIncrementalTransformHelper.java:111)
	at com.android.build.gradle.internal.transforms.DesugarTransform.incrementalAnalysis(DesugarTransform.java:305)
	at com.android.build.gradle.internal.transforms.DesugarTransform.transform(DesugarTransform.java:264)
	... 125 more
Caused by: java.lang.IllegalArgumentException
	at org.objectweb.asm.ClassReader.<init>(Unknown Source)
	at org.objectweb.asm.ClassReader.<init>(Unknown Source)
	at org.objectweb.asm.ClassReader.<init>(Unknown Source)
	at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:142)
	at com.android.builder.desugaring.DesugaringClassAnalyzer.analyzeJar(DesugaringClassAnalyzer.java:92)
	at com.android.builder.desugaring.DesugaringClassAnalyzer.analyze(DesugaringClassAnalyzer.java:63)
	at com.android.build.gradle.internal.transforms.DesugarIncrementalTransformHelper.lambda$getInitalGraphData$4(DesugarIncrementalTransformHelper.java:150)
	at java.util.concurrent.ForkJoinTask$AdaptedCallable.exec(ForkJoinTask.java:1424)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
	at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)

Sequence number concurrent update

Hi Jan!
I figured out an issue related to Sequence number update. It might be that it updates as normal, then it stucks at the same number and for couple of messages it is the same. Then It updates. So, the behavior looks like it does not properly work with concurrent data receiving.

Steps To Reproduce:
I tested it with orderbook subscription. I subscribed to couple of Currency Pairs. And when I started to receive big amount of messages sequence number started to have a problem.

My observations:
Class BitFinexApiBroker contains this method. I use this code to connect to differemt currency pairs feed;

private void handleChannelCallback(final String message) {
		// Channel callback
		logger.debug("Channel callback");
		updateConnectionHeartbeat();

		// JSON callback
		final JSONTokener tokener = new JSONTokener(message);
		final JSONArray jsonArray = new JSONArray(tokener);
	    if(connectionFeatureManager.isConnectionFeatureActive(BitfinexConnectionFeature.SEQ_ALL)) {
			sequenceNumberAuditor.auditPackage(jsonArray);
		}
		final int channel = jsonArray.getInt(0);	
		if(channel == 0) {
			handleSignalingChannelData(message, jsonArray);
		} else {
			handleChannelData(jsonArray);
		}
	}

sequenceNumberAuditor.auditPackage(jsonArray); updates sequence number and then pushes message to parsing. If there are more than one thread invokes this method and might invoke auditPackage before previous one will finish parsing messages.

final OrderbookConfiguration orderbookConfiguration = new OrderbookConfiguration(f.getCurrencyPair().getBitfinexCurrencyPair(), OrderBookPrecision.P0, OrderBookFrequency.F0, 25);

            final OrderbookManager orderbookManager = bitfinexApiBroker.getOrderbookManager();

            final BiConsumer<OrderbookConfiguration, OrderbookEntry> callback = (orderbookConfig, entry) -> {
                long publicSequence = sequenceNumberAuditor.getPublicSequence();
                OrderBook orderBook = convertOrderBook(entry, f.getCurrencyPair(), publicSequence);
                orderBookService.pushForCalculation(orderBook);
                System.out.println("Got a sequence number - " + publicSequence);
            };

            try {
                ConnectionFeatureManager cfManager = bitfinexApiBroker.getConnectionFeatureManager();
                sequenceNumberAuditor = bitfinexApiBroker.getSequenceNumberAuditor();

                sequenceNumberAuditor.setErrorPolicy(SequenceNumberAuditor.ErrorPolicy.LOG_ONLY);
                cfManager.enableConnectionFeature(BitfinexConnectionFeature.SEQ_ALL);

                orderbookManager.registerOrderbookCallback(orderbookConfiguration, callback);
                orderbookManager.subscribeOrderbook(orderbookConfiguration);
            } catch (Exception e) {
                logger.error("Error while trying to subscribe to Bitfinex {} currency pair OrderBook", f.getCurrencyPair().getStringFormat());
            }

So, when I get sequence number here it might be wrong. I guess it is better to send Some Wrapper object on top of OrderBook object which can contain such number, or list of OrderBook objects with one field which is sequence and push these values in time of object creating.

PlaceOrder Error: cid: invalid

Hi.

Trying to place order:
final BitfinexOrder order = BitfinexOrderBuilder.create(currency, BitfinexOrderType.MARKET, 0.002).build(); bitfinexApiBroker.getOrderManager().placeOrder(order);

but have this error:
8061 [pool-2-thread-2] 2021-02-25 08:07:14,683 INFO OrderManager placeOrder() - Executing new order BitfinexOrder [id=0, cid=1614240434683000, apikey=null, symbol=BTC_USD, type=MARKET, price=null, priceTrailing=null, priceAuxLimit=null, amount=0.002, postOnly=false, hidden=false, groupId=4711]
8576 [ tyrus-jdk-client-3] 2021-02-25 08:07:15,198 ERROR BitfinexApiBroker handleSignalingChannelData() - Got Error message: [0,"n",[1614240437592,"on-req",null,null,[null,4711,1614240434683000,"tBTCUSD",null,null,0.002,null,"MARKET",null,null,null,null,null,null,null,null,null,0,0,null,null,null,0,0,null,null,null,null,null,null,null],null,"ERROR","cid: invalid"]]
8576 [ tyrus-jdk-client-3] 2021-02-25 08:07:15,198 ERROR NotificationHandler handleErrorNotification() - State for order 0Β is ERROR, reason is cid: invalid

What's wrong with cid here?

RawOrderbookConfiguration

Looks like RawOrderbookConfiguration returns the wrong values:
entry.getPrice() -> id
entry.getAmount() -> amount
entry.getCount() -> price

when the getCount (price) = 0, I assume its because that order is removed/completed

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.