GithubHelp home page GithubHelp logo

crypto-chassis / ccapi Goto Github PK

View Code? Open in Web Editor NEW
528.0 38.0 185.0 61.95 MB

A header-only C++ library for interacting with crypto exchanges. Bindings for Python, Java, C#, Go, and Javascript are provided.

Home Page: https://discord.gg/b5EKcp9s8T

License: MIT License

Shell 0.03% C++ 93.38% CMake 2.37% C 1.63% Python 0.50% SWIG 0.01% Java 0.58% C# 0.47% Go 0.57% JavaScript 0.46%
algo-trading api arbitrage automated-trading bitcoin c-plus-plus crypto cryptocurrency exchange library

ccapi's People

Contributors

andynavy23 avatar brndnmtthws avatar broban avatar brucewaynebrucewayne avatar cryptochassis avatar donzthefonz avatar enricodetoma avatar evanaze avatar fedeitc avatar kizzx2 avatar markysha avatar meansquarederror avatar mrrdrr avatar parkesb avatar shubhkabra avatar sirotopr avatar trescommas avatar vakakav avatar woonsangcho avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ccapi's Issues

unable to get trades from binance family

We can try some examples, including:

Subscription subscription("binance", "ETHBTC", CCAPI_TRADE, "");

Subscription trade_subscription("binance-us", "ethusd", CCAPI_TRADE, "")

outputs:

terminate called after throwing an instance of 'std::out_of_range'
  what():  map::at

ErisX Integration

  • Market data subscription: order book, trade.
  • Order entry: create order, cancel order, retrieve order status, retrieve open orders, cancel open orders.

enable post only order when available.

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

FTX services don't correctly escape numbers represented in scientific notation

Describe the bug
FTX orderbook sporadically contains entries represented in scientific notation which the quoting regex doesn't handle.

To Reproduce
subscribe to FTX market data feed with logging enabled and CCAPI_ENABLE_LOG_ERROR defined.

Expected behavior
Numbers represented in scientific notation should be correctly escaped.

Additional context

A quick grep of the codebase shows that some of the exchanges handle this and other don't. Shouldn't this logic be exchange agnostic, as it's based on the json standard for number representation? Below is a link to Doug Crockford's regex for parsing numbers. Perhaps this could be added as a common utility which can then be used across the various exchanges?

https://github.com/douglascrockford/JSON-js/blob/594c8fa5f8e3fb38b0977f1ff8a87e9d709e7db1/json2.js#L166

Multiple private subscriptions

Describe the bug
Subscribing to both the CCAPI_EM_ORDER_UPDATE and CCAPI_EM_PRIVATE_TRADE channels as well as orderbook updates on FTX is resulting in the following message:

Message [type = GENERIC_ERROR, recapType = UNKNOWN, time = 2021-05-25T18:07:55.277796000Z, timeReceived = 2021-05-25T18:07:55.277796000Z, elementList = [ Element [nameValueMap = {ERROR_MESSAGE=timer: The operation was aborted, category: websocketpp.transport}] ], correlationIdList = [ ]]

To Reproduce
Steps to reproduce the behavior:

Subscription spotDepthSub("ftx", "BTC/USD", CCAPI_MARKET_DEPTH, "", "BTC");
Subscription perpDepthSub("ftx", "ETH/USD", CCAPI_MARKET_DEPTH, "", "ETH");
Subscription ordersSub("ftx"," ", CCAPI_EM_ORDER_UPDATE, "", "ORDERS");
Subscription fillsSub("ftx", "", CCAPI_EM_PRIVATE_TRADE, "", "FILLS");

session.subscribe({spotDepthSub, perpDepthSub, fillsSub, ordersSub});

Expected behavior
No error and receive events on both private fill and order channels plus book updates.

Additional Context
The strange thing is when I try to debug with a debugger it appears to work, not tracked down why this is the case perhaps build setting or XCode is using a different version of clang.

I've added a print statement to Service::connectionAddressToString to print the connection address. In the working example the connection address is different for the book, order and fills subscriptions. In the non-working case the address is always the same, which looks wrong. Any ideas what could be causing this?

Market Order

How may I execute a market order, please? A short code snippet would be helpful.
Thanks!

Issues running app - spot_market_making, kParseErrorDocumentEmpty exception thrown.

Running the spot_market_making binary with kraken as the exchange generates the following in either Backtest, Paper or Live mode:

[2022-05-24T19:24:19.629910626Z] ******** Trading mode is paper! ********
terminate called after throwing an instance of 'std::runtime_error'
what(): kParseErrorDocumentEmpty
Aborted (core dumped)

I've set all necessary env variables based on the 'config.env.example' file.
Your assistance is greatly appreciated.
Evan

Failed to specialize function template 'unknown-type date::parse

On Windows (MSVC) get this error during compile

ccapi_util_private.h:278: Error: C2893: Failed to specialize function template 'unknown-type date::parse(const std::basic_string<CharT,Traits,Alloc> &,Parsable &)'
......\contrib\ccapi_cpp/ccapi_date.h(5506): note: see declaration of 'date::parse'
......\contrib\ccapi_cpp/ccapi_util_private.h(278): note: With the following template arguments:
......\contrib\ccapi_cpp/ccapi_util_private.h(278): note: 'Parsable=ccapi::TimePoint'
......\contrib\ccapi_cpp/ccapi_util_private.h(278): note: 'CharT=char'
......\contrib\ccapi_cpp/ccapi_util_private.h(278): note: 'Traits=std::char_traits'
......\contrib\ccapi_cpp/ccapi_util_private.h(278): note: 'Alloc=std::allocator'

Error comparing decimals values with enableCheckOrderBookCrossed = true

Hi team,
when the enableCheckOrderBookCross is true and checks that ask greater than bid always the function return false when it compares big decimals. Please, you can see the error in Huobi with trxbtc.

@"0x70000d080000: [2020-12-13T11:31:46.489025000Z] {ccapi_market_data_service.h:1323} INFO requestString = {"sub":"market.trxbtc.depth.step0"}\r\n"
@"0x70000d080000: [2020-12-13T11:31:55.121450000Z] {ccapi_market_data_service.h:1128} ERROR bid = 1.51E-6\r\n"
@"0x70000d080000: [2020-12-13T11:31:55.121487000Z] {ccapi_market_data_service.h:1129} ERROR ask = 1.5113E-6\r\n"
@"0x70000d080000: [2020-12-13T11:31:55.121494000Z] {ccapi_market_data_service.h:455} ERROR lastNToString(snapshotBid, 1) = {1.51E-6=100000, }\r\n"
@"0x70000d080000: [2020-12-13T11:31:55.121514000Z] {ccapi_market_data_service.h:456} ERROR firstNToString(snapshotAsk, 1) = {1.5113E-6=6645.2, }\r\n"
@"0x70000d080000: [2020-12-13T11:31:55.121548000Z] {ccapi_market_data_service.h:1144} ERROR incorrect states found: connection = WsConnection [id = 0x10340e620, url = wss://api-aws.huobi.pro/ws, instrumentGroup = , subscriptionList = [ Subscription [exchange = huobi, instrument = trxbtc, field = MARKET_DEPTH, optionMap = {CONFLATE_GRACE_PERIOD_MILLISECONDS=-1, CONFLATE_INTERVAL_MILLISECONDS=0, MARKET_DEPTH_MAX=2}, correlationId = 0, credential = {}, serviceName = market_data] ], status = OPEN]

0.000001511 (BID) is lower than 0.0000015117

BR,
Naza

ORDER U{DATE subscription on Kraken, only receiving one message.

How may I retrieve order updates on Kraken? I'm subscribing via the line of code below:
_Subscription subscription("Kraken", "ETH-USD", "ORDER_UPDATE");
I only receive one update with a STATUS, of "pending" despite the order being completely filled.
Any help would be greatly appreciated.

Thanks
Evan

Feature request - making book update messages available

What is your thought on making individual update messages available to the end-user?

Currently, the end-result of book update messages are available, through, e.g.,

Subscription subscription("coinbase", "BTC-USD", "MARKET_DEPTH", "MARKET_DEPTH_MAX=10");

The update messages wsMessageList are processed via the following function, and no longer forwarded to the end-user.

https://github.com/crypto-chassis/ccapi_cpp/blob/8efe25d646e843f04dd74173d5f621cb0d5225ed/include/ccapi_cpp/service/ccapi_market_data_service.h#L433

It would be a great enhancement if such a feature is available in a user-friendly manner.

Telegram Account Issue

We are experiencing an account issue on Telegram and have escalated it to their support team for resolution. Meanwhile, please join our Discord server for immediate discussions and urgent issues:

https://discord.gg/b5EKcp9s8T

We sincerely apologize for the inconvenience.

Support Windows build for Python bindings

Describe the solution you'd like
SWIG was used to create Python bindings for this library. Currently the procedure documented at https://github.com/crypto-chassis/ccapi/tree/v3.4.2#python isn't applicable for creating Python bindings on Windows. Modify the CMake files used in the build process to create successful Python bindings using MinGW (if you can also make it work for MSVC that will be great, otherwise only MinGW is fine). Document the successful build procedure in this ticket.

Is backtest mode support microseconds history data ?

Thanks for the great repo!
I saw the config files writes the history data format is 'time_seconds,price,size,is_buyer_maker',
So I'm wondering if the backtest mode support more higher frequency than seconds? (some data I collect myself through websocket to exchanges ) Do I need to do some modifcation in source and config file?

another small question, by using the api crpyto-chassis provided, how to download a more frequent data such as less than one seconds? or maby I can only collect by myself ?

Missing symbols.

Given a vector of 9 symbols and I am trying to access the data stream from Binance spot.
I am trying to save the data stream I am receiving in the CSV file but somehow randomly it is missing one or two or sometimes 5 out of 9 symbols for a given timestamp.

Code

  1. Go to 'https://github.com/hachi-27/Show/blob/main/main.cpp' to see the modified implementation to perform the action.
  2. I have used if/else block to identify the point to reset the CSV after completing one round of symbol lists.
  3. The code is taken and modified from your save_to_csv branch.

Expected behavior
All 9 symbol data is on the file every 3 seconds but the program loses track randomly and it misses the stream of some symbol at any given time. The logic seems to be correct to me and I don't know what else is going wrong but it missing data quite often

Screenshots
Screenshot (42)
As you can see data is missing in the file as time goes forward. But it'll return back to normal after 2 3 iterations then it'll show a full list of symbols and but then it'll again miss some symbols and so on.

Additional context
I am using binance to extract the spot data every 3 sec and if you need additional info on the issue please do let me know.

cannot find OpenSSL on Centos 8

Describe the bug

CMake Error at /usr/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:165 (message):
Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY) (found
version "1.1.1g")

To Reproduce
Steps to reproduce the behavior:
mkdir app/build
cd app/build
rm -rf * (if rebuild from scratch)
cmake -DCMAKE_PROJECT_INCLUDE=<path-to-user_specified_cmake_include> ..
cmake --build . -j

Expected behavior
I guess it should build

Additional context
openssl openssl-libs openssl-devel openssl-pkcs11 - are installed

adding -DOPENSSL_ROOT_DIR=? (/usr /usr/lib, ...) doesnt help

Get account balances via rest api

Is your feature request related to a problem? Please describe.
Getting account balances of assets via rest api is important: it allows syncing of information between the exchange and the customer's trading server; it allows algorithms to determine the right action to take knowing the balances.

Describe the solution you'd like
Add an operation type of GET_ACCOUNT_BALANCES to class Request. Add a type of GET_ACCOUNT_BALANCES to class Message. Take bitmex as an example.

  • Modify member function void convertReq(http::request<http::string_body>& req, const Request& request, const Request::Operation operation, const TimePoint& now, const std::string& symbolId, const std::map<std::string, std::string>& credential) in include/ccapi_cpp/service/ccapi_execution_management_service_bitmex.h so that its switch statement can handle Request::Operation::GET_ACCOUNT_BALANCES. Use member function appendParam to handle optional parameter of ACCOUNT_ID and ASSET (the name of the asset such as "USD") for operation GET_ACCOUNT_BALANCES.

  • Modify member function std::vector<Message> convertTextMessageToMessage(const Request& request, const std::string& textMessage, const TimePoint& timeReceived) in include/ccapi_cpp/service/ccapi_execution_management_service.h so that its switch statement can handle Request::Operation::GET_ACCOUNT_BALANCES and adds a Message to its return. This Message will contain one or more Elements with each Element having a nameValueMap with keys: ACCOUNT_ID (optional), ASSET (optional), QUANTITY_AVAILABLE_FOR_TRADING (required, the amount of the asset available for trading).

  • Add appropriate unit tests on request conversions and response conversions.

Support websocket api to receive order updates (i.e. execution report)

Is your feature request related to a problem? Please describe.
Receiving execution reports on order and trade status in real time is important for high frequency trading.

Describe the solution you'd like
In include/ccapi_cpp/service/ccapi_execution_management_service.h some skeleton code was copy/paste'd from include/ccapi_cpp/service/ccapi_market_data_service.h which already support websocket api. To add support for a given exchange, we would override function void logonToExchange(const WsConnection& wsConnection, const TimePoint& tp) and function void onTextMessage(wspp::connection_hdl hdl, const std::string& textMessage, const TimePoint& timeReceived) in a concrete exchange implementation.

  • For logonToExchange implementation, depending on the exchange, it might need to send messages to the websocket connection which can be achieved by calling its existing void send(wspp::connection_hdl hdl, std::string const& payload, wspp::frame::opcode::value op, ErrorCode& ec). It might also need to send requests to some restful API endpoint, which can be achieved by calling its existing void sendRequest(const std::string& host, const std::string& port, const http::request<http::string_body>& req, std::function<void(const beast::error_code&)> errorHandler, std::function<void(const http::response<http::string_body>&)> responseHandler, long timeoutMilliSeconds). In particular the implementation will need to take care of authentication.
  • For onTextMessage, it would need to handle various text messages received from the websocket connection (protocol level and application level ping/pong/heartbeats have already been taken care of in the skeleton code). In particular, when a websocket message with data related to order updates (i.e. execution report) is received, the implementation needs to parse the websocket message using rapidjson, and create a Event with type SUBSCRIPTION_DATA which has one Message with type EXECUTION_MANAGEMENT_EVENTS which has many Elements with each element having its nameValueMap containing the final results (We'd discuss how to standardize the keys in this map). The Event is emitted via a call to this->eventHandler(event);.
  • Test the implementation end-to-end with one or more possible Events (e.g. create order). For other harder-to-test events (e.g. order matching), we'd have to rely on unit tests for quality assurance.

Support for subaccounts/program name

Describe the bug
rest_execution_management_simple doesn't appear to support subaccounts/program name despite the usage message indicating it does i.e. "Usage: <program name> get_open_orders <symbol>

To Reproduce

  1. build examples
  2. attempt to run rest_execution_management_simple example as usage suggests i.e. main get_open_orders BTCUSD

Expected behavior

Correct subaccount is passed to the api, in my case FTX. Instead I get either "Please provide the first command line argument from this list:" if passing the subaccount or if I leave out, then I get an error message from the api indicating I only have permissions for subaccount "foo".

It looks like the Request object doesn't support subaccounts.

Kucoin Future

Is your feature request related to a problem? Please describe.
I would like to get market data for Kucoin future but the normal one does not work.
Kucoin Futures

Describe the solution you'd like
I think the dev is pretty similar to what have been done for Binance, need a base class and extends it for the sport and future market.

Describe alternatives you've considered
doing the dev myselft but would like to know if it is in the pipeline already.

Additional context
I don't think it is a big dev as the API looks really similar to what have been coded for the spot API, need to have new URL and check the data has the same layout.

Using custom_service_class causes errors even using the default file given in ccapi/example/custom_service_class.

Describe the bug
I need to use a custom request method at deribit exchange for which I thought of using the custom_service_class but apparently, that file has some errors by default even without altering anything in the file, the file can't be compiled successfully.

To Reproduce
Steps to reproduce the behavior:

  1. Go to ccapi/example/src/custom_service_class
  2. Set the Env Var for the coinbase exchange i.e. API_KEY, SECRET & PASSPHRASE.
  3. make the file.
  4. See error

Error

/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:32:8: error: ‘void ccapi::ExecutionManagementServiceDeribitCustom::processSuccessfulTextMessageRest(int, const ccapi::Request&, const string&, const TimePoint&, ccapi::Queue<ccapi::Event>*)’ marked ‘override’, but does not override
   void processSuccessfulTextMessageRest(int statusCode, const Request& request, const std::string& textMessage, const TimePoint& timeReceived,
        ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp: In constructor ‘ccapi::ExecutionManagementServiceDeribitCustom::ExecutionManagementServiceDeribitCustom(std::function<void(ccapi::Event&, ccapi::Queue<ccapi::Event>*)>, ccapi::SessionOptions, ccapi::SessionConfigs, ccapi::Service::ServiceContextPtr)’:
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:15:106: error: no matching function for call to ‘ccapi::ExecutionManagementServiceDeribit::ExecutionManagementServiceDeribit(std::function<void(ccapi::Event&, ccapi::Queue<ccapi::Event>*)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, ccapi::Service::ServiceContextPtr&)’
       : ExecutionManagementServiceDeribit(eventHandler, sessionOptions, sessionConfigs, serviceContextPtr) {}
                                                                                                          ^
In file included from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/ccapi_session.h:118:0,
                 from /home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:1:
/home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:9:3: note: candidate: ccapi::ExecutionManagementServiceDeribit::ExecutionManagementServiceDeribit(std::function<void(ccapi::Event&)>, ccapi::SessionOptions, ccapi::SessionConfigs, ccapi::Service::ServiceContextPtr)
   ExecutionManagementServiceDeribit(std::function<void(Event& event)> eventHandler, SessionOptions sessionOptions, SessionConfigs sessionConfigs,
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:9:3: note:   no known conversion for argument 1 from ‘std::function<void(ccapi::Event&, ccapi::Queue<ccapi::Event>*)>’ to ‘std::function<void(ccapi::Event&)>’
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp: In member function ‘virtual void ccapi::ExecutionManagementServiceDeribitCustom::convertRequestForRestCustom(boost::beast::http::request<boost::beast::http::basic_string_body<char> >&, const ccapi::Request&, const TimePoint&, const string&, const std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&)’:
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:25:48: error: no matching function for call to ‘ccapi::ExecutionManagementServiceDeribitCustom::signRequest(boost::beast::http::request<boost::beast::http::basic_string_body<char> >&, const char [1], const std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&)’
           this->signRequest(req, "", credential);
                                                ^
In file included from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/ccapi_session.h:118:0,
                 from /home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:1:
/home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:65:8: note: candidate: void ccapi::ExecutionManagementServiceDeribit::signRequest(boost::beast::http::request<boost::beast::http::basic_string_body<char> >&, const string&, const TimePoint&, const std::map<std::__cxx11::basic_string<char>, std::__cxx11::basic_string<char> >&)
   void signRequest(http::request<http::string_body>& req, const std::string& body, const TimePoint& now, const std::map<std::string, std::string>& credential) {
        ^~~~~~~~~~~
/home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:65:8: note:   candidate expects 4 arguments, 3 provided
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp: In member function ‘void ccapi::ExecutionManagementServiceDeribitCustom::processSuccessfulTextMessageRest(int, const ccapi::Request&, const string&, const TimePoint&, ccapi::Queue<ccapi::Event>*)’:
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:55:50: error: no match for call to ‘(std::function<void(ccapi::Event&)>) (ccapi::Event&, ccapi::Queue<ccapi::Event>*&)’
           this->eventHandler(event, eventQueuePtr);
                                                  ^
In file included from /usr/include/c++/7/functional:58:0,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service.h:5,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:5,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/ccapi_session.h:118,
                 from /home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:1:
/usr/include/c++/7/bits/std_function.h:701:5: note: candidate: _Res std::function<_Res(_ArgTypes ...)>::operator()(_ArgTypes ...) const [with _Res = void; _ArgTypes = {ccapi::Event&}]
     function<_Res(_ArgTypes...)>::
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/std_function.h:701:5: note:   candidate expects 1 argument, 2 provided
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:59:138: error: no matching function for call to ‘ccapi::ExecutionManagementServiceDeribitCustom::processSuccessfulTextMessageRest(int&, const ccapi::Request&, const string&, const TimePoint&, ccapi::Queue<ccapi::Event>*&)’
         ExecutionManagementServiceDeribit::processSuccessfulTextMessageRest(statusCode, request, textMessage, timeReceived, eventQueuePtr);
                                                                                                                                          ^
In file included from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:5:0,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/ccapi_session.h:118,
                 from /home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:1:
/home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service.h:79:14: note: candidate: virtual void ccapi::ExecutionManagementService::processSuccessfulTextMessageRest(int, const ccapi::Request&, const string&, const TimePoint&)
 virtual void processSuccessfulTextMessageRest(int statusCode, const Request& request, const std::string& textMessage, const TimePoint& timeReceived) override {
              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service.h:79:14: note:   candidate expects 4 arguments, 5 provided
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/string:41,
                 from /usr/include/c++/7/stdexcept:39,
                 from /usr/include/c++/7/array:39,
                 from /usr/include/c++/7/tuple:39,
                 from /usr/include/c++/7/functional:54,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service.h:5,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/service/ccapi_execution_management_service_deribit.h:5,
                 from /home/ubuntu/project/options/ccapi/include/ccapi_cpp/ccapi_session.h:118,
                 from /home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:1:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = ccapi::ExecutionManagementServiceDeribitCustom; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}; _Tp = ccapi::ExecutionManagementServiceDeribitCustom]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = ccapi::ExecutionManagementServiceDeribitCustom; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}; _Tp = ccapi::ExecutionManagementServiceDeribitCustom; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<ccapi::ExecutionManagementServiceDeribitCustom>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39:   required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}; _Tp = ccapi::ExecutionManagementServiceDeribitCustom; _Alloc = std::allocator<ccapi::ExecutionManagementServiceDeribitCustom>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4:   required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = ccapi::ExecutionManagementServiceDeribitCustom; _Alloc = std::allocator<ccapi::ExecutionManagementServiceDeribitCustom>; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35:   required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<ccapi::ExecutionManagementServiceDeribitCustom>; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}; _Tp = ccapi::ExecutionManagementServiceDeribitCustom; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64:   required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<ccapi::ExecutionManagementServiceDeribitCustom>; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}; _Tp = ccapi::ExecutionManagementServiceDeribitCustom]’
/usr/include/c++/7/bits/shared_ptr.h:690:14:   required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = ccapi::ExecutionManagementServiceDeribitCustom; _Alloc = std::allocator<ccapi::ExecutionManagementServiceDeribitCustom>; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39:   required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = ccapi::ExecutionManagementServiceDeribitCustom; _Args = {std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&}]’
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:86:91:   required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘ccapi::ExecutionManagementServiceDeribitCustom::ExecutionManagementServiceDeribitCustom(std::function<void(ccapi::Event&)>&, ccapi::SessionOptions&, ccapi::SessionConfigs&, std::shared_ptr<ccapi::ServiceContext>&)’
  { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:13:3: note: candidate: ccapi::ExecutionManagementServiceDeribitCustom::ExecutionManagementServiceDeribitCustom(std::function<void(ccapi::Event&, ccapi::Queue<ccapi::Event>*)>, ccapi::SessionOptions, ccapi::SessionConfigs, ccapi::Service::ServiceContextPtr)
   ExecutionManagementServiceDeribitCustom(std::function<void(Event&, Queue<Event>*)> eventHandler, SessionOptions sessionOptions,
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/ubuntu/project/options/ccapi/example/src/custom_service_class/main.cpp:13:3: note:   no known conversion for argument 1 from ‘std::function<void(ccapi::Event&)>’ to ‘std::function<void(ccapi::Event&, ccapi::Queue<ccapi::Event>*)>’
src/custom_service_class/CMakeFiles/custom_service_class.dir/build.make:75: recipe for target 'src/custom_service_class/CMakeFiles/custom_service_class.dir/main.cpp.o' failed
make[2]: *** [src/custom_service_class/CMakeFiles/custom_service_class.dir/main.cpp.o] Error 1
CMakeFiles/Makefile2:723: recipe for target 'src/custom_service_class/CMakeFiles/custom_service_class.dir/all' failed
make[1]: *** [src/custom_service_class/CMakeFiles/custom_service_class.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2

Additional context

I have converted everything for Deribit exchange because I have access only to that exchange. But this is a compilation issue which is why it applies universally to all the exchanges. I am using Linux compiling with g++ 6.0 with C++14.
Let me know if I need to provide additional details.

Fix github workflow for checking C++ code style

Describe the bug
Currently github workflow defined by .github/workflows/check_cpp_code_style.yml.d doesn't work.

Expected behavior
The workflow, when triggered, should perform clang-format:
find . -type f -not -path "*/dependency/*" -not -path "*/build/*" \( -name "*.h" -or -name "*.cpp" \) | xargs clang-format -i -style="{BasedOnStyle: Google, ColumnLimit: 160}". Then if git diff produces nothing, it should be considered pass (otherwise fail).

Note
cpplint part does work as expected.

Get account positions via rest api

Is your feature request related to a problem? Please describe.
Getting account positions of derivatives via rest api is important: it allows syncing of information between the exchange and the customer's trading server; it allows algorithms to determine the right action to take knowing the positions.

Describe the solution you'd like
Add an operation type of GET_ACCOUNT_POSITIONS to class Request. Add a type of GET_ACCOUNT_POSITIONS to class Message. Take bitmex as an example.

  • Modify member function void convertReq(http::request<http::string_body>& req, const Request& request, const Request::Operation operation, const TimePoint& now, const std::string& symbolId, const std::map<std::string, std::string>& credential) in include/ccapi_cpp/service/ccapi_execution_management_service_bitmex.h so that its switch statement can handle Request::Operation::GET_ACCOUNT_POSITIONS. Use member function appendParam to handle optional parameter of ACCOUNT_ID and SYMBOL (i.e. the contract code) for operation GET_ACCOUNT_POSITIONS.

  • Modify member function std::vector<Message> convertTextMessageToMessage(const Request& request, const std::string& textMessage, const TimePoint& timeReceived) in include/ccapi_cpp/service/ccapi_execution_management_service.h so that its switch statement can handle Request::Operation::GET_ACCOUNT_POSITIONS and adds a Message to its return. This Message will contain one or more Elements with each Element having a nameValueMap with keys: ACCOUNT_ID (optional), SYMBOL (optional), POSITION_SIDE (required), QUANTITY (required), COST (required).

  • Add appropriate unit tests on request conversions and response conversions.

can give an example to Subscribe multiple exchange multiple symbols ?

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

Unsubscribe a channel

A great repo :)
I have a suggestion. Currently, Subscription::Status::UNSUBSCRIBING is defined, but this status is never used, and there is no function similar to "unsubscribe" defined in the "Session" class.

"Unsubscribe a channel" is very useful when I'm no longer interested in certain channels, which would otherwise waste network and processor resources.

Build with error when env is python 3.7 or above, cannot run in python 3.5 env

Describe the bug
I am trying to build and run the service with the use of python, below is the log of build and run
Log

(ccapi_env) macuser@MacBook-Pro binding % sh python-version-unix.sh
[INFO] Running
PATH_CORE=/Users/macuser/Desktop/GitRes/ccapi/binding
PATH_CMAKE_REQ=python-version-unix.cmake
macOS



Warning: [email protected] 1.1.1k is already installed and up-to-date.
To reinstall 1.1.1k, run:
  brew reinstall [email protected]
mkdir: build: File exists
-- BUILD_VERSION: ...
CMake Warning (dev) at /usr/local/Cellar/cmake/3.21.1/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (OpenSSL)
  does not match the name of the calling package (openssl).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.21.1/share/cmake/Modules/Findopenssl.cmake:574 (find_package_handle_standard_args)
  python-version-unix.cmake:49 (find_package)
  CMakeLists.txt:5 (project)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- CMAKE_BUILD_TYPE: Release
-- CMAKE_INSTALL_LIBDIR: lib
-- Build Python: ON
-- CCAPI_PROJECT_DIR: /Users/macuser/Desktop/GitRes/ccapi
CMake Warning (dev) at /usr/local/Cellar/cmake/3.21.1/share/cmake/Modules/FindPackageHandleStandardArgs.cmake:438 (message):
  The package name passed to `find_package_handle_standard_args` (OpenSSL)
  does not match the name of the calling package (openssl).  This can lead to
  problems in calling code that expects `find_package` result variables
  (e.g., `_FOUND`) to follow a certain pattern.
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.21.1/share/cmake/Modules/Findopenssl.cmake:574 (find_package_handle_standard_args)
  python-version-unix.cmake:49 (find_package)
  python/CMakeLists.txt:5 (project)
This warning is for project developers.  Use -Wno-dev to suppress it.

-- Found Python: /Users/macuser/anaconda3/envs/ccapi_env/bin/python3.5 (found version "3.5.6") found components: Interpreter Development Development.Module Development.Embed 
-- Python_VERSION: 3.5.6
-- Python_EXECUTABLE: /Users/macuser/anaconda3/envs/ccapi_env/bin/python3.5
-- Found python module: setuptools (found version "40.2.0")
-- Found python module: wheel (found version "0.36.2")
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/macuser/Desktop/GitRes/ccapi/binding/build
[ 25%] Swig compile /Users/macuser/Desktop/GitRes/ccapi/binding/swig_interface.i for python
/Users/macuser/Desktop/GitRes/ccapi/include/ccapi_cpp/ccapi_event.h:79: Warning 509: Overloaded method ccapi::Event::addMessage(ccapi::Message &) effectively ignored,
/Users/macuser/Desktop/GitRes/ccapi/include/ccapi_cpp/ccapi_event.h:78: Warning 509: as it is shadowed by ccapi::Event::addMessage(ccapi::Message const &).
/Users/macuser/Desktop/GitRes/ccapi/include/ccapi_cpp/ccapi_logger.h:110: Warning 454: Setting a pointer/reference variable may leak memory.
[ 25%] Built target ccapi_binding_python_swig_compilation
Consolidate compiler generated dependencies of target ccapi_binding_python
[ 75%] Building CXX object python/CMakeFiles/ccapi_binding_python.dir/ccapi_binding_python/swig_interfacePYTHON_wrap.cxx.o
[ 75%] Building CXX object python/CMakeFiles/ccapi_binding_python.dir/__/ccapi_logger.cpp.o

[100%] Linking CXX shared module ../lib/_ccapi_binding_python.so
[100%] Built target ccapi_binding_python
WARNING: '' not a valid package name; please use only .-separated package names in setup.py
/Users/macuser/anaconda3/envs/ccapi_env/lib/python3.5/site-packages/setuptools/dist.py:407: UserWarning: The version specified ('...') is an invalid version, this may not work as expected with newer versions of setuptools, pip, and PyPI. Please see PEP 440 for more details.
  "details." % self.metadata.version
running bdist_wheel
running build
running build_py
copying ccapi.py -> build/lib
copying _ccapi_binding_python.so -> build/lib
running build_ext
installing to build/bdist.macosx-10.6-x86_64/wheel
running install
running install_lib
creating build/bdist.macosx-10.6-x86_64
creating build/bdist.macosx-10.6-x86_64/wheel
copying build/lib/_ccapi_binding_python.so -> build/bdist.macosx-10.6-x86_64/wheel
copying build/lib/ccapi.py -> build/bdist.macosx-10.6-x86_64/wheel
running install_egg_info
running egg_info
writing top-level names to ccapi.egg-info/top_level.txt
writing ccapi.egg-info/PKG-INFO
writing dependency_links to ccapi.egg-info/dependency_links.txt
reading manifest file 'ccapi.egg-info/SOURCES.txt'
writing manifest file 'ccapi.egg-info/SOURCES.txt'
Copying ccapi.egg-info to build/bdist.macosx-10.6-x86_64/wheel/ccapi-...-py3.5.egg-info
running install_scripts
[WARNING] This wheel needs a higher macOS version than the version your Python interpreter is compiled against.  To silence this warning, set MACOSX_DEPLOYMENT_TARGET to at least 11_0 or recreate these files with lower MACOSX_DEPLOYMENT_TARGET:  
build/bdist.macosx-10.6-x86_64/wheel/_ccapi_binding_python.so[WARNING] This wheel needs a higher macOS version than the version your Python interpreter is compiled against.  To silence this warning, set MACOSX_DEPLOYMENT_TARGET to at least 11_0 or recreate these files with lower MACOSX_DEPLOYMENT_TARGET:  
build/bdist.macosx-10.6-x86_64/wheel/_ccapi_binding_python.socreating build/bdist.macosx-10.6-x86_64/wheel/ccapi-....dist-info/WHEEL
creating 'dist/ccapi-...-cp35-cp35m-macosx_11_0_x86_64.whl' and adding 'build/bdist.macosx-10.6-x86_64/wheel' to it
adding '_ccapi_binding_python.so'
adding 'ccapi.py'
adding 'ccapi-....dist-info/METADATA'
adding 'ccapi-....dist-info/WHEEL'
adding 'ccapi-....dist-info/top_level.txt'
adding 'ccapi-....dist-info/RECORD'
removing build/bdist.macosx-10.6-x86_64/wheel
[100%] Built target python_packaging
-- Install configuration: "Release"
Processing /Users/macuser/Desktop/GitRes/ccapi/binding/build/python/packaging
Building wheels for collected packages: ccapi
  Running setup.py bdist_wheel for ccapi: started
  Running setup.py bdist_wheel for ccapi: finished with status 'done'
  Stored in directory: /private/var/folders/rc/909vssg96nx8frmzmnhx0s9w0000gp/T/pip-ephem-wheel-cache-7vq85zxr/wheels/2b/62/67/00047fd5374cc52f956b927443bb129a1c1c174574cb2dc0c5
Successfully built ccapi
Installing collected packages: ccapi
  Found existing installation: ccapi ...
    Can't uninstall 'ccapi'. No files were found to uninstall.
Successfully installed ccapi-...
You are using pip version 10.0.1, however version 20.3.4 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.







(ccapi_env) macuser@MacBook-Pro binding % python
Python 3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 16:30:03) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
i>>> import ccapi
zsh: segmentation fault  python

And below is the sh script i used to run the installation:
python-version-unix.sh

#!/bin/sh
cd `dirname $0`
PATH_CORE=`pwd`
PATH_CMAKE_REQ=python-version-unix.cmake

echo "[INFO] Running"
echo "PATH_CORE=${PATH_CORE}"
echo "PATH_CMAKE_REQ=${PATH_CMAKE_REQ}"

######################
if [[ $OSTYPE == 'darwin'* ]]; then
  echo 'macOS'
  brew install openssl
  OPENSSL_ROOT_DIR=/usr/local/opt/openssl/
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
  echo "Linux Machine - Like Ubuntu"
  sudo apt-get install libssl-dev
fi

mkdir build
cd build
cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/[email protected] -DCMAKE_PROJECT_INCLUDE=${PATH_CORE}/${PATH_CMAKE_REQ} -DBUIL$
cmake --build . -j
cmake --install .

python-version-unix.cmake

add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
#
add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
#
add_compile_definitions(CCAPI_ENABLE_SERVICE_FIX)
#
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_COINBASE)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_GEMINI)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_KRAKEN)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BITSTAMP)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BITFINEX)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BITMEX)
#
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_US)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_USDS_FUTURES)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_COIN_FUTURES)
#
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_HUOBI)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_HUOBI_USDT_SWAP)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_HUOBI_COIN_SWAP)
#
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_OKEX)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_ERISX)
#
# add_compile_definitions(CCAPI_ENABLE_EXCHANGE_KUCOIN)
#
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_FTX)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_FTX_US)
#
add_compile_definitions(CCAPI_ENABLE_LOG_TRACE)
#
add_compile_definitions(CCAPI_ENABLE_LOG_DEBUG)
#
add_compile_definitions(CCAPI_ENABLE_LOG_INFO)
#
add_compile_definitions(CCAPI_ENABLE_LOG_WARN)
#
add_compile_definitions(CCAPI_ENABLE_LOG_ERROR)
#
add_compile_definitions(CCAPI_ENABLE_LOG_FATAL)
#
find_package(openssl REQUIRED)
find_package(ZLIB REQUIRED)
link_libraries(ZLIB::ZLIB)

sandbox rest and websocket urls

Is your feature request related to a problem? Please describe.
Can't test an app with the sandbox environment easily, need to modify the ccapi_macro.h file and input the sandbox Urls

Describe the solution you'd like
Would be nice to have a compile definition like CCAPI_ENABLE_SANSBOX_SERVICE that uses the sandbox urls instead of the production ones (could be separated for market data and execution)

Describe alternatives you've considered
modify the file manually each time.

Additional context
Everyone needs to test an app with the sandbox API before using the real produciton url.

Intermittent create order failures

Describe the bug
Create order intermittently fails with the following:

2021-05-18T01:38:12.933153084Z ERROR - errorMessage = read: end of stream, category: beast.http
2021-05-18T01:38:12.933272015Z ERROR - correlationIdList = [ SPOT_BTC ]
Event [
  type = REQUEST_STATUS,
  messageList = [
    Message [
      type = REQUEST_FAILURE,
      recapType = UNKNOWN,
      time = 2021-05-18T01:38:12.933380067Z,
      timeReceived = 2021-05-18T01:38:12.933380067Z,
      elementList = [
        Element [
          nameValueMap = {
            ERROR_MESSAGE = read: end of stream, category: beast.http
          }
        ]
      ],
      correlationIdList = [ SPOT_BTC ]
    ]
  ]
]
2021-05-18T01:38:12.933618040Z ERROR - max retry exceeded
2021-05-18T01:38:12.933712752Z ERROR - errorMessage = max retry exceeded
2021-05-18T01:38:12.933810483Z ERROR - correlationIdList = [ SPOT_BTC]
Event [
  type = REQUEST_STATUS,
  messageList = [
    Message [
      type = REQUEST_FAILURE,
      recapType = UNKNOWN,
      time = 2021-05-18T01:38:12.933906665Z,
      timeReceived = 2021-05-18T01:38:12.933906665Z,
      elementList = [
        Element [
          nameValueMap = {
            ERROR_MESSAGE = max retry exceeded
          }
        ]
      ],
      correlationIdList = [ SPOT_BTC ]
    ]
  ]
]

To Reproduce
Steps to reproduce the behavior:

  1. I just need to run my code for any reasonable period of time using the FTX services. I've checked the request payload and it all looks fine when printed.

Expected behavior
Order submitted successfully.

Additional context
Based on a bit of googling it seems read: end of stream, category: beast.http means the connection was closed by the remote side. Perhaps there is something wrong with my request or the connection is stale?

At this point I'm just checking whether you've seen this issue before or have any suggestions for how to debug?

Thanks

Decimal doesn't correctly handle negative numbers

Describe the bug
stoul fails in Decimal constructor for negative numbers.

To Reproduce
Steps to reproduce the behavior:

  1. construct a Decimal from Decimal{"-0.001"}

Expected behavior

  1. Correctly handles negative numbers

I think the issue is here
I think it should be fixedPointValue.erase(0, 1);

timeReceived is before exchange publish time

To replicate the issue, we can try running market_data_simple in one of the examples.

  1. In ccapi_session_options.h, Initialize to 1.
    long warnLateEventMaxMilliSeconds{1}; // used to print a warning log message if an event arrives late
  2. Enable CCAPI_ENABLE_LOG_WARN
  3. Extend Logger class to simply std:cout << ...
  4. Remove condition wsMessage.recapType == MarketDataMessage::RecapType::NONE in ccapi_market_data_service.h:470
    This condition is assuming timeReceived is always after the message publish time from the exchange. However, often it is not the case. Notice that timeReceived is before wsMessage.tp, even after local machine time sync. This issue is easily seen if you flip the condition to std::chrono::duration_cast<std::chrono::milliseconds>(timeReceived - wsMessage.tp).count() < -this->sessionOptions.warnLateEventMaxMilliSeconds.

On a different matter, this example is simply streaming live market data. Was there a reason why wsMessage.recapType is SOLICITED rather than NONE? It can also be classified into a normal tick data as you commented inline, or changing the condition to include SOLICITED would be a workaround.

Thanks!

Get all available instruments

Is your feature request related to a problem? Please describe.
The end user would like to find an easy way to subscribe to all instruments for a given exchange for market data streaming.

Describe the solution you'd like
Implement the request operation Request::Operation::GET_INSTRUMENTS (which to some extent might possess similarities to Request::Operation::GET_INSTRUMENT) for each and every supported exchange.

Order updates on Kraken. Only receiving a pending status update.

How may I retrieve order updates on Kraken? I'm subscribing via the line of code below:
Subscription subscription("Kraken", "ETH-USD", "ORDER_UPDATE");
I only receive one update with a STATUS, of "pending" despite orders being completely filled.
Any help would be greatly appreciated.

Thanks
Evan

binance cancel orders not working.

Describe the bug
A clear and concise description of what the bug is.
The first time spot_market_maker will send a cancel orders.
this show error.
To Reproduce
Steps to reproduce the behavior:
use spot market maker. start on binance will show error.

Expected behavior
not show error

Screenshots
If applicable, add screenshots to help explain your problem.
image

Additional context
Add any other context about the problem here (such as operating system, compiler used, git commit hash used, etc.).

Assertion `IsArray()' failed on CANCEL_ORDER for BitFinex exchange

Describe the bug
When sending CANCEL_ORDER request for bitfinex a providing an EventQueue, I get the folowing failed assertion:

rapidjson::GenericValue<Encoding, Allocator>& rapidjson::GenericValue<Encoding, Allocator>::operator[](rapidjson::SizeType) [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; rapidjson::SizeType = unsigned int]: Assertion IsArray()' failed.
`

The assertion fails because the function
ExecutionManagementServiceBitfinex::extractOrderInfo assumes that it is called with an array type for argument const rj::Value& x but it is called with an individual value for x and calls operator[] on that x.

The cause for this is:
ExecutionManagementServiceBitfinex::extractOrderInfoFromRequest handles CREATE_ORDER and CANCEL_ORDER in the same manner:

void extractOrderInfoFromRequest(std::vector<Element>& elementList, const Request& request, const Request::Operation operation, const rj::Document& document) override {
    if (operation == Request::Operation::CREATE_ORDER || operation == Request::Operation::CANCEL_ORDER) {
      Element element;
      this->extractOrderInfo(element, document[4][0]);
      elementList.emplace_back(std::move(element));
    } else if (operation == Request::Operation::GET_ORDER) {

But looking at the responses which we receive from bitfinex there is a difference. You can see, that for CREATE_ORDER the 4th entry is an array of arrays, while for CANCEL_ORDER it is just an array.

Response for CREATE_ORDER:
"[1670537236,"on-req",null,null,[[109833343300,null,21121987,"tTESTBTC:TESTUSD",1670537236127,1670537236127,0.1,0.1,"EXCHANGE LIMIT",null,null,null,0,"ACTIVE",null,null,1000,0,0,0,null,null,null,0,0,null,null,null,"API>BFX",null,null,{}]],null,"SUCCESS","Submitting 1 orders."]"

Response CANCEL_ORDER:
"[1670537288153,"oc-req",null,null,[109833343300,null,21121987,"tTESTBTC:TESTUSD",1670537236127,1670537236128,0.1,0.1,"EXCHANGE LIMIT",null,null,null,0,"ACTIVE",null,null,1000,0,0,0,null,null,null,0,0,null,null,null,"API>BFX",null,null,{}],null,"SUCCESS","Submitted for cancellation; waiting for confirmation (ID: 109833343300)."]"

To Reproduce
Almost pseudo code:

ccapi::Request request{ccapi::Request::Operation::CANCEL_ORDER, CCAPI_EXCHANGE_NAME_BITFINEX, "myinstrument")};
request->appendParam({
{"ORDER_ID", "myorderid"}
});
ccapi::Queueccapi::Event event_queue;
session.sendRequest(request, &event_queue); // <--- assertion fails on this call

Expected behavior
Assertion should not fail.

Additional context
git commit 077fbf7

freeing unallocated memory in market_data_advanced_subscription

Describe the bug
when running the market_data_advanced_subscription example with parameter "dispatch_events_to_multiple_threads" on an M1 Mac (compiled used clang) or Ubuntu Linux in a VM (compiled using gcc), the example dies before completing:

market_data_advanced_subscription(11633,0x105248580) malloc: *** error for object 0x16d8eb4a8: pointer being freed was not allocated
market_data_advanced_subscription(11633,0x105248580) malloc: *** set a breakpoint in malloc_error_break to debug
zsh: abort      ./market_data_advanced_subscription dispatch_events_to_multiple_threads

To Reproduce

  1. Run market_data_advanced_subscription dispatch_events_to_multiple_threads

Expected behavior
Should finish after 10seconds and print "Bye"

can not receive some exchange market data

1、user_specified_cmake_include.cmake

include_guard(DIRECTORY)
add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_HUOBI)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_KRAKEN)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_US)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BITMEX)
find_package(ZLIB REQUIRED)
link_libraries(ZLIB::ZLIB)

2、CMakeLists.txt
set(NAME aggregate_arbitrage)
project(${NAME})
add_compile_definitions(CCAPI_ENABLE_SERVICE_MARKET_DATA)
add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_HUOBI)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_KRAKEN)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE_US)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BINANCE)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_BITMEX)
find_package(ZLIB REQUIRED)
link_libraries(ZLIB::ZLIB)
add_executable(${NAME} main.cpp)

3、main.cpp
#include "ccapi_cpp/ccapi_session.h"
#include
#include <pthread.h>
#include
#include

namespace ccapi {
Logger* Logger::logger = nullptr; // This line is needed.

class MarketDataEventHandler : public EventHandler {
public:
bool processEvent(const Event& event, Session* session) override {
// std::cout << toString(event) + "\n" << std::endl;
if (event.getType() == Event::Type::SUBSCRIPTION_DATA) {
for (const auto& message : event.getMessageList()) {
auto correlationId = message.getCorrelationIdList().at(0);
std::cout << std::string("getTimeReceived: ") + std::to_string(UtilTime::getUnixTimestamp(message.getTimeReceived()))+
" getTime: "+ std::to_string(UtilTime::getUnixTimestamp(message.getTime())) << std::endl;
}
}
return true;
}

};

} /* namespace ccapi */

std::string roundPrice(double price) {
std::stringstream stream;
stream << std::fixed << std::setprecision(2) << price;
return stream.str();
}

using ::ccapi::Event;
using ::ccapi::EventDispatcher;
using ::ccapi::MarketDataEventHandler;
using ::ccapi::Request;
using ::ccapi::Session;
using ::ccapi::SessionConfigs;
using ::ccapi::SessionOptions;
using ::ccapi::Subscription;
using ::ccapi::UtilSystem;

void thread01_market_data_subscribe(void)
{
SessionOptions sessionOptions;
SessionConfigs sessionConfigs;
MarketDataEventHandler eventHandler;
Session session(sessionOptions, sessionConfigs, &eventHandler);
std::vector subscriptionList;
subscriptionList.emplace_back("huobi", "btcusdt", "MARKET_DEPTH", "", "huobi");
subscriptionList.emplace_back("kraken", "BTC/USDT", "MARKET_DEPTH", "", "kraken");
subscriptionList.emplace_back("binance-us", "BTCUSDT", "MARKET_DEPTH", "", "binance-us");
subscriptionList.emplace_back("binance", "BTCUSDT", "MARKET_DEPTH", "", "binance");
subscriptionList.emplace_back("bitmex", "BTCUSD", "MARKET_DEPTH", "", "bitmex");
session.subscribe(subscriptionList);

while (true) {
std::cout << "I'm waiting for arbitrage opportunities" << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
}
return EXIT_SUCCESS;
}

int main(int argc, char** argv) {
std::cout << "Created Main thread!" << std::endl;
pthread_t market_data_thread;
pthread_create(&market_data_thread, NULL, &thread01_market_data_subscribe, NULL);
pthread_join(market_data_thread, NULL);
}

floating point exception on M1 Mac

Describe the bug
floating point exception on M1 Mac architecture running compiled Mach-O 64-bit executable x86_64
To Reproduce
Steps to reproduce the behavior:

  1. According documentation spot market making
  2. compiled binary in src/spot_market_making/spot_market_making crashes on M1 Mac
    with floating point exception message

Expected behavior
Working binary for liquidity providing.

Additional context
Any chance to add support for M1 mac or discuss which instructions are not supported here?

Request Python API single order submit for gateio-perpetual-futures

Is your feature request related to a problem? Please describe.
I'm trying to create orders with the python bindings of gateio-perpetual-futures, however, I cannot do it because I'm not quite familiar with C++.

OS: ubuntu 20.04

My cmake:

include_guard(DIRECTORY)

# If you encountered segmentation fault at run-time, comment out the following line.
if (CMAKE_BUILD_TYPE STREQUAL "Release")
  set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
endif()

add_compile_definitions(CCAPI_ENABLE_SERVICE_EXECUTION_MANAGEMENT)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_GATEIO)
add_compile_definitions(CCAPI_ENABLE_EXCHANGE_GATEIO_PERPETUAL_FUTURES)

My python script:

import os
import sys
import time
from ccapi import Event, SessionOptions, SessionConfigs, Session, EventHandler, Request
class MyEventHandler(EventHandler):
    def __init__(self):
        super().__init__()
    def processEvent(self, event: Event, session: Session) -> bool:
        print(f'Received an event:\n{event.toStringPretty(2, 2)}')
        return True  # This line is needed.
if __name__ == '__main__':
    eventHandler = MyEventHandler()

    option = SessionOptions()
    config = SessionConfigs()
    config.setCredential({"CCAPI_GATEIO_PERPETUAL_FUTURES_API_KEY":"xxx", \
                          "CCAPI_GATEIO_PERPETUAL_FUTURES_API_SECRET":"xxx"})
    session = Session(option, config, eventHandler)
    request = Request(Request.Operation_CREATE_ORDER, "gateio-perpetual-futures", "ETH_USDT")
    request.appendParam({
        "size":   "0.01",
        "price":"2500",
        "tif": "gtc"
    })
    session.sendRequest(request)
    time.sleep(10)
    session.stop()
    print('Bye')

The error message:

  Event [
    type = RESPONSE,
    messageList = [
      Message [
        type = RESPONSE_ERROR,
        recapType = UNKNOWN,
        time = 1970-01-01T00:00:00.000000000Z,
        timeReceived = 2022-03-15T21:42:18.578651194Z,
        elementList = [
          Element [
            nameValueMap = {
              ERROR_MESSAGE = {"label":"INVALID_KEY","message":"Invalid key provided"},
              HTTP_STATUS_CODE = 401
            }
          ]
        ],
        correlationIdList = [ dsnhvXZo ]
      ]
    ]
  ]
Bye
(worldbreak) nana@nana:~/cppapi/binding/python/example/src/gateio_create_order$ python main.py 
Received an event:
  Event [
    type = RESPONSE,
    messageList = [
      Message [
        type = RESPONSE_ERROR,
        recapType = UNKNOWN,
        time = 1970-01-01T00:00:00.000000000Z,
        timeReceived = 2022-03-15T21:44:25.059816210Z,
        elementList = [
          Element [
            nameValueMap = {
              ERROR_MESSAGE = {"label":"INVALID_KEY","message":"Invalid key provided"},
              HTTP_STATUS_CODE = 401
            }
          ]
        ],
        correlationIdList = [ T6NOe8yS ]
      ]
    ]
  ]
Bye

It looks my API Key and Secret are not right, however, I confirm it is right, I also changed my API key and secret to other invalid numbers, which show the same error.

Describe the solution you'd like
A bunch of examples to submit orders for each exchange.

Describe alternatives you've considered
A script to submit an order for gateio-perpetual-futures

Add market data service for FTX

Describe the solution you'd like

  • Modify include/ccapi_cpp/service/ccapi_service.h so that market data service class for FTX is enabled there. Modify /include/ccapi_cpp/ccapi_macro.h and /include/ccapi_cpp/ccapi_session_configs.h accordingly. Create /include/ccapi_cpp/service/ccapi_market_data_service_ftx.h and add appropriate logics.
  • End-to-end test it so that market depth and trade data can be successfully streamed.

Coinbase error in streaming trades

Since the new release, it fails to stream trades, at least from Coinbase that I tried.

When we run:

int main(int argc, char **argv) {
  using namespace ccapi;  // NOLINT(build/namespaces)
  SessionOptions sessionOptions;
  SessionConfigs sessionConfigs;
  MyEventHandler eventHandler;
  Session session(sessionOptions, sessionConfigs, &eventHandler);
  std::vector<Subscription> subscriptionList;
  Subscription subscription("coinbase", "BTC-USD", CCAPI_TRADE);
  subscriptionList.push_back(subscription);
  session.subscribe(subscriptionList);
  std::this_thread::sleep_for(std::chrono::seconds(100));
  session.stop();
  std::cout << "Bye" << std::endl;
  return EXIT_SUCCESS;
}

I enabled logging to trace, and it outputs:

Event [type = SESSION_STATUS, messageList = [ Message [type = SESSION_CONNECTION_UP, recapType = UNKNOWN, time = 1970-01-01T00:00:00.000000000Z, timeReceived = 2021-02-01T19:46:49.768657000Z, elementList = [ Element [nameValueMap = {CONNECTION=WsConnection [id = 0x7ffff00020c0, url = wss://ws-feed.pro.coinbase.com, instrumentGroup = wss://ws-feed.pro.coinbase.com|TRADE|CONFLATE_GRACE_PERIOD_MILLISECONDS=-1&CONFLATE_INTERVAL_MILLISECONDS=0&MARKET_DEPTH_MAX=1&MARKET_DEPTH_RETURN_UPDATE=0, subscriptionList = [ Subscription [exchange = coinbase, instrument = BTC-USD, field = TRADE, optionMap = {CONFLATE_GRACE_PERIOD_MILLISECONDS=-1, CONFLATE_INTERVAL_MILLISECONDS=0, MARKET_DEPTH_MAX=1, MARKET_DEPTH_RETURN_UPDATE=0}, correlationId = fa37JncCHryDsbzayy4cBWDxS22JjzhM, credential = {}, serviceName = market_data] ], status = OPEN]}] ], correlationIdList = [  ]] ]]

Event [type = SUBSCRIPTION_STATUS, messageList = [ Message [type = ERROR, recapType = UNKNOWN, time = 2021-02-01T19:46:49.841734900Z, timeReceived = 2021-02-01T19:46:49.841734900Z, elementList = [ Element [nameValueMap = {ERROR_MESSAGE=rapidjson internal assertion failure}] ], correlationIdList = [  ]] ]]

Event [type = SUBSCRIPTION_STATUS, messageList = [ Message [type = ERROR, recapType = UNKNOWN, time = 2021-02-01T19:46:51.045225200Z, timeReceived = 2021-02-01T19:46:51.045225200Z, elementList = [ Element [nameValueMap = {ERROR_MESSAGE=rapidjson internal assertion failure}] ], correlationIdList = [  ]] ]]

and continues with the same error message. It points to {ERROR_MESSAGE=rapidjson internal assertion failure}.

Please let me know if this issue can be replicated on your machine. Thank you.

Generic websocket subscription

Is your feature request related to a problem? Please describe.
Our end user needs to find an easy way to subscribe to an arbitrary public topic via a websocket connection to collect custom market data.

Describe the solution you'd like
Create a way to let the end user to achieve the above goal.

Add execution management service for Kucoin

Describe the solution you'd like

  • Modify include/ccapi_cpp/service/ccapi_service.h so that market data service class for Kucoin is enabled there. Modify /include/ccapi_cpp/ccapi_macro.h and /include/ccapi_cpp/ccapi_session_configs.h accordingly. Create /include/ccapi_cpp/service/ccapi_execution_management_service_kucoin.h and add appropriate logics. Kucoin's execution management is very similar to (but not identical to) Coinbase, therefore /include/ccapi_cpp/service/ccapi_execution_management_service_coinbase.h can be used as a decent starting point.
  • End-to-end test it. At least you'd be able to get open orders to successfully return.
  • Add appropriate unit tests on request conversions and response conversions.

Enhancement idea: streaming historical data in ccapi_cpp

Currently, historical data *(1-second book snapshots + trades + OHLC) are provided from REST API https://github.com/crypto-chassis/cryptochassis-api-docs. This ccapi_cpp repo is for streaming live data and execution.

Enhancement: streaming coarse historical data through the same ccapi_cpp repo

This enhancement benefits the training pipeline:

Easier features generation for training models, through three events * streamed chronologically.

Without much changes in code, the user simply 'switch on' live mode and stream the same custom features in real-time.

The user can have confidence that it's the same set of features that the model was trained upon.

From a design perspective, it could make auto-download daily * event files to user's local tmp folder and read from there. It also requires implementing subscriptions to OHLC events https://github.com/crypto-chassis/cryptochassis-api-docs#ohlc in the current ccapi_cpp repo.

On your roadmap, do you have plans for such an enhancement? Please let me know how I can contribute if this is something you have in mind.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.