use of tech.cassandre.trading.bot.strategy.CassandreStrategy in project cassandre-trading-bot by cassandre-tech.
the class StrategiesAutoConfiguration method configure.
/**
* Search for strategies and runs them.
*/
@PostConstruct
@SuppressWarnings("checkstyle:MethodLength")
public void configure() {
// Retrieving all the beans have the @Strategy annotation.
final Map<String, Object> strategies = applicationContext.getBeansWithAnnotation(CassandreStrategy.class);
// =============================================================================================================
// Configuration check.
// We run tests to display and check if everything is ok with the configuration.
final UserDTO user = checkConfiguration(strategies);
// =============================================================================================================
// Maintenance code.
// If a position is blocked in OPENING or CLOSING, we send again the trades.
// This could happen if cassandre crashes after saving a trade and did not have time to send it to
// positionService. Here we force the status recalculation in PositionDTO, and we save it.
positionRepository.findByStatusIn(Stream.of(OPENING, CLOSING).toList()).stream().map(POSITION_MAPPER::mapToPositionDTO).map(POSITION_MAPPER::mapToPosition).forEach(positionRepository::save);
// =============================================================================================================
// Importing tickers & candles into database.
// Feature documentation is here: https://trading-bot.cassandre.tech/learn/import-historical-data.html
loadTickersFromFiles();
loadCandlesFromFiles();
// =============================================================================================================
// Creating flux.
final ConnectableFlux<Set<AccountDTO>> connectableAccountFlux = accountFlux.getFlux().publish();
final ConnectableFlux<Set<PositionDTO>> connectablePositionFlux = positionFlux.getFlux().publish();
final ConnectableFlux<Set<OrderDTO>> connectableOrderFlux = orderFlux.getFlux().publish();
final ConnectableFlux<Set<TickerDTO>> connectableTickerFlux = tickerFlux.getFlux().publish();
final ConnectableFlux<Set<TradeDTO>> connectableTradeFlux = tradeFlux.getFlux().publish();
// =============================================================================================================
// Configuring strategies.
// Data in database, services, flux...
logger.info("Running the following strategies:");
strategies.values().forEach(s -> {
CassandreStrategyInterface strategy = (CassandreStrategyInterface) s;
CassandreStrategy annotation = s.getClass().getAnnotation(CassandreStrategy.class);
// Retrieving strategy information from annotation.
final String strategyId = annotation.strategyId();
final String strategyName = annotation.strategyName();
// Displaying information about strategy.
logger.info("- Strategy '{}/{}' (requires {})", strategyId, strategyName, strategy.getRequestedCurrencyPairs().stream().map(CurrencyPairDTO::toString).collect(Collectors.joining(", ")));
// StrategyDTO: saving or updating the strategy in database.
StrategyDTO strategyDTO;
final Optional<Strategy> strategyInDatabase = strategyRepository.findByStrategyId(annotation.strategyId());
if (strategyInDatabase.isEmpty()) {
// =============================================================================================
// If the strategy is NOT in database.
Strategy newStrategy = new Strategy();
newStrategy.setStrategyId(annotation.strategyId());
newStrategy.setName(annotation.strategyName());
strategyDTO = STRATEGY_MAPPER.mapToStrategyDTO(strategyRepository.save(newStrategy));
logger.debug("Strategy created in database: {}", newStrategy);
} else {
// =============================================================================================
// If the strategy is in database.
strategyInDatabase.get().setName(strategyName);
strategyDTO = STRATEGY_MAPPER.mapToStrategyDTO(strategyRepository.save(strategyInDatabase.get()));
logger.debug("Strategy updated in database: {}", strategyInDatabase.get());
}
strategyDTO.initializeLastPositionIdUsed(positionRepository.getLastPositionIdUsedByStrategy(strategyDTO.getUid()));
// Setting up configuration, dependencies and accounts in strategy.
strategy.initializeAccounts(user.getAccounts());
strategy.setConfiguration(getCassandreStrategyConfiguration(strategyDTO));
strategy.setDependencies(getCassandreStrategyDependencies());
// Calling user defined initialize() method.
strategy.initialize();
// Connecting flux to strategy.
connectableAccountFlux.subscribe(strategy::accountsUpdates, throwable -> logger.error("AccountsUpdates failing: {}", throwable.getMessage()));
connectablePositionFlux.subscribe(strategy::positionsUpdates, throwable -> logger.error("PositionsUpdates failing: {}", throwable.getMessage()));
connectableOrderFlux.subscribe(strategy::ordersUpdates, throwable -> logger.error("OrdersUpdates failing: {}", throwable.getMessage()));
connectableTradeFlux.subscribe(strategy::tradesUpdates, throwable -> logger.error("TradesUpdates failing: {}", throwable.getMessage()));
connectableTickerFlux.subscribe(strategy::tickersUpdates, throwable -> logger.error("TickersUpdates failing: {}", throwable.getMessage()));
});
// =============================================================================================================
// Starting flux.
connectableAccountFlux.connect();
connectablePositionFlux.connect();
connectableOrderFlux.connect();
connectableTradeFlux.connect();
connectableTickerFlux.connect();
}
Aggregations