Adding cassandre tutorial (#10757)
* Adding Cassandre * Added a logger * Added a logger * Change test name * Change test name * Moved to spring-boot-modules * remove cassandre from the spring-boot-modules pom, and add it in the main pom.
This commit is contained in:
parent
38aeae6685
commit
3c5b7234d9
1
pom.xml
1
pom.xml
@ -1276,6 +1276,7 @@
|
||||
</build>
|
||||
|
||||
<modules>
|
||||
<module>spring-boot-modules/spring-boot-cassandre</module>
|
||||
<module>core-java-modules/core-java-9</module>
|
||||
<module>core-java-modules/core-java-9-improvements</module>
|
||||
<module>core-java-modules/core-java-9-jigsaw</module>
|
||||
|
11
spring-boot-modules/spring-boot-cassandre/README.md
Normal file
11
spring-boot-modules/spring-boot-cassandre/README.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Cassandre trading bot example
|
||||
|
||||
This project is an example of a trading bot developed with Cassandre
|
||||
|
||||
## Running the examples
|
||||
|
||||
* `mvn test` - Run strategy backtesting
|
||||
* `mvn spring-boot:run` - Run the bot
|
||||
|
||||
## Relevant Articles
|
||||
- [Build a Trading Bot with Cassandre Spring Boot Starter](https://www.baeldung.com/build-a-trading-bot-with-cassandre-spring-boot-starter/)
|
68
spring-boot-modules/spring-boot-cassandre/pom.xml
Normal file
68
spring-boot-modules/spring-boot-cassandre/pom.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.4.5</version>
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>demo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>Cassandre trading bot tutorial</name>
|
||||
<description>Cassandre trading bot tutorial</description>
|
||||
<properties>
|
||||
<java.version>11</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Cassandre dependencies -->
|
||||
<dependency>
|
||||
<groupId>tech.cassandre.trading.bot</groupId>
|
||||
<artifactId>cassandre-trading-bot-spring-boot-starter</artifactId>
|
||||
<version>4.2.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.knowm.xchange</groupId>
|
||||
<artifactId>xchange-kucoin</artifactId>
|
||||
<version>5.0.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hsqldb</groupId>
|
||||
<artifactId>hsqldb</artifactId>
|
||||
<version>2.5.1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Cassandre dependencies -->
|
||||
<dependency>
|
||||
<groupId>tech.cassandre.trading.bot</groupId>
|
||||
<artifactId>cassandre-trading-bot-spring-boot-starter-test</artifactId>
|
||||
<version>4.2.1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.4.5</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
package com.example.demo;
|
||||
|
||||
import static tech.cassandre.trading.bot.dto.position.PositionStatusDTO.CLOSED;
|
||||
import static tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED;
|
||||
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.BTC;
|
||||
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import tech.cassandre.trading.bot.dto.market.TickerDTO;
|
||||
import tech.cassandre.trading.bot.dto.position.PositionDTO;
|
||||
import tech.cassandre.trading.bot.dto.position.PositionRulesDTO;
|
||||
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;
|
||||
|
||||
@CassandreStrategy
|
||||
public class MyFirstStrategy extends BasicCassandreStrategy {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MyFirstStrategy.class);
|
||||
|
||||
@Override
|
||||
public Set<CurrencyPairDTO> getRequestedCurrencyPairs() {
|
||||
return Set.of(new CurrencyPairDTO(BTC, USDT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<AccountDTO> getTradeAccount(Set<AccountDTO> accounts) {
|
||||
return accounts.stream()
|
||||
.filter(a -> "trade".equals(a.getName()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTickerUpdate(TickerDTO ticker) {
|
||||
logger.info("Received a new ticker : {}", ticker);
|
||||
|
||||
if (new BigDecimal("56000").compareTo(ticker.getLast()) == -1) {
|
||||
|
||||
if (canBuy(new CurrencyPairDTO(BTC, USDT), new BigDecimal("0.01"))) {
|
||||
PositionRulesDTO rules = PositionRulesDTO.builder()
|
||||
.stopGainPercentage(4f)
|
||||
.stopLossPercentage(25f)
|
||||
.build();
|
||||
createLongPosition(new CurrencyPairDTO(BTC, USDT), new BigDecimal("0.01"), rules);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPositionStatusUpdate(PositionDTO position) {
|
||||
if (position.getStatus() == OPENED) {
|
||||
logger.info("> New position opened : {}", position.getPositionId());
|
||||
}
|
||||
if (position.getStatus() == CLOSED) {
|
||||
logger.info("> Position closed : {}", position.getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Exchange configuration.
|
||||
cassandre.trading.bot.exchange.name=kucoin
|
||||
cassandre.trading.bot.exchange.username=kucoin.cassandre.test@gmail.com
|
||||
cassandre.trading.bot.exchange.passphrase=cassandre
|
||||
cassandre.trading.bot.exchange.key=6054ad25365ac6000689a998
|
||||
cassandre.trading.bot.exchange.secret=af080d55-afe3-47c9-8ec1-4b479fbcc5e7
|
||||
#
|
||||
# Modes
|
||||
cassandre.trading.bot.exchange.modes.sandbox=true
|
||||
cassandre.trading.bot.exchange.modes.dry=false
|
||||
#
|
||||
# Exchange API calls rates (ms or standard ISO 8601 duration like 'PT5S').
|
||||
cassandre.trading.bot.exchange.rates.account=2000
|
||||
cassandre.trading.bot.exchange.rates.ticker=2000
|
||||
cassandre.trading.bot.exchange.rates.trade=2000
|
||||
#
|
||||
# Database configuration.
|
||||
cassandre.trading.bot.database.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||
cassandre.trading.bot.database.datasource.url=jdbc:hsqldb:mem:cassandre
|
||||
cassandre.trading.bot.database.datasource.username=sa
|
||||
cassandre.trading.bot.database.datasource.password=
|
@ -0,0 +1,13 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class DemoApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,55 @@
|
||||
package com.example.demo;
|
||||
|
||||
import static org.awaitility.Awaitility.await;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static tech.cassandre.trading.bot.dto.position.PositionStatusDTO.OPENED;
|
||||
import static tech.cassandre.trading.bot.dto.util.CurrencyDTO.USDT;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import tech.cassandre.trading.bot.dto.util.CurrencyDTO;
|
||||
import tech.cassandre.trading.bot.dto.util.GainDTO;
|
||||
import tech.cassandre.trading.bot.test.mock.TickerFluxMock;
|
||||
|
||||
@SpringBootTest
|
||||
@Import(TickerFluxMock.class)
|
||||
@DisplayName("Simple strategy test")
|
||||
public class MyFirstStrategyUnitTest {
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger(MyFirstStrategyUnitTest.class);
|
||||
|
||||
@Autowired
|
||||
private MyFirstStrategy strategy;
|
||||
|
||||
@Autowired
|
||||
private TickerFluxMock tickerFluxMock;
|
||||
|
||||
@Test
|
||||
@DisplayName("Check gains")
|
||||
public void whenTickersArrives_thenCheckGains() {
|
||||
await().forever().until(() -> tickerFluxMock.isFluxDone());
|
||||
|
||||
final HashMap<CurrencyDTO, GainDTO> gains = strategy.getGains();
|
||||
|
||||
logger.info("Cumulated gains:");
|
||||
gains.forEach((currency, gain) -> logger.info(currency + " : " + gain.getAmount()));
|
||||
|
||||
logger.info("Position still opened :");
|
||||
strategy.getPositions()
|
||||
.values()
|
||||
.stream()
|
||||
.filter(p -> p.getStatus().equals(OPENED))
|
||||
.forEach(p -> logger.info(" - {} " + p.getDescription()));
|
||||
|
||||
assertTrue(gains.get(USDT).getPercentage() > 0);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Exchange configuration.
|
||||
cassandre.trading.bot.exchange.name=kucoin
|
||||
cassandre.trading.bot.exchange.username=kucoin.cassandre.test@gmail.com
|
||||
cassandre.trading.bot.exchange.passphrase=cassandre
|
||||
cassandre.trading.bot.exchange.key=6054ad25365ac6000689a998
|
||||
cassandre.trading.bot.exchange.secret=af080d55-afe3-47c9-8ec1-4b479fbcc5e7
|
||||
#
|
||||
# Modes
|
||||
cassandre.trading.bot.exchange.modes.sandbox=true
|
||||
cassandre.trading.bot.exchange.modes.dry=true
|
||||
#
|
||||
# Exchange API calls rates (ms or standard ISO 8601 duration like 'PT5S').
|
||||
cassandre.trading.bot.exchange.rates.account=2000
|
||||
cassandre.trading.bot.exchange.rates.ticker=2000
|
||||
cassandre.trading.bot.exchange.rates.trade=2000
|
||||
#
|
||||
# Database configuration.
|
||||
cassandre.trading.bot.database.datasource.driver-class-name=org.hsqldb.jdbc.JDBCDriver
|
||||
cassandre.trading.bot.database.datasource.url=jdbc:hsqldb:mem:cassandre
|
||||
cassandre.trading.bot.database.datasource.username=sa
|
||||
cassandre.trading.bot.database.datasource.password=
|
@ -0,0 +1,89 @@
|
||||
1612569600 38294.4 39195.5 40964.2 38217.5 3882.29460938 153897343.463150723
|
||||
1612656000 39195.4 38807.6 39623.6 37341.4 2389.96820017 91972455.834535369
|
||||
1612742400 38807.6 46373.5 46767.9 38010 4971.54731481 212132648.426718929
|
||||
1612828800 46374.6 46434.8 48139.3 44961 4330.72854712 201891604.027160303
|
||||
1612915200 46430 44812.2 47300 43687.5 4351.84907778 198189685.592028516
|
||||
1613001600 44806.1 47941.5 48647.6 44005.8 4045.91883504 188171651.974437139
|
||||
1613088000 47963.1 47310.7 48958.8 46181.2 3356.01832119 159561721.419695848
|
||||
1613174400 47305.4 47152.6 48120.5 46225.5 2740.99221759 129227867.922246174
|
||||
1613260800 47152.5 48591.9 49686.9 47026.3 3359.4690565 163299915.839307312
|
||||
1613347200 48587.2 47904.4 49003.6 42841.6 3974.98461358 188990056.26923591
|
||||
1613433600 47913.1 49147.7 50619.3 47023.9 3599.85370182 176084748.845657596
|
||||
1613520000 49147.7 52118.1 52609.6 48931.1 3356.85082847 170893567.530348564
|
||||
1613606400 52114.3 51568.9 52522.9 50906.4 2183.18379408 113272339.172174965
|
||||
1613692800 51561.1 55890.5 56317.7 50727 3749.6920105 200656740.865959032
|
||||
1613779200 55893.6 55851.5 57622.6 53463.3 3394.87226216 190744601.429330887
|
||||
1613865600 55851.4 57423 58336.3 55489.6 2514.02340013 143658132.671448082
|
||||
1613952000 57420.6 54096.6 57517.8 44160 6125.32442907 330513978.457310237
|
||||
1614038400 54085.9 48908.3 54174.2 44900 8048.96505298 389277314.445372085
|
||||
1614124800 48902.9 49685.2 51361.9 47003.2 4816.75027676 239303706.844272809
|
||||
1614211200 49676.5 47082.7 52019.6 46624.4 3701.80236678 184044004.383578525
|
||||
1614297600 47082 46289.6 48408.8 44135 5329.77125908 247604118.914146591
|
||||
1614384000 46290.2 46114.4 48381.9 44836.5 2872.64640734 134946360.020429589
|
||||
1614470400 46111.3 45141.6 46626.1 43004.3 3940.17863714 175990962.484551548
|
||||
1614556800 45136.5 49590.3 49771.3 44958.9 3548.51026561 169389196.772247159
|
||||
1614643200 49590.3 48441.2 50201.6 47052.8 2936.94454126 142575425.463057812
|
||||
1614729600 48440.6 50345.5 52623.9 48100 3177.38943911 160801620.821885745
|
||||
1614816000 50347.6 48374.5 51762.1 47505.7 3624.17683614 178873453.27515484
|
||||
1614902400 48374.5 48758.9 49450 46189.8 3697.34556922 176318969.507294567
|
||||
1614988800 48746.9 48871.9 49255.1 47001 1949.15311354 94201823.810314647
|
||||
1615075200 48885 50930.4 51424.7 48885 2444.3584982 122962479.787996993
|
||||
1615161600 50956.6 52377 52387.5 49287.5 2710.99151191 137751640.241286989
|
||||
1615248000 52376.9 54867.6 54867.6 51833.8 3070.93581512 165487483.114064122
|
||||
1615334400 54867.5 55865.5 57364 52911.4 4049.50553851 224565244.752334892
|
||||
1615420800 55863.7 57781.1 58150 54238 3403.69441456 191915265.020541521
|
||||
1615507200 57781 57238.5 58057.5 55013.7 4031.0376629 228810606.091302364
|
||||
1615593600 57220.7 61180.9 61815.3 56059.3 4394.62318443 259602986.875738328
|
||||
1615680000 61174.3 59000 61700 59000 3084.33952274 186155667.656432156
|
||||
1615766400 59000 55607.1 60632.9 54525.6 5910.33518227 338468393.188725572
|
||||
1615852800 55607.1 56880.3 56918.9 53240.3 7410.49057723 409052587.523700888
|
||||
1615939200 56880.3 58875.8 58951.8 54147.5 5828.79026943 328135601.648660052
|
||||
1616025600 58882.9 57648.9 60107.7 57000 5073.7458698 297279816.540519693
|
||||
1616112000 57648.9 58024.2 59450.1 56071 3727.09434161 217005823.723994618
|
||||
1616198400 58024.3 58113.5 59874.6 57825.6 2746.52973805 161565114.165299707
|
||||
1616284800 58113.5 57350.2 58591.6 55501 3265.35649781 186845535.507151609
|
||||
1616371200 57345.3 54096.1 58415.5 53667 4219.99501831 237141977.003568352
|
||||
1616457600 54086.8 54348.4 55823.1 52986.3 4374.34046303 239135883.538398977
|
||||
1616544000 54348.4 52307.4 57200 51499.6 6416.76024581 351202326.218690674
|
||||
1616630400 52307.1 51301.7 53239.1 50455 7242.6466396 375950351.557038048
|
||||
1616716800 51301.7 55032 55062.5 51225.3 4609.48192944 245299757.451540308
|
||||
1616803200 55031.9 55820.4 56628.6 53967.5 3634.73588532 200758048.816804103
|
||||
1616889600 55820.3 55772.9 56541 54666.6 3158.20452681 176119911.151714842
|
||||
1616976000 55772.8 57628.9 58400.5 54926.5 4413.63121553 251384747.301649587
|
||||
1617062400 57630.8 58754.6 59351.9 57072.8 3563.87315049 208118726.050535887
|
||||
1617148800 58753.2 58745.9 59800 56357.5 4921.45848213 288469053.074870873
|
||||
1617235200 58745.5 58735.7 59487.1 57879 3163.98213108 186078130.901422269
|
||||
1617321600 58735.7 58963.6 60179.1 58460.7 2553.76427314 151446539.609794648
|
||||
1617408000 58963.6 57058.3 59795 56721.2 2512.19109578 147434403.06515736
|
||||
1617494400 57052.5 58201.4 58481.2 56432.6 2069.14670128 119228330.17272614
|
||||
1617580800 58201.4 59116.2 59254.1 56501 3003.76043377 174821106.684799505
|
||||
1617667200 59116.2 57988.3 59497.5 57304.8 2964.86183859 173169186.845682699
|
||||
1617753600 57988.3 55958.2 58668.6 55439 5277.04906389 299996660.411940246
|
||||
1617840000 55958.2 58076.7 58141 55700.6 3175.60482079 181817013.517575328
|
||||
1617926400 58076.7 58131.6 58900 57666.9 3516.19104669 204849717.059779284
|
||||
1618012800 58138.2 59770.2 61350 57902.1 5533.50675561 332014577.538990658
|
||||
1618099200 59770.2 60007.6 60687.4 59247.6 3896.37426019 233158562.799039154
|
||||
1618185600 60007.6 59863.4 61270.7 59417.4 4611.409014 277430208.743380477
|
||||
1618272000 59863.4 63578.7 63759.7 59815 6906.310253 430518557.569547626
|
||||
1618358400 63578.7 62958.7 64840 61000 7696.509177 487298143.928065301
|
||||
1618444800 62954.4 63152.6 63772.1 62023.9 4709.82427144 296178401.81115496
|
||||
1618531200 63152.6 61342.6 63509.7 59930.8 8295.32523869 510423835.691643255
|
||||
1618617600 61342.7 59995.2 62497.8 59599.6 5367.42979289 328364887.709585395
|
||||
1618704000 59995.3 56150.6 60409.5 49001 11485.97101449 637797282.448645379
|
||||
1618790400 56152.7 55618.8 57583.4 54205.2 7721.306905 432634348.931871989
|
||||
1618876800 55618.7 56427.8 57061.6 53328 8677.75606016 480164200.559836543
|
||||
1618963200 56426.1 53793.6 56761.7 53602 6240.82191836 345339357.806167462
|
||||
1619049600 53793.5 51696.4 55474.7 50400 8879.16016304 475394174.249706678
|
||||
1619136000 51691.2 51102.7 52112.1 47502.1 8885.07060366 441295812.644904319
|
||||
1619222400 51109.8 50033 51157.9 48676.5 4833.41744745 241336360.887795675
|
||||
1619308800 50041.5 49086.9 50554.6 46966.2 4805.34664069 237153315.222670555
|
||||
1619395200 49069 54000.2 54336.4 48775.8 6695.12934907 353727728.269533971
|
||||
1619481600 53997.1 55014.3 55439 53240.8 4344.22291318 237020455.905144335
|
||||
1619568000 55014.2 54833.2 56399.1 53808.3 4801.04618634 262912695.604761319
|
||||
1619654400 54833.1 53558.4 55181.2 52340.1 4356.05177188 234153663.397444462
|
||||
1619740800 53558.5 57697.3 57936.4 53042.6 5000.47557303 277531927.921795199
|
||||
1619827200 57697.3 57794.7 58471.4 57006.3 3639.78966647 210179438.189007639
|
||||
1619913600 57794.7 56568.5 57903.7 56044.3 3508.52428767 199206958.05741809
|
||||
1620000000 56568.5 57159.7 58977.9 56451.3 4780.43387226 276554749.540429296
|
||||
1620086400 57159.7 53196.3 57188.2 53083.3 7079.55804728 390469293.396018923
|
||||
1620172800 53196.3 57834.5 57979.7 52888 4224.63060355 233779565.506303973
|
|
@ -0,0 +1,3 @@
|
||||
BTC 1
|
||||
USDT 100000
|
||||
ETH 10
|
|
Loading…
x
Reference in New Issue
Block a user