Basic Setup
Introduction
Hi! Welcome to the first part of this tutorial series on creating your own strategy using the CryptoStruct Strategy SDK.
In the course of this series you will learn how to program your own strategies, upload and configure them – and finally how to run them on real crypto exchanges. In the fourth video, you’ll also learn how to locally test-run any strategies you developed.
In this first tutorial we will start a new Java project and create a strategy class that will hold our entire trading logic.
Classes that want to use the Strategy SDK simply need to implement Strategy. Almost all included methods (that you’ll need to override in your code) describe some form of event that originates directly from the crypto exchange.
That means, you can write event-based code that reacts instantly to any new information, such as incoming public trades, or changes to your positions.
Other events include start, stop and error events that communicate status updates of your strategy, or the methods onHeartbeat() or onTimer() that get called every 500 ms or once a timer (set by you) runs out respectively.
Prerequisites
- The CryptoStruct Strategy SDK that you received from us
- Any Java IDE (we recommend IntelliJ)
- Apache Maven – a common build-management tool for Java
- A pre-configured pom.xml file containing information for Maven on how to include the Strategy SDK
<?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>com.cryptostruct</groupId>
<artifactId>example-strategy</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<cryptostruct.sdk.version>3.12.5</cryptostruct.sdk.version>
</properties>
<dependencies>
<dependency>
<groupId>com.cryptostruct</groupId>
<artifactId>strategy-api</artifactId>
<version>${cryptostruct.sdk.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
<finalName>${artifactId}</finalName>
</build>
</project>Steps
- Unzip and install the Strategy SDK using the install script (available for Linux and Windows machines)
- Open your Java IDE with the provided pom.xml file
- Create a new Java file and call it e.g.
ExampleStrategy.java - Let your class implement
Strategy - Add the
@Slf4jfor easier logging - Add the
@ExportStrategyannotation and give your strategy a name (i.e.@ExportStrategy(name = "ExampleStrategy")) - Each implemented method gets called upon receiving an event – let’s add simple log messages to each method (use e.g.
log.info("onStarted()")) - Use
instrument.getSnapshot().printBook(5, log::info)to log the current state of an instrument’s order book (with a depth of 5) - Use
instrument.getLastTrades()inonInstrumentTrades()to get all newly recorded public trades
▶ Part 1: Setupimport com.cryptostruct.commons.annotations.ExportStrategy;
import com.cryptostruct.sdk.StopReason;
import com.cryptostruct.sdk.Strategy;
import com.cryptostruct.sdk.StrategyContext;
import com.cryptostruct.sdk.StrategyTimer;
import com.cryptostruct.sdk.instruments.DataInstrument;
import com.cryptostruct.sdk.instruments.TradingInstrument;
import com.cryptostruct.sdk.orders.*;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@ExportStrategy(name = "ExampleStrategy")
public class ExampleStrategy implements Strategy {
private StrategyContext context;
public ExampleStrategy(StrategyContext context) {
this.context = context;
}
@Override
public void onStarted() {
log.info("onStarted()");
}
@Override
public void onStop(StopReason stopReason, String message) {
log.info("onStop(): {}", message);
}
@Override
public void onMarketDataState(DataInstrument instrument) {
log.info("onMarketDataState()");
}
@Override
public void onInstrumentSnapshot(DataInstrument instrument) {
log.info("onInstrumentSnapshot()");
instrument.getSnapshot().printBook(5, log::info);
}
@Override
public void onInstrumentTrades(DataInstrument instrument) {
log.info("onInstrumentTrades()");
instrument.getLastTrades().forEach(trade -> log.info(trade.toString()));
}
@Override
public void onInstrumentPosition(TradingInstrument instrument) {
log.info("onInstrumentPosition()");
}
@Override
public void onOrderFill(Order order) {
log.info("onOrderFill: {}", order.getDescriptiveString());
}
@Override
public void onOrderUpdate(Order order) {
log.info("onOrderUpdate(): {}", order.getDescriptiveString());
}
@Override
public void onOrderError(Order order, OrderError orderError) {
log.error("onOrderError(): {}", orderError.getMessage());
}
@Override
public void onHeartbeat() {
}
@Override
public void onTimer(StrategyTimer timer) {
}
}Let’s move on to the next video where we’ll add the actual strategy logic to our code!