Skip to content

Commit

Permalink
Merge branch 'release/2.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
straumat committed Oct 7, 2020
2 parents 7f1ef64 + 2e8db99 commit 6383aa8
Show file tree
Hide file tree
Showing 108 changed files with 2,222 additions and 668 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ jobs:

- name: Build, run tests, package and deploy to Maven central
env: # Environment variables.
# Maven options.
MAVEN_OPTS: -Xmx1024m -XX:MaxPermSize=128m
# Kucoin credentials.
KUCOIN_NAME: ${{ secrets.KUCOIN_NAME }}
KUCOIN_USERNAME: ${{ secrets.KUCOIN_USERNAME }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ jobs:
# ================================================================================================================
- name: Build, run tests, package and deploy to Maven central
env: # Environment variables.
# Maven options.
MAVEN_OPTS: -Xmx1024m -XX:MaxPermSize=128m
# Ossrh credentials.
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ jobs:
# ================================================================================================================
- name: Build, run tests, package and deploy to Maven central
env: # Environment variables.
# Maven options.
MAVEN_OPTS: -Xmx1024m -XX:MaxPermSize=128m
# Kucoin credentials.
KUCOIN_NAME: ${{ secrets.KUCOIN_NAME }}
KUCOIN_USERNAME: ${{ secrets.KUCOIN_USERNAME }}
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/release-creation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
- name: Build, run tests, package
id: package
env: # Environment variables.
# Maven options.
MAVEN_OPTS: -Xmx1024m -XX:MaxPermSize=128m
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Ossrh credentials.
MAVEN_USERNAME: ${{ secrets.OSSRH_USERNAME }}
Expand Down
38 changes: 30 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,32 @@
# Cassandre
![Continuous integration](https://github.com/cassandre-tech/cassandre-trading-bot/workflows/Continuous%20integration/badge.svg) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/f26dc41008a64bb18dcd404b46b69fc8)](https://www.codacy.com/gh/cassandre-tech/cassandre-trading-bot?utm_source=github.com&utm_medium=referral&utm_content=cassandre-tech/cassandre-trading-bot&utm_campaign=Badge_Grade) [![Maven Central](https://img.shields.io/maven-central/v/tech.cassandre.trading.bot/cassandre-trading-bot-spring-boot-starter-archetype.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22tech.cassandre.trading.bot%22%20AND%20a:%22cassandre-trading-bot-spring-boot-starter-archetype%22)
<h3 align="center">
<a href="https://hexagonkt.com">
<img alt="Cassandre trading bot" src="https://github.com/cassandre-tech/cassandre-trading-bot-web-site/blob/master/.gitbook/assets/logo_with_text.png?raw=true" />
</a>
<br>
Cassandre trading bot
</h3>
<p align="center">Cassandre makes it easy to create and run a Java crypto trading bot</p>

With our Spring boot starter you can easily create your trading bot in minutes.
<p align="center">
<a href="https://github.com/cassandre-tech/cassandre-trading-bot/actions">
<img
src="https://github.com/cassandre-tech/cassandre-trading-bot/workflows/Continuous%20integration/badge.svg"
alt="GitHub Actions" />
</a>
<a href="https://www.codacy.com/gh/cassandre-tech/cassandre-trading-bot?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cassandre-tech/cassandre-trading-bot&amp;utm_campaign=Badge_Grade">
<img
src="https://api.codacy.com/project/badge/Grade/f26dc41008a64bb18dcd404b46b69fc8"
alt="Codacy" />
</a>
<a href="https://search.maven.org/search?q=g:tech.cassandre.trading.bot">
<img
src="https://img.shields.io/maven-central/v/tech.cassandre.trading.bot/cassandre-trading-bot-project.svg?label=Maven%20Central"
alt="Maven Central Repository" />
</a>
</p>

A trading bot is a computer program that can automatically place orders to a market or exchange without the need for human intervention. Automated trading strategies are the future of investing, they are working for you 24/7 and never lose their focus.

Our goal with this project was to learn trading & data analysis by building an automated trading system for the cryptocurrencies markets. While learning, we built the bot and we decided to share our code, the problems encountered, the lessons learned and technologies used.

[A complete documentation is available here](https://trading-bot.cassandre.tech/)
<p align="center">
<a href="https://trading-bot.cassandre.tech/">Web site</a> |
<a href="https://trading-bot.cassandre.tech/learn/quickstart">Quick Start</a> |
<a href="mailto:[email protected]">Contact us</a>
</p>
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

| Version | Supported |
| ------- | ------------------ |
| 2.0.x | :white_check_mark: |
| 1.0.x | :white_check_mark: |
| 2.x.x | :white_check_mark: |
| 1.0.x | :x: |

## Reporting a Vulnerability

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<!-- Project information -->
<groupId>tech.cassandre.trading.bot</groupId>
<artifactId>cassandre-trading-bot-project</artifactId>
<version>2.1.1</version>
<version>2.2.0</version>
<packaging>pom</packaging>
<name>Cassandre trading bot</name>
<url>https://github.com/cassandre-tech/cassandre-trading-bot</url>
Expand Down
6 changes: 3 additions & 3 deletions spring-boot-starter-test/autoconfigure/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<version>0.9.0</version>
<version>1.0.0</version>
</dependency>
</dependencies>
<!-- =========================================================================================================== -->
Expand All @@ -64,7 +64,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.36.1</version>
<version>8.36.2</version>
</dependency>
</dependencies>
<executions>
Expand Down Expand Up @@ -134,7 +134,7 @@
<parent>
<groupId>tech.cassandre.trading.bot</groupId>
<artifactId>cassandre-trading-bot-project</artifactId>
<version>2.1.1</version>
<version>2.2.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<!-- =========================================================================================================== -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import tech.cassandre.trading.bot.batch.TickerFlux;
import tech.cassandre.trading.bot.dto.market.TickerDTO;
import tech.cassandre.trading.bot.service.MarketService;
import tech.cassandre.trading.bot.util.dto.CurrencyDTO;
import tech.cassandre.trading.bot.util.dto.CurrencyPairDTO;
import tech.cassandre.trading.bot.dto.util.CurrencyDTO;
import tech.cassandre.trading.bot.dto.util.CurrencyPairDTO;

import java.io.FileNotFoundException;
import java.io.IOException;
Expand Down Expand Up @@ -61,7 +61,7 @@ public class TickerFluxMock {
private static final String TICKERS_FILE_PREFIX = "tickers-";

/** Tickers file suffix. */
private static final String TICKERS_FILE_SUFFIX = ".tsv";
private static final String TICKERS_FILE_SUFFIX = ".*sv";

/** Flux status - true if the flux is over. */
private final HashMap<CurrencyPairDTO, Boolean> fluxTerminated = new LinkedHashMap<>();
Expand Down Expand Up @@ -137,7 +137,7 @@ public CurrencyPairDTO getCurrencyPairFromFileName(final Resource file) {
// Getting the string value of currency pair.
if (file.getFilename() != null) {
final int currencyPairIndexStart = file.getFilename().indexOf(TICKERS_FILE_PREFIX) + TICKERS_FILE_PREFIX.length();
final int currencyPairIndexStop = file.getFilename().indexOf(TICKERS_FILE_SUFFIX);
final int currencyPairIndexStop = file.getFilename().indexOf("sv") - 2;
final String currencyPairAsString = file.getFilename().substring(currencyPairIndexStart, currencyPairIndexStop);
final String[] currencyPairAsSplit = currencyPairAsString.split("-");
return new CurrencyPairDTO(new CurrencyDTO(currencyPairAsSplit[0].toUpperCase()), new CurrencyDTO(currencyPairAsSplit[1].toUpperCase()));
Expand All @@ -155,20 +155,24 @@ public CurrencyPairDTO getCurrencyPairFromFileName(final Resource file) {
private List<TickerDTO> getTickersFromFile(final Resource file) {
final CurrencyPairDTO currencyPair = getCurrencyPairFromFileName(file);
final List<TickerDTO> tickers = new LinkedList<>();
// Replies from CSV files.
// Replies from TSV files.
try (Scanner scanner = new Scanner(file.getFile())) {
while (scanner.hasNextLine()) {
try (Scanner rowScanner = new Scanner(scanner.nextLine())) {
rowScanner.useDelimiter("\t");
if (file.getFilename().endsWith("tsv")) {
rowScanner.useDelimiter("\t");
} else {
rowScanner.useDelimiter(",");
}
while (rowScanner.hasNext()) {
// Data retrieved from file.
final String time = rowScanner.next();
final String open = rowScanner.next();
final String close = rowScanner.next();
final String high = rowScanner.next();
final String low = rowScanner.next();
final String volume = rowScanner.next();
final String turnover = rowScanner.next();
final String time = rowScanner.next().replaceAll("\"", "");
final String open = rowScanner.next().replaceAll("\"", "");
final String close = rowScanner.next().replaceAll("\"", "");
final String high = rowScanner.next().replaceAll("\"", "");
final String low = rowScanner.next().replaceAll("\"", "");
final String volume = rowScanner.next().replaceAll("\"", "");
final String turnover = rowScanner.next().replaceAll("\"", "");

// Creating the ticker.
TickerDTO t = TickerDTO.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,24 @@
import org.springframework.context.annotation.Import;
import org.springframework.core.io.Resource;
import tech.cassandre.trading.bot.dto.market.TickerDTO;
import tech.cassandre.trading.bot.service.MarketService;
import tech.cassandre.trading.bot.test.strategy.TestableStrategy;
import tech.cassandre.trading.bot.test.util.BaseTest;
import tech.cassandre.trading.bot.util.dto.CurrencyPairDTO;
import tech.cassandre.trading.bot.dto.util.CurrencyPairDTO;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

import static org.awaitility.Awaitility.await;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.BTC;
import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.ETH;
import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.KCS;
import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.USDT;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.BTC;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.ETH;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.KCS;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT;

@SpringBootTest
@Import(TickerFluxMock.class)
Expand All @@ -34,6 +37,9 @@ public class TickerFluxMockTest extends BaseTest {
@Autowired
private TickerFluxMock tickerFluxMock;

@Autowired
private MarketService marketService;

@Test
@DisplayName("Check tickers received")
public void checkTickersReceived() {
Expand All @@ -59,6 +65,13 @@ public void checkTickersReceived() {
assertTrue(file2.getFilename().contains("tickers-ETH-BTC.tsv"));
assertEquals(cp2, tickerFluxMock.getCurrencyPairFromFileName(file2));

// Check file 2 (ETC-BTC).
Resource file3 = resources.get(2);
assertNotNull(file3);
assertNotNull(file3.getFilename());
assertTrue(file3.getFilename().contains("tickers-KCS-USDT.csv"));
assertEquals(cp3, tickerFluxMock.getCurrencyPairFromFileName(file3));

// Checking results.
await().untilAsserted(() -> assertTrue(tickerFluxMock.isFluxDone(cp1)));
await().untilAsserted(() -> assertTrue(tickerFluxMock.isFluxDone(cp2)));
Expand All @@ -71,6 +84,12 @@ public void checkTickersReceived() {
assertEquals(1508630400000L, tickersReceived.get(3).getTimestamp().toInstant().toEpochMilli());
assertEquals(1508803200000L, tickersReceived.get(4).getTimestamp().toInstant().toEpochMilli());
assertEquals(1508716800000L, tickersReceived.get(5).getTimestamp().toInstant().toEpochMilli());

// Checking some data.
final Optional<TickerDTO> ticker1 = marketService.getTicker(cp3);
assertTrue(ticker1.isPresent());
assertEquals(1601596800000L, ticker1.get().getTimestamp().toInstant().toEpochMilli());
assertEquals(0, new BigDecimal("0.85652").compareTo(ticker1.get().getLast()));
}

}
Original file line number Diff line number Diff line change
@@ -1,48 +1,55 @@
package tech.cassandre.trading.bot.test.strategy;

import tech.cassandre.trading.bot.dto.market.TickerDTO;
import tech.cassandre.trading.bot.dto.user.AccountDTO;
import tech.cassandre.trading.bot.dto.util.CurrencyPairDTO;
import tech.cassandre.trading.bot.strategy.BasicCassandreStrategy;
import tech.cassandre.trading.bot.strategy.CassandreStrategy;
import tech.cassandre.trading.bot.util.dto.CurrencyPairDTO;

import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.BTC;
import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.ETH;
import static tech.cassandre.trading.bot.util.dto.CurrencyDTO.USDT;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.BTC;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.ETH;
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT;

/**
* Testable strategy.
*/
@CassandreStrategy(name = "Testable strategy")
public final class TestableStrategy extends BasicCassandreStrategy {

/** Tickers update received. */
private final List<TickerDTO> tickersUpdateReceived = new LinkedList<>();

@Override
public Set<CurrencyPairDTO> getRequestedCurrencyPairs() {
Set<CurrencyPairDTO> list = new LinkedHashSet<>();
list.add(new CurrencyPairDTO(BTC, USDT));
list.add(new CurrencyPairDTO(ETH, BTC));
return list;
}

@Override
public void onTickerUpdate(TickerDTO ticker) {
tickersUpdateReceived.add(ticker);
}

/**
* Getter tickersUpdateReceived.
*
* @return tickersUpdateReceived
*/
public final List<TickerDTO> getTickersUpdateReceived() {
return tickersUpdateReceived;
}
/** Tickers update received. */
private final List<TickerDTO> tickersUpdateReceived = new LinkedList<>();

@Override
public Set<CurrencyPairDTO> getRequestedCurrencyPairs() {
Set<CurrencyPairDTO> list = new LinkedHashSet<>();
list.add(new CurrencyPairDTO(BTC, USDT));
list.add(new CurrencyPairDTO(ETH, BTC));
return list;
}

@Override
public Optional<AccountDTO> getTradeAccount(Set<AccountDTO> accounts) {
return accounts.stream().filter(a -> a.getId().equals("trade")).findFirst();
}

@Override
public void onTickerUpdate(TickerDTO ticker) {
tickersUpdateReceived.add(ticker);
}

/**
* Getter tickersUpdateReceived.
*
* @return tickersUpdateReceived
*/
public final List<TickerDTO> getTickersUpdateReceived() {
return tickersUpdateReceived;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tech.cassandre.trading.bot.dto.market.TickerDTO;
import tech.cassandre.trading.bot.util.dto.CurrencyPairDTO;
import tech.cassandre.trading.bot.dto.util.CurrencyPairDTO;

import java.math.BigDecimal;
import java.time.ZoneId;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
"1601596800","0.8494","0.85652","0.87","0.82001","6402298.90377638","5396388.7386519256337"
"1601683200","0.85653","0.84261","0.88888","0.82","7349493.47425826","6292644.8212960955051"
"1601769600","0.84251","0.83751","0.8506","0.823","7306874.10063719","6158682.638871191526"

This file was deleted.

4 changes: 2 additions & 2 deletions spring-boot-starter-test/starter/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>8.36.1</version>
<version>8.36.2</version>
</dependency>
</dependencies>
<executions>
Expand Down Expand Up @@ -115,7 +115,7 @@
<parent>
<groupId>tech.cassandre.trading.bot</groupId>
<artifactId>cassandre-trading-bot-project</artifactId>
<version>2.1.1</version>
<version>2.2.0</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<!-- =========================================================================================================== -->
Expand Down
Loading

0 comments on commit 6383aa8

Please sign in to comment.