|
|
|
#BinanceJ
|
|
|
|
|
|
|
|
[![CircleCI](https://circleci.com/gh/angrygoats/binancej/tree/master.svg?style=svg&circle-token=ec4614038357b8ff4bcc4773bedd4a264a1947b7)](https://circleci.com/gh/angrygoats/binancej/tree/master)
|
|
|
|
|
|
|
|
A Java 8 implementation of the [Binance API Specification](https://github.com/binance-exchange/binance-official-api-docs/blob/master/rest-api.md).
|
|
|
|
|
|
|
|
## Licensing
|
|
|
|
|
|
|
|
BinanceJ is released under the MIT license.
|
|
|
|
|
|
|
|
## Rate Limiting
|
|
|
|
|
|
|
|
BinanceJ does not perform rate limiting, so you are responsible for limiting your requests. Pay attention to the errors
|
|
|
|
you receive from Binance and check to see if they are a 429. If they are, you need to back off or face a temporary
|
|
|
|
ban.
|
|
|
|
|
|
|
|
## API Coverage
|
|
|
|
|
|
|
|
The following endpoints are currently covered:
|
|
|
|
|
|
|
|
1. `GET /api/v1/ping`
|
|
|
|
2. `GET /api/v1/time`
|
|
|
|
3. `GET /api/v1/exchangeInfo`
|
|
|
|
4. `GET /api/v1/depth`
|
|
|
|
5. `GET /api/v1/klines`
|
|
|
|
6. `GET /api/v3/ticker/price`
|
|
|
|
|
|
|
|
More will be added in future PRs as they become necessary to me or the people using the library.
|
|
|
|
|
|
|
|
## Return Types
|
|
|
|
|
|
|
|
All functions return an `Either` type. For those of you not in the know - an Either type represents a disjoint union.
|
|
|
|
Typically this means a "success" and "failure" case that must be handled uniquely. They work well with stream
|
|
|
|
processing and are a very natural way to delineate success and failure cleanly. Additionally it eliminates the pattern
|
|
|
|
of throwing exceptions on errors, and allows exceptions to be reserved for truly exceptional behavior as intended.
|
|
|
|
|
|
|
|
By convention I adapted the Haskell Either type style to this code. What this means is that the Either type's Right
|
|
|
|
value is the correct one (mnemonic: "right" as in correct) and the Left value is the serviceError.
|
|
|
|
|
|
|
|
### How do I extract the raw value from the Either type?
|
|
|
|
|
|
|
|
There are a few ways to do this using Ambivalent, but the most prevalent way in BinanceJ's tests is:
|
|
|
|
|
|
|
|
```java
|
|
|
|
Either<TypeA, TypeB> val = clazz.getThing();
|
|
|
|
|
|
|
|
// Good path case
|
|
|
|
if(val.isRight()) {
|
|
|
|
TypeB thing = val.right().join(Function.identity(), Function.identity());
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
Alternatively you are welcome to use `Helpers.extractEitherValueSafely` method to make your code cleaner.
|
|
|
|
|
|
|
|
|
|
|
|
## Examples
|
|
|
|
|
|
|
|
### Server alive check with ping
|
|
|
|
|
|
|
|
```java
|
|
|
|
GeneralUtilities generalUtilities = GeneralUtilities.builder().apiKey("KEY").secretKey("KEY").build();
|
|
|
|
Either<ServiceError, Ping> res = generalUtilities.ping();
|
|
|
|
if(res.isRight()) {
|
|
|
|
// Successful ping
|
|
|
|
}
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
### Getting current server time
|
|
|
|
|
|
|
|
```java
|
|
|
|
GeneralUtilities generalUtilities = GeneralUtilities.builder().apiKey("KEY").secretKey("KEY").build();
|
|
|
|
Either<ServiceError, ServerTime> res = generalUtilities.getServerTime();
|
|
|
|
|
|
|
|
if(res.isRight() {
|
|
|
|
ServerTime response = Helpers.extractEitherValueSafely(res.right());
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Getting Exchange Information
|
|
|
|
|
|
|
|
```java
|
|
|
|
GeneralUtilities generalUtilities = GeneralUtilities.builder().apiKey("KEY").secretKey("KEY").build();
|
|
|
|
Either<ServiceError, ExchangeInfo> res = generalUtilities.getExchangeInfo();
|
|
|
|
|
|
|
|
if(res.isRight() {
|
|
|
|
ExchangeInfo response = Helpers.extractEitherValueSafely(res.right());
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Getting Candlestick data
|
|
|
|
|
|
|
|
```java
|
|
|
|
MarketData marketData = MarketData.builder().apiKey("KEY").secretKey("KEY").build();
|
|
|
|
Either<ServiceError, List<Candlestick>> res = marketData.getCandlestickData("ETHBTC", Interval.ONE_MINUTE);
|
|
|
|
|
|
|
|
if(res.isRight() {
|
|
|
|
List<Candlestick> data = Helpers.extractEitherValueSafely(res.right());
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Getting market depth
|
|
|
|
|
|
|
|
```java
|
|
|
|
MarketData marketData = MarketData.builder().apiKey("KEY").secretKey("KEY").build();
|
|
|
|
Either<ServiceError, OrderBookDepth> res = marketData.getOrderBookDepth("ETHBTC", 1000);
|
|
|
|
|
|
|
|
if(res.isRight() {
|
|
|
|
OrderBookDepth orderBookDepth = Helpers.extractEitherValueSafely(res.right());
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
### Getting ticker price for an instrument
|
|
|
|
|
|
|
|
```java
|
|
|
|
MarketData marketData = MarketData.builder().apiKey("KEY").secretKey("KEY").build();
|
|
|
|
Either<ServiceError, TickerPrice> res = marketData.getTickerPriceForSymbol("ETHBTC");
|
|
|
|
|
|
|
|
if(res.isRight() {
|
|
|
|
TickerPrice tickerPrice = Helpers.extractEitherValueSafely(res.right());
|
|
|
|
//...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Contributing
|
|
|
|
|
|
|
|
Head over to our [CONTRIBUTING.md](CONTRIBUTING.md) to get started. All features are welcome as long as they are
|
|
|
|
in scope of the API and following the contributing guide.
|
|
|
|
|