Skip to main content
Version: Next

Trading strategies

 License: MIT 

Description

Binance4j-strategy adds technical analysis for the binance4j ecosystem thanks to ta4j indicators and rules.

Installation

pom.xml
<dependency>
<groupId>{{groupId}}</groupId>
<artifactId>{{artifactId}}</artifactId>
<version>{{version}}</version>
</dependency>

What is a trading strategy?

A trading strategy is a class containing two methods receiveing a BarSeries as an input and returning a trading Rule as an output, the first will send a BUY signal and the other a SELL signal.

Every trading strategy must implement the TradingStrategy interface. This is the signature of the interface:

public interface TradingStrategy {
// The BUY signal
Rule entry(BarSeries series);

// The SELL signal
Rule exit(BarSeries series);
}
note

Binance4j-strategy uses ta4j for technical analysis, don't hesitate to read their documentation to understand what are indicators and rules.

Creating a trading strategy

Here is a trading strategy using the two period RSI indicator:

public class TwoPeriodRSIStrategy implements TradingStrategy {
@Override
public Rule entry(BarSeries series) {
ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
SMAIndicator shortSma = new SMAIndicator(closePrice, 5);
SMAIndicator longSma = new SMAIndicator(closePrice, 200);
// We use a 2-period RSI indicator to identify buying
// or selling opportunities within the bigger trend.
RSIIndicator rsi = new RSIIndicator(closePrice, 2); // Entry rule
// The long-term trend is up when a security is above its 200-period SMA.
return new OverIndicatorRule(shortSma, longSma) // Trend
.and(new CrossedDownIndicatorRule(rsi, 5)) // Signal 1
.and(new OverIndicatorRule(shortSma, closePrice)); // Signal 2
}

@Override
public Rule exit(BarSeries series) {
ClosePriceIndicator closePrice = new ClosePriceIndicator(series);
SMAIndicator shortSma = new SMAIndicator(closePrice, 5);
SMAIndicator longSma = new SMAIndicator(closePrice, 200); // We use a 2-period RSI indicator to identify buying
// or selling opportunities within the bigger trend.
RSIIndicator rsi = new RSIIndicator(closePrice, 2); // Exit rule
// The long-term trend is down when a security is below its 200-period SMA.
return new UnderIndicatorRule(shortSma, longSma) // Trend
.and(new CrossedUpIndicatorRule(rsi, 95)) // Signal 1
.and(new UnderIndicatorRule(shortSma, closePrice)); // Signal 2
}
}

Backtesting a strategy

Binance4j can backtest a trading strategy in many ways.

With existing data

// Here we get historical klines data from the public data API.
List<Candle> bars = new VisionSpotClient().getKlines("BTCBUSD", CandlestickInterval.FIVE_MINUTES, "2022", "01").getData();

// let's give it to the BackTestService. CandlestickInterval must match.
BackTestResult result = BackTestService.backTest(strategy, bars, CandlestickInterval.FIVE_MINUTES);

// we can also use a ta4j Barseries instance. Let's convert the existing candles
BarSeries series = BarSeriesService.convert(bars,CandlestickInterval.FIVE_MINUTES);

BackTestResult result = BackTestService.backTest(strategy, series);

With inner vision client

The service can automatically use an instance of a VisionSpotClient to collect public data from the Binance API.

// The service will automatically use an instance of a VisionClient to get the data from the API
BackTestResult result = BackTestService.backTest(strategy, "BTCBUSD", CandlestickInterval.FIVE_MINUTES, "2022", "01");

Get the strategy position other a BarSeries

The PositionService service can give us the position of our strategy over a BarSeries instance.

//The service will tell us if the strategy sends a BUY signal over the given index on the BarSeries
boolean shouldEnter = PositionService.shouldEnter(strategy, series, index);

//The service will tell us if the strategy sends a SELL signal over the given index on the BarSeries
boolean shouldExit = PositionService.shouldExit(strategy, series, index);

//The service will tell us if the strategy sends a BUY signal over the last Bar in the BarSeries
boolean shouldEnter = PositionService.shouldEnter(strategy, series);

//The service will tell us if the strategy sends a SELL signal over the last Bar in the BarSeries
boolean shouldExit = PositionService.shouldExit(strategy, series);

Live trading

In order to handle your strategy signals, you need to implement a StrategyCallback.

public class MyStrategyCallback implements StrategyCallback {

public MyStrategyCallback() {
//...
}

// Handle BUY signal
@Override
public void onEnter(BarSeries series) {
//...
}

// Handle SELL signal
@Override
public void onExit(BarSeries series) {
//...
}

// server sent data
@Override
public void onMessage(SymbolBar symbolBar) {
//...
}

// Stream is open
@Override
public void onOpen(Response response) {
//...
}

// Stream is closing
@Override
public void onClosing(WebsocketCloseObject closeObject) {
//...
}

// Stream is closed
@Override
public void onClosed(WebsocketCloseObject closeObject) {
//...
}

// Something went wrong
@Override
public void onFailure(ApiException apiException) {
//...
}
}

Let's instantiate and run a service.

//we will use the previous strategy
WatchService service = new WatchService(strategy, myStrategyCallback);
service.watch("BTCBUSD", CandlestickInterval.FIVE_MINUTE);

When done, stop the service:

service.unwatch();