8#include "fastmm/core/config_macros.hpp"
9#include "fastmm/core/containers/flat_map.hpp"
10#include "fastmm/core/containers/static_vector.hpp"
13#include "fastmm/core/fixed_string.hpp"
25using Symbol = FixedString<20>;
28 enum Flags : std::uint8_t {
33 kReduceOnlySupported = 1U << 2,
37 kCoinQuoted = 1U << 3,
44 std::uint8_t flags = 0;
45 std::uint8_t price_decimals = 8;
51 Qty contract_multiplier = Qty::from_int(1);
54 std::int64_t expiry_ns = 0;
57 FixedString<8> base{};
58 FixedString<8> quote{};
60 std::uint8_t cold_pad_[8] = {};
62 [[nodiscard]]
constexpr bool enabled() const noexcept {
return (flags & kEnabled) != 0; }
63 [[nodiscard]]
constexpr bool inverse() const noexcept {
return (flags & kInverse) != 0; }
64 [[nodiscard]]
constexpr bool coin_quoted() const noexcept {
return (flags & kCoinQuoted) != 0; }
72 [[nodiscard]]
constexpr Price ticks(std::int64_t n)
const noexcept {
return tick * n; }
74 return p.is_positive() &&
on_tick(p, tick);
77 return q.is_positive() &&
on_lot(q, lot) && q >= min_qty && (max_qty.is_zero() || q <= max_qty);
84 if (!p.is_positive())
return Notional{};
85 return Notional::from_raw(
86 static_cast<std::int64_t
>(
static_cast<Int128
>(q.raw) * contract_multiplier.
raw / p.raw));
89 if (contract_multiplier == Qty::from_int(1))
return n;
90 return Notional::from_raw(
mul_raw(n, contract_multiplier));
97 return Notional::from_raw(
mul_raw(tick, contract_multiplier));
102 if (!from.is_positive() || !to.is_positive())
return Notional{};
103 const Int128 num =
static_cast<Int128
>(qty.raw) * contract_multiplier.
raw * (to.raw - from.raw);
104 const Int128 den =
static_cast<Int128
>(from.raw) * to.raw;
105 return Notional::from_raw(
static_cast<std::int64_t
>(num / den));
110 return inverse() ? base.view() : quote.view();
113 return asset_class == AssetClass::Perpetual || asset_class == AssetClass::Future ||
114 asset_class == AssetClass::Option;
117static_assert(
sizeof(Instrument) == 128);
118static_assert(
alignof(Instrument) == 64);
119static_assert(std::is_trivially_copyable_v<Instrument>);
128 [[nodiscard]]
bool mixed() const noexcept {
return other !=
nullptr; }
150 if (inst.symbol.empty())
return fail(InstrumentError::EmptySymbol);
151 if (!inst.tick.is_positive())
return fail(InstrumentError::InvalidTick);
152 if (!inst.lot.is_positive())
return fail(InstrumentError::InvalidLot);
153 if (by_id_.full())
return fail(InstrumentError::TableFull);
154 const InstrumentId id{
static_cast<std::uint32_t
>(by_id_.size())};
155 auto [p, inserted] = by_symbol_.insert(
Key{inst.
venue, inst.symbol}, id);
156 if (!inserted)
return fail(InstrumentError::DuplicateSymbol);
157 by_id_.push_back(inst);
158 by_id_[
id.value].id = id;
162 [[nodiscard]] std::size_t
size() const noexcept {
return by_id_.size(); }
165 FASTMM_ASSERT(contains(
id));
166 return by_id_[
id.value];
169 FASTMM_ASSERT(contains(
id));
170 return by_id_[
id.value];
175 return id ==
nullptr ? nullptr : &by_id_[
id->value];
178 [[nodiscard]]
const Instrument*
end() const noexcept {
return by_id_.end(); }
186 if (!inst.enabled())
continue;
187 if (m.
first ==
nullptr) {
190 (inst.settlement_ccy().empty() && inst.inverse() != m.
first->
inverse())) {
203 StaticVector<Instrument, kMaxInstruments> by_id_;
204 FlatMap<Key, InstrumentId, kMaxInstruments> by_symbol_;
Dense-by-id table built at startup; symbol lookup is a sorted FlatMap keyed by (venue,...
Definition instrument.hpp:141
bool contains(InstrumentId id) const noexcept
Definition instrument.hpp:163
SettlementMix settlement_mix() const noexcept
Two instruments settle alike when they name the same settlement currency, linear or inverse (Deribit'...
Definition instrument.hpp:183
const Instrument * find(VenueId venue, std::string_view symbol) const noexcept
Definition instrument.hpp:173
std::size_t size() const noexcept
Definition instrument.hpp:162
const Instrument & operator[](InstrumentId id) const noexcept
Definition instrument.hpp:172
Instrument & get(InstrumentId id) noexcept
Definition instrument.hpp:168
const Instrument & get(InstrumentId id) const noexcept
Definition instrument.hpp:164
void clear() noexcept
Definition instrument.hpp:197
Result< InstrumentId, InstrumentError > add(const Instrument &inst) noexcept
Definition instrument.hpp:149
const Instrument * begin() const noexcept
Definition instrument.hpp:177
const Instrument * end() const noexcept
Definition instrument.hpp:178
const Instrument * data() const noexcept
Definition instrument.hpp:179
Minimal expected<T, E>: the hot path never throws, it returns Result.
Fixed<Tag>: int64 fixed point with a global 1e-8 scale (ADR-0001).
Definition strategy.hpp:16
constexpr Qty round_to_lot(Qty q, Qty lot) noexcept
Quantities always round down (never send more than intended).
Definition fixed_point.hpp:405
AssetClass
Definition enums.hpp:51
Side
Definition enums.hpp:12
constexpr Unexpected< std::decay_t< E > > fail(E &&e) noexcept
Definition result.hpp:25
constexpr std::size_t kMaxInstruments
Definition instrument.hpp:26
constexpr std::int64_t mul_raw(Fixed< A > a, Fixed< B > b) noexcept
Generic scaled multiply for fixed*fixed in one domain (e.g. qty * multiplier).
Definition fixed_point.hpp:367
constexpr bool on_lot(Qty q, Qty lot) noexcept
Definition fixed_point.hpp:409
InstrumentError
Definition instrument.hpp:131
OptionType
Definition enums.hpp:77
FixedString< 20 > Symbol
Definition instrument.hpp:27
constexpr Notional mul(Price p, Qty q) noexcept
price * qty with a 128-bit intermediate, truncated toward zero to 1e-8.
Definition fixed_point.hpp:362
constexpr Price round_to_tick(Price p, Price tick, Side side) noexcept
Round to the tick grid in the passive direction: bids down, asks up. tick > 0.
Definition fixed_point.hpp:388
constexpr bool on_tick(Price p, Price tick) noexcept
Definition fixed_point.hpp:401
Strongly typed identifiers.
std::int64_t raw
Definition fixed_point.hpp:152
Definition instrument.hpp:143
Symbol symbol
Definition instrument.hpp:145
VenueId venue
Definition instrument.hpp:144
constexpr auto operator<=>(const Key &) const noexcept=default
Definition instrument.hpp:29
constexpr bool inverse() const noexcept
Definition instrument.hpp:63
constexpr std::string_view settlement_ccy() const noexcept
The currency PnL, fees and notional are denominated in: the base coin for an inverse contract,...
Definition instrument.hpp:109
constexpr Qty round_qty(Qty q) const noexcept
Definition instrument.hpp:70
constexpr bool valid_qty(Qty q) const noexcept
Definition instrument.hpp:76
constexpr Notional notional(Price p, Qty q) const noexcept
Notional in the settlement currency: price * qty * multiplier for a linear contract,...
Definition instrument.hpp:82
constexpr Price ticks(std::int64_t n) const noexcept
n ticks as a price distance (tick * n).
Definition instrument.hpp:72
constexpr bool is_derivative() const noexcept
Definition instrument.hpp:112
constexpr bool coin_quoted() const noexcept
Definition instrument.hpp:64
constexpr bool enabled() const noexcept
Definition instrument.hpp:62
constexpr Notional inverse_pnl(Price from, Price to, Qty qty) const noexcept
PnL in the base coin of moving qty contracts from from to to: qty * multiplier * (1/from - 1/to).
Definition instrument.hpp:101
constexpr Price round_price(Price p, Side side) const noexcept
Passive rounding: bids down, asks up.
Definition instrument.hpp:67
constexpr Notional pnl_per_tick() const noexcept
PnL change (settlement ccy) for one tick move on one contract.
Definition instrument.hpp:95
constexpr bool valid_price(Price p) const noexcept
Definition instrument.hpp:73
Instruments do not all settle in the same currency: an inverse contract settles in its base coin,...
Definition instrument.hpp:125
bool mixed() const noexcept
Definition instrument.hpp:128
const Instrument * first
first enabled instrument
Definition instrument.hpp:126
const Instrument * other
first enabled instrument that settles in another currency
Definition instrument.hpp:127