binance-java-api is a lightweight Java library for the Binance API, supporting synchronous and asynchronous requests, as well as event streaming using WebSockets.
MIT License
834
stars
627
forks
source link
Problems and Discrepancies with Java SPOT and FUTURES libraries #401
I have worked (and worked around shortcomings) with Java FUTURES and SPOT libraries for a couple of months, and there are fundamental capabilities that are missing or inconsistently implemented. Here are a few that I consider 'Major' that prevent using the Java libraries in their current form for serious development.
1) neither library cleanly exposes HTTP response headers, so it is 'out-of-the-box' impossible to monitor things like x-mbx-used-weight-1m to prevent exceeding thresholds (I have a less-than-elegant workaround, but headers should be directly accessible).
2) the FUTURES library use of OKHttp3 is unstable - stream and http errors are poorly handled, and the Binance library level error mechanism is flaky. Even when I programmatically closed and reopened streams to attempt to keep them alive over multiple days, the underlying libraries would instead open multiple duplicated streams, resulting in two datastreams slightly out of synch. On the other hand, the retrofit2 libraries and higher level code in the SPOT library are both rock-solid and will run for days using the same reinitialization logic. SO KEEP USING RETROFIT2, even though the current SPOT library interface with hard-coded routes specifically for the SPOT API is not sufficiently robust to handle different routes for different markets. That's an architecture issue that could be handled by a proper Configuration class that is dynamically passed to underlying libraries when a REST or a STREAM client is created.
3) Arguably most critical - define a set of classes in a single library that span the range of entities (and corresponding values) required for each specific market (SPOT, FUTURES, SWAP, etc.). As a specific example, the Asset.java class for SPOT library is different (different fields, and price and quantity use Strings) from the Asset.java class in the FUTURES library, which not only has some different fields, but also uses BigDecimal for numeric price and quantity values. Defining ENUMs in the aforementioned Configuration class (for Markets: SPOT, FUTURES, etc.), servers (TESTNET, STANDARD), and API route versions (that provide a 'getter' method to get the exact string: v1, v2, v3 that a specific method needs (so V2 clients, V2 clients, etc. can be created once and used to access methods in a market that have different versions - e.g. getAccount in Futures is v2, but most other methods are v1.
I have worked (and worked around shortcomings) with Java FUTURES and SPOT libraries for a couple of months, and there are fundamental capabilities that are missing or inconsistently implemented. Here are a few that I consider 'Major' that prevent using the Java libraries in their current form for serious development. 1) neither library cleanly exposes HTTP response headers, so it is 'out-of-the-box' impossible to monitor things like
x-mbx-used-weight-1m
to prevent exceeding thresholds (I have a less-than-elegant workaround, but headers should be directly accessible). 2) the FUTURES library use of OKHttp3 is unstable - stream and http errors are poorly handled, and the Binance library level error mechanism is flaky. Even when I programmatically closed and reopened streams to attempt to keep them alive over multiple days, the underlying libraries would instead open multiple duplicated streams, resulting in two datastreams slightly out of synch. On the other hand, theretrofit2
libraries and higher level code in the SPOT library are both rock-solid and will run for days using the same reinitialization logic. SO KEEP USING RETROFIT2, even though the current SPOT library interface with hard-coded routes specifically for the SPOT API is not sufficiently robust to handle different routes for different markets. That's an architecture issue that could be handled by a proper Configuration class that is dynamically passed to underlying libraries when a REST or a STREAM client is created. 3) Arguably most critical - define a set of classes in a single library that span the range of entities (and corresponding values) required for each specific market (SPOT, FUTURES, SWAP, etc.). As a specific example, the Asset.java class for SPOT library is different (different fields, and price and quantity use Strings) from the Asset.java class in the FUTURES library, which not only has some different fields, but also usesBigDecimal
for numeric price and quantity values. Defining ENUMs in the aforementioned Configuration class (for Markets: SPOT, FUTURES, etc.), servers (TESTNET, STANDARD), and API route versions (that provide a 'getter' method to get the exact string:v1, v2, v3
that a specific method needs (so V2 clients, V2 clients, etc. can be created once and used to access methods in a market that have different versions - e.g.getAccount
in Futures isv2
, but most other methods are v1.