Skip to content

flashnuke/BinanceExtensionCPP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BinanceExtensionCPP

Intro

This library is an extension for the API of Binance. It is designed for writing trading algorithms on Binance.
The design is delibaretly attempting to reduce execution time during runtime, by using methods such as CRTP and the Params object; no virtual classes/methods are used in this library.

Dependencies

  1. JsonCPP (latest version tested: jsoncpp 1.9.3)
  2. CURL (latest version tested: curl 7.72.0)
  3. Boost/Beast websockets (latest version tested: boost-1.73.0)

These 3 must be installed in order to use the library.

Documentation

In order to use this library, you must have all dependencies installed. Only one #include statement is required - #include "include/Binance_Client.h", and all source files are inside the /src directory (You can copy an example from /examples into /src and compile using the compilation lines provided below).
Note that .inl files are included inside the main header.


You must initialize a Client object, which is one of the following: [SpotClient, FuturesClientUSDT, FuturesClientCoin, OpsClient]

Unique methods

Many endpoints are divided by category into different structs inside Client. In order to use them, you must instantiate a struct object first.

  • Wallet
  • FuturesWallet
  • SubAccount
  • MarginAccount
  • Savings
  • Mining
  • BLVT
  • BSWAP
  • Fiat
  • C2C


They should be initialized from within other Client classes, and by passing the Client object to the constructor. i.e:

SpotClient::Wallet my_wallet{ my_client_obj }.

Exchange client

In order to initialize a client that is not public, api-key and api-secret must be passed in std::string format to the constructor.

FuturesClientUSDT(api_key, api_secret)


Futures and Options clients may be set in testnet mode by using the method set_testnet_mode(bool). SpotClient has test_new_order() method but no testnet mode endpoints.

  • CRTP implementation

    The CRTP is implemented as follows:

    └── Client
       ├── SpotClient
       │
       ├── FuturesClient
       │ │
       │ ├── FuturesClientUSDT
       │ └── FuturesClientCoin
       │
       └── OpsClient

    As was mentioned earlier, unique endpoints are located as separate structs inside Client.
    CRTP interface and implementations are separated inside Binance_Client.cpp. Generally speaking, implementations are marked by a v_ prefix.
    Deeper implementations (i.e Client -> FuturesClient -> [FuturesClientUSDT, FuturesClientCoin]) include an additional underscore: v__.

  • Exceptions

    The library contains several exception classes, all of which derive from base class ClientException.


    └── ClientException
       ├── BadSetupSessionREST (error in setting up a REST session)
       ├── BadRequestREST (error in sending a REST request)
       ├── BadCleanupREST (error in REST client destructor)
       ├── BadSetupHeadersREST (error in setting up headers)
       │
       ├── BadStreamOpenWS (error in opening a websocket stream)
       ├── BadStreamCloseWS (error in closing a websocket stream)
       ├── BadStreamCallbackWS (error in callback from websocket stream message)
       ├── BadSetupPathWS (error in setting up host / port)
       │
       ├── BadQuery (error in generating query)
       ├── MissingCredentials (missing keys)
       ├── MissingEndpoint (missing endpoint for a specific client)
       │
       └── CustomException (a custom exception. description in what())

    ClientException base class contains a what() method which returns a c-string which is a description of the problem and a traceback.
    Each time an exception is thrown and a function inside the library catches it, the name of the method will be appended to the traceback using the __FUNCTION__ macro and later on also added to what() c-string.

    The main idea is to catch(ClientException& e) in order handle any exception which is one of the aforementioned, since they are all derived. It is also possible to catch() a specific exception.

  • Notes

      1. No copy assignment / constructor are implemented for Client classes. Each object has its own unique Session, WS, and running streams.
      2. All unique endpoint structs require that the client object contains keys and is not a public client.
      3. `ClientException` derives from `std::exception` therefore `catch(std::exception)` would also work.
    

REST client

All (except for ones that don't have mandatory parameters) REST request methods take a pointer to a Params object. This object holds the parameters that would be generated to a query string and sent as the request body.
Endpoints that do not require any params, have a default argument which is a nullptr (beware if using threads).
* Signing requests is done after generating the query, and the Params object remains unchanged.

  • 'Params' object

    The Params object holds all parameters in an unordered_map, and thus allows quick access and modification during runtime. The idea here is to prepare most of the request body and have it ready at all time. (i.e: have the side and quantity ready at all times. Price may be set on signal, using the time complexity of unordered_map insertion)
    You can set or delete parameters from the object using the methods set_param<type>() and delete_param(). Usingflush_params() method will delete all params from the object.
    It is also possible to set a default recvWindow value that would be set again after each flush, using the set_recv() method.

  • Response type

    Each REST request returns a JSON type objet, that holds the three following keys:

    1. "response" = Actual response from the exchange in std::string format
    2. "request_status" = Request status (bool; 1 success 0 failure)
    3. "parse_status" = Returns a string generated by the JSON parser, containing parsing errors (if any)
  • Custom Requests

    You can send a custom request, using custom_{request_type}_req() method.
    This method accepts four arguments: base_path std::string, endpointstd::string, Params object, and sign_request bool (true = append signature to request body).

  • Debugging

    You can set verbose mode for debugging, which will make all rest requests verbose. my_client.rest_set_verbose(1);

  • Notes

       1. There are four curl handles that are alive throughout the entire life of a RestSession object, one for each request type: GET, POST, PUT and DELETE.
       2. In order to avoid a race condition by using the same handle at the same time for different requests, mutex is used.
       3. Passing an `std::string` format to `set_param()` method is quicker, because conversion-to-string is required.
       4. Passing `const char*` to `set_param()` is currently not supported, please use `std::string`, as shown in the examples.
    

Websocket client