Price Type#
OUCH 5.0 uses a custom price format: UInt64 on wire (8 bytes), UInt32 for value (4 bytes) with 4 implied decimals. The library provides a Price type for type-safe price handling.
Overview#
OUCH 5.0 prices are encoded as 64-bit unsigned integers on the wire (8 bytes), though only the lower 32 bits are used, with 4 implied decimal places:
Raw value: Integer representation (e.g., 1505000)
Decimal value: $150.50 (1505000 / 10000)
The Price type provides:
Type-safe price operations
Conversion to/from floating-point values
Market order sentinel value for cross orders
Automatic handling of the 4-decimal format
Creating Prices#
From Double#
The most common way to create a price:
Price price = Price::from_double(150.50); // $150.50 -> 1505000 (raw value)
From Raw Value#
If you have the raw integer value:
UInt64 raw_value = 1505000; // $150.50
Price price(raw_value);
// Or using factory method:
Price price = Price::from_uint64(1505000);
// For backward compatibility with UInt32:
Price price = Price::from_uint32(1505000);
Converting Prices#
To Double#
Price price = Price::from_double(150.50);
double float_value = price.to_double(); // 150.50
To Raw Value#
Price price = Price::from_double(150.50);
UInt64 raw_value = price.value(); // 1505000
Market Order Sentinel#
For market orders in cross orders, OUCH 5.0 uses a special sentinel value:
Price market_price = Price::market_order_sentinel();
// Raw value: 0xFFFFFFFF (4294967295)
// Used as market order indicator in cross orders
Price Operations#
Comparison#
Price price1 = Price::from_double(150.50);
Price price2 = Price::from_double(150.75);
if (price1 < price2) {
// price1 is lower
}
if (price1 == price2) {
// prices are equal
}
Arithmetic#
The Price type does not provide arithmetic operators. To perform arithmetic operations, convert to raw values:
Price price1 = Price::from_double(150.50);
Price price2 = Price::from_double(0.25);
// Manual arithmetic using raw values
UInt64 sum_raw = price1.value() + price2.value();
Price sum = Price::from_uint64(sum_raw);
UInt64 diff_raw = price1.value() - price2.value();
Price diff = Price::from_uint64(diff_raw);
Using Prices in Messages#
Setting Prices#
EnterOrder order;
order.set_price(Price::from_double(150.50));
Getting Prices#
void on_order_accepted(Session* s, std::uint64_t seq, const OrderAccepted* msg) {
Price accepted_price = msg->get_price();
double price_value = accepted_price.to_double();
std::cout << "Accepted price: $" << price_value << std::endl;
}
Price Limits#
OUCH 5.0 has specific price limits:
Maximum price: $199,999.9900 (raw value: 0x7735939C)
Market order sentinel: 0xFFFFFFFF (4294967295) - used as indicator for market orders in cross orders
API Reference#
Price Class#
class Price {
public:
// Constructors
Price();
explicit Price(UInt64 value);
// Factory methods
static Price from_double(double price);
static Price from_uint64(UInt64 raw_value) noexcept;
static Price from_uint32(UInt32 raw_value) noexcept; // Backward compatibility
static Price market_order_sentinel();
// Conversions
double to_double() const;
UInt64 value() const; // Get raw UInt64 value
// Validation
bool is_market_order_sentinel() const;
bool is_valid() const;
// Comparison operators
bool operator==(const Price& other) const noexcept;
bool operator!=(const Price& other) const noexcept;
bool operator<(const Price& other) const noexcept;
bool operator<=(const Price& other) const noexcept;
bool operator>(const Price& other) const noexcept;
bool operator>=(const Price& other) const noexcept;
};
from_double#
static Price from_double(double value);
Creates a Price from a floating-point value.
Parameters:
value: Price as double (e.g., 150.50)
Returns: Price object
Example:
Price price = Price::from_double(150.50);
to_double#
double to_double() const;
Converts the price to a floating-point value.
Returns: Price as double
Example:
Price price = Price::from_double(150.50);
double value = price.to_double(); // 150.50
value#
UInt64 value() const;
Returns the raw integer value (UInt64, with 4 implied decimals).
Returns: Raw price value as UInt64
Example:
Price price = Price::from_double(150.50);
UInt64 raw = price.value(); // 1505000
market_order_sentinel#
static Price market_order_sentinel();
Returns the special sentinel value used for market orders in cross orders.
Returns: Market order sentinel price
Example:
Price market = Price::market_order_sentinel();
// Use in cross orders
order.set_price(market);
Example: Complete Price Usage#
#include <nasdaq/ouch50/Types.h>
using namespace b2bits::nasdaq::ouch5;
// Create prices
Price limit_price = Price::from_double(150.50);
Price market_price = Price::market_order_sentinel();
// Use in order
EnterOrder order;
order.set_price(limit_price);
// Compare prices
Price price1 = Price::from_double(150.50);
Price price2 = Price::from_double(150.75);
if (price1 < price2) {
std::cout << "Price1 is lower" << std::endl;
}
// Convert for display
double display_price = limit_price.to_double();
std::cout << "Price: $" << display_price << std::endl;
// Get price from message
void on_order_executed(Session* s, std::uint64_t seq, const OrderExecuted* msg) {
Price exec_price = msg->get_execution_price();
double price_value = exec_price.to_double();
std::cout << "Executed at: $" << price_value << std::endl;
}
Best Practices#
Use from_double(): Prefer
Price::from_double()for creating prices from user inputType safety: Always use
Pricetype instead of raw integersMarket orders: Use
market_order_sentinel()for market orders in cross ordersDisplay: Convert to double only when displaying to users
Precision: Be aware of the 4-decimal precision limit