WCCommon is a collection of frequently used functions and tools in HFT development.
Fast, simple and user-friendly utils to read and write CSV file, very efficient for large file. Watch the progress bar and leave off with confidence.
using Depth = std::tuple<
uint32_t ,
wcc::NumericTime,
double ,
double ,
unsigned long ,
double ,
unsigned long ,
char ,
wcc::NumericTime
>;
static constexpr std::size_t k_len = 1<<20;
std::vector<Depth> depths;
TEST_CASE("CsvIOTest", "[WCCommon]") {
std::string test_file_name = "CsvIOTest.csv";
generate_depth(depths, k_len);
SECTION("write") {
write_csv(test_file_name, depths);
}
SECTION("read") {
std::vector<Depth> read_depths;
read_csv(test_file_name, read_depths);
}
SECTION("read with filter") {
std::vector<Depth> read_depths;
read_csv(test_file_name, read_depths, [](Depth const& depth){
return std::get<DepthField::Instrument>(depth) > (k_len + 1) / 2;
});
}
}
A convenient function to configure loggers in spdlog according to an yaml file.
%YAML 1.2
---
default_format : "[%m-%d %H:%M:%S.%f] [%-8l] [%-12n] %v"
default_level : "info"
default_log_dir : "./log/${today}"
default_log_prefix: "WCCommon"
sinks:
- stdout
- basic_file
loggers:
- main
- default
set_error_loggers:
- default
set_debug_loggers:
- default
And loggers are created and configured as
int main() {
wcc::config_log("LogConfig.yaml");
auto p_logger = wcc::get_logger("main");
p_logger->debug("This is a {} message", "debug");
p_logger->info("pi = {:.4f}", 3.1415926);
p_logger->warn("The answer is {:6d}", 42);
p_logger->error("{:06d} is SZ stock", 5);
p_logger->critical("{} is not a {}", "cat", "fruit");
return 0;
}
An fast and handy class to store and calculate trading time
#include "NumericTime.h"
using wcc::NumericTime;
TEST_CASE("NumericTimeTest", "[NumericTime]") {
SECTION("InitInt") {
REQUIRE(NumericTime(103159010) == NumericTime(10, 31, 59, 10));
}
SECTION("InitStr") {
REQUIRE(NumericTime("10:31:59.010") == NumericTime(10, 31, 59, 10));
}
SECTION("Invalid convert") {
REQUIRE(NumericTime(23, 59, 59, 1000)== NumericTime(0, 0, 0, 0));
}
SECTION("GetField") {
auto ntime = NumericTime(10, 31, 59, 10);
REQUIRE(ntime.hour() == 10);
REQUIRE(ntime.min() == 31);
REQUIRE(ntime.sec() == 59);
REQUIRE(ntime.ms() == 10);
}
SECTION("ToStr") {
REQUIRE(NumericTime(10, 31, 59, 10).str() == "10:31:59.010");
}
SECTION("Negative time") {
REQUIRE(NumericTime(10, 31, 59, -1) == NumericTime(10, 31, 58, 999));
REQUIRE(NumericTime(10, 31, -1, 10) == NumericTime(10, 30, 59, 10));
REQUIRE(NumericTime(10, -1, 59, 10) == NumericTime( 9, 59, 59, 10));
REQUIRE(NumericTime(-1, 31, 59, 10) == NumericTime(23, 31, 59, 10));
}
SECTION("Now") {
NumericTime now_time = NumericTime::now();
std::string now_str = now_time.str();
std::cout << "Now = " << now_str << std::endl;
}
}
Show a progress bar to happily wait for a result.
TEST_CASE("ProgressBarTest", "[WCCommon]") {
SECTION("show") {
std::size_t data_len = 128;
wcc::ProgressBar prog_bar(70, std::cout);
for(std::size_t i = 0; i < data_len ; ++i) {
// proccessing data
std::this_thread::sleep_for(std::chrono::milliseconds(20));
prog_bar.update( (i + 1) * 100 / data_len ); // input ranges from 0(start) to 100(completed)
}
prog_bar.finish();
}
}
Get field of a given yaml file, replace "${today}" string as its value, and print clear error message if field not exist or type bad conversion.
%YAML 1.2
---
data_folder : Data/${today}
trader_id : 42
username : username
server_ip : 127.0.0.1
server_port : 8888
Get field with code
#include "YAMLGetField.h"
TEST_CASE("YAMLGetFieldTest", "[WCCommon]") {
SECTION("YAMLGetField") {
std::string config_file("YAMLGetFieldTest.yaml");
wcc::check_file_exist(config_file);
std::string today_str { wcc::get_today_str() };
YAML::Node config = YAML::LoadFile(config_file);
std::string data_folder; YAML_GET_FIELD(data_folder, config, data_folder);
uint64_t trader_id ; YAML_GET_FIELD(trader_id , config, trader_id );
std::string username ; YAML_GET_FIELD(username , config, username );
std::string server_ip ; YAML_GET_FIELD(server_ip , config, server_ip );
uint32_t server_port; YAML_GET_FIELD(server_port, config, server_port);
REQUIRE(data_folder == fmt::format("Data/{}", today_str));
REQUIRE(trader_id == 42);
REQUIRE(username == "username");
REQUIRE(server_ip == "127.0.0.1");
REQUIRE(server_port == 8888);
}
}
Convert GBK strings to UTF8 encoding strings;
namespace wcc {
// get today string as format YYYYMMDD
inline std::string get_today_str() ;
// get current time string as format HHMMSS
inline std::string get_time_str() ;
// create folder if the folder not exist
// returns:
// 0: if the folder has already been exist
// 1: if the folder is created
// throw:
// runtime_error: if not have permission or need recursive create
inline int mkdir_if_not_exist(const std::string& folder) ;
// check if file exist
// throw:
// runtime_error: if file not exist or not have permission to read
inline void check_file_exist(std::string const& name) ;
// create and management *nix FIFO
class FIFOInfo;
}