File size: 4,807 Bytes
8f4d2d0 a3b10ab 8f4d2d0 5759f0b 8f4d2d0 5759f0b 8f4d2d0 5759f0b 8f4d2d0 a3b10ab 8f4d2d0 a3b10ab 8f4d2d0 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #pragma once
#include <cstdint>
#include <string>
#include <chrono>
#include <limits>
namespace eunex {
// ββ Price representation (fixed-point, 8 decimal places) βββββββββββ
// Optiq uses integer-scaled prices to avoid floating-point in the hot path.
// 1 price unit = 10^-8. E.g., price 12.50 EUR = 1'250'000'000.
using Price_t = int64_t;
constexpr int64_t PRICE_SCALE = 100'000'000LL;
constexpr Price_t NULL_PRICE = std::numeric_limits<int64_t>::min();
inline Price_t toFixedPrice(double p) {
return static_cast<Price_t>(p * PRICE_SCALE);
}
inline double toDouble(Price_t p) {
return static_cast<double>(p) / PRICE_SCALE;
}
// ββ Quantity ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
using Quantity_t = uint64_t;
// ββ Identifiers ββββββββββββββββββββββββββββββββββββββββββββββββββββ
using OrderId_t = uint64_t;
using ClOrdId_t = uint64_t;
using SymbolIndex_t = uint32_t;
using TradeId_t = uint64_t;
using SessionId_t = uint16_t;
using MemberId_t = uint16_t;
// ββ Enumerations matching Optiq/SBE definitions ββββββββββββββββββββ
enum class Side : uint8_t {
Buy = 1,
Sell = 2
};
enum class OrderType : uint8_t {
Market = 1,
Limit = 2,
StopMarket = 3,
StopLimit = 4
};
enum class TimeInForce : uint8_t {
Day = 0,
GTC = 1,
IOC = 3,
FOK = 4
};
enum class OrderStatus : uint8_t {
New = 0,
PartiallyFilled = 1,
Filled = 2,
Cancelled = 4,
Rejected = 8
};
enum class MessageType : uint8_t {
NewOrder = 1,
ModifyOrder = 2,
CancelOrder = 3,
MassCancel = 4
};
// ββ Trading phases βββββββββββββββββββββββββββββββββββββββββββββββββ
enum class TradingPhase : uint8_t {
PreOpen = 0,
Opening = 1,
CTS = 2,
Closed = 3
};
// ββ Timestamps βββββββββββββββββββββββββββββββββββββββββββββββββββββ
using Timestamp_ns = uint64_t;
inline Timestamp_ns nowNs() {
auto now = std::chrono::steady_clock::now();
return std::chrono::duration_cast<std::chrono::nanoseconds>(
now.time_since_epoch()).count();
}
// ββ Order structure (compact, cache-friendly) ββββββββββββββββββββββ
// This is the resting order on the book. Incoming order events use
// the Event structs defined in actor headers.
#pragma pack(push, 1)
struct Order {
OrderId_t orderId;
ClOrdId_t clOrdId;
SymbolIndex_t symbolIdx;
Side side;
OrderType ordType;
TimeInForce tif;
Price_t price;
Quantity_t quantity;
Quantity_t remainingQty;
Timestamp_ns entryTime;
SessionId_t sessionId;
OrderStatus status;
Price_t stopPrice;
};
#pragma pack(pop)
// ββ Trade structure ββββββββββββββββββββββββββββββββββββββββββββββββ
#pragma pack(push, 1)
struct Trade {
TradeId_t tradeId;
SymbolIndex_t symbolIdx;
Price_t price;
Quantity_t quantity;
OrderId_t buyOrderId;
OrderId_t sellOrderId;
ClOrdId_t buyClOrdId;
ClOrdId_t sellClOrdId;
Timestamp_ns matchTime;
SessionId_t buySessionId;
SessionId_t sellSessionId;
};
#pragma pack(pop)
// ββ Execution report βββββββββββββββββββββββββββββββββββββββββββ
struct ExecutionReport {
OrderId_t orderId;
ClOrdId_t clOrdId;
OrderStatus status;
Quantity_t filledQty;
Quantity_t remainingQty;
Price_t lastPrice;
Quantity_t lastQty;
TradeId_t tradeId;
};
// ββ Member holding (for Clearing House) βββββββββββββββββββββββββββ
struct MemberHolding {
SymbolIndex_t symbolIdx;
int64_t quantity;
Price_t avgCost;
};
// ββ Symbol definition ββββββββββββββββββββββββββββββββββββββββββββββ
struct SymbolDef {
SymbolIndex_t index;
char isin[12];
char mnemonic[8];
Price_t tickSize;
Quantity_t lotSize;
};
} // namespace eunex
|