Skip to content

Commit

Permalink
[EN-7412] Implement DXFeedConnect sample
Browse files Browse the repository at this point in the history
  • Loading branch information
ttldtor committed Sep 6, 2023
1 parent cdfb5f2 commit 0f636a9
Show file tree
Hide file tree
Showing 11 changed files with 225 additions and 53 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ FetchContent_MakeAvailable(DxFeedGraalNativeSdk)
add_subdirectory(third_party/utfcpp-3.2.3)
set(FMT_INSTALL OFF)
add_subdirectory(third_party/fmt-10.0.0)
set(BUILD_TZ_LIB ON)
set(USE_SYSTEM_TZ_DB ON)
#set(BUILD_TZ_LIB ON)
#set(USE_SYSTEM_TZ_DB ON)
add_subdirectory(third_party/date-3.0.1)

# find_package(utf8cpp)
Expand Down
22 changes: 17 additions & 5 deletions include/dxfeed_graal_cpp_api/event/EventTypeEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ class DXFCPP_EXPORT EventTypeEnum {

const std::string name_;

const std::string className_;

// A flag that indicates that the current enum element is characterizing the Lasting (TICKER) event.
const bool isLasting_;

Expand All @@ -34,10 +36,11 @@ class DXFCPP_EXPORT EventTypeEnum {
// TimeSeries) event.
const bool isOnlyIndexed_;

EventTypeEnum(std::uint32_t id, std::string name, bool isLasting, bool isIndexed = false,
EventTypeEnum(std::uint32_t id, std::string name, std::string className, bool isLasting, bool isIndexed = false,
bool isTimeSeries = false) noexcept
: id_{id}, name_{std::move(name)}, isLasting_{isLasting}, isIndexed_{isIndexed || isTimeSeries},
isTimeSeries_{isTimeSeries}, isOnlyIndexed_{isIndexed && !isTimeSeries} {
: id_{id}, name_{std::move(name)}, className_{std::move(className)}, isLasting_{isLasting},
isIndexed_{isIndexed || isTimeSeries}, isTimeSeries_{isTimeSeries},
isOnlyIndexed_{isIndexed && !isTimeSeries} {
}

public:
Expand Down Expand Up @@ -69,7 +72,9 @@ class DXFCPP_EXPORT EventTypeEnum {

static const std::unordered_map<std::string, std::reference_wrapper<const EventTypeEnum>> ALL_BY_NAME;

explicit EventTypeEnum() noexcept : EventTypeEnum{static_cast<std::uint32_t>(-1), "INVALID", false} {
static const std::unordered_map<std::string, std::reference_wrapper<const EventTypeEnum>> ALL_BY_CLASS_NAME;

explicit EventTypeEnum() noexcept : EventTypeEnum{static_cast<std::uint32_t>(-1), "INVALID", "Invalid", false} {
}

/**
Expand All @@ -82,10 +87,17 @@ class DXFCPP_EXPORT EventTypeEnum {
/**
* @return The current enum element name
*/
const std::string &getName() const noexcept {
const std::string &getName() const & noexcept {
return name_;
}

/**
* @return The current enum element class name
*/
const std::string &getClassName() const & noexcept {
return className_;
}

bool operator==(const EventTypeEnum &eventTypeEnum) const noexcept {
return id_ == eventTypeEnum.id_;
}
Expand Down
2 changes: 2 additions & 0 deletions include/dxfeed_graal_cpp_api/internal/utils/CmdArgsUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,6 @@ struct DXFCPP_EXPORT CmdArgsUtils final {
*/
static std::unordered_set<std::reference_wrapper<const EventTypeEnum>> parseTypes(const std::string &types);
};

DXFCPP_EXPORT std::int64_t parseDateTimeOrPeriod(const std::string& string);
} // namespace dxfcpp
8 changes: 8 additions & 0 deletions include/dxfeed_graal_cpp_api/internal/utils/EnumUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,13 @@ namespace dxfcpp::enum_utils {
*/
DXFCPP_EXPORT std::string getEventTypeEnumNamesList(std::string separator = std::string(",")) noexcept;

/**
* Returns a separated list of class names of EventTypeEnum elements.
*
* @param separator The list separator
* @return A separated list of class names
*/
DXFCPP_EXPORT std::string getEventTypeEnumClassNamesList(std::string separator = std::string(",")) noexcept;

}

2 changes: 2 additions & 0 deletions include/dxfeed_graal_cpp_api/internal/utils/TimeFormat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ namespace dxfcpp {

/**
* Utility class for parsing and formatting dates and times in ISO-compatible format.
*
* TBD
*/
struct DXFCPP_EXPORT TimeFormat {
template <typename Entry, std::size_t maxSize = 256>
Expand Down
6 changes: 4 additions & 2 deletions samples/cpp/DxFeedConnect/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ endif ()

add_executable(${PROJECT_NAME} src/main.cpp)

target_include_directories(${PROJECT_NAME} PRIVATE ../../../third_party/range-v3-0.12/include)

if (DXFCXX_ENABLE_VS_ASAN)
target_compile_options(${PROJECT_NAME} PRIVATE "/fsanitize=address")
target_link_options(${PROJECT_NAME} PRIVATE "/fsanitize=address")
Expand All @@ -49,7 +51,7 @@ if (DXFCXX_ENABLE_VS_ASAN)
endif ()

if (DXFCXX_ENABLE_ASAN_UBSAN)
target_link_libraries(${PROJECT_NAME} PRIVATE dxfcxx date::date date::date-tz)
target_link_libraries(${PROJECT_NAME} PRIVATE dxfcxx )
target_compile_definitions(${PROJECT_NAME} PRIVATE DXFCPP_USE_DLLS)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:dxfcxx::graal>
Expand All @@ -59,7 +61,7 @@ if (DXFCXX_ENABLE_ASAN_UBSAN)
target_compile_options(${PROJECT_NAME} PRIVATE "-fsanitize=address" "-fsanitize=undefined")
target_link_options(${PROJECT_NAME} PRIVATE "-fsanitize=address" "-fsanitize=undefined")
else ()
target_link_libraries(${PROJECT_NAME} PRIVATE dxfcxx date::date date::date-tz)
target_link_libraries(${PROJECT_NAME} PRIVATE dxfcxx date::date)
target_compile_definitions(${PROJECT_NAME} PRIVATE DXFCPP_USE_DLLS)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different
$<TARGET_FILE:dxfcxx::graal>
Expand Down
29 changes: 17 additions & 12 deletions samples/cpp/DxFeedConnect/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
#include <dxfeed_graal_cpp_api/api.hpp>

#include <atomic>
#include <chrono>
#include <mutex>
#include <date/date.h>
#include <date/tz.h>
#include <range/v3/all.hpp>
#include <string>

using namespace dxfcpp;
using namespace dxfcpp::literals;
Expand All @@ -22,7 +23,8 @@ DxFeedConnect <address> <types> <symbols> [<time>]
To pass an authorization token, add to the address: "[login=entitle:<token>]",
e.g.: demo.dxfeed.com:7300[login=entitle:<token>]
types - Is comma-separated list of dxfeed event types ()" +
dxfcpp::enum_utils::getEventTypeEnumNamesList() + R"().
dxfcpp::enum_utils::getEventTypeEnumNamesList() + " or " +
dxfcpp::enum_utils::getEventTypeEnumClassNamesList() + R"().
symbols - Is comma-separated list of symbol names to get events for (e.g. "IBM,AAPL,MSFT").
for Candle event specify symbol with aggregation like in "AAPL{=d}"
time - Is from-time for history subscription in standard formats.
Expand All @@ -36,18 +38,14 @@ DxFeedConnect <address> <types> <symbols> [<time>]
123456789 - value-in-milliseconds
Examples:
DXFeedConnect demo.dxfeed.com:7300 Quote,Trade MSFT,IBM
DXFeedConnect demo.dxfeed.com:7300 TimeAndSale AAPL
DXFeedConnect demo.dxfeed.com:7300 Candle AAPL{=d} 20230201Z)";
DxFeedConnect demo.dxfeed.com:7300 Quote,Trade MSFT,IBM
DxFeedConnect demo.dxfeed.com:7300 TimeAndSale AAPL
DxFeedConnect demo.dxfeed.com:7300 Candle AAPL{=d} 20230901Z)";

std::cout << usageString << std::endl;
}

int main(int argc, char *argv[]) {
//std::cout << date::current_zone()->name() << std::endl;

return 0;

if (argc < 4) {
printUsage();

Expand All @@ -61,9 +59,10 @@ int main(int argc, char *argv[]) {
std::string address = argv[1];
auto types = CmdArgsUtils::parseTypes(argv[2]);
auto symbols = CmdArgsUtils::parseSymbols(argv[3]);
auto time = -1ULL;

if (argc >= 5) {
// std::chrono::parse
time = parseDateTimeOrPeriod(argv[4]);
}

// Create an endpoint and connect to specified address.
Expand All @@ -82,7 +81,13 @@ int main(int argc, char *argv[]) {
});

// Add symbols.
sub->addSymbols(symbols);
if (time != -1) {
sub->addSymbols(symbols | ranges::views::transform([time](const auto &s) {
return TimeSeriesSubscriptionSymbol(s, time);
}));
} else {
sub->addSymbols(symbols);
}

std::cin.get();

Expand Down
3 changes: 2 additions & 1 deletion samples/cpp/DxFeedFileParser/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ DxFeedFileParser <file> <type> <symbol>
Where:
file - Is a file name.
types - Is comma-separated list of dxfeed event types ()" +
dxfcpp::enum_utils::getEventTypeEnumNamesList() + R"().
dxfcpp::enum_utils::getEventTypeEnumNamesList() + " or " +
dxfcpp::enum_utils::getEventTypeEnumClassNamesList() + R"().
symbols - Is comma-separated list of symbol names to get events for (e.g. "IBM,AAPL,MSFT").)";

std::cout << usageString << std::endl;
Expand Down
61 changes: 42 additions & 19 deletions src/event/EventTypeEnum.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,32 @@

namespace dxfcpp {

const EventTypeEnum EventTypeEnum::QUOTE{DXFG_EVENT_QUOTE, "QUOTE", true};
const EventTypeEnum EventTypeEnum::PROFILE{DXFG_EVENT_PROFILE, "PROFILE", true};
const EventTypeEnum EventTypeEnum::SUMMARY{DXFG_EVENT_SUMMARY, "SUMMARY", true};
const EventTypeEnum EventTypeEnum::GREEKS{DXFG_EVENT_GREEKS, "GREEKS", true, true, true};
const EventTypeEnum EventTypeEnum::CANDLE{DXFG_EVENT_CANDLE, "CANDLE", true, true, true};
const EventTypeEnum EventTypeEnum::QUOTE{DXFG_EVENT_QUOTE, "QUOTE", "Quote", true};
const EventTypeEnum EventTypeEnum::PROFILE{DXFG_EVENT_PROFILE, "PROFILE", "Profile", true};
const EventTypeEnum EventTypeEnum::SUMMARY{DXFG_EVENT_SUMMARY, "SUMMARY", "Summary", true};
const EventTypeEnum EventTypeEnum::GREEKS{DXFG_EVENT_GREEKS, "GREEKS", "Greeks", true, true, true};
const EventTypeEnum EventTypeEnum::CANDLE{DXFG_EVENT_CANDLE, "CANDLE", "Candle", true, true, true};

// const EventTypeEnum EventTypeEnum::DAILY_CANDLE{DXFG_EVENT_DAILY_CANDLE, "DAILY_CANDLE", true, true, true};
// const EventTypeEnum EventTypeEnum::DAILY_CANDLE{DXFG_EVENT_DAILY_CANDLE, "DAILY_CANDLE", "DailyCandle", true, true,
// true};

const EventTypeEnum EventTypeEnum::UNDERLYING{DXFG_EVENT_UNDERLYING, "UNDERLYING", true, true, true};
const EventTypeEnum EventTypeEnum::THEO_PRICE{DXFG_EVENT_THEO_PRICE, "THEO_PRICE", true, true, true};
const EventTypeEnum EventTypeEnum::TRADE{DXFG_EVENT_TRADE, "TRADE", true};
const EventTypeEnum EventTypeEnum::TRADE_ETH{DXFG_EVENT_TRADE_ETH, "TRADE_ETH", true};
const EventTypeEnum EventTypeEnum::CONFIGURATION{DXFG_EVENT_CONFIGURATION, "CONFIGURATION", true};
const EventTypeEnum EventTypeEnum::MESSAGE{DXFG_EVENT_MESSAGE, "MESSAGE", false};
const EventTypeEnum EventTypeEnum::TIME_AND_SALE{DXFG_EVENT_TIME_AND_SALE, "TIME_AND_SALE", false, true, true};
const EventTypeEnum EventTypeEnum::UNDERLYING{DXFG_EVENT_UNDERLYING, "UNDERLYING", "Underlying", true, true, true};
const EventTypeEnum EventTypeEnum::THEO_PRICE{DXFG_EVENT_THEO_PRICE, "THEO_PRICE", "TheoPrice", true, true, true};
const EventTypeEnum EventTypeEnum::TRADE{DXFG_EVENT_TRADE, "TRADE", "Trade", true};
const EventTypeEnum EventTypeEnum::TRADE_ETH{DXFG_EVENT_TRADE_ETH, "TRADE_ETH", "TradeETH", true};
const EventTypeEnum EventTypeEnum::CONFIGURATION{DXFG_EVENT_CONFIGURATION, "CONFIGURATION", "Configuration", true};
const EventTypeEnum EventTypeEnum::MESSAGE{DXFG_EVENT_MESSAGE, "MESSAGE", "Message", false};
const EventTypeEnum EventTypeEnum::TIME_AND_SALE{
DXFG_EVENT_TIME_AND_SALE, "TIME_AND_SALE", "TimeAndSale", false, true, true};

// const EventTypeEnum EventTypeEnum::ORDER_BASE{DXFG_EVENT_ORDER_BASE, "ORDER_BASE", false, true};
// const EventTypeEnum EventTypeEnum::ORDER_BASE{DXFG_EVENT_ORDER_BASE, "ORDER_BASE", "OrderBase", false, true};

const EventTypeEnum EventTypeEnum::ORDER{DXFG_EVENT_ORDER, "ORDER", false, true};
const EventTypeEnum EventTypeEnum::ANALYTIC_ORDER{DXFG_EVENT_ANALYTIC_ORDER, "ANALYTIC_ORDER", false, true};
const EventTypeEnum EventTypeEnum::SPREAD_ORDER{DXFG_EVENT_SPREAD_ORDER, "SPREAD_ORDER", false, true};
const EventTypeEnum EventTypeEnum::SERIES{DXFG_EVENT_SERIES, "SERIES", false, true};
const EventTypeEnum EventTypeEnum::OPTION_SALE{DXFG_EVENT_OPTION_SALE, "OPTION_SALE", false, true};
const EventTypeEnum EventTypeEnum::ORDER{DXFG_EVENT_ORDER, "ORDER", "Order", false, true};
const EventTypeEnum EventTypeEnum::ANALYTIC_ORDER{DXFG_EVENT_ANALYTIC_ORDER, "ANALYTIC_ORDER", "AnalyticOrder", false,
true};
const EventTypeEnum EventTypeEnum::SPREAD_ORDER{DXFG_EVENT_SPREAD_ORDER, "SPREAD_ORDER", "SpreadOrder", false, true};
const EventTypeEnum EventTypeEnum::SERIES{DXFG_EVENT_SERIES, "SERIES", "Series", false, true};
const EventTypeEnum EventTypeEnum::OPTION_SALE{DXFG_EVENT_OPTION_SALE, "OPTION_SALE", "OptionSale", false, true};

const std::vector<std::reference_wrapper<const EventTypeEnum>> EventTypeEnum::ALL{
std::cref(QUOTE),
Expand Down Expand Up @@ -71,4 +74,24 @@ const std::unordered_map<std::string, std::reference_wrapper<const EventTypeEnum
{OPTION_SALE.getName(), std::cref(OPTION_SALE)},
};

const std::unordered_map<std::string, std::reference_wrapper<const EventTypeEnum>> EventTypeEnum::ALL_BY_CLASS_NAME{
{QUOTE.getClassName(), std::cref(QUOTE)},
{PROFILE.getClassName(), std::cref(PROFILE)},
{SUMMARY.getClassName(), std::cref(SUMMARY)},
{GREEKS.getClassName(), std::cref(GREEKS)},
{CANDLE.getClassName(), std::cref(CANDLE)},
{UNDERLYING.getClassName(), std::cref(UNDERLYING)},
{THEO_PRICE.getClassName(), std::cref(THEO_PRICE)},
{TRADE.getClassName(), std::cref(TRADE)},
{TRADE_ETH.getClassName(), std::cref(TRADE_ETH)},
// {CONFIGURATION.getClassName(), std::cref(CONFIGURATION)},
// {MESSAGE.getClassName(), std::cref(MESSAGE)},
{TIME_AND_SALE.getClassName(), std::cref(TIME_AND_SALE)},
{ORDER.getClassName(), std::cref(ORDER)},
{ANALYTIC_ORDER.getClassName(), std::cref(ANALYTIC_ORDER)},
{SPREAD_ORDER.getClassName(), std::cref(SPREAD_ORDER)},
{SERIES.getClassName(), std::cref(SERIES)},
{OPTION_SALE.getClassName(), std::cref(OPTION_SALE)},
};

} // namespace dxfcpp
Loading

0 comments on commit 0f636a9

Please sign in to comment.