ores.trading.structure_member

Table of Contents

The link between a structure and one of its legs. The trade is not owned by the deal: it points at it, so the same trade can be unlinked from one structure and linked to another without being rewritten.

The row is keyed by the trade and is temporal, which says the rule directly: a trade sits in at most one structure at a time, and unlinking closes the row rather than deleting it. The history of what a trade belonged to survives.

The member copies the party and the counterparty from its structure, and the pins hold the copies to their source, so a leg cannot disagree with the deal it belongs to. The insert trigger holds a leg to the roles its template allows, and to the number of legs the template states for that role.

1. Flags

2. Columns

2.1. trade_id

The trade that is a leg of the deal. Keying the table on it is the rule that a trade belongs to one structure at a time.

ctx.generate_uuid()

2.2. structure_id

The deal the trade is a leg of.

ctx.generate_uuid()

2.3. role

The part the leg plays, which the structure's template must allow: the body of a butterfly, the wing of a risk reversal, the premium leg.

std::string("leg")

2.4. sequence_number

The leg's ordinal within its role, counting from one.

1

2.5. member_label

The name the parent states the member by, when it is not the member's own id: a total return swap names each underlying by its Derivative/Id, while the trade inside states an id of its own.

3. SQL

3.1. Flags

3.2. Checks

An ordinal counts from one.

expression
"sequence_number" >= 1

3.3. Extra drops

drop function if exists ores_trading_validate_structure_member_fn;

4. Insert trigger

-- A leg fills a role its template allows, and no more legs than the
-- template states for that role. A package rests on no template, so it
-- constrains nothing and any role is allowed.
declare
    v_template text;
    v_max      integer;
    v_used     integer;
begin
    select template_code into v_template
    from ores_trading_structures_tbl
    where tenant_id = NEW.tenant_id and id = NEW.structure_id;

    if v_template is not null then
        select max_legs into v_max
        from ores_trading_structure_template_roles_tbl
        where tenant_id = ores_utility_system_tenant_id_fn()
          and template_code = v_template
          and role = NEW.role
          and valid_to = ores_utility_infinity_timestamp_fn();

        if not found then
            raise exception 'Invalid role: %. The template % does not allow this role.',
                NEW.role, v_template
                using errcode = '23514';
        end if;

        -- A maximum of zero means the role states no upper bound.
        if v_max > 0 then
            select count(*) into v_used
            from ores_trading_structure_members_tbl
            where tenant_id = NEW.tenant_id
              and structure_id = NEW.structure_id
              and role = NEW.role
              and valid_to = ores_utility_infinity_timestamp_fn();

            if v_used >= v_max then
                raise exception 'Invalid role: %. The template % allows % of that role and the structure holds %.',
                    NEW.role, v_template, v_max, v_used
                    using errcode = '23514';
            end if;
        end if;
    end if;
end;

5. Foreign keys

5.1. trade_id

A database foreign key: the anchor is immutable.

5.2. structure_id

A database foreign key: the structure is immutable.

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
trade_id Trade
structure_id Structure
role Role
sequence_number Sequence
version Version

6.6. Custom repository methods

7. See also

Emacs 29.3 (Org mode 9.6.15)