93 lines
4.8 KiB
C
93 lines
4.8 KiB
C
#ifndef FUSED_QUEUE_H
|
|
#define FUSED_QUEUE_H
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include <stdatomic.h>
|
|
#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
|