#ifndef FUSED_QUEUE_H #define FUSED_QUEUE_H #include #include #include #include "book.h" #include "triangle.h" #define MAX_SIGNAL_LEN 4096 #define Spsc_QUEUE_DEPTH 1024 /* Single price+size level in an order book snapshot */ typedef struct { double price; /* price at this level */ double size; /* available size at this level */ } book_level_t; /* Snapshot of one leg's order book included in a signal */ typedef struct { char symbol[SYMBOL_NAME_LEN]; /* trading pair symbol name */ int64_t ts_ms; /* book timestamp (milliseconds) */ book_level_t bids[MAX_BOOK_LEVELS]; /* bid levels (top of book) */ book_level_t asks[MAX_BOOK_LEVELS]; /* ask levels (top of book) */ uint8_t bid_count; /* number of valid bid levels */ uint8_t ask_count; /* number of valid ask levels */ } signal_book_t; /* One leg of a triangular arbitrage signal */ typedef struct { char symbol[SYMBOL_NAME_LEN]; /* trading pair symbol */ char input_currency[CURRENCY_NAME_LEN]; /* currency being traded in */ char output_currency[CURRENCY_NAME_LEN]; /* currency being traded out */ char fee_currency[CURRENCY_NAME_LEN]; /* currency used to pay fees */ double fee_rate; /* fee rate for this leg */ double exchange_rate; /* computed exchange rate for the leg */ char side[5]; /* trade side: "buy" or "sell" */ char order_param[32]; /* order parameter string for the executor */ double quote_volume; /* notional quote volume for the leg */ double base_increment; /* base asset lot size step */ double quote_increment; /* quote asset lot size step */ double base_min_size; /* minimum base asset order size */ } signal_leg_t; /* Collection of up to 3 legs comprising a triangular signal */ typedef struct { uint8_t leg_count; /* number of legs (typically 3) */ signal_leg_t legs[3]; /* the individual leg descriptors */ } signal_legs_t; /* Entry describing one triangular arbitrage opportunity */ typedef struct { char triangle_key[CURRENCY_NAME_LEN * 3 + 4]; /* unique triangle identifier e.g. "BTC-ETH-USDT" */ char primary_quote[CURRENCY_NAME_LEN]; /* primary quote currency of the triangle */ double predicted_bps; /* predicted profit in basis points */ char max_volume[32]; /* max trade volume as string */ double starting_volume; /* recommended starting volume */ bool live; /* whether this entry is from live (vs simulated) data */ int64_t ts_ms; /* signal generation timestamp */ int64_t book_ts_ms; /* reference order book timestamp */ int64_t t_sock_arrive_ms; /* timestamp when bytes arrived at SSL_read */ int64_t t_arrive_ms; /* arrival timestamp at evaluator (post-parse) */ int64_t t_eval_ms; /* evaluation completion timestamp */ uint8_t book_count; /* number of books used (typically 3) */ signal_book_t books[3]; /* order book snapshots for each leg */ signal_legs_t legs; /* leg descriptors for execution */ } signal_entry_t; /* Lock-free single-producer single-consumer queue for signal entries */ typedef struct { signal_entry_t *buffer; /* ring buffer of entries */ _Atomic uint32_t head; /* consumer read index (atomic) */ _Atomic uint32_t tail; /* producer write index (atomic) */ int eventfd; /* eventfd for waking consumer */ uint32_t depth; /* capacity of the ring buffer */ uint32_t dropped; /* count of dropped entries due to full queue */ } spsc_queue_t; /* Initialise an SPSC queue backed by a wakeup eventfd */ int spsc_init(spsc_queue_t *q, int wakeup_fd); /* Destroy an SPSC queue and free its buffer */ void spsc_destroy(spsc_queue_t *q); /* Push an entry into the queue (non-blocking); returns false if full */ bool spsc_push(spsc_queue_t *q, const signal_entry_t *entry); /* Pop an entry from the queue (non-blocking); returns false if empty */ bool spsc_pop(spsc_queue_t *q, signal_entry_t *entry); /* Returns true if the queue is empty */ bool spsc_empty(const spsc_queue_t *q); /* Returns the number of entries currently in the queue */ uint32_t spsc_count(const spsc_queue_t *q); #endif