Skip to content
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
12 changes: 12 additions & 0 deletions .github/workflows/ubuntu-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,24 @@ jobs:
- name: Run metatrader_file_bridge_test
run: ./build-linux/metatrader_file_bridge_test --gtest_brief=1

- name: Build metatrader_file_command_writer_test
run: cmake --build build-linux --target metatrader_file_command_writer_test -j

- name: Run metatrader_file_command_writer_test
run: ./build-linux/metatrader_file_command_writer_test --gtest_brief=1

- name: Build metatrader_file_bridge_smoke
run: cmake --build build-linux --target metatrader_file_bridge_smoke -j

- name: Run metatrader_file_bridge_smoke
run: ./build-linux/metatrader_file_bridge_smoke --self-test

- name: Build metatrader_file_command_writer_smoke
run: cmake --build build-linux --target metatrader_file_command_writer_smoke -j

- name: Run metatrader_file_command_writer_smoke
run: ./build-linux/metatrader_file_command_writer_smoke --self-test

- name: Build market_data_subscription_contract_test
run: cmake --build build-linux --target market_data_subscription_contract_test -j

Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/windows-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,23 @@ jobs:
cmake --build build-windows --config Debug --target
metatrader_file_config_include_test
metatrader_file_bridge_test
metatrader_file_command_writer_test
bridge_umbrella_include_test

- name: Build MetaTrader file smoke example
run: cmake --build build-windows --config Debug --target metatrader_file_bridge_smoke

- name: Build MetaTrader file command writer smoke example
run: cmake --build build-windows --config Debug --target metatrader_file_command_writer_smoke

- name: Run MetaTrader file tests
shell: pwsh
run: |
$env:PATH = "$PWD\build-windows\bin;$PWD\build-windows\Debug;$env:PATH"
.\build-windows\Debug\metatrader_paths_test.exe --gtest_brief=1
.\build-windows\Debug\metatrader_file_config_include_test.exe --gtest_brief=1
.\build-windows\Debug\metatrader_file_bridge_test.exe --gtest_brief=1
.\build-windows\Debug\metatrader_file_command_writer_test.exe --gtest_brief=1
.\build-windows\Debug\bridge_umbrella_include_test.exe --gtest_brief=1
.\build-windows\Debug\metatrader_file_bridge_smoke.exe --self-test
.\build-windows\Debug\metatrader_file_command_writer_smoke.exe --self-test
47 changes: 47 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,52 @@ if(OPTIONX_BUILD_EXAMPLES)
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/copy_runtime_dlls.cmake"
)
endif()

add_executable(metatrader_file_command_writer_smoke examples/metatrader_file_command_writer_smoke.cpp)
target_compile_features(metatrader_file_command_writer_smoke PRIVATE cxx_std_17)

target_include_directories(metatrader_file_command_writer_smoke PRIVATE
${EXAMPLE_INCLUDE_DIRS}
${EXAMPLE_DEPS_INCLUDE_DIRS}
)

target_link_directories(metatrader_file_command_writer_smoke PRIVATE ${EXAMPLE_LIBRARY_DIRS})
target_compile_definitions(
metatrader_file_command_writer_smoke PRIVATE
${EXAMPLE_DEFINES}
LOGIT_BASE_PATH="${LOGIT_BASE_PATH_FWD}"
)
if(MINGW)
target_compile_options(metatrader_file_command_writer_smoke PRIVATE -Wa,-mbig-obj)
endif()
if(OPTIONX_LIGHTWEIGHT_BRIDGE_SMOKE_TESTS)
target_link_libraries(metatrader_file_command_writer_smoke PRIVATE ${EXAMPLE_LIBS})
if(WIN32)
target_link_libraries(metatrader_file_command_writer_smoke PRIVATE ${OPTIONX_WINDOWS_SYSTEM_LIBS})
endif()
else()
target_link_libraries(metatrader_file_command_writer_smoke PRIVATE ${EXAMPLE_LIBS} optionx_cpp)
endif()

if(OPTIONX_BUILD_DEPS AND NOT OPTIONX_LIGHTWEIGHT_BRIDGE_SMOKE_TESTS)
add_dependencies(metatrader_file_command_writer_smoke mdbx-static AES)
endif()

foreach(dll ${EXAMPLE_DLL_FILES})
add_custom_command(TARGET metatrader_file_command_writer_smoke POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${dll}" "$<TARGET_FILE_DIR:metatrader_file_command_writer_smoke>"
)
endforeach()

if(WIN32)
add_custom_command(TARGET metatrader_file_command_writer_smoke POST_BUILD
COMMAND ${CMAKE_COMMAND}
-DOPTIONX_RUNTIME_DLL_DIR="${EXAMPLE_BUILD_LIBS_DIR}/bin"
-DOPTIONX_RUNTIME_TARGET_DIR="$<TARGET_FILE_DIR:metatrader_file_command_writer_smoke>"
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/copy_runtime_dlls.cmake"
)
endif()
endif()

if(OPTIONX_BUILD_TESTS)
Expand Down Expand Up @@ -528,6 +574,7 @@ if(OPTIONX_BUILD_TESTS)
list(APPEND OPTIONX_LIGHTWEIGHT_TESTS
bridge_umbrella_include_test
metatrader_file_bridge_test
metatrader_file_command_writer_test
metatrader_file_config_include_test
)
endif()
Expand Down
165 changes: 165 additions & 0 deletions examples/metatrader_file_command_writer_smoke.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#include <optionx_cpp/bridges/metatrader_file.hpp>
#include <optionx_cpp/utils/json_comments.hpp>

#include <cstdlib>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <system_error>

namespace {

using optionx::bridges::metatrader_file::MetaTraderFileBridgeConfig;
using optionx::bridges::metatrader_file::MetaTraderFileCommandWriter;
using optionx::bridges::metatrader_file::MetaTraderFileTradeCommand;

bool has_arg(int argc, char** argv, const std::string& value) {
for (int i = 1; i < argc; ++i) {
if (argv[i] == value) {
return true;
}
}
return false;
}

std::string option_value(int argc, char** argv, const std::string& name) {
for (int i = 1; i + 1 < argc; ++i) {
if (argv[i] == name) {
return argv[i + 1];
}
}
return {};
}

std::filesystem::path smoke_root() {
return std::filesystem::temp_directory_path() /
"optionx-metatrader-file-command-writer-smoke";
}

MetaTraderFileBridgeConfig default_config(const bool self_test) {
MetaTraderFileBridgeConfig config;
config.bridge_id = 1;
config.client_id = "mql-smoke";
if (self_test || config.common_files_root.empty()) {
config.common_files_root = smoke_root().u8string();
}
return config;
}

bool load_config(const std::string& path, MetaTraderFileBridgeConfig& config) {
if (path.empty()) {
return true;
}

std::ifstream input(path);
if (!input) {
std::cerr << "Could not open config: " << path << '\n';
return false;
}

try {
std::ostringstream buffer;
buffer << input.rdbuf();
config.from_json(optionx::utils::parse_json_with_comments(buffer.str()));
} catch (const std::exception& ex) {
std::cerr << "Could not parse config: " << ex.what() << '\n';
return false;
}
return true;
}

std::string read_text_file(const std::filesystem::path& path) {
std::ifstream input(path, std::ios::binary);
std::ostringstream buffer;
buffer << input.rdbuf();
return buffer.str();
}

void print_usage() {
std::cout
<< "Usage: metatrader_file_command_writer_smoke [--self-test] [--config path]\n"
<< "Writes account.balance.get, signal.submit and trade.open commands to commands.ndjson.\n";
}

} // namespace

int main(int argc, char** argv) {
if (has_arg(argc, argv, "--help")) {
print_usage();
return 0;
}

const bool self_test = has_arg(argc, argv, "--self-test");
auto config = default_config(self_test);
if (!load_config(option_value(argc, argv, "--config"), config)) {
return 2;
}

const auto validation = config.validate();
if (!validation.first) {
std::cerr << "Invalid config: " << validation.second << '\n';
return 2;
}

if (self_test) {
std::error_code ec;
std::filesystem::remove_all(std::filesystem::u8path(config.common_files_root), ec);
}

try {
MetaTraderFileCommandWriter writer(config);

const auto balance = writer.account_balance_get("7", "smoke-balance");

MetaTraderFileTradeCommand signal;
signal.symbol = "EURUSD";
signal.order_type = "BUY";
signal.amount_value = "1.00";
signal.currency = "USD";
signal.duration_ms = 60000;
signal.signal_name = "writer_smoke";
signal.account_id = "7";
signal.id = "smoke-signal";
signal.idempotency_key = "smoke-signal-idem";
signal.unique_hash = "smoke-signal-hash";
const auto submitted = writer.signal_submit(signal);

MetaTraderFileTradeCommand trade = signal;
trade.id = "smoke-trade";
trade.idempotency_key = "smoke-trade-idem";
trade.unique_hash = "smoke-trade-hash";
const auto opened = writer.trade_open(trade);

const auto content = read_text_file(writer.layout().commands_log());
std::cout << "MetaTrader command writer root: "
<< writer.layout().root.u8string() << '\n';
std::cout << "Commands log: "
<< writer.layout().commands_log().u8string() << '\n';
std::cout << "Wrote file_seq values: "
<< balance.file_seq << ", "
<< submitted.file_seq << ", "
<< opened.file_seq << '\n';
std::cout << content;

if (self_test) {
const bool ok =
content.find("\"account.balance.get\"") != std::string::npos &&
content.find("\"signal.submit\"") != std::string::npos &&
content.find("\"trade.open\"") != std::string::npos &&
content.find("\"file_seq\"") != std::string::npos &&
content.find("\"idempotency_key\"") != std::string::npos &&
content.find("\"valid_until_ms\"") != std::string::npos;
if (!ok) {
std::cerr << "Self-test did not find the expected command fields.\n";
return 3;
}
}
} catch (const std::exception& ex) {
std::cerr << "Smoke failed: " << ex.what() << '\n';
return 1;
}

return 0;
}
Loading
Loading