fix: use double-precision timestamps for sub-millisecond signal timing
This commit is contained in:
parent
17aac4b4ef
commit
60257f068f
|
|
@ -21,10 +21,10 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static inline int64_t now_ms(void) {
|
||||
static double now_ms(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return (int64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1000000.0;
|
||||
}
|
||||
|
||||
/* ── Copied from executor.c for paper-trade simulation ── */
|
||||
|
|
@ -54,7 +54,7 @@ void evaluator_init(evaluator_t *ev, const triangle_set_t *triangles,
|
|||
ev->stats.best_triangle_key[0] = '\0';
|
||||
}
|
||||
|
||||
bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive_ms, int64_t t_arrive_ms) {
|
||||
bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive_ms, double t_arrive_ms) {
|
||||
const triangle_set_t *tris = ev->triangles;
|
||||
const order_book_t *books = ev->books;
|
||||
const config_t *cfg = ev->cfg;
|
||||
|
|
@ -79,7 +79,7 @@ bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive
|
|||
uint32_t *tri_flat = tris->tri_flat;
|
||||
if (!tri_flat) return false;
|
||||
|
||||
static int64_t last_status_ms = 0;
|
||||
static double last_status_ms = 0.0;
|
||||
|
||||
for (uint32_t j = 0; j < count; j++) {
|
||||
uint32_t i = tri_flat[offset + j];
|
||||
|
|
@ -161,7 +161,7 @@ bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive
|
|||
}
|
||||
if (net_bps < ev->stats.worst_net_bps) ev->stats.worst_net_bps = net_bps;
|
||||
|
||||
int64_t now = now_ms();
|
||||
double now = now_ms();
|
||||
if (now - last_status_ms >= 30000) {
|
||||
last_status_ms = now;
|
||||
log_write_screen("[STATUS] evals=%lu signals=%lu "
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ typedef struct {
|
|||
uint64_t triangles_skipped; /* count of triangles skipped for other reasons */
|
||||
double best_net_bps; /* best net profit seen (basis points) */
|
||||
double worst_net_bps; /* worst net profit seen (basis points) */
|
||||
int64_t last_eval_ts_ms; /* timestamp of last evaluation (milliseconds) */
|
||||
double last_eval_ts_ms; /* timestamp of last evaluation (milliseconds) */
|
||||
char best_triangle_key[48]; /* triangle key that produced best_net_bps */
|
||||
} eval_stats_t;
|
||||
|
||||
|
|
@ -37,6 +37,6 @@ void evaluator_init(evaluator_t *ev, const triangle_set_t *triangles,
|
|||
executor_slot_t *slots, int n_slots, bool kcs_discount);
|
||||
|
||||
/* Evaluate all triangles involving the given symbol; returns true if a signal was fired */
|
||||
bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive_ms, int64_t t_arrive_ms);
|
||||
bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive_ms, double t_arrive_ms);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -178,10 +178,10 @@ void executor_execute_triangle(executor_thread_t *et,
|
|||
double exec_start_mono = now_mono_ms();
|
||||
double leg_timings[6] = {0}; /* leg0_order, leg0_fill, leg1_order, leg1_fill, leg2_order, leg2_fill */
|
||||
snprintf(corr_id, sizeof(corr_id), "%08x%08x%08x%08x",
|
||||
(unsigned)(uintptr_t)&sig->legs.legs[0] ^ (unsigned)sig->ts_ms,
|
||||
(unsigned)sig->ts_ms ^ (unsigned)sig->book_ts_ms,
|
||||
(unsigned)(uintptr_t)&sig->legs.legs[0] ^ (unsigned)(uint64_t)sig->ts_ms,
|
||||
(unsigned)(uint64_t)sig->ts_ms ^ (unsigned)sig->book_ts_ms,
|
||||
(unsigned)sig->predicted_bps,
|
||||
(unsigned)sig->t_arrive_ms);
|
||||
(unsigned)(uint64_t)sig->t_arrive_ms);
|
||||
|
||||
double leg_output[3] = {0};
|
||||
double fills[3][6] = {{0}}; /* leg, output, avg_price, fee, input_vol, latency_ms */
|
||||
|
|
@ -410,13 +410,13 @@ void executor_execute_triangle(executor_thread_t *et,
|
|||
/* ── Build timing string (t0 = book_update_arrived = 0.0ms) ── */
|
||||
char timings_str[512] = "";
|
||||
int tp = 0;
|
||||
int64_t book_base = sig->t_arrive_ms;
|
||||
double book_base = sig->t_arrive_ms;
|
||||
|
||||
if (book_base > 0) {
|
||||
if (sig->book_ts_ms > 0)
|
||||
tp += snprintf(timings_str + tp, sizeof(timings_str) - tp,
|
||||
"t-1_snapshot=%.3fms ",
|
||||
(double)((int64_t)sig->book_ts_ms - book_base));
|
||||
sig->book_ts_ms - book_base);
|
||||
|
||||
tp += snprintf(timings_str + tp, sizeof(timings_str) - tp,
|
||||
"t0_arrival=0.0ms ");
|
||||
|
|
@ -424,9 +424,9 @@ void executor_execute_triangle(executor_thread_t *et,
|
|||
if (sig->ts_ms > 0)
|
||||
tp += snprintf(timings_str + tp, sizeof(timings_str) - tp,
|
||||
"t1_signal=%.3fms ",
|
||||
(double)((int64_t)sig->ts_ms - book_base));
|
||||
sig->ts_ms - book_base);
|
||||
|
||||
double sig_recv = (double)(exec_start_rt - book_base);
|
||||
double sig_recv = exec_start_rt - book_base;
|
||||
for (int l = 0; l < 3; l++) {
|
||||
double o = leg_timings[l * 2];
|
||||
double f = leg_timings[l * 2 + 1];
|
||||
|
|
|
|||
|
|
@ -98,11 +98,11 @@ typedef struct {
|
|||
char max_volume[32];
|
||||
double starting_volume;
|
||||
bool live;
|
||||
int64_t ts_ms;
|
||||
double ts_ms;
|
||||
int64_t book_ts_ms;
|
||||
int64_t t_sock_arrive_ms;
|
||||
int64_t t_arrive_ms;
|
||||
int64_t t_eval_ms;
|
||||
double t_arrive_ms;
|
||||
double t_eval_ms;
|
||||
uint8_t book_count;
|
||||
signal_book_t books[3];
|
||||
signal_legs_t legs;
|
||||
|
|
|
|||
|
|
@ -42,10 +42,10 @@ uint64_t ws_client_now_ms(void) {
|
|||
return now_ms_impl();
|
||||
}
|
||||
|
||||
static uint64_t now_realtime_ms(void) {
|
||||
static double now_realtime_ms(void) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
|
||||
return (double)ts.tv_sec * 1000.0 + (double)ts.tv_nsec / 1000000.0;
|
||||
}
|
||||
|
||||
/* Reset a WebSocket connection to its initial disconnected state, freeing
|
||||
|
|
@ -955,7 +955,7 @@ int ws_client_read(ws_client_t *client, uint32_t conn_idx) {
|
|||
|
||||
/* Flush: evaluate all symbols updated in this burst */
|
||||
if (dirty_count > 0) {
|
||||
int64_t t_arrive = (int64_t)now_realtime_ms();
|
||||
double t_arrive = now_realtime_ms();
|
||||
for (uint32_t d = 0; d < dirty_count; d++) {
|
||||
evaluate_symbol(client->evaluator, dirty[d],
|
||||
conn->t_sock_arrive_ms, t_arrive);
|
||||
|
|
|
|||
Loading…
Reference in New Issue