Skip to content

Commit

Permalink
Checkpoint 5
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenewald committed Oct 4, 2024
1 parent 764918a commit 0184576
Show file tree
Hide file tree
Showing 23 changed files with 214 additions and 127 deletions.
2 changes: 1 addition & 1 deletion docker/dev/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ services:
restart: unless-stopped
build:
context: ../..
dockerfile: linter/LinterDockerfile
dockerfile: exchange/docker/linter/LinterDockerfile
args:
firebase_emulator: "false"

Expand Down
1 change: 1 addition & 0 deletions exchange/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ add_library(COMMON_lib OBJECT
src/common/types/decimal.cpp
src/common/types/algorithm/local_algorithm.cpp
src/common/logging/logging.cpp
src/common/compilation/compile_cpp.cpp
)

target_include_directories(
Expand Down
Binary file modified exchange/docker/dev/grafana_data/grafana.db
Binary file not shown.
34 changes: 18 additions & 16 deletions exchange/docker/linter/LinterDockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ RUN pip install conan numpy pandas polars scipy scikit-learn sortedcontainers li
&& apt update \
&& apt install -y --no-install-recommends build-essential libssl-dev cmake git

WORKDIR /app/linter
COPY ./linter/conanfile.py /app/linter/conanfile.py
COPY ./.github/scripts/conan-profile.sh /app/linter
WORKDIR /app/exchange
COPY ./exchange/conanfile.py /app/exchange/conanfile.py
COPY ./.github/scripts/conan-profile.sh /app/exchange

RUN cat conan-profile.sh | bash \
&& conan install . -b missing

COPY ./linter/src /app/linter/src
COPY ./linter/CMakeLists.txt /app/linter
COPY ./linter/CMakePresets.json /app/linter
COPY ./linter/cmake /app/linter/cmake
COPY ./linter/test /app/linter/test
COPY ./exchange/src /app/exchange/src
COPY ./exchange/CMakeLists.txt /app/exchange
COPY ./exchange/CMakePresets.json /app/exchange
COPY ./exchange/cmake /app/exchange/cmake
COPY ./exchange/test /app/exchange/test

ARG firebase_emulator=false

Expand All @@ -27,17 +27,19 @@ RUN if [ "$firebase_emulator" = "false" ]; then \
cmake --preset=ci-docker -DLOCAL_DEV=ON; \
fi

RUN cmake --build build --config Release -j6
RUN cmake --build build --config Release -j

ENV NUTC_SPAWNER_BINARY_PATH="/bin/NUTC-linter-spawner"
ENV NUTC_LINTER_SPAWNER_BINARY_PATH="/bin/LINTER_spawner"

RUN mv /app/linter/build/NUTC-linter-spawner /bin/NUTC-linter-spawner
RUN mv /app/linter/build/NUTC-linter /bin/NUTC-linter
RUN mv /app/exchange/build/LINTER_spawner /bin/LINTER_spawner
RUN mv /app/exchange/build/linter /bin/LINTER

RUN chmod +x /bin/NUTC-linter
RUN chmod +x /bin/NUTC-linter-spawner
RUN chmod +x /bin/LINTER
RUN chmod +x /bin/LINTER_spawner

EXPOSE 18081
COPY ./exchange/template.cpp /app/template.cpp
ENV NUTC_CPP_TEMPLATE_PATH="/app/template.cpp"

EXPOSE 18081

CMD NUTC-linter
CMD LINTER
5 changes: 4 additions & 1 deletion exchange/docker/sandbox/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ RUN if [ "$firebase_emulator" = "false" ]; then \
cmake --preset=ci-docker -DLOCAL_DEV=ON; \
fi

RUN cmake --build build --config Release -j6
RUN cmake --build build --config Release -j

RUN mv /app/exchange/build/NUTC /usr/bin/NUTC-exchange
RUN mv /app/exchange/build/WRAPPER /usr/bin/WRAPPER
Expand All @@ -36,8 +36,11 @@ COPY ./exchange/config.yml /app/exchange/config.yml

RUN chmod +x /usr/bin/NUTC-exchange /usr/bin/WRAPPER

COPY ./exchange/template.cpp /app/template.cpp

ENV NUTC_WRAPPER_BINARY_PATH="/usr/bin/WRAPPER"
ENV NUTC_CONFIG_FILE="/app/exchange/config.yml"
ENV NUTC_CPP_TEMPLATE_PATH="/app/template.cpp"

EXPOSE 4152 18080

Expand Down
45 changes: 45 additions & 0 deletions exchange/src/common/compilation/compile_cpp.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#include "compile_cpp.hpp"

#include "common/file_operations/file_operations.hpp"

namespace nutc::common {
namespace {
std::string
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");
}
if (!file_exists(template_path_env)) {
throw std::runtime_error(
fmt::format("File {} does not exist", template_path_env)
);
}

return template_path_env;
}
} // namespace

std::string
compile_cpp(const std::filesystem::path& filepath)
{
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(), get_cpp_template_path()
);

int result = system(command.c_str());

if (result != 0) {
throw std::runtime_error(
fmt::format("Compilation of {} failed", filepath.string())
);
}
return binary_output;
}
} // namespace nutc::common
13 changes: 13 additions & 0 deletions exchange/src/common/compilation/compile_cpp.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <boost/filesystem.hpp>
#include <fmt/format.h>

#include <filesystem>
#include <string>

namespace nutc::common {

// TODO: shouldnt return filepath as string
std::string compile_cpp(const std::filesystem::path& filepath);
} // namespace nutc::common
35 changes: 2 additions & 33 deletions exchange/src/common/types/algorithm/local_algorithm.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "local_algorithm.hpp"

#include "base_algorithm.hpp"
#include "common/compilation/compile_cpp.hpp"
#include "common/file_operations/file_operations.hpp"

#include <boost/filesystem.hpp>
Expand All @@ -10,38 +11,6 @@
#include <filesystem>

namespace nutc::common {
namespace {
std::string
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)
{
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(), get_cpp_template_path()
);

int result = system(command.c_str());

if (result != 0) {
throw std::runtime_error(
fmt::format("Compilation of {} failed", filepath.string())
);
}
return binary_output;
}

LocalAlgorithm::LocalAlgorithm(AlgoLanguage language, std::filesystem::path filepath) :
BaseAlgorithm{language}, filepath_{std::move(filepath)}
Expand All @@ -57,7 +26,7 @@ std::string
LocalAlgorithm::get_algo_string() const
{
if (get_language() == AlgoLanguage::cpp) {
return common::read_file_content(compile_cpp(filepath_));
return common::read_file_content(common::compile_cpp(filepath_));
}
if (get_language() == AlgoLanguage::python) {
return common::read_file_content(filepath_);
Expand Down
1 change: 0 additions & 1 deletion exchange/src/common/types/algorithm/local_algorithm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,5 @@ class LocalAlgorithm : public BaseAlgorithm {
std::string get_id() const;

private:
static std::string compile_cpp(const std::filesystem::path& filepath);
};
} // namespace nutc::common
25 changes: 24 additions & 1 deletion exchange/src/common/types/algorithm/remote_algorithm.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#pragma once

#include "base_algorithm.hpp"
#include "common/compilation/compile_cpp.hpp"
#include "common/file_operations/file_operations.hpp"

#include <boost/filesystem/operations.hpp>

#include <fstream>

namespace nutc::common {
// TODO
Expand All @@ -17,7 +23,24 @@ class RemoteAlgorithm : public BaseAlgorithm {
std::string
get_algo_string() const
{
return algo_data_;
if (get_language() == AlgoLanguage::cpp) {
// TODO: clean up
std::string binary_output =
(boost::filesystem::temp_directory_path()
/ boost::filesystem::unique_path("%%%%-%%%%-%%%%.tmp"))
.string();

std::ofstream algo_file(binary_output);
algo_file << algo_data_ << std::flush;
algo_file.close();

return common::read_file_content(common::compile_cpp(binary_output));
}
if (get_language() == AlgoLanguage::python) {
return algo_data_;
}

throw std::runtime_error("Unknown algo language");
}

std::string
Expand Down
2 changes: 1 addition & 1 deletion exchange/src/exchange/sandbox_server/crow.cpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#include "crow.hpp"

#include "common/logging/logging.hpp"
#include "common/messages_exchange_to_wrapper.hpp"
#include "common/types/algorithm/base_algorithm.hpp"
#include "exchange/config/dynamic/config.hpp"
#include "common/logging/logging.hpp"
#include "exchange/traders/trader_types/algo_trader.hpp"

#include <crow/common.h>
Expand Down
49 changes: 25 additions & 24 deletions exchange/src/linter/runtime/cpp/cpp_runtime.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include "cpp_runtime.hpp"

#include "common/compilation/compile_cpp.hpp"
#include "common/file_operations/file_operations.hpp"

#include <dlfcn.h>
#include <fcntl.h>
#include <fmt/core.h>
Expand All @@ -12,6 +15,7 @@

#include <filesystem>
#include <fstream>
#include <iostream>
#include <stdexcept>

namespace {
Expand Down Expand Up @@ -51,27 +55,34 @@ namespace nutc::lint {
CppRuntime::CppRuntime(
std::string algo, LimitOrderFunction limit_order, MarketOrderFunction market_order,
CancelOrderFunction cancel_order
) : Runtime(std::move(algo), limit_order, market_order, cancel_order)
) :
Runtime(
std::move(algo), std::move(limit_order), std::move(market_order),
std::move(cancel_order)
)
{}

CppRuntime::~CppRuntime()
{
// TODO: shoudl not do
dlclose(dl_handle_);
close(fd_);
}

std::optional<std::string>
CppRuntime::init()
{
auto [fd, path] = get_temp_file();

fd_ = fd;
boost::filesystem::path temp_dir = boost::filesystem::temp_directory_path();
boost::filesystem::path temp_file =
temp_dir / boost::filesystem::unique_path("tempfile-%%%%-%%%%");

std::ofstream algo_file(path);
std::ofstream algo_file(temp_file.string());
algo_file << algo_ << std::flush;
algo_file.close();

dl_handle_ = dlopen(path.c_str(), RTLD_NOW);
std::string compiled_binary_path = common::compile_cpp(temp_file.string());

dl_handle_ = dlopen(compiled_binary_path.c_str(), RTLD_NOW);
if (dl_handle_ == nullptr) {
std::string err = dlerror();
close(fd_);
Expand All @@ -87,8 +98,8 @@ CppRuntime::init()
on_account_update_func_ =
reinterpret_cast<OnAccountUpdateFunc>(dlsym(dl_handle_, "on_account_update"));

if (!init_func || !on_trade_update_func_ || !on_orderbook_update_func_
|| !on_account_update_func_) {
if (init_func == nullptr || on_trade_update_func_ == nullptr
|| on_orderbook_update_func_ == nullptr || on_account_update_func_ == nullptr) {
dlclose(dl_handle_);
close(fd_);
return fmt::format("[linter] failed to dynamically load functions");
Expand All @@ -101,36 +112,26 @@ CppRuntime::init()

void
CppRuntime::fire_on_trade_update(
common::Ticker ticker, common::Side side, double price, double quantity
common::Ticker ticker, common::Side side, float price, float quantity
) const
{
on_trade_update_func_(
strategy_object_, ticker, side, static_cast<double>(quantity),
static_cast<double>(price)
);
on_trade_update_func_(strategy_object_, ticker, side, quantity, price);
}

void
CppRuntime::fire_on_orderbook_update(
common::Ticker ticker, common::Side side, double price, double quantity
common::Ticker ticker, common::Side side, float price, float quantity
) const
{
on_orderbook_update_func_(
strategy_object_, ticker, side, static_cast<double>(quantity),
static_cast<double>(price)
);
on_orderbook_update_func_(strategy_object_, ticker, side, quantity, price);
}

void
CppRuntime::fire_on_account_update(
common::Ticker ticker, common::Side side, double price, double quantity,
double capital
common::Ticker ticker, common::Side side, float price, float quantity, float capital
) const
{
on_account_update_func_(
strategy_object_, ticker, side, static_cast<double>(quantity),
static_cast<double>(price), static_cast<double>(capital)
);
on_account_update_func_(strategy_object_, ticker, side, quantity, price, capital);
}

} // namespace nutc::lint
Loading

0 comments on commit 0184576

Please sign in to comment.