Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initiate basic indicators for trading #597

Merged
merged 1 commit into from
Jun 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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