dmikushin / bitrader

Trading and Alering Service for Binance Cryptocurrency Exchange
MIT License
27 stars 13 forks source link

Rasberry Clock Problem #3

Closed DaRabus closed 11 months ago

DaRabus commented 4 years ago

Hey, thanks for your aweasome work, does help me alot with my project.

Now, I did build your project nd tried it out on my ubuntu VM, there it works perfectly as it is supposed to be. So yeah but I want to let it run on my small "Server" a Rasberry Pi B^^

Anyway the error I get is that the recvWindow is not enough, I found some solutions like checking my timezone from my PI and stuff but nothing worked, the time is synchronised by NTP as it should be, and I did put it on my actual Timezone where I live.

I tried to extend the string in the binance_account.cpp but it didnt help.

So yeah, here I am, dont know what to try else, I think it could be cause of the Pi has no Hardware Clock and maybe binance detects that and doesnt like it?

grafik

Please help :)

BTW: just seen that you are from Zurich aswell so you can answear in german aswell if you prefer :D

dmikushin commented 4 years ago

Hi this is an interesting one, thanks!

Right, I saw this before on x86, and the reason was a clock skew. Even a small skew of milliseconds is important for Binance. So you should sync your clock with NTP server quite often. Aside of this, the code in binance::get_current_ms_epoch() utility function could very well be involved:

unsigned long binance::get_current_ms_epoch( )
{
        struct timeval tv;
        gettimeofday(&tv, NULL);

        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}

Blind guess is the embedded ARM chip does not offer enough accuracy for gettimeofday() function, which is actually not mandated. I mean it's rather our issue here that we should use some high-precision timer explicitly.

I think this API code should be replaced with C++11 chrono (with care - without breaking Windows as well). If you have time to experiment, patches on this to binance-cxx-api are very welcome!

DaRabus commented 4 years ago

https://stackoverflow.com/questions/47658329/std-chrono-time-synchronization

Found this actually, so it seems not that easy. Cause yeah if I just use chrono with the time from my system it will probably still be wrong.

Or do you think the accuracy from chrono to the usual time function is enough to fit?

EDIT: Gonna try now setting up the frequency from NTP to check the time EDIT2: Seems like that's not that solution https://access.redhat.com/solutions/39194

dmikushin commented 4 years ago

System always should have a high-precision realtime clock such as clock_gettime on Linux. There should be its equivalent in chrono. But this is not epoch time. The second part is to somehow align this clock to the low-precision epoch clock.

DaRabus commented 4 years ago

So yeah changed that one now to chrono, doesnt solve the problem but makes the code more handy^^

What another idea is which binance is recommending is extending the recvWindow. https://github.com/ccxt/ccxt/issues/936

grafik In your code I found this in the binance_account.cpp, but if I try to just add some value, this doesnt change anything, and yeah this is a value which should be given by calling the function, hmm.

grafik (has a namespace for chrono in it, and didnt delete your functions cause I just wanted to test^^)

EDIT: So Basically, is there a way to implay that function they recommend in the other gitproblem to the project? You know your source better and probably could do that in 5min :)

dmikushin commented 4 years ago

Please try the following and let me know if it works better for you:

--- a/src/binance_utils.cpp
+++ b/src/binance_utils.cpp
@@ -78,16 +78,20 @@ time_t binance::get_current_epoch( )
 {
        struct timeval tv;
        gettimeofday(&tv, NULL); 
-
        return tv.tv_sec ;
 }

 unsigned long binance::get_current_ms_epoch( )
 {
+#ifdef _WIN32
        struct timeval tv;
        gettimeofday(&tv, NULL); 
-
        return tv.tv_sec * 1000 + tv.tv_usec / 1000;
+#else
+       struct timespec tv;
+       clock_gettime(CLOCK_REALTIME, &tv);
+       return tv.tv_sec * 1000 + tv.tv_nsec / 1000 / 1000;
+#endif
 }
DaRabus commented 4 years ago

Just did the update but still the same error, prob I have to increase the recvWindow

grafik

dmikushin commented 4 years ago

OK, could you please tell us what actually happens when you call ntpdate:

$ sudo ntpdate pool.ntp.org
17 May 17:22:17 ntpdate[17498]: adjust time server 216.229.0.49 offset -0.005519 sec

If you repeatedly call ntpdate, does the second offset show almost zero, like above?

DaRabus commented 4 years ago

grafik

Looks quite good to me

dmikushin commented 4 years ago

Thanks for testing. Meanwhile, I've bumped bitrader to 92d907e4c9691832f7c50bf055534d5cfb8019f1 which cleans out redundant dependency on OpenSSL. I also re-checked that everything works.

In fact, your run fails at

// Get account info.
BINANCE_ERR_CHECK(account.getInfo(result));

where the recvWindow argument actually equals zero, by default!

Maybe you'd want to confirm your issue on a clean build of the newest version (thanks in advance!)

DaRabus commented 4 years ago

Just did a clean rebuilt, deleted everything and started from a new git clone.

grafik