Serving the Quantitative Finance Community

 
User avatar
Amin
Topic Author
Posts: 2572
Joined: July 14th, 2002, 3:00 am

Binance C++ API Question

September 11th, 2022, 11:11 am

Friends, I am trying to learn Binance C++ API for algorithmic trading on Binance platform. 
Here is the github page for Binance C++ API:  https://github.com/tensaix2j/binacpp
I am copying a code example from above github project and have a few questions. I pretty much understand everything in the code example but do not understand the last three lines of the code and their precise purpose. Here are the three lines I what to understand.

BinaCPP_websocket::init();
BinaCPP_websocket::connect_endpoint( ws_depth_onData ,"/ws/bnbbtc@depth" );
BinaCPP_websocket::enter_event_loop();

Can somebody explain the meanings and significance of each of the three lines of code above. Do I have to place these lines at the end of the code or I could possibly place them at start of the code. 

Here is the full code example from github project on Binance C++ API.
#include <map>
#include <vector>
#include <string>


#include "binacpp.h"
#include "binacpp_websocket.h"
#include <json/json.h>



using namespace std;

map < string, map <double,double> >  depthCache;
int lastUpdateId;

//------------------------------
void print_depthCache() {

	map < string, map <double,double> >::iterator it_i;

	for ( it_i = depthCache.begin() ; it_i != depthCache.end() ; it_i++ ) {
			
		string bid_or_ask = (*it_i).first ;
		cout << bid_or_ask << endl ;
		cout << "Price             Qty" << endl ;		

		map <double,double>::reverse_iterator it_j;

		for ( it_j = depthCache[bid_or_ask].rbegin() ; it_j != depthCache[bid_or_ask].rend() ; it_j++ ) {

			double price = (*it_j).first;
			double qty   = (*it_j).second;
			printf("%.08f          %.08f\n", price, qty );
		}
	}
}





//-------------
int ws_depth_onData( Json::Value &json_result ) {
	
	int i;

	int new_updateId  = json_result["u"].asInt();
	
	if ( new_updateId > lastUpdateId ) {
	
		for ( i = 0 ; i < json_result["b"].size() ; i++ ) {
			double price = atof( json_result["b"][i][0].asString().c_str());
			double qty 	= atof( json_result["b"][i][1].asString().c_str());
			if ( qty == 0.0 ) {
				depthCache["bids"].erase(price);
			} else {
				depthCache["bids"][price] = qty;
			}
		}
		for ( i = 0 ; i < json_result["a"].size() ; i++ ) {
			double price = atof( json_result["a"][i][0].asString().c_str());
			double qty 	= atof( json_result["a"][i][1].asString().c_str());
			if ( qty == 0.0 ) {
				depthCache["asks"].erase(price);
			} else {
				depthCache["asks"][price] = qty;
			}
		}		
		lastUpdateId = new_updateId;
	}
	print_depthCache();
}


//---------------------------
/*
	To compile, type
	make example_depthCache

*/

//--------------------------

int main() {

	Json::Value result;
	long recvWindow = 10000;	

		
	// Market Depth 
	int i;
	string symbol = "BNBBTC";
	BinaCPP::get_depth( symbol.c_str(), 20, result ) ;

	// Initialize the lastUpdateId
	lastUpdateId = result["lastUpdateId"].asInt();
 		
	for ( int i = 0 ; i < result["asks"].size(); i++ ) {

		double price = atof( result["asks"][i][0].asString().c_str() );
		double qty   = atof( result["asks"][i][1].asString().c_str() );
		depthCache["asks"][price] = qty;
	}
	for  ( int i = 0 ; i < result["bids"].size() ; i++ ) {

		double price = atof( result["bids"][i][0].asString().c_str() );
		double qty   = atof( result["bids"][i][1].asString().c_str() );
		depthCache["bids"][price] = qty;
	}
	print_depthCache();
 	

	BinaCPP_websocket::init();
 	BinaCPP_websocket::connect_endpoint( ws_depth_onData ,"/ws/bnbbtc@depth" ); 
 	BinaCPP_websocket::enter_event_loop(); 
	
}
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
GiusArg
Posts: 17
Joined: January 26th, 2022, 5:35 pm

Re: Binance C++ API Question

September 11th, 2022, 6:46 pm

You must leave them at the end of the main function, as all the examples show. This is pretty standard in networking applications (e.g. Boost ASIO).

The last three lines effectively start the execution.

The first one initialises the websocket, the second one creates the connection to the endpoint (the server you connect to) and registers the callback ws_depth_onData (that is, the function that will be called when receiving data in json format) and the third enters an infinite loop, waiting for events (in this case, the reception of data).

The second argument of connect_endpoint, I think you can leave it as it is. It's a URI path whose description you can find in the libwebsockets documentation
 .
 
User avatar
Amin
Topic Author
Posts: 2572
Joined: July 14th, 2002, 3:00 am

Re: Binance C++ API Question

September 12th, 2022, 9:05 am

Thank you GuisArg. I really appreciate your help. Many thanks for this favor.

I am starting to understand basic concepts about websocket but I am still a beginner here.
Yes, your post made it very clear especially about second line of code where program subscribes to data stream and registers the callback function to interpret the data and to make appropriate actions once the incoming data stream is updated.
I still have a few questions.

Question 1. Let us suppose I receive the updated data at a certain time and I process the received json data in callback function to determine whether I should make a trade in the market. Do I have to insert the buy or sell order in the callback function or Can I insert the order command right above the enter-event-loop command like as follows

BinaCPP_websocket::init();
BinaCPP_websocket::connect_endpoint( ws_depth_onData ,"/ws/bnbbtc@depth" );
Insert Code For Buy or Sell Order Here Based On Some Calculation In Callback Function..
BinaCPP_websocket::enter_event_loop();

So my question boils down to Whether I can insert my own functions in between websocket commands before enter_event_loop() and after init() websocket functions or I have to handle other things in the callback function/functions.

Question 2.

My algorithmic trading strategy depends upon prices of more than ten currencies. Can I subscribe to for example four symbols simultaneously with one command by passing an array/vector of symbol strings and by registering just one appropriate common callback function given by ws_depth_onData(that I will write later)? as possibly given in code below.


std::string ws_ticker[4]= {"/ws/bnbbtc@depth","/ws/ethbtc@depth","/ws/bnbeth@depth","/ws/btcbusd@depth"};
BinaCPP_websocket::connect_endpoint( ws_depth_onData ,ws_ticker);



Thank you very much again.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Amin
Topic Author
Posts: 2572
Joined: July 14th, 2002, 3:00 am

Re: Binance C++ API Question

September 12th, 2022, 12:55 pm

Still Just trying to learn.  It seems that I would have to do my order management by embedding order functions of the Rest API that would be called inside the callback functions after manipulation of data in callback functions of the websocket API. GiusArg, is that right? Thank you for your help yesterday.

I will try to play with simple toy programs to see how it goes. I have a decent background in C++ but have never dealt with networking before.

I still do not know anything about question 2. So any help would be appreciated.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
GiusArg
Posts: 17
Joined: January 26th, 2022, 5:35 pm

Re: Binance C++ API Question

September 12th, 2022, 9:04 pm

I still have a few questions.

Question 1.

So my question boils down to Whether I can insert my own functions in between websocket commands before enter_event_loop() and after init() websocket functions or I have to handle other things in the callback function/functions.
No. All the examples invoke the user code via the callback function. You can write more complex operations invoking other helper functions from within your callback, but the general structure should be the same of this example.

Question 2.

My algorithmic trading strategy depends upon prices of more than ten currencies. Can I subscribe to for example four symbols simultaneously with one command by passing an array/vector of symbol strings and by registering just one appropriate common callback function given by ws_depth_onData(that I will write later)? as possibly given in code below.
It doesn't look like connect_endpoint accepts a std::vector<std::string> (please don't use arrays, this is C++ not C), but you can maybe wrap it into your own defined function which takes a vector of strings.

You can see in the most comprehensive example that you can connect to as many endpoints as you want, before entering the event loop, each with its own callback. I guess you can pass the same callback, after all, as long as you check which symbol the current json data refers to. See the usage of the callback ws_userStream_OnData,  in the same example.
 
User avatar
Amin
Topic Author
Posts: 2572
Joined: July 14th, 2002, 3:00 am

Re: Binance C++ API Question

September 13th, 2022, 3:30 am

Thank you GiusArg. Your answers to my questions are very helpful for me. I understand all the examples now and can start programming for appropriate callback functions.
Thank you again for your time and I wish you a good day.
You think life is a secret, Life is only love of flying, It has seen many ups and downs, But it likes travel more than the destination. Allama Iqbal
 
User avatar
Cuchulainn
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: Binance C++ API Question

September 14th, 2022, 11:26 am

C++ is 40 years old and still doesn't have a native networkinng library..
It doesn't even have a native matrix class.

Does Binance have Java/C#? Much easier than Boost asio.

??

https://github.com/JKorf/Binance.Net
 
User avatar
GiusArg
Posts: 17
Joined: January 26th, 2022, 5:35 pm

Re: Binance C++ API Question

September 15th, 2022, 6:39 am

Not sure what native means here: C++ has no std:: networking library, but Asio is a native C++ library (it's not a wrapper around a C library, for example). And it's widely used in industry. I know nothing about Java/C# and whether their libraries are better, but the fact is, Binance doesn't use Asio and doesn't require knowing much about network programming either.
 
User avatar
Cuchulainn
Posts: 20254
Joined: July 16th, 2004, 7:38 am
Location: 20, 000

Re: Binance C++ API Question

September 15th, 2022, 8:21 am

Not sure what native means here: C++ has no std:: networking library, but Asio is a native C++ library (it's not a wrapper around a C library, for example). And it's widely used in industry. I know nothing about Java/C# and whether their libraries are better, but the fact is, Binance doesn't use Asio and doesn't require knowing much about network programming either.
By 'native' I meant the C++ compiler itself., without the need to include an external library. 

"40 years after C++’s birth, it still doesn’t have a standard network library. 40 years means two generations of programmers. The standard committee is probably thinking of the planned standard network library as a gift to their grandsons and granddaughters."
 
User avatar
GiusArg
Posts: 17
Joined: January 26th, 2022, 5:35 pm

Re: Binance C++ API Question

September 15th, 2022, 5:22 pm

I understand.

I have read reasons for this being the case, including security issues, the fact they (the committee) will end up making many people unhappy whatever they decide,that once you put something in the standard, it's difficult to revert mistakes, and the fact that there are already third party libraries available.