diff --git a/.github/workflows/exchange-ci.yml b/.github/workflows/exchange-ci.yml index cf917fb8..912d547b 100644 --- a/.github/workflows/exchange-ci.yml +++ b/.github/workflows/exchange-ci.yml @@ -287,6 +287,7 @@ jobs: CLANG_DIR: '/usr/lib/llvm-18/lib/cmake/clang' LLVM_DIR: '/usr/lib/llvm-18/lib/cmake/llvm' NUTC_WRAPPER_BINARY_PATH: ${{ github.workspace }}/exchange/build/WRAPPER + NUTC_CPP_TEMPLATE_PATH: ${{ github.workspace }}/exchange/template.cpp steps: - uses: actions/checkout@v3 @@ -332,7 +333,7 @@ jobs: run: | pip3 install conan numpy - sudo apt install libssl-dev rabbitmq-server -y + sudo apt install libssl-dev -y bash < ../.github/scripts/conan-profile.sh conan install . -s build_type=Release -b missing @@ -359,23 +360,6 @@ jobs: - name: Move test algo files run: cp -r -L test/src/integration/test_algos build/test/test_algos - # TODO: use secrets - - name: Configure RabbitMQ - run: | - sudo rabbitmqctl add_user NUFT ADMIN - sudo rabbitmqctl set_permissions -p / NUFT ".*" ".*" ".*" - sudo rabbitmqctl set_user_tags NUFT administrator - - - name: Start RabbitMQ - run: | - sudo systemctl start rabbitmq-server - sudo rabbitmqctl status - - - name: Configure RabbitMQ Port - run: | - echo "listeners.tcp.default = 5672" | sudo tee -a /etc/rabbitmq/rabbitmq.conf - sudo systemctl restart rabbitmq-server - - name: Test exchange working-directory: exchange/build run: ctest --output-on-failure --no-tests=error --timeout 10 -C Release -R "Integration*" diff --git a/exchange/Taskfile.yml b/exchange/Taskfile.yml index 1aade733..9fe99796 100644 --- a/exchange/Taskfile.yml +++ b/exchange/Taskfile.yml @@ -78,6 +78,7 @@ tasks: run: env: + NUTC_CPP_TEMPLATE_PATH: 'template.cpp' NUTC_WRAPPER_BINARY_PATH: '{{if eq .RELEASE_BUILD "true"}}./build/WRAPPER{{else}}./build/dev/WRAPPER{{end}}' NUTC_EXPOSE_METRICS: 1 vars: @@ -131,6 +132,7 @@ tasks: RELEASE_TEST_FLAGS: '--output-on-failure --no-tests=error --timeout 10 -C Release' TEST_FLAGS: '{{if eq .RELEASE_BUILD "true"}}{{.RELEASE_TEST_FLAGS}}{{else}}{{.DEV_TEST_FLAGS}}{{end}}' env: + NUTC_CPP_TEMPLATE_PATH: 'test_algos/cpp/template.cpp' NUTC_WRAPPER_BINARY_PATH: '{{.PWD}}/{{.WRAPPER_RELATIVE_PATH}}' cmds: - ctest -j 4 {{.TEST_FLAGS}} -R "Integration*" diff --git a/exchange/src/common/types/algorithm/local_algorithm.cpp b/exchange/src/common/types/algorithm/local_algorithm.cpp index f7cab22a..cffd6296 100644 --- a/exchange/src/common/types/algorithm/local_algorithm.cpp +++ b/exchange/src/common/types/algorithm/local_algorithm.cpp @@ -8,27 +8,36 @@ #include #include -#include namespace nutc::common { +namespace { std::string -LocalAlgorithm::compile_cpp_() const +get_cpp_template_path() +{ + static const char* template_path_env = std::getenv("NUTC_CPP_TEMPLATE_PATH"); + if (template_path_env == nullptr) + throw std::runtime_error("Template.cpp path not set, unable to compile cpp"); + return template_path_env; +} +} // namespace + +std::string +LocalAlgorithm::compile_cpp(const std::filesystem::path& filepath) { - assert(get_language() == AlgoLanguage::cpp); - static constexpr std::string_view TEMPLATE_PATH = "test_algos/cpp/template.cpp"; std::string binary_output = (boost::filesystem::temp_directory_path() / boost::filesystem::unique_path("%%%%-%%%%-%%%%.tmp")) .string(); + std::string command = fmt::format( "g++ -std=c++20 -fPIC -shared -o {} -include {} {}", binary_output, - filepath_.string(), TEMPLATE_PATH + filepath.string(), get_cpp_template_path() ); int result = system(command.c_str()); if (result != 0) { throw std::runtime_error( - fmt::format("Compilation of {} failed", filepath_.string()) + fmt::format("Compilation of {} failed", filepath.string()) ); } return binary_output; @@ -36,13 +45,7 @@ LocalAlgorithm::compile_cpp_() const LocalAlgorithm::LocalAlgorithm(AlgoLanguage language, std::filesystem::path filepath) : BaseAlgorithm{language}, filepath_{std::move(filepath)} -{ - if (!std::filesystem::exists(filepath_)) [[unlikely]] { - throw std::runtime_error( - fmt::format("Local algorithm file not found: {}", filepath_.string()) - ); - } -} +{} const std::filesystem::path& LocalAlgorithm::get_path() const @@ -53,21 +56,14 @@ LocalAlgorithm::get_path() const std::string LocalAlgorithm::get_algo_string() const { - std::optional algorithm; if (get_language() == AlgoLanguage::cpp) { - algorithm = common::read_file_content(compile_cpp_()); - } - else { - algorithm = common::read_file_content(filepath_); + return common::read_file_content(compile_cpp(filepath_)); } - - if (!algorithm) { - throw std::runtime_error( - fmt::format("Unable to find algorithm at {}", filepath_.string()) - ); + if (get_language() == AlgoLanguage::python) { + return common::read_file_content(filepath_); } - return algorithm.value(); + throw std::runtime_error("Unknown algo language"); } std::string diff --git a/exchange/src/common/types/algorithm/local_algorithm.hpp b/exchange/src/common/types/algorithm/local_algorithm.hpp index c47c48e6..d1770916 100644 --- a/exchange/src/common/types/algorithm/local_algorithm.hpp +++ b/exchange/src/common/types/algorithm/local_algorithm.hpp @@ -17,6 +17,6 @@ class LocalAlgorithm : public BaseAlgorithm { std::string get_id() const; private: - std::string compile_cpp_() const; + static std::string compile_cpp(const std::filesystem::path& filepath); }; } // namespace nutc::common diff --git a/exchange/src/exchange/algos/dev_mode/dev_mode.cpp b/exchange/src/exchange/algos/dev_mode/dev_mode.cpp index 4a6e016a..25483d2d 100644 --- a/exchange/src/exchange/algos/dev_mode/dev_mode.cpp +++ b/exchange/src/exchange/algos/dev_mode/dev_mode.cpp @@ -5,7 +5,6 @@ #include "exchange/traders/trader_types/algo_trader.hpp" #include "exchange/wrappers/creation/rmq_wrapper_init.hpp" -#include #include namespace nutc::exchange { @@ -28,15 +27,15 @@ DevModeAlgoInitializer::initialize_trader_container( void DevModeAlgoInitializer::initialize_files() { - if (!algorithms_.empty()) - return; - for (size_t i = 0; i < NUM_ALGOS; i++) { - auto relative_path = fmt::format("{}/algo_{}.py", ALGO_DIR, i); - algorithms_.emplace_back(common::AlgoLanguage::python, relative_path); + auto relative_py_path = fmt::format("{}/algo_{}.py", ALGO_DIR, i); + auto relative_cpp_path = fmt::format("{}/algo_{}.hpp", ALGO_DIR, i); + algorithms_.emplace_back(common::AlgoLanguage::python, relative_py_path); + algorithms_.emplace_back(common::AlgoLanguage::cpp, relative_cpp_path); } - std::string content = common::read_file_content("template.py"); + std::string py_content = common::read_file_content("template.py"); + std::string cpp_content = common::read_file_content("template.hpp"); if (!common::create_directory(ALGO_DIR)) throw std::runtime_error("Failed to create directory"); @@ -50,7 +49,12 @@ DevModeAlgoInitializer::initialize_files() if (!file) throw std::runtime_error("Failed to create local algo"); - file << content; + if (algo.get_language() == common::AlgoLanguage::python) { + file << py_content; + } + else { + file << cpp_content; + } file.close(); } } diff --git a/exchange/src/exchange/algos/dev_mode/dev_mode.hpp b/exchange/src/exchange/algos/dev_mode/dev_mode.hpp index 7de41d74..536fd09b 100644 --- a/exchange/src/exchange/algos/dev_mode/dev_mode.hpp +++ b/exchange/src/exchange/algos/dev_mode/dev_mode.hpp @@ -1,6 +1,6 @@ #pragma once -#include "common/types/algorithm/algorithm.hpp" +#include "common/types/algorithm/local_algorithm.hpp" #include "common/types/decimal.hpp" #include "exchange/algos/algo_manager.hpp" #include "exchange/traders/trader_container.hpp" diff --git a/exchange/src/exchange/main.cpp b/exchange/src/exchange/main.cpp index 6c7ed2ad..0ae24249 100644 --- a/exchange/src/exchange/main.cpp +++ b/exchange/src/exchange/main.cpp @@ -25,7 +25,6 @@ create_cycle(TraderContainer& traders, const auto& mode) double order_fee = Config::get().constants().ORDER_FEE; auto tickers = TickerContainer(ticker_config, traders); - return std::make_unique(tickers, traders, order_fee); switch (mode) { case Mode::normal: return std::make_unique(tickers, traders, order_fee);