Skip to content

Commit

Permalink
Initiate basic indicators for trading
Browse files Browse the repository at this point in the history
  • Loading branch information
sjanel committed Jun 29, 2024
1 parent 0c0b21c commit 9c96c42
Show file tree
Hide file tree
Showing 16 changed files with 216 additions and 42 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ FetchContent_Declare(

set(JWT_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)

list(APPEND fetchContentPackagesToMakeAvailable jwt-cpp)
list(APPEND fetchContentPackagesToMakeAvailable jwt-cpp)

# protobuf - serialization / deserialization library
set(PROTOBUF_FETCHED_CONTENT OFF)
Expand All @@ -172,7 +172,7 @@ if(CCT_ENABLE_PROTO)
else()
# Check here for a new version: https://protobuf.dev/support/version-support/#cpp
if (NOT PROTOBUF_VERSION)
set(PROTOBUF_VERSION v5.27.1)
set(PROTOBUF_VERSION v5.27.2)
endif()

message(STATUS "Configuring protobuf ${PROTOBUF_VERSION} from sources")
Expand Down
8 changes: 5 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ARG BUILD_WITH_PROTOBUF=1
# Install base & build dependencies, needed certificates for curl to work with https
RUN apt update && \
apt upgrade -y && \
apt install build-essential ninja-build libssl-dev zlib1g-dev libcurl4-openssl-dev cmake git ca-certificates -y --no-install-recommends
apt install -y --no-install-recommends build-essential ninja-build libssl-dev zlib1g-dev libcurl4-openssl-dev cmake git ca-certificates

# Copy source files
WORKDIR /app/src
Expand Down Expand Up @@ -38,12 +38,14 @@ COPY data/cache/fiatcache.json ./
WORKDIR /app/bin

# Configure
RUN cmake -DCMAKE_BUILD_TYPE=${BUILD_MODE} \
RUN cmake \
-DCMAKE_BUILD_TYPE=${BUILD_MODE} \
-DCCT_ENABLE_TESTS=${BUILD_TEST} \
-DCCT_ENABLE_ASAN=${BUILD_ASAN} \
-DCCT_BUILD_PROMETHEUS_FROM_SRC=${BUILD_WITH_PROMETHEUS} \
-DCCT_ENABLE_PROTO=${BUILD_WITH_PROTOBUF} \
-GNinja ..
-GNinja \
..

# Build
RUN cmake --build .
Expand Down
7 changes: 0 additions & 7 deletions src/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,6 @@ add_unit_test(
../api/common/test/include
)

add_unit_test(
replay-algorithm-name-iterator_test
test/replay-algorithm-name-iterator_test.cpp
LIBRARIES
coincenter_engine
)

add_unit_test(
stringoptionparser_test
test/stringoptionparser_test.cpp
Expand Down
13 changes: 6 additions & 7 deletions src/engine/src/coincenter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <thread>
#include <utility>

#include "algorithm-name-iterator.hpp"
#include "balanceoptions.hpp"
#include "cct_const.hpp"
#include "cct_exception.hpp"
Expand Down Expand Up @@ -37,7 +38,6 @@
#include "query-result-type-helpers.hpp"
#include "queryresultprinter.hpp"
#include "queryresulttypes.hpp"
#include "replay-algorithm-name-iterator.hpp"
#include "replay-options.hpp"
#include "time-window.hpp"
#include "timedef.hpp"
Expand Down Expand Up @@ -618,8 +618,8 @@ void Coincenter::replay(const AbstractMarketTraderFactory &marketTraderFactory,

MarketSet allMarkets = ComputeAllMarkets(marketTimestampSetsPerExchange);

ReplayAlgorithmNameIterator replayAlgorithmNameIterator(replayOptions.algorithmNames(),
marketTraderFactory.allSupportedAlgorithms());
AlgorithmNameIterator replayAlgorithmNameIterator(replayOptions.algorithmNames(),
marketTraderFactory.allSupportedAlgorithms());

while (replayAlgorithmNameIterator.hasNext()) {
std::string_view algorithmName = replayAlgorithmNameIterator.next();
Expand All @@ -629,8 +629,7 @@ void Coincenter::replay(const AbstractMarketTraderFactory &marketTraderFactory,

// Create the MarketTraderEngines based on this market, filtering out exchanges without available amount to
// trade
MarketTraderEngineVector marketTraderEngines =
createMarketTraderEngines(replayOptions, replayMarket, exchangesWithThisMarketData);
auto marketTraderEngines = createMarketTraderEngines(replayOptions, replayMarket, exchangesWithThisMarketData);

replayAlgorithm(marketTraderFactory, algorithmName, replayOptions, marketTraderEngines,
exchangesWithThisMarketData);
Expand Down Expand Up @@ -688,10 +687,10 @@ Coincenter::MarketTraderEngineVector Coincenter::createMarketTraderEngines(

MarketTraderEngineVector marketTraderEngines;
for (decltype(nbExchanges) exchangePos = 0; exchangePos < nbExchanges; ++exchangePos) {
const MonetaryAmount startBaseAmount =
const auto startBaseAmount =
isValidateOnly ? MonetaryAmount{0, market.base()}
: ComputeStartAmount(market.base(), convertedBaseAmountPerExchange[exchangePos].second);
const MonetaryAmount startQuoteAmount =
const auto startQuoteAmount =
isValidateOnly ? MonetaryAmount{0, market.quote()}
: ComputeStartAmount(market.quote(), convertedQuoteAmountPerExchange[exchangePos].second);

Expand Down
7 changes: 4 additions & 3 deletions src/objects/src/monetaryamount.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@ inline int ParseNegativeChar(std::string_view &amountStr) {
}

inline MonetaryAmount::AmountType HeuristicRounding(std::size_t dotPos, std::string_view &amountStr) {
static constexpr std::string_view kHeuristicRoundingPatterns[] = {"000", "999"};

std::size_t bestFindPos = 0;
for (std::string_view pattern : {"000", "999"}) {
for (std::string_view pattern : kHeuristicRoundingPatterns) {
std::size_t findPos = amountStr.rfind(pattern);
if (findPos != std::string_view::npos && findPos > dotPos) {
while (amountStr[findPos - 1] == pattern.front()) {
while (amountStr[findPos - 1] == amountStr[findPos]) {
--findPos;
}
if (amountStr[findPos - 1] == '.') {
Expand All @@ -84,7 +86,6 @@ inline MonetaryAmount::AmountType HeuristicRounding(std::size_t dotPos, std::str
}
if (bestFindPos != 0) {
const bool roundingUp = amountStr[bestFindPos] == '9';
log::trace("Heuristic rounding {} for {}", roundingUp ? "up" : "down", amountStr);
amountStr.remove_suffix(amountStr.size() - bestFindPos);
if (roundingUp) {
return 1;
Expand Down
3 changes: 2 additions & 1 deletion src/trading/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(algorithms)
add_subdirectory(common)
add_subdirectory(common)
add_subdirectory(indicators)
2 changes: 2 additions & 0 deletions src/trading/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ add_library(coincenter_trading-algorithms STATIC ${TRADING-ALGORITHMS_SRC})
target_link_libraries(coincenter_trading-algorithms PUBLIC coincenter_api-objects)
target_link_libraries(coincenter_trading-algorithms PUBLIC coincenter_objects)
target_link_libraries(coincenter_trading-algorithms PUBLIC coincenter_tech)

target_link_libraries(coincenter_trading-algorithms PUBLIC coincenter_trading-common)
target_link_libraries(coincenter_trading-algorithms PUBLIC coincenter_trading-indicators)

target_include_directories(coincenter_trading-algorithms PUBLIC include)
1 change: 1 addition & 0 deletions src/trading/algorithms/include/market-trader-factory.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <memory>
#include <span>
#include <string_view>

#include "abstract-market-trader-factory.hpp"
Expand Down
9 changes: 8 additions & 1 deletion src/trading/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,11 @@ add_library(coincenter_trading-common STATIC ${TRADING-COMMON_SRC})
target_link_libraries(coincenter_trading-common PUBLIC coincenter_api-objects)
target_link_libraries(coincenter_trading-common PUBLIC coincenter_objects)
target_link_libraries(coincenter_trading-common PUBLIC coincenter_tech)
target_include_directories(coincenter_trading-common PUBLIC include)
target_include_directories(coincenter_trading-common PUBLIC include)

add_unit_test(
algorithm-name-iterator_test
test/algorithm-name-iterator_test.cpp
LIBRARIES
coincenter_trading-common
)
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ namespace cct {

/// Convenient class to iterate on the algorithm names, comma separated.
/// If 'algorithmNames' is empty, it will loop on all available ones (given by 'allAlgorithms')
class ReplayAlgorithmNameIterator {
class AlgorithmNameIterator {
public:
ReplayAlgorithmNameIterator(std::string_view algorithmNames, std::span<const std::string_view> allAlgorithms);
AlgorithmNameIterator(std::string_view algorithmNames, std::span<const std::string_view> allAlgorithms);

/// Returns true if and only if there is at least one additional algorithm name to iterate on.
bool hasNext() const;
Expand Down
1 change: 1 addition & 0 deletions src/trading/common/include/market-trader-engine.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <cstdint>
#include <memory>
#include <type_traits>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "replay-algorithm-name-iterator.hpp"
#include "algorithm-name-iterator.hpp"

#include <algorithm>
#include <span>
Expand All @@ -20,8 +20,8 @@ auto FindNextSeparatorPos(std::string_view str, std::string_view::size_type pos
}
} // namespace

ReplayAlgorithmNameIterator::ReplayAlgorithmNameIterator(std::string_view algorithmNames,
std::span<const std::string_view> allAlgorithms)
AlgorithmNameIterator::AlgorithmNameIterator(std::string_view algorithmNames,
std::span<const std::string_view> allAlgorithms)
: _allAlgorithms(allAlgorithms),
_algorithmNames(algorithmNames),
_begPos(0),
Expand All @@ -33,7 +33,7 @@ ReplayAlgorithmNameIterator::ReplayAlgorithmNameIterator(std::string_view algori
}
}

bool ReplayAlgorithmNameIterator::hasNext() const {
bool AlgorithmNameIterator::hasNext() const {
using PosT = decltype(_begPos);

if (_algorithmNames.empty()) {
Expand All @@ -43,7 +43,7 @@ bool ReplayAlgorithmNameIterator::hasNext() const {
return _begPos != static_cast<PosT>(_algorithmNames.length());
}

std::string_view ReplayAlgorithmNameIterator::next() {
std::string_view AlgorithmNameIterator::next() {
if (_algorithmNames.empty()) {
return _allAlgorithms[_begPos++];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "replay-algorithm-name-iterator.hpp"
#include "algorithm-name-iterator.hpp"

#include <gtest/gtest.h>

Expand All @@ -7,20 +7,20 @@
#include "cct_exception.hpp"

namespace cct {
class ReplayAlgorithmNameIteratorTest : public ::testing::Test {
class AlgorithmNameIteratorTest : public ::testing::Test {
protected:
static constexpr std::string_view kInvalidAlgorithmNames[] = {"any", "so-what,"};
static constexpr std::string_view kAlgorithmNames[] = {"any", "so-what", "angry",
"bird", "Jack", "a-more-complex algorithm Name"};
};

TEST_F(ReplayAlgorithmNameIteratorTest, AlgorithmNamesValidity) {
EXPECT_THROW(ReplayAlgorithmNameIterator("", kInvalidAlgorithmNames), exception);
EXPECT_NO_THROW(ReplayAlgorithmNameIterator("", kAlgorithmNames));
TEST_F(AlgorithmNameIteratorTest, AlgorithmNamesValidity) {
EXPECT_THROW(AlgorithmNameIterator("", kInvalidAlgorithmNames), exception);
EXPECT_NO_THROW(AlgorithmNameIterator("", kAlgorithmNames));
}

TEST_F(ReplayAlgorithmNameIteratorTest, IteratorWithAll) {
ReplayAlgorithmNameIterator it("", kAlgorithmNames);
TEST_F(AlgorithmNameIteratorTest, IteratorWithAll) {
AlgorithmNameIterator it("", kAlgorithmNames);

int algorithmPos = 0;
while (it.hasNext()) {
Expand Down Expand Up @@ -50,8 +50,8 @@ TEST_F(ReplayAlgorithmNameIteratorTest, IteratorWithAll) {
EXPECT_EQ(algorithmPos, 6);
}

TEST_F(ReplayAlgorithmNameIteratorTest, IteratorWithUniqueAlgorithmSpecified) {
ReplayAlgorithmNameIterator it("so-What", kAlgorithmNames);
TEST_F(AlgorithmNameIteratorTest, IteratorWithUniqueAlgorithmSpecified) {
AlgorithmNameIterator it("so-What", kAlgorithmNames);

int algorithmPos = 0;
while (it.hasNext()) {
Expand All @@ -71,8 +71,8 @@ TEST_F(ReplayAlgorithmNameIteratorTest, IteratorWithUniqueAlgorithmSpecified) {
EXPECT_EQ(algorithmPos, 1);
}

TEST_F(ReplayAlgorithmNameIteratorTest, IteratorWithSpecifiedList) {
ReplayAlgorithmNameIterator it("Jack,whatever,so-what,some-algorithmNameThatIsNotInAll,with spaces", kAlgorithmNames);
TEST_F(AlgorithmNameIteratorTest, IteratorWithSpecifiedList) {
AlgorithmNameIterator it("Jack,whatever,so-what,some-algorithmNameThatIsNotInAll,with spaces", kAlgorithmNames);

int algorithmPos = 0;
while (it.hasNext()) {
Expand Down
8 changes: 8 additions & 0 deletions src/trading/indicators/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
aux_source_directory(src TRADING-INDICATORS_SRC)

add_library(coincenter_trading-indicators STATIC ${TRADING-INDICATORS_SRC})
target_link_libraries(coincenter_trading-indicators PUBLIC coincenter_trading-common)
target_link_libraries(coincenter_trading-indicators PUBLIC coincenter_api-objects)
target_link_libraries(coincenter_trading-indicators PUBLIC coincenter_objects)
target_link_libraries(coincenter_trading-indicators PUBLIC coincenter_tech)
target_include_directories(coincenter_trading-indicators PUBLIC include)
26 changes: 26 additions & 0 deletions src/trading/indicators/include/basic-stats.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "monetaryamount.hpp"
#include "timedef.hpp"

namespace cct {

class MarketDataView;

class BasicStats {
public:
explicit BasicStats(const MarketDataView &marketDataView) : _marketDataView(marketDataView) {}

MonetaryAmount movingAverageFromLastPublicTradesPrice(TimePoint oldestTime) const;

MonetaryAmount movingAverageFromMarketOrderBooks(TimePoint oldestTime,
Duration minFrequencyBetweenTwoPoints = Duration{}) const;

MonetaryAmount standardDeviationFromMarketOrderBooks(TimePoint oldestTime,
Duration minFrequencyBetweenTwoPoints = Duration{}) const;

private:
const MarketDataView &_marketDataView;
};

} // namespace cct
Loading

0 comments on commit 9c96c42

Please sign in to comment.