ores.trading.structure
Table of Contents
The immutable identity of a deal assembled from several trades. It holds what never changes for the deal's life: the party, the counterparty, the kind of binding, the template it was shaped by, and its parent when it is itself a leg of a larger deal.
It is the anchor of the composition ladder. The legs are not owned children: a trade points at the structure that holds it, so the same trade can be unlinked from one deal and linked to another without being rewritten. The economics live on the legs, and the structure's internal version is read from them rather than stored beside them.
A structure nests one level at most, because a deal inside a deal inside a deal has no confirmation to hang on. The insert trigger enforces it.
1. Flags
2. Columns
2.1. id
The structure id: the firm's own identifier of the deal.
ctx.generate_uuid()
2.2. party_id
The firm's legal entity that is party to the deal. Every leg shares it, and the pin on the leg is what keeps the sharing true.
ctx.generate_uuid()
2.3. counterparty_id
The counterparty the deal is struck with. Every leg shares it.
ctx.generate_uuid()
2.4. kind
The rung of the composition ladder the deal sits on, which is what decides whether it confirms as one document or trade by trade.
std::string("Strategy")
2.5. template_code
The template that shaped the deal, when one did. A package has none, because it binds its legs to nothing and no template describes it.
std::string("Straddle")
2.6. parent_structure_id
The structure this one is a leg of, when the deal nests. Null for a deal the customer sees on its own.
ctx.generate_uuid()
3. SQL
3.1. Flags
3.2. Indexes
The two indexes answer a lookup by party or by counterparty.
| name | columns | unique | current_only | where_extra |
3.3. Extra drops
drop function if exists ores_trading_validate_structure_fn;
4. Insert trigger
-- Structures nest one level at most. A structure that has a parent is a -- leg of a larger deal, and a leg carries no legs of its own: the -- confirmation hangs on the deal the customer sees, and there is no -- second deal above it to confirm. if NEW.parent_structure_id is not null and exists ( select 1 from ores_trading_structures_tbl where tenant_id = NEW.tenant_id and id = NEW.parent_structure_id and parent_structure_id is not null ) then raise exception 'Invalid parent_structure_id: %. The parent is itself a leg, and structures nest one level at most.', NEW.parent_structure_id using errcode = '23514'; end if; -- A structure is not its own parent. if NEW.parent_structure_id = NEW.id then raise exception 'Invalid parent_structure_id: %. A structure cannot be its own parent.', NEW.parent_structure_id using errcode = '23514'; end if;
5. Foreign keys
5.1. kind
The kind catalogue is system reference data.
5.2. template_code
The template catalogue is system reference data. A package rests on no template, so the column is nullable.
5.3. parent_structure_id
A database foreign key: the parent is immutable, so the key can be enforced rather than checked.
6. C++
6.1. Flags
6.2. Repository
6.3. Domain includes
#include <string> #include <boost/uuid/uuid.hpp>
6.4. Conventions
6.5. Table display
| column | header |
|---|---|
| id | Structure Id |
| kind | Kind |
| template_code | Template |
| parent_structure_id | Parent |
| party_id | Party |
6.6. Custom repository methods
6.7. Naming a structure
A structure is grouped before anybody can book a leg into it, so the grouping is where it needs a name: every write gives a structure that has no internal reference one. The service names it after the repository writes the row.
#include "ores.trading.api/domain/structure_identifier.hpp" #include "ores.trading.core/repository/structure_identifier_repository.hpp"
/** * @brief The prefix a deal reference carries for a kind of structure. * * The desk reads a reference and knows what it is looking at, so the prefix is * the kind's and not a house-wide one. An unknown kind takes the structure * prefix rather than no prefix at all: a reference is what makes a deal * addressable, and a missing one is worse than an approximate one. */ std::string reference_prefix(const std::string& kind) { if (kind == "Package") return "PKG"; if (kind == "Strategy") return "STR"; if (kind == "Typed") return "TYP"; if (kind == "Dynamic") return "DYN"; return "STR"; } /** * @brief Names a structure that has no reference yet. * * A structure is grouped before anybody can book a leg into it, so the grouping * is where it needs a name. The value is derived from the structure's own id, * which is unique already, so two structures cannot collide and no counter has * to be kept. * * This runs on every write and not only on a creation. The structure and its * identifier are two statements, so a run cut between them would otherwise * leave a deal that no later write ever names again. */ void name_structure(const ores::database::context& ctx, const domain::structure& value) { repository::structure_identifier_repository identifiers; const auto named = identifiers.read_latest(ctx, boost::uuids::to_string(value.id), std::string("Internal")); if (!named.empty()) return; domain::structure_identifier identifier; identifier.tenant_id = value.tenant_id; identifier.structure_id = value.id; identifier.id_type = "Internal"; identifier.id_value = reference_prefix(value.kind) + "-" + boost::uuids::to_string(value.id).substr(0, 8); identifier.modified_by = value.modified_by; identifier.performed_by = value.performed_by; identifier.change_reason_code = value.change_reason_code; identifier.change_commentary = value.change_commentary; identifier.recorded_at = value.recorded_at; // The claim is the identifier's own: a structure's claim speaks about the // structure, and a version on it would mean nothing here. identifiers.write( ctx, identifier, {ores::utility::domain::precondition_kind::must_not_exist, std::nullopt}); }
name_structure(ctx_, value);
for (const auto& written_value : batch) name_structure(ctx_, written_value);
7. See also
- ores.trading — component group overview.
- Trade Structures and Deal Composition — the ladder, the topology and the versioning rules.
- ores.trading.structure_kind — the rung this row states.
- ores.trading.structure_template — the shape the deal was built from.