Index: docs/P1-ConceptualModel/ERModel.md
===================================================================
--- docs/P1-ConceptualModel/ERModel.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/ERModel.md	(revision 1549dae4501012cfe2bffe1c5e9bdfdfb9dd62bd)
@@ -1,7 +1,7 @@
-# Entity-Relationship Model v.04
+# Entity-Relationship Model v.05
 
 ## Diagram
 
-![ERModel_v04](ERModel_v04.png)
+![ERModel_v05](ERModel_v05.png)
 
 Notation: Chen. Rectangles are entity sets, diamonds are relationships, ellipses
@@ -11,12 +11,22 @@
 single line marks partial participation.
 
-Two deliberate modeling decisions worth stating up front:
+Three deliberate modeling decisions worth stating up front:
 
 - **No foreign keys appear in the diagram.** Connections between entity sets are
   expressed as relationships, per the notation. Foreign-key columns appear only
   in the relational model in [RelationalDesign](../P2-RelationalDesign/RelationalDesign.md).
-- **`Holds` and `Contains` are relationships, not entity sets.** Both are M:N and
-  both carry their own attributes, which is exactly what a Chen relationship is
-  for. They become tables (`holdings`, `watchlist_items`) only in P2.
+- **A position and a watchlist entry are entity sets, not M:N relationships.**
+  `Holdings` (a user's position in an asset) and `WatchlistItems` (an asset on a
+  watchlist) each have their own identifier `id`, and each is connected by two
+  1:N relationships: `Holds` and `PositionIn` for a holding, `Contains` and
+  `Lists` for a watchlist item. Until v04 they were drawn as the M:N
+  relationships `Holds` and `Contains`, but the database has always given
+  `holdings` and `watchlist_items` their own `id` primary key. That is how an
+  entity set is implemented, not an M:N relationship, whose key would be the
+  pair of participating keys. v05 corrects the model to match; see
+  [history](#entity-relationship-model-history).
+- **Key and uniqueness rules are stated with entity and relationship names,
+  never with foreign-key columns.** For example: "a crypto is quoted at most
+  once per currency", not "`{crypto_id, quote_currency}` is unique".
 
 ## Data requirements
@@ -46,5 +56,5 @@
 | `id` | UUID | PK, required |
 | `username` | text(50) | required, unique |
-| `email` | text(255) | required, unique, contains `@` |
+| `email` | text(255) | required, unique, contains `@` (checked by the application at registration, not by a database constraint) |
 | `full_name` | text(200) | optional |
 | `password_hash` | text(255) | required — never the password itself; the prototype stores a SHA-256 hex digest |
@@ -79,8 +89,10 @@
 trades, candles and orders all reference the pair, not the asset.
 
-**Keys:** candidates `{id}`, `{crypto_id, quote_currency}` — that pair is
-unique by definition, since a given asset can only be quoted once per
-currency; primary key **`id`**, so that the many entity sets referencing a
-market carry one narrow column instead of a composite key.
+**Keys:** candidate `{id}`; primary key **`id`**, so that the many entity sets
+related to a market need one narrow identifier instead of a composite one.
+**Uniqueness rule:** a crypto is quoted at most once per currency, so the crypto
+a market is `QuotedOn` together with its `quote_currency` identifies the market
+as well. Chen notation cannot draw this, because half of it comes through a
+relationship. P2 enforces it as `UNIQUE(crypto_id, quote_currency)`.
 
 | Attribute | Type | Constraints |
@@ -98,5 +110,5 @@
 
 Placing an order is what triggers a **reservation** of whatever it commits:
-the crypto being sold (`Holds.reserved_quantity`, below) on a sell, and the
+the crypto being sold (`Holdings.reserved_quantity`, below) on a sell, and the
 cash (`Users.reserved_balance`) on a buy. Since v04 (after P7) an order can
 wait in the order book and be filled in parts, so `status` is a real
@@ -121,5 +133,5 @@
 | `quantity` | numeric(20,4) | required, > 0 |
 | `filled_quantity` | numeric(20,4) | required, default 0, between 0 and `quantity` — how much has been traded; remaining = `quantity − filled_quantity` (added in v04, after P7) |
-| `price` | numeric(18,6) | the limit price; for a market order, the market price when it was placed |
+| `price` | numeric(18,6) | optional — the limit price; for a market order, the market price when it was placed |
 | `placed_at` | timestamptz | required, defaults to now |
 | `executed_at` | timestamptz | optional, set when the order settles |
@@ -148,6 +160,6 @@
 writes directly.
 
-**Keys:** candidate `{id}` — `{market_id, executed_at}` looks unique in
-principle, but two trades can share a timestamp, so it is not a safe key;
+**Keys:** candidate `{id}` — "market plus `executed_at`" looks unique in
+principle, but two trades on a market can share a timestamp, so it is not a safe key;
 primary key **`id`** (a plain auto-incrementing integer here rather than a
 UUID, because this is the highest-volume entity set and it is only ever read
@@ -156,5 +168,5 @@
 | Attribute | Type | Constraints |
 |---|---|---|
-| `id` | integer | PK, required, auto-generated |
+| `id` | big integer | PK, required, auto-generated (`bigserial` in P2) |
 | `executed_at` | timestamptz | required |
 | `price` | numeric(18,6) | required, > 0 |
@@ -177,10 +189,10 @@
 | Attribute | Type | Constraints |
 |---|---|---|
-| `id` | integer | PK, required, auto-generated |
+| `id` | big integer | PK, required, auto-generated (`bigserial` in P2) |
 | `event_type` | text | required, `placed`, `partially_filled`, `filled` or `cancelled` |
 | `quantity` | numeric(20,4) | required — the ordered quantity for `placed`, the filled amount for a fill, the unfilled rest for `cancelled` |
 | `price` | numeric(18,6) | optional — the order price, or the trade price for a fill |
 | `status_after` | text | required, the order's status after the event |
-| `created_at` | timestamptz | required, defaults to now |
+| `created_at` | timestamptz | required, set automatically when the event is recorded (`clock_timestamp()`, so events inside one transaction keep their real order) |
 
 #### MarketCandles
@@ -190,12 +202,13 @@
 screen refresh does not scale.
 
-**Keys:** candidates `{id}`, `{market_id, timeframe, candle_time}` — a market
-has exactly one candle per timeframe per time bucket; primary key **`id`**, the
-composite is enforced as a uniqueness rule because it is the real-world
-constraint and it is what prevents duplicate candles.
-
-| Attribute | Type | Constraints |
-|---|---|---|
-| `id` | integer | PK, required, auto-generated |
+**Keys:** candidate `{id}`; primary key **`id`**. **Uniqueness rule:** a market
+has exactly one candle per timeframe per time bucket, so the market a candle
+`Aggregates` together with `timeframe` and `candle_time` also identifies it.
+This is the real-world constraint that prevents duplicate candles. P2 enforces
+it as `UNIQUE(market_id, timeframe, candle_time)`.
+
+| Attribute | Type | Constraints |
+|---|---|---|
+| `id` | big integer | PK, required, auto-generated (`bigserial` in P2) |
 | `timeframe` | text | required, `1m`, `5m`, `1h` or `1d` |
 | `open`, `high`, `low`, `close` | numeric(18,6) | all required |
@@ -208,7 +221,7 @@
 several lists ("long term", "watching today") and each needs its own name.
 
-**Keys:** candidate `{id}` — `{user_id, name}` would also work if list names
-were required to be unique per user, which the model does not impose, so it is
-not listed as a candidate key; primary key **`id`**.
+**Keys:** candidate `{id}`; primary key **`id`**. "Owner plus `name`" would
+also identify a list if names had to be unique per user, but the model does
+not require that, so there is no uniqueness rule here.
 
 | Attribute | Type | Constraints |
@@ -218,59 +231,18 @@
 | `created_at` | timestamptz | required, defaults to now |
 
-### Relationships
-
-#### QuotedOn — Cryptos (1) : Markets (N), total on Markets
-Ties a market to the asset it trades. One asset can be quoted in many markets;
-every market must have exactly one asset, hence total participation on the
-`Markets` side. No attributes.
-
-#### PlacedOn — Markets (1) : Orders (N), total on Orders
-Records which market an order was placed on. Every order must name a market;
-a market may have no orders yet. No attributes.
-
-#### Places — Users (1) : Orders (N), total on Orders
-Records who placed an order. Every order belongs to exactly one user; a new
-user has no orders. No attributes.
-
-#### Records — Users (1) : Transactions (N), total on Transactions
-Attributes each ledger entry to a user. Every entry belongs to exactly one
-user. No attributes.
-
-#### Settles — Orders (1) : Transactions (N), partial on both sides
-Links a ledger entry to the order that caused it. Partial on the
-`Transactions` side because deposits have no originating order, and partial on
-the `Orders` side because an order that never executes never produces a
-ledger entry — which is why the corresponding column is nullable in P2. No
-attributes.
-
-#### Fills — Markets (1) : MarketTrades (N), total on MarketTrades
-Every executed trade happened on exactly one market. No attributes.
-
-#### FillsBuy — Orders (1) : MarketTrades (N), partial on both sides
-*Added in v04, after P7.* The buy order a trade filled. An order can be
-filled by many trades (partial fills); a trade fills at most one buy order,
-and none when the simulated market was the buyer. No attributes.
-
-#### FillsSell — Orders (1) : MarketTrades (N), partial on both sides
-*Added in v04, after P7.* The sell order a trade filled, symmetric to
-`FillsBuy`. A trade between two users' orders participates in both. No
-attributes.
-
-#### Logs — Orders (1) : OrderEvents (N), total on OrderEvents
-*Added in v04, after P7.* Every event belongs to exactly one order. No
-attributes.
-
-#### Aggregates — Markets (1) : MarketCandles (N), total on MarketCandles
-Every candle summarises trades of exactly one market. No attributes.
-
-#### Owns — Users (1) : Watchlists (N), total on Watchlists
-Every watchlist belongs to exactly one user. No attributes.
-
-#### Holds — Users (M) : Cryptos (N), partial on both sides, **with attributes**
-A user's position in an asset. M:N because one user holds many assets and one
-asset is held by many users, and partial on both sides because a user may hold
-nothing and an asset may be held by nobody. Modeled as a relationship rather
-than an entity set because a position has no identity of its own — it is
-entirely described by *which user*, *which asset*, and how much.
+#### Holdings
+A user's position in one crypto asset: how much of it the user owns, how much
+of that is already promised to open sell orders, and at what average price it
+was accumulated. *An entity set since v05* (until v04 it was the M:N
+relationship `Holds`). A holding has its own identifier and its own
+lifecycle: it is created on the first buy, updated on every later fill, and
+the prototype reads and locks it as a unit (`SELECT … FOR UPDATE` on the sell
+path). It is linked to its owner through `Holds` and to its asset through
+`PositionIn`.
+
+**Keys:** candidate `{id}`; primary key **`id`**. **Uniqueness rule:** a user
+has at most one holding per crypto, so the user who `Holds` it together with
+the crypto it is a `PositionIn` also identifies a holding. P2 enforces this as
+`UNIQUE(user_id, crypto_id)`.
 
 `reserved_quantity` mirrors `available_balance`/`invested_balance` on `Users`:
@@ -284,18 +256,97 @@
 | Attribute | Type | Constraints |
 |---|---|---|
+| `id` | UUID | PK, required |
 | `quantity` | numeric(20,4) | required, ≥ 0 — total amount owned |
 | `reserved_quantity` | numeric(20,4) | required, default 0, `0 ≤ reserved_quantity ≤ quantity` — committed to the user's own open sell orders, not yet removed from the position |
-| `avg_price` | numeric(18,6) | required, ≥ 0, **derived** (dashed ellipse) — the weighted average of the prices at which the position was accumulated; derivable from the buy history, stored anyway so unrealised P/L can be shown without replaying the whole ledger |
+| `avg_price` | numeric(18,6) | required, default 0, ≥ 0, **derived** (dashed ellipse) — the weighted average of the prices at which the position was accumulated; derivable from the buy history, stored anyway so unrealised P/L can be shown without replaying the whole ledger |
 | `created_at` | timestamptz | required, defaults to now |
 | `updated_at` | timestamptz | optional |
 
-#### Contains — Watchlists (M) : Cryptos (N), partial on both sides, **with attribute**
-Which assets are on which watchlist. M:N: a list holds many assets, an asset
-appears on many lists. Partial on both sides — an empty list is valid and an
-asset need not be on any list.
-
-| Attribute | Type | Constraints |
-|---|---|---|
+#### WatchlistItems
+One asset placed on one watchlist. *An entity set since v05* (until v04 it was
+the M:N relationship `Contains`). It has its own identifier, and it is linked
+to its list through `Contains` and to its asset through `Lists`.
+
+**Keys:** candidate `{id}`; primary key **`id`**. **Uniqueness rule:** an asset
+appears at most once on a given list, so the watchlist that `Contains` an item
+together with the crypto it `Lists` also identifies the item. P2 enforces this
+as `UNIQUE(watchlist_id, crypto_id)`.
+
+| Attribute | Type | Constraints |
+|---|---|---|
+| `id` | UUID | PK, required |
 | `added_at` | timestamptz | required, defaults to now — recorded so a list can be shown in the order the user built it |
+
+### Relationships
+
+#### QuotedOn — Cryptos (1) : Markets (N), total on Markets
+Ties a market to the asset it trades. One asset can be quoted in many markets;
+every market must have exactly one asset, hence total participation on the
+`Markets` side. No attributes.
+
+#### PlacedOn — Markets (1) : Orders (N), total on Orders
+Records which market an order was placed on. Every order must name a market;
+a market may have no orders yet. No attributes.
+
+#### Places — Users (1) : Orders (N), total on Orders
+Records who placed an order. Every order belongs to exactly one user; a new
+user has no orders. No attributes.
+
+#### Records — Users (1) : Transactions (N), total on Transactions
+Attributes each ledger entry to a user. Every entry belongs to exactly one
+user. No attributes.
+
+#### Settles — Orders (1) : Transactions (N), partial on both sides
+Links a ledger entry to the order that caused it. Partial on the
+`Transactions` side because deposits have no originating order, and partial on
+the `Orders` side because an order that never executes never produces a
+ledger entry — which is why the corresponding column is nullable in P2. No
+attributes.
+
+#### Fills — Markets (1) : MarketTrades (N), total on MarketTrades
+Every executed trade happened on exactly one market. No attributes.
+
+#### FillsBuy — Orders (1) : MarketTrades (N), partial on both sides
+*Added in v04, after P7.* The buy order a trade filled. An order can be
+filled by many trades (partial fills); a trade fills at most one buy order,
+and none when the simulated market was the buyer. The role of `Orders` in this
+relationship is *the buy order* of the trade. No attributes.
+
+#### FillsSell — Orders (1) : MarketTrades (N), partial on both sides
+*Added in v04, after P7.* The sell order a trade filled, symmetric to
+`FillsBuy`; the role of `Orders` here is *the sell order* of the trade. A
+trade between two users' orders participates in both. No attributes.
+
+#### Logs — Orders (1) : OrderEvents (N), total on OrderEvents
+*Added in v04, after P7.* Every event belongs to exactly one order. No
+attributes.
+
+#### Aggregates — Markets (1) : MarketCandles (N), total on MarketCandles
+Every candle summarises trades of exactly one market. No attributes.
+
+#### Owns — Users (1) : Watchlists (N), total on Watchlists
+Every watchlist belongs to exactly one user. No attributes.
+
+#### Holds — Users (1) : Holdings (N), total on Holdings
+*1:N since v05.* Every holding belongs to exactly one user. A user may hold
+nothing yet, so participation is partial on the `Users` side. No attributes.
+
+#### PositionIn — Cryptos (1) : Holdings (N), total on Holdings
+*Added in v05.* Every holding is a position in exactly one crypto asset. An
+asset may be held by nobody. No attributes.
+
+Together, `Holds` and `PositionIn` still say what the old M:N `Holds` said:
+a user can hold many assets and an asset can be held by many users. The
+difference is that the position is now a thing with its own identity, not
+just a pair. The rule "at most one holding per user and crypto" is stated
+under [Holdings](#holdings).
+
+#### Contains — Watchlists (1) : WatchlistItems (N), total on WatchlistItems
+*1:N since v05.* Every watchlist item is on exactly one list. An empty list is
+valid, so participation is partial on the `Watchlists` side. No attributes.
+
+#### Lists — Cryptos (1) : WatchlistItems (N), total on WatchlistItems
+*Added in v05.* Every watchlist item names exactly one crypto asset. An asset
+need not be on any list. No attributes.
 
 ## Entity-Relationship Model History
@@ -341,5 +392,36 @@
   Nothing existing was removed or changed. See
   [AdvancedDatabaseDevelopment](../P7-AdvancedDatabaseDevelopment/AdvancedDatabaseDevelopment.md).
-  The diagram files are `ERModel_v04.xml` / `ERModel_v04.png`; earlier versions
+  The diagram files are `ERModel_v04.xml` / `ERModel_v04.png`.
+- **v05 — correction after review.** The review of P2 found that two parts of
+  the model were implemented differently in the database:
+  - `Contains` was an M:N relationship in the model, but `watchlist_items`
+    has its own `id` primary key;
+  - `Holds` was an M:N relationship in the model, but `holdings` has its own
+    `id` primary key.
+
+  An M:N relationship has no identifier of its own; its table's key is the pair
+  of participating keys. A table with its own `id` is the implementation of an
+  entity set. Every phase after P2 (the prototype, the reports and the P7
+  logic) already uses the database as it is. So the **model** was corrected to
+  match P2, not the other way round:
+  - `Holds` (M:N, with attributes) became the entity set `Holdings` (its former
+    attributes plus `id`) with two 1:N relationships, `Holds` (Users → Holdings)
+    and `PositionIn` (Cryptos → Holdings), both total on the `Holdings` side;
+  - `Contains` (M:N, with `added_at`) became the entity set `WatchlistItems`
+    (`id`, `added_at`) with `Contains` (Watchlists → WatchlistItems) and
+    `Lists` (Cryptos → WatchlistItems), both total on the `WatchlistItems`
+    side;
+  - the former keys of the two relationships are kept as uniqueness rules
+    ("one holding per user and crypto", "an asset at most once per list");
+  - the key descriptions of `Markets`, `MarketTrades`, `MarketCandles` and
+    `Watchlists` no longer name foreign-key columns (`crypto_id`,
+    `market_id`, `user_id`), which do not exist in an ER model;
+  - the diagram was redrawn on a grid with no overlapping attributes. In v04,
+    `Watchlists.id` was hidden behind `added_at`, and several attributes of
+    `Orders`, `Transactions`, `MarketTrades` and `MarketCandles` overlapped.
+    The grid also makes it easier to compare the diagram with the P2
+    relational diagram.
+
+  The diagram files are `ERModel_v05.xml` / `ERModel_v05.png`; earlier versions
   are kept.
 
Index: docs/P1-ConceptualModel/ERModelAIUsage.md
===================================================================
--- docs/P1-ConceptualModel/ERModelAIUsage.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/ERModelAIUsage.md	(revision 1549dae4501012cfe2bffe1c5e9bdfdfb9dd62bd)
@@ -13,5 +13,6 @@
 ### Diagram
 
-`ERModel_v01.xml` / `ERModel_v01.png`.
+Current version: `ERModel_v05.xml` / `ERModel_v05.png` (see session 5 below). First
+version: `ERModel_v01.xml` / `ERModel_v01.png`.
 
 **Declaration of how the diagram was produced.** The initial model is the
@@ -313,2 +314,32 @@
 **What I decided:** to add the P7 structure to the ER model. The new elements are placed
 automatically, so the layout can be tidied by hand in TerraER.
+
+
+### Session 5 — 2026-09-29 (Claude Opus 5.5): v05, correction after review
+
+**Prompt (student, excerpt):** I pasted the reviewer's comments that `Holds` and `Contains`
+are implemented differently in the database than in the model, with the suggestion to
+"correct only the Phase 1 model so that it matches Phase 2", and asked:
+
+> Can you take a look at this stuff? and fix them, but don't push anything just make the
+> changes requested and try to explain it to me to see if you understand the problem with
+> the solution
+
+**Response (AI, summarised):**
+
+- Explained that an M:N relationship has no identifier of its own, while `holdings` and
+  `watchlist_items` each have an `id` primary key, so the database treats them as entity
+  sets.
+- Changed the model to v05. `Holdings` (`id`, `quantity`, `reserved_quantity`, derived
+  `avg_price`, `created_at`, `updated_at`) and `WatchlistItems` (`id`, `added_at`) became
+  entity sets, with the 1:N relationships `Holds`, `PositionIn`, `Contains` and `Lists`,
+  each total on the new entity's side. The old relationship keys are now stated as
+  uniqueness rules. The key descriptions no longer name foreign-key columns.
+- Generated `ERModel_v05.xml` / `ERModel_v05.png` from scratch with TerraER 3.11's own figure
+  classes and writer (adapted from the v01 generator), on a grid, with no overlapping
+  attributes. It was verified by reading the file back with TerraER's reader (184 figures)
+  and by inspecting the rendered PNG.
+- Updated [ERModel](ERModel.md) (v05 sections and history entry).
+
+**What I decided:** to follow the reviewer's advice and change the model rather than the
+database, since every later phase already uses the database as it is.
Index: docs/P1-ConceptualModel/ERModel_v05.xml
===================================================================
--- docs/P1-ConceptualModel/ERModel_v05.xml	(revision 1549dae4501012cfe2bffe1c5e9bdfdfb9dd62bd)
+++ docs/P1-ConceptualModel/ERModel_v05.xml	(revision 1549dae4501012cfe2bffe1c5e9bdfdfb9dd62bd)
@@ -0,0 +1,1 @@
+<drawing><figures><ent id="0"><children><r id="1" x="255" y="396" w="210" h="72"/><t id="2" x="318.095703125" y="423.82794284820557"><a><text><string>WatchlistItems</string></text></a></t></children></ent><ent id="3"><children><r id="4" x="1263" y="396" w="210" h="72"/><t id="5" x="1346.3098373413086" y="423.82794284820557"><a><text><string>Cryptos</string></text></a></t></children></ent><ent id="6"><children><r id="7" x="2271" y="396" w="210" h="72"/><t id="8" x="2353.0858306884766" y="423.82794284820557"><a><text><string>Markets</string></text></a></t></children></ent><ent id="9"><children><r id="a" x="3279" y="396" w="210" h="72"/><t id="b" x="3341.5976943969727" y="423.82794284820557"><a><text><string>MarketCandles</string></text></a></t></children></ent><ent id="c"><children><r id="d" x="255" y="1188" w="210" h="72"/><t id="e" x="331.289794921875" y="1215.8279428482056"><a><text><string>Watchlists</string></text></a></t></children></ent><ent id="f"><children><r id="10" x="1263" y="1188" w="210" h="72"/><t id="11" x="1342.865821838379" y="1215.8279428482056"><a><text><string>Holdings</string></text></a></t></children></ent><ent id="12"><children><r id="13" x="3279" y="1332" w="210" h="72"/><t id="14" x="3344.831718444824" y="1359.8279428482056"><a><text><string>MarketTrades</string></text></a></t></children></ent><ent id="15"><children><r id="16" x="255" y="2052" w="210" h="72"/><t id="17" x="344.0038757324219" y="2079.8279428482056"><a><text><string>Users</string></text></a></t></children></ent><ent id="18"><children><r id="19" x="2271" y="2052" w="210" h="72"/><t id="1a" x="2356.4098510742188" y="2079.8279428482056"><a><text><string>Orders</string></text></a></t></children></ent><ent id="1b"><children><r id="1c" x="1263" y="2916" w="210" h="72"/><t id="1d" x="1332.0657501220703" y="2943.8279428482056"><a><text><string>Transactions</string></text></a></t></children></ent><ent id="1e"><children><r id="1f" x="2271" y="2916" w="210" h="72"/><t id="20" x="2340.7677459716797" y="2943.8279428482056"><a><text><string>OrderEvents</string></text></a></t></children></ent><rel id="21"><children><diamond id="22" x="764" y="384" w="200" h="96"/><t id="23" x="851.3939056396484" y="423.82794284820557"><a><text><string>Lists</string></text></a></t></children></rel><rel id="24"><children><diamond id="25" x="260" y="780" w="200" h="96"/><t id="26" x="335.20782470703125" y="819.8279428482056"><a><text><string>Contains</string></text></a></t></children></rel><rel id="27"><children><diamond id="28" x="1772" y="384" w="200" h="96"/><t id="29" x="1842.3417892456055" y="423.82794284820557"><a><text><string>QuotedOn</string></text></a></t></children></rel><rel id="2a"><children><diamond id="2b" x="2780" y="384" w="200" h="96"/><t id="2c" x="2847.44376373291" y="423.82794284820557"><a><text><string>Aggregates</string></text></a></t></children></rel><rel id="2d"><children><diamond id="2e" x="1268" y="780" w="200" h="96"/><t id="2f" x="1339.523796081543" y="819.8279428482056"><a><text><string>PositionIn</string></text></a></t></children></rel><rel id="30"><children><diamond id="31" x="260" y="1608" w="200" h="96"/><t id="32" x="344.01588439941406" y="1647.8279428482056"><a><text><string>Owns</string></text></a></t></children></rel><rel id="33"><children><diamond id="34" x="764" y="1608" w="200" h="96"/><t id="35" x="847.811882019043" y="1647.8279428482056"><a><text><string>Holds</string></text></a></t></children></rel><rel id="36"><children><diamond id="37" x="1268" y="2040" w="200" h="96"/><t id="38" x="1350.31787109375" y="2079.8279428482056"><a><text><string>Places</string></text></a></t></children></rel><rel id="39"><children><diamond id="3a" x="2276" y="1212" w="200" h="96"/><t id="3b" x="2349.107810974121" y="1251.8279428482056"><a><text><string>PlacedOn</string></text></a></t></children></rel><rel id="3c"><children><diamond id="3d" x="2780" y="852" w="200" h="96"/><t id="3e" x="2869.367919921875" y="891.8279428482056"><a><text><string>Fills</string></text></a></t></children></rel><rel id="3f"><children><diamond id="40" x="2636" y="1536" w="200" h="96"/><t id="41" x="2714.699851989746" y="1575.8279428482056"><a><text><string>FillsBuy</string></text></a></t></children></rel><rel id="42"><children><diamond id="43" x="2924" y="1737.6" w="200" h="96"/><t id="44" x="3003.593849182129" y="1777.4279428482055"><a><text><string>FillsSell</string></text></a></t></children></rel><rel id="45"><children><diamond id="46" x="764" y="2472" w="200" h="96"/><t id="47" x="841.3318328857422" y="2511.8279428482056"><a><text><string>Records</string></text></a></t></children></rel><rel id="48"><children><diamond id="49" x="1772" y="2472" w="200" h="96"/><t id="4a" x="1853.1838607788086" y="2511.8279428482056"><a><text><string>Settles</string></text></a></t></children></rel><rel id="4b"><children><diamond id="4c" x="2276" y="2472" w="200" h="96"/><t id="4d" x="2362.6619033813477" y="2511.8279428482056"><a><text><string>Logs</string></text></a></t></children></rel><llabelUm id="4e"><points><p colinear="true" x="1262.5" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="964.4327310675848" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="4f"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="50"><Owner><diamond ref="22"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="51"><points><p colinear="true" x="763.5672689324152" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="465.5" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="52"><Owner><diamond ref="22"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="53"><Owner><r ref="1"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="54"><points><p colinear="true" x="360" y="1187.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="360" y="876.9015230574684" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="55"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="56"><Owner><diamond ref="25"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="57"><points><p colinear="true" x="360" y="779.0984769425318" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="360" y="468.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="58"><Owner><diamond ref="25"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="59"><Owner><r ref="1"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="5a"><points><p colinear="true" x="1473.5" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1771.5672689324151" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="5b"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="5c"><Owner><diamond ref="28"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="5d"><points><p colinear="true" x="1972.4327310675847" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2270.5" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="5e"><Owner><diamond ref="28"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="5f"><Owner><r ref="7"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="60"><points><p colinear="true" x="2481.5" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2779.567268932415" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="61"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="62"><Owner><diamond ref="2b"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="63"><points><p colinear="true" x="2980.4327310675844" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3278.5" y="432" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="64"><Owner><diamond ref="2b"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="65"><Owner><r ref="a"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="66"><points><p colinear="true" x="1368" y="468.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1368" y="779.0984769425318" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="67"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="68"><Owner><diamond ref="2e"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="69"><points><p colinear="true" x="1368" y="876.9015230574684" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1368" y="1187.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="6a"><Owner><diamond ref="2e"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="6b"><Owner><r ref="10"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="6c"><points><p colinear="true" x="360" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="360" y="1704.9015230574682" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="6d"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="6e"><Owner><diamond ref="31"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="6f"><points><p colinear="true" x="360" y="1607.0984769425318" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="360" y="1260.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="70"><Owner><diamond ref="31"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="71"><Owner><r ref="d"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="72"><points><p colinear="true" x="402.58333333333337" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="827.6163211207464" y="1687.1860104679317" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="73"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="74"><Owner><diamond ref="34"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="75"><points><p colinear="true" x="900.3836788792536" y="1624.8139895320683" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1325.4166666666667" y="1260.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="76"><Owner><diamond ref="34"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="77"><Owner><r ref="10"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="78"><points><p colinear="true" x="465.5" y="2088" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1267.5672689324151" y="2088" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="79"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="7a"><Owner><diamond ref="37"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="7b"><points><p colinear="true" x="1468.4327310675847" y="2088" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2270.5" y="2088" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="7c"><Owner><diamond ref="37"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="7d"><Owner><r ref="19"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="7e"><points><p colinear="true" x="2376" y="468.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2376" y="1211.0984769425318" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="7f"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="80"><Owner><diamond ref="3a"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="81"><points><p colinear="true" x="2376" y="1308.9015230574682" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2376" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="82"><Owner><diamond ref="3a"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="83"><Owner><r ref="19"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="84"><points><p colinear="true" x="2415.3076923076924" y="468.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2845.4523306986234" y="867.9200213630073" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="85"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="86"><Owner><diamond ref="3d"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="87"><points><p colinear="true" x="2914.5476693013766" y="932.0799786369927" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3344.6923076923076" y="1331.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="88"><Owner><diamond ref="3d"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="89"><Owner><r ref="13"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="8a"><points><p colinear="true" x="2402.0714285714284" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2710.0837830122005" y="1620.2827037829193" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="8b"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="8c"><Owner><diamond ref="40"/></Owner></diamondConnector></endConnector></llabelUm><llabelMuitos id="8d"><points><p colinear="true" x="2795.6184409547654" y="1564.1271863484114" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3278.5" y="1403.1666666666667" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="8e"><Owner><diamond ref="40"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="8f"><Owner><r ref="13"/></Owner></rConnector></endConnector></llabelMuitos><llabelUm id="90"><points><p colinear="true" x="2454.214285714286" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2972.7176902815563" y="1809.5317445352737" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="91"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="92"><Owner><diamond ref="43"/></Owner></diamondConnector></endConnector></llabelUm><llabelMuitos id="93"><points><p colinear="true" x="3053.6929253517355" y="1751.1562065919868" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3352.5344827586205" y="1404.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="94"><Owner><diamond ref="43"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="95"><Owner><r ref="13"/></Owner></rConnector></endConnector></llabelMuitos><llabelUm id="96"><points><p colinear="true" x="402.58333333333337" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="827.6163211207464" y="2488.8139895320683" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="97"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="98"><Owner><diamond ref="46"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="99"><points><p colinear="true" x="900.3836788792536" y="2551.1860104679317" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1325.4166666666667" y="2915.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="9a"><Owner><diamond ref="46"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="9b"><Owner><r ref="1c"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><llabelUm id="9c"><points><p colinear="true" x="2333.4166666666665" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1908.3836788792537" y="2488.8139895320683" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="9d"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="9e"><Owner><diamond ref="49"/></Owner></diamondConnector></endConnector></llabelUm><llabelMuitos id="9f"><points><p colinear="true" x="1835.6163211207463" y="2551.1860104679317" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1410.5833333333333" y="2915.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="a0"><Owner><diamond ref="49"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="a1"><Owner><r ref="1c"/></Owner></rConnector></endConnector></llabelMuitos><llabelUm id="a2"><points><p colinear="true" x="2376" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2376" y="2471.0984769425318" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="a3"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><diamondConnector id="a4"><Owner><diamond ref="4c"/></Owner></diamondConnector></endConnector></llabelUm><llabelDoubleMuitos id="a5"><points><p colinear="true" x="2376" y="2568.9015230574682" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2376" y="2915.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><diamondConnector id="a6"><Owner><diamond ref="4c"/></Owner></diamondConnector></startConnector><endConnector><rConnector id="a7"><Owner><r ref="1f"/></Owner></rConnector></endConnector><a><innerStrokeWidthFactor><double>3</double></innerStrokeWidthFactor></a></llabelDoubleMuitos><atrchave id="a8" nullable="false" attributeType="NUMBER"><children><e id="a9" x="-68.39695907392695" y="246.4050605385342" w="168" h="50"/><t id="aa" x="9.975004427049612" y="263.23300338673977"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="ab"><points><p colinear="true" x="281.7254974014012" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="62.01277773449584" y="293.31312239618217" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="ac"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="ad"><Owner><e ref="a9"/></Owner></ellipseConnector></endConnector></llabel><atr id="ae" nullable="false" attributeType="VARCHAR2(128)"><children><e id="af" x="436.59493946146586" y="62.60304092607305" w="168" h="50"/><t id="b0" x="494.5787651450596" y="79.43098377427862"><a><text><string>added_at</string></text></a></t></children></atr><llabel id="b1"><points><p colinear="true" x="377.0202295226575" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="509.3201060987341" y="113.35425256029824" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="b2"><Owner><r ref="1"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="b3"><Owner><e ref="af"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="b4" nullable="false" attributeType="NUMBER"><children><e id="b5" x="956.3391822844033" y="177.56942545958162" w="168" h="50"/><t id="b6" x="1034.7111457853798" y="194.3973683077872"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="b7"><points><p colinear="true" x="1315.8725977539127" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1074.2831689371824" y="226.48715702164253" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="b8"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="b9"><Owner><e ref="b5"/></Owner></ellipseConnector></endConnector></llabel><atr id="ba" nullable="false" attributeType="VARCHAR2(128)"><children><e id="bb" x="1158.1820975393546" y="27.302942570786456" w="168" h="50"/><t id="bc" x="1221.769950017382" y="44.13088541899202"><a><text><string>symbol</string></text></a></t></children></atr><llabel id="bd"><points><p colinear="true" x="1355.9052171989251" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1251.0899448243847" y="78.17639746873897" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="be"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="bf"><Owner><e ref="bb"/></Owner></ellipseConnector></endConnector></llabel><atr id="c0" nullable="false" attributeType="VARCHAR2(128)"><children><e id="c1" x="1409.8179024606454" y="27.302942570786456" w="168" h="50"/><t id="c2" x="1477.749794855665" y="44.13088541899202"><a><text><string>name</string></text></a></t></children></atr><llabel id="c3"><points><p colinear="true" x="1380.0947828010749" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1485.9100551756153" y="78.17639746873897" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="c4"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="c5"><Owner><e ref="c1"/></Owner></ellipseConnector></endConnector></llabel><atr id="c6" nullable="false" attributeType="VARCHAR2(128)"><children><e id="c7" x="1611.6608177155967" y="177.56942545958154" w="168" h="50"/><t id="c8" x="1666.1166130036827" y="194.3973683077871"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="c9"><points><p colinear="true" x="1420.127402246087" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1662.7168310628176" y="226.48715702164245" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="ca"><Owner><r ref="4"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="cb"><Owner><e ref="c7"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="cc" nullable="false" attributeType="NUMBER"><children><e id="cd" x="2000.9031116147885" y="162.740708319115" w="168" h="50"/><t id="ce" x="2079.275075115765" y="179.56865116732055"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="cf"><points><p colinear="true" x="2332.5009938703115" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2113.999678160262" y="212.23607676035843" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="d0"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="d1"><Owner><e ref="cd"/></Owner></ellipseConnector></endConnector></llabel><atr id="d2" nullable="false" attributeType="VARCHAR2(128)"><children><e id="d3" x="2183.014771569786" y="42.963985320114205" w="168" h="50"/><t id="d4" x="2223.1964656005475" y="59.79192816831977"><a><text><string>quote_currency</string></text></a></t></children></atr><llabel id="d5"><points><p colinear="true" x="2365.0726173310054" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2275.118003483917" y="93.86054854775956" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="d6"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="d7"><Owner><e ref="d3"/></Owner></ellipseConnector></endConnector></llabel><atr id="d8" nullable="false" attributeType="VARCHAR2(128)"><children><e id="d9" x="2400.985228430214" y="42.963985320114205" w="168" h="50"/><t id="da" x="2461.5070637573626" y="59.79192816831977"><a><text><string>is_active</string></text></a></t></children></atr><llabel id="db"><points><p colinear="true" x="2386.9273826689946" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2477.881996516083" y="93.86054854775956" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="dc"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="dd"><Owner><e ref="d9"/></Owner></ellipseConnector></endConnector></llabel><atr id="de" nullable="false" attributeType="VARCHAR2(128)"><children><e id="df" x="2583.0968883852115" y="162.74070831911507" w="168" h="50"/><t id="e0" x="2637.5526836732975" y="179.56865116732064"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="e1"><points><p colinear="true" x="2419.4990061296885" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2639.000321839738" y="212.23607676035851" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="e2"><Owner><r ref="7"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="e3"><Owner><e ref="df"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="e4" nullable="false" attributeType="NUMBER"><children><e id="e5" x="3122.1495254706524" y="-81.64016280867236" w="168" h="50"/><t id="e6" x="3200.521488971629" y="-64.81221996046679"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="e7"><points><p colinear="true" x="3370.7150864492837" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3215.8752825761353" y="-30.792603483984927" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="e8"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="e9"><Owner><e ref="e5"/></Owner></ellipseConnector></endConnector></llabel><atr id="ea" nullable="false" attributeType="VARCHAR2(128)"><children><e id="eb" x="3332.392271727323" y="-111.99011621835655" w="168" h="50"/><t id="ec" x="3386.7820574939246" y="-95.16217337015098"><a><text><string>timeframe</string></text></a></t></children></atr><llabel id="ed"><points><p colinear="true" x="3386.2781125903944" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3415.300995849721" y="-60.99463817333623" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="ee"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="ef"><Owner><e ref="eb"/></Owner></ellipseConnector></endConnector></llabel><atr id="f0" nullable="false" attributeType="VARCHAR2(128)"><children><e id="f1" x="3537.229541823645" y="-55.733340581963716" w="168" h="50"/><t id="f2" x="3606.8174400780395" y="-38.90539773375815"><a><text><string>open</string></text></a></t></children></atr><llabel id="f3"><points><p colinear="true" x="3402.7124581636435" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3608.810156433815" y="-5.0331470742506355" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="f4"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="f5"><Owner><e ref="f1"/></Owner></ellipseConnector></endConnector></llabel><atr id="f6" nullable="false" attributeType="VARCHAR2(128)"><children><e id="f7" x="3702.479016298438" y="77.74228719824731" w="168" h="50"/><t id="f8" x="3773.824933046485" y="94.57023004645288"><a><text><string>high</string></text></a></t></children></atr><llabel id="f9"><points><p colinear="true" x="3428.616977898216" y="395.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3757.7345449658733" y="127.166435670914" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="fa"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="fb"><Owner><e ref="f7"/></Owner></ellipseConnector></endConnector></llabel><atr id="fc" nullable="false" attributeType="VARCHAR2(128)"><children><e id="fd" x="3800.564608414006" y="266.1629565656373" w="168" h="50"/><t id="fe" x="3874.670534927678" y="282.99089941384284"><a><text><string>low</string></text></a></t></children></atr><llabel id="ff"><points><p colinear="true" x="3489.5" y="402.31690248856694" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3823.2597553724627" y="309.0521459448973" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="100"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="101"><Owner><e ref="fd"/></Owner></ellipseConnector></endConnector></llabel><atr id="102" nullable="false" attributeType="VARCHAR2(128)"><children><e id="103" x="3815.118237094787" y="478.0858763212382" w="168" h="50"/><t id="104" x="3884.802128391174" y="494.91381916944374"><a><text><string>close</string></text></a></t></children></atr><llabel id="105"><points><p colinear="true" x="3489.5" y="446.55890980328587" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3822.7719573934014" y="492.98115542180165" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="106"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="107"><Owner><e ref="103"/></Owner></ellipseConnector></endConnector></llabel><atr id="108" nullable="false" attributeType="VARCHAR2(128)"><children><e id="109" x="3743.711258448721" y="678.146305757339" w="168" h="50"/><t id="10a" x="3806.783112086416" y="694.9742486055445"><a><text><string>volume</string></text></a></t></children></atr><llabel id="10b"><points><p colinear="true" x="3443.729602024792" y="468.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3790.795958034731" y="680.7822916200306" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="10c"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="10d"><Owner><e ref="109"/></Owner></ellipseConnector></endConnector></llabel><atr id="10e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="10f" x="3598.259746902544" y="832.9590630302757" w="168" h="50"/><t id="110" x="3648.3115123444386" y="849.7870058784813"><a><text><string>candle_time</string></text></a></t></children></atr><llabel id="111"><points><p colinear="true" x="3409.5575751446545" y="468.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3665.290202517464" y="833.5099680380305" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="112"><Owner><r ref="a"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="113"><Owner><e ref="10f"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="114" nullable="false" attributeType="NUMBER"><children><e id="115" x="-70.4101615137755" y="999" w="168" h="50"/><t id="116" x="7.961801987201056" y="1015.8279428482056"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="117"><points><p colinear="true" x="296.780145523736" y="1187.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="53.232620375753754" y="1047.0990956607504" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="118"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="119"><Owner><e ref="115"/></Owner></ellipseConnector></endConnector></llabel><atr id="11a" nullable="false" attributeType="VARCHAR2(128)"><children><e id="11b" x="-124" y="1199" w="168" h="50"/><t id="11c" x="-56.06810760498047" y="1215.8279428482056"><a><text><string>name</string></text></a></t></children></atr><llabel id="11d"><points><p colinear="true" x="254.5" y="1224" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="45" y="1224.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="11e"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="11f"><Owner><e ref="11b"/></Owner></ellipseConnector></endConnector></llabel><atr id="120" nullable="false" attributeType="VARCHAR2(128)"><children><e id="121" x="-70.41016151377545" y="1399" w="168" h="50"/><t id="122" x="-15.954366225689512" y="1415.8279428482056"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="123"><points><p colinear="true" x="296.780145523736" y="1260.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="53.23262037575381" y="1401.9009043392496" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="124"><Owner><r ref="d"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="125"><Owner><e ref="121"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="126" nullable="false" attributeType="NUMBER"><children><e id="127" x="1623.4112549695428" y="859.5887450304572" w="168" h="50"/><t id="128" x="1701.7832184705194" y="876.4166878786627"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="129"><points><p colinear="true" x="1404.5" y="1187.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1683.498644392971" y="909.5013556070288" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="12a"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="12b"><Owner><e ref="127"/></Owner></ellipseConnector></endConnector></llabel><atr id="12c" nullable="false" attributeType="VARCHAR2(128)"><children><e id="12d" x="1711.6831316104167" y="981.0845601250176" w="168" h="50"/><t id="12e" x="1772.2709764590495" y="997.9125029732231"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="12f"><points><p colinear="true" x="1439.635283450938" y="1187.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1753.1223466522588" y="1028.5251259364059" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="130"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="131"><Owner><e ref="12d"/></Owner></ellipseConnector></endConnector></llabel><atr id="132" nullable="false" attributeType="VARCHAR2(128)"><children><e id="133" x="1758.0904034856662" y="1123.9114567806892" w="168" h="50"/><t id="134" x="1791.2940472844944" y="1140.7393996288947"><a><text><string>reserved_quantity</string></text></a></t></children></atr><llabel id="135"><points><p colinear="true" x="1473.5" y="1207.2904415457615" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1767.7694330432068" y="1161.2619343087567" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="136"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="137"><Owner><e ref="133"/></Owner></ellipseConnector></endConnector></llabel><atrderivado id="138"><children><e id="139" x="1758.0904034856662" y="1274.0885432193108" w="168" h="50"><a><fillColor><color rgba="#ffffebeb"/></fillColor><strokeDashes><doubleArray><double>5</double></doubleArray></strokeDashes></a></e><t id="13a" x="1815.3422192815647" y="1290.9164860675164"><a><text><string>avg_price</string></text></a></t></children></atrderivado><llabel id="13b"><points><p colinear="true" x="1473.5" y="1240.7095584542385" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1767.7694330432068" y="1287.7380656912433" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="13c"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="13d"><Owner><e ref="139"/></Owner></ellipseConnector></endConnector></llabel><atr id="13e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="13f" x="1711.6831316104167" y="1416.9154398749824" w="168" h="50"/><t id="140" x="1766.1389268985026" y="1433.743382723188"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="141"><points><p colinear="true" x="1439.635283450938" y="1260.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1753.1223466522588" y="1420.4748740635941" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="142"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="143"><Owner><e ref="13f"/></Owner></ellipseConnector></endConnector></llabel><atr id="144" nullable="false" attributeType="VARCHAR2(128)"><children><e id="145" x="1623.4112549695428" y="1538.4112549695428" w="168" h="50"/><t id="146" x="1675.5210419568475" y="1555.2391978177484"><a><text><string>updated_at</string></text></a></t></children></atr><llabel id="147"><points><p colinear="true" x="1404.5" y="1260.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1683.498644392971" y="1539.498644392971" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="148"><Owner><r ref="10"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="149"><Owner><e ref="145"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="14a" nullable="false" attributeType="NUMBER"><children><e id="14b" x="3575.316689448502" y="949.8070187412839" w="168" h="50"/><t id="14c" x="3653.6886529494786" y="966.6349615894894"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="14d"><points><p colinear="true" x="3409.5575751446545" y="1331.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3642.347145063422" y="1000.2561137335291" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="14e"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="14f"><Owner><e ref="14b"/></Owner></ellipseConnector></endConnector></llabel><atr id="150" nullable="false" attributeType="VARCHAR2(128)"><children><e id="151" x="3707.0630861550844" y="1088.6387531680616" w="168" h="50"/><t id="152" x="3757.0968538552797" y="1105.4666960162672"><a><text><string>executed_at</string></text></a></t></children></atr><llabel id="153"><points><p colinear="true" x="3442.4122103099985" y="1331.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3754.8155242942967" y="1137.1011783322601" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="154"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="155"><Owner><e ref="151"/></Owner></ellipseConnector></endConnector></llabel><atr id="156" nullable="false" attributeType="VARCHAR2(128)"><children><e id="157" x="3774.0904034856662" y="1267.9114567806892" w="168" h="50"/><t id="158" x="3844.1103009466037" y="1284.7393996288947"><a><text><string>price</string></text></a></t></children></atr><llabel id="159"><points><p colinear="true" x="3489.5" y="1351.2904415457615" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3783.769433043207" y="1305.2619343087567" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="15a"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="15b"><Owner><e ref="157"/></Owner></ellipseConnector></endConnector></llabel><atr id="15c" nullable="false" attributeType="VARCHAR2(128)"><children><e id="15d" x="3765.741948612478" y="1459.1225098878406" w="168" h="50"/><t id="15e" x="3826.329793461111" y="1475.9504527360461"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="15f"><points><p colinear="true" x="3489.5" y="1394.3041042999555" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3785.099442339135" y="1468.3806588985085" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="160"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="161"><Owner><e ref="15d"/></Owner></ellipseConnector></endConnector></llabel><atr id="162" nullable="false" attributeType="VARCHAR2(128)"><children><e id="163" x="3683.3450448227004" y="1631.8712111129832" w="168" h="50"/><t id="164" x="3755.848958702095" y="1648.6991539611888"><a><text><string>side</string></text></a></t></children></atr><llabel id="165"><points><p colinear="true" x="3432.4371359891447" y="1404.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3736.4308097196013" y="1633.6988870201615" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="166"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="167"><Owner><e ref="163"/></Owner></ellipseConnector></endConnector></llabel><atr id="168" nullable="false" attributeType="VARCHAR2(128)"><children><e id="169" x="3540" y="1758.6921938165306" w="168" h="50"/><t id="16a" x="3605.0458602905273" y="1775.5201366647361"><a><text><string>source</string></text></a></t></children></atr><llabel id="16b"><points><p colinear="true" x="3405.0732848254215" y="1404.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="3609.996063690191" y="1759.070639218198" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="16c"><Owner><r ref="13"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="16d"><Owner><e ref="169"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="16e" nullable="false" attributeType="NUMBER"><children><e id="16f" x="-79.61739053764865" y="1555.125732540825" w="168" h="50"/><t id="170" x="-1.2454270366720834" y="1571.9536753890306"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="171"><points><p colinear="true" x="334.44242485534556" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="22.35215384743159" y="1605.5748275330702" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="172"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="173"><Owner><e ref="16f"/></Owner></ellipseConnector></endConnector></llabel><atr id="174" nullable="false" attributeType="VARCHAR2(128)"><children><e id="175" x="-191.13025572314973" y="1655.3367514871807" w="168" h="50"/><t id="176" x="-135.6424551250052" y="1672.1646943353862"><a><text><string>username</string></text></a></t></children></atr><llabel id="177"><points><p colinear="true" x="318.1756403205456" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-79.01493755402784" y="1704.936561284582" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="178"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="179"><Owner><e ref="175"/></Owner></ellipseConnector></endConnector></llabel><atr id="17a" nullable="false" attributeType="VARCHAR2(128)"><children><e id="17b" x="-275.3281927323858" y="1779.3854307366398" w="168" h="50"/><t id="17c" x="-206.7843008256475" y="1796.2133735848454"><a><text><string>email</string></text></a></t></children></atr><llabel id="17d"><points><p colinear="true" x="289.04638472205664" y="2051.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-148.0718827364814" y="1826.880156568963" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="17e"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="17f"><Owner><e ref="17b"/></Owner></ellipseConnector></endConnector></llabel><atr id="180" nullable="false" attributeType="VARCHAR2(128)"><children><e id="181" x="-327.28781975949073" y="1920.018160139687" w="168" h="50"/><t id="182" x="-270.8880089684751" y="1936.8461029878927"><a><text><string>full_name</string></text></a></t></children></atr><llabel id="183"><points><p colinear="true" x="254.5" y="2062.996040677107" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-176.33272171632424" y="1961.2683077062293" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="184"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="185"><Owner><e ref="181"/></Owner></ellipseConnector></endConnector></llabel><atr id="186" nullable="false" attributeType="VARCHAR2(128)"><children><e id="187" x="-343.9708547344802" y="2069.0115954453063" w="168" h="50"/><t id="188" x="-303.6091603985427" y="2085.839538293512"><a><text><string>password_hash</string></text></a></t></children></atr><llabel id="189"><points><p colinear="true" x="254.5" y="2089.022988927038" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-175.01444209639942" y="2093.692657294158" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="18a"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="18b"><Owner><e ref="187"/></Owner></ellipseConnector></endConnector></llabel><atr id="18c" nullable="false" attributeType="VARCHAR2(128)"><children><e id="18d" x="-324.4017755272396" y="2217.6535093159487" w="168" h="50"/><t id="18e" x="-289.87210481190755" y="2234.4814521641542"><a><text><string>available_balance</string></text></a></t></children></atr><llabel id="18f"><points><p colinear="true" x="254.5" y="2115.1750449413726" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-175.63096569337222" y="2226.598417887951" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="190"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="191"><Owner><e ref="18d"/></Owner></ellipseConnector></endConnector></llabel><atr id="192" nullable="false" attributeType="VARCHAR2(128)"><children><e id="193" x="-269.72486253166903" y="2357.252229243537" w="168" h="50"/><t id="194" x="-234.13319535637606" y="2374.0801720917425"><a><text><string>invested_balance</string></text></a></t></children></atr><llabel id="195"><points><p colinear="true" x="292.30651970381484" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-143.95601093481392" y="2360.500262337795" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="196"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="197"><Owner><e ref="193"/></Owner></ellipseConnector></endConnector></llabel><atr id="198" nullable="false" attributeType="VARCHAR2(128)"><children><e id="199" x="-183.13728812758285" y="2479.6448735444237" w="168" h="50"/><t id="19a" x="-148.46363547865707" y="2496.4728163926293"><a><text><string>reserved_balance</string></text></a></t></children></atr><llabel id="19b"><points><p colinear="true" x="319.77746978118057" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="-71.97240910262072" y="2480.947786013721" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="19c"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="19d"><Owner><e ref="199"/></Owner></ellipseConnector></endConnector></llabel><atr id="19e" nullable="false" attributeType="VARCHAR2(128)"><children><e id="19f" x="-69.70216554052774" y="2573.6420459197734" w="168" h="50"/><t id="1a0" x="-15.246370252441807" y="2590.469988767979"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="1a1"><points><p colinear="true" x="335.2896786642366" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="31.71183453898649" y="2574.158113314706" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1a2"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1a3"><Owner><e ref="19f"/></Owner></ellipseConnector></endConnector></llabel><atr id="1a4" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1a5" x="63.94751113808553" y="2649.6420458596826" w="168" h="50"/><t id="1a6" x="116.05729812539022" y="2666.469988707888"><a><text><string>updated_at</string></text></a></t></children></atr><llabel id="1a7"><points><p colinear="true" x="346.80640793123246" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="157.61059799292497" y="2649.792416398774" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1a8"><Owner><r ref="16"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1a9"><Owner><e ref="1a5"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="1aa" nullable="false" attributeType="NUMBER"><children><e id="1ab" x="2992" y="2063" w="168" h="50"/><t id="1ac" x="3070.3719635009766" y="2079.8279428482056"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="1ad"><points><p colinear="true" x="2481.5" y="2088" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2992" y="2088.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1ae"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1af"><Owner><e ref="1ab"/></Owner></ellipseConnector></endConnector></llabel><atr id="1b0" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1b1" x="2984.3111043533418" y="2166.4665877907273" w="168" h="50"/><t id="1b2" x="3056.8150182327363" y="2183.294530638933"><a><text><string>side</string></text></a></t></children></atr><llabel id="1b3"><points><p colinear="true" x="2481.5" y="2103.767080642333" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2993.0883684502273" y="2180.649749085111" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1b4"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1b5"><Owner><e ref="1b1"/></Owner></ellipseConnector></endConnector></llabel><atr id="1b6" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1b7" x="2961.4133291741246" y="2267.6601933059155" w="168" h="50"/><t id="1b8" x="3033.113242199027" y="2284.488136154121"><a><text><string>type</string></text></a></t></children></atr><llabel id="1b9"><points><p colinear="true" x="2481.5" y="2120.2545868938887" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2986.55310628215" y="2275.0119519096143" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1ba"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1bb"><Owner><e ref="1b7"/></Owner></ellipseConnector></endConnector></llabel><atr id="1bc" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1bd" x="2923.8096990449026" y="2364.357767765807" w="168" h="50"/><t id="1be" x="2990.655577645977" y="2381.1857106140124"><a><text><string>status</string></text></a></t></children></atr><llabel id="1bf"><points><p colinear="true" x="2452.5238413667184" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2963.130858075615" y="2368.308566027795" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1c0"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1c1"><Owner><e ref="1bd"/></Owner></ellipseConnector></endConnector></llabel><atr id="1c2" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1c3" x="2872.326300788529" y="2444.5088818206123" w="168" h="50"/><t id="1c4" x="2932.9141456371617" y="2461.336824668818"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="1c5"><points><p colinear="true" x="2431.521407202103" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2921.5740998439587" y="2446.833940850671" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1c6"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1c7"><Owner><e ref="1c3"/></Owner></ellipseConnector></endConnector></llabel><atr id="1c8" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1c9" x="2808.0941357670868" y="2519.9723742392835" w="168" h="50"/><t id="1ca" x="2852.2358593998993" y="2536.800317087489"><a><text><string>filled_quantity</string></text></a></t></children></atr><llabel id="1cb"><points><p colinear="true" x="2417.2222642273664" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2865.334720203274" y="2521.33569260066" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1cc"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1cd"><Owner><e ref="1c9"/></Owner></ellipseConnector></endConnector></llabel><atr id="1ce" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1cf" x="2732.5242737348863" y="2595.1040785055266" w="168" h="50"/><t id="1d0" x="2802.5441711958238" y="2611.932021353732"><a><text><string>price</string></text></a></t></children></atr><llabel id="1d1"><points><p colinear="true" x="2406.2180280904504" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2796.5425916598115" y="2595.864496111119" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1d2"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1d3"><Owner><e ref="1cf"/></Owner></ellipseConnector></endConnector></llabel><atr id="1d4" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1d5" x="2647.276854072493" y="2670.2355253829633" w="168" h="50"/><t id="1d6" x="2704.5226731642897" y="2687.063468231169"><a><text><string>placed_at</string></text></a></t></children></atr><llabel id="1d7"><points><p colinear="true" x="2397.3551490839864" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2717.084748554333" y="2670.6239305491463" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1d8"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1d9"><Owner><e ref="1d5"/></Owner></ellipseConnector></endConnector></llabel><atr id="1da" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1db" x="2554.2246153911383" y="2745.6986013377973" w="168" h="50"/><t id="1dc" x="2604.2583830913336" y="2762.526544186003"><a><text><string>executed_at</string></text></a></t></children></atr><llabel id="1dd"><points><p colinear="true" x="2390.0196544170753" y="2124.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2628.9952042826358" y="2745.868197684778" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1de"><Owner><r ref="19"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1df"><Owner><e ref="1db"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="1e0" nullable="false" attributeType="NUMBER"><children><e id="1e1" x="832.947542022764" y="3091.169668796321" w="168" h="50"/><t id="1e2" x="911.3195055237405" y="3107.9976116445264"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="1e3"><points><p colinear="true" x="1267.7170741899063" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="971.3812226795658" y="3097.0394144128263" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1e4"><Owner><r ref="1c"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1e5"><Owner><e ref="1e1"/></Owner></ellipseConnector></endConnector></llabel><atr id="1e6" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1e7" x="962.8173089477482" y="3283.7095162291494" w="168" h="50"/><t id="1e8" x="1034.5172219726505" y="3300.537459077355"><a><text><string>type</string></text></a></t></children></atr><llabel id="1e9"><points><p colinear="true" x="1335.1352523831288" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1069.4742367933363" y="3284.601754873672" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1ea"><Owner><r ref="1c"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1eb"><Owner><e ref="1e7"/></Owner></ellipseConnector></endConnector></llabel><atr id="1ec" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1ed" x="1167.8774901121594" y="3392.741948612478" w="168" h="50"/><t id="1ee" x="1229.6893416136243" y="3409.5698914606837"><a><text><string>amount</string></text></a></t></children></atr><llabel id="1ef"><points><p colinear="true" x="1358.8995278962238" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1258.717433644473" y="3392.8138239733807" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1f0"><Owner><r ref="1c"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1f1"><Owner><e ref="1ed"/></Owner></ellipseConnector></endConnector></llabel><atr id="1f2" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1f3" x="1400.1225098878404" y="3392.741948612478" w="168" h="50"/><t id="1f4" x="1459.5463380128404" y="3409.5698914606837"><a><text><string>currency</string></text></a></t></children></atr><llabel id="1f5"><points><p colinear="true" x="1377.1004721037762" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1478.2825663555268" y="3392.8138239733807" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1f6"><Owner><r ref="1c"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1f7"><Owner><e ref="1f3"/></Owner></ellipseConnector></endConnector></llabel><atr id="1f8" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1f9" x="1605.1826910522518" y="3283.7095162291494" w="168" h="50"/><t id="1fa" x="1659.6384863403377" y="3300.537459077355"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="1fb"><points><p colinear="true" x="1400.8647476168712" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1667.5257632066637" y="3284.601754873672" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="1fc"><Owner><r ref="1c"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="1fd"><Owner><e ref="1f9"/></Owner></ellipseConnector></endConnector></llabel><atr id="1fe" nullable="false" attributeType="VARCHAR2(128)"><children><e id="1ff" x="1735.052457977236" y="3091.169668796321" w="168" h="50"/><t id="200" x="1787.4562284240133" y="3107.9976116445264"><a><text><string>description</string></text></a></t></children></atr><llabel id="201"><points><p colinear="true" x="1468.2829258100937" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="1765.618777320434" y="3097.0394144128263" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="202"><Owner><r ref="1c"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="203"><Owner><e ref="1ff"/></Owner></ellipseConnector></endConnector></llabel><atrchave id="204" nullable="false" attributeType="NUMBER"><children><e id="205" x="2105.947998459971" y="3378.052457977236" w="168" h="50"/><t id="206" x="2184.3199619609477" y="3394.8804008254415"><a><fontUnderlined><boolean>true</boolean></fontUnderlined><fontBold><boolean>true</boolean></fontBold><text><string>id</string></text></a></t></children></atrchave><llabel id="207"><points><p colinear="true" x="2360.9443275696467" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2200.885790867172" y="3378.2477480995985" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="208"><Owner><r ref="1f"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="209"><Owner><e ref="205"/></Owner></ellipseConnector></endConnector></llabel><atr id="20a" nullable="false" attributeType="VARCHAR2(128)"><children><e id="20b" x="2307.9385594324212" y="3406.707596969166" w="168" h="50"/><t id="20c" x="2361.284346480761" y="3423.5355398173715"><a><text><string>event_type</string></text></a></t></children></atr><llabel id="20d"><points><p colinear="true" x="2377.21273338792" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2391.591349924995" y="3406.708878677839" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="20e"><Owner><r ref="1f"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="20f"><Owner><e ref="20b"/></Owner></ellipseConnector></endConnector></llabel><atr id="210" nullable="false" attributeType="VARCHAR2(128)"><children><e id="211" x="2509.9291204048714" y="3365.5018196684487" w="168" h="50"/><t id="212" x="2570.516965253504" y="3382.3297625166542"><a><text><string>quantity</string></text></a></t></children></atr><llabel id="213"><points><p colinear="true" x="2394.1399769350837" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2581.8961563370854" y="3365.7838610066906" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="214"><Owner><r ref="1f"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="215"><Owner><e ref="211"/></Owner></ellipseConnector></endConnector></llabel><atr id="216" nullable="false" attributeType="VARCHAR2(128)"><children><e id="217" x="2637.2831041625523" y="3260.4360178203187" w="168" h="50"/><t id="218" x="2707.3030016234898" y="3277.2639606685243"><a><text><string>price</string></text></a></t></children></atr><llabel id="219"><points><p colinear="true" x="2413.7968564533558" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2696.5790646318837" y="3261.596759765758" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="21a"><Owner><r ref="1f"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="21b"><Owner><e ref="217"/></Owner></ellipseConnector></endConnector></llabel><atr id="21c" nullable="false" attributeType="VARCHAR2(128)"><children><e id="21d" x="2737.048250192058" y="3106.811164839638" w="168" h="50"/><t id="21e" x="2787.772012704265" y="3123.6391076878435"><a><text><string>status_after</string></text></a></t></children></atr><llabel id="21f"><points><p colinear="true" x="2466.3406701496947" y="2988.5" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2770.9818121166277" y="3111.8809977100946" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="220"><Owner><r ref="1f"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="221"><Owner><e ref="21d"/></Owner></ellipseConnector></endConnector></llabel><atr id="222" nullable="false" attributeType="VARCHAR2(128)"><children><e id="223" x="2772" y="2927" w="168" h="50"/><t id="224" x="2826.455795288086" y="2943.8279428482056"><a><text><string>created_at</string></text></a></t></children></atr><llabel id="225"><points><p colinear="true" x="2481.5" y="2952" c1x="0" c1y="0" c2x="0" c2y="0"/><p colinear="true" x="2772" y="2952.5" c1x="0" c1y="0" c2x="0" c2y="0"/></points><startConnector><rConnector id="226"><Owner><r ref="1f"/></Owner></rConnector></startConnector><endConnector><ellipseConnector id="227"><Owner><e ref="223"/></Owner></ellipseConnector></endConnector></llabel></figures></drawing>
Index: docs/P1-ConceptualModel/wiki/ERModel.md
===================================================================
--- docs/P1-ConceptualModel/wiki/ERModel.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/wiki/ERModel.md	(revision 1549dae4501012cfe2bffe1c5e9bdfdfb9dd62bd)
@@ -1,7 +1,7 @@
-= Entity-Relationship Model v.04 =
+= Entity-Relationship Model v.05 =
 
 == Diagram ==
 
-[[Image(ERModel_v04.png, 800px)]]
+[[Image(ERModel_v05.png, 800px)]]
 
 Notation: Chen. Rectangles are entity sets, diamonds are relationships, ellipses
@@ -11,8 +11,9 @@
 single line marks partial participation.
 
-Two deliberate modeling decisions worth stating up front:
+Three deliberate modeling decisions worth stating up front:
 
  * '''No foreign keys appear in the diagram.''' Connections between entity sets are expressed as relationships, per the notation. Foreign-key columns appear only in the relational model in [wiki:RelationalDesign].
- * '''`Holds` and `Contains` are relationships, not entity sets.''' Both are M:N and both carry their own attributes, which is exactly what a Chen relationship is for. They become tables (`holdings`, `watchlist_items`) only in P2.
+ * '''A position and a watchlist entry are entity sets, not M:N relationships.''' `Holdings` (a user's position in an asset) and `WatchlistItems` (an asset on a watchlist) each have their own identifier `id`, and each is connected by two 1:N relationships: `Holds` and `PositionIn` for a holding, `Contains` and `Lists` for a watchlist item. Until v04 they were drawn as the M:N relationships `Holds` and `Contains`, but the database has always given `holdings` and `watchlist_items` their own `id` primary key. That is how an entity set is implemented, not an M:N relationship, whose key would be the pair of participating keys. v05 corrects the model to match; see history.
+ * '''Key and uniqueness rules are stated with entity and relationship names, never with foreign-key columns.''' For example: "a crypto is quoted at most once per currency", not "`{crypto_id, quote_currency}` is unique".
 
 == Data requirements ==
@@ -41,5 +42,5 @@
 || `id` || UUID || PK, required ||
 || `username` || text(50) || required, unique ||
-|| `email` || text(255) || required, unique, contains `@` ||
+|| `email` || text(255) || required, unique, contains `@` (checked by the application at registration, not by a database constraint) ||
 || `full_name` || text(200) || optional ||
 || `password_hash` || text(255) || required — never the password itself; the prototype stores a SHA-256 hex digest ||
@@ -73,8 +74,10 @@
 trades, candles and orders all reference the pair, not the asset.
 
-'''Keys:''' candidates `{id}`, `{crypto_id, quote_currency}` — that pair is
-unique by definition, since a given asset can only be quoted once per
-currency; primary key '''`id`''', so that the many entity sets referencing a
-market carry one narrow column instead of a composite key.
+'''Keys:''' candidate `{id}`; primary key '''`id`''', so that the many entity sets
+related to a market need one narrow identifier instead of a composite one.
+'''Uniqueness rule:''' a crypto is quoted at most once per currency, so the crypto
+a market is `QuotedOn` together with its `quote_currency` identifies the market
+as well. Chen notation cannot draw this, because half of it comes through a
+relationship. P2 enforces it as `UNIQUE(crypto_id, quote_currency)`.
 
 ||= Attribute =||= Type =||= Constraints =||
@@ -91,5 +94,5 @@
 
 Placing an order is what triggers a '''reservation''' of whatever it commits:
-the crypto being sold (`Holds.reserved_quantity`, below) on a sell, and the
+the crypto being sold (`Holdings.reserved_quantity`, below) on a sell, and the
 cash (`Users.reserved_balance`) on a buy. Since v04 (after P7) an order can
 wait in the order book and be filled in parts, so `status` is a real
@@ -113,5 +116,5 @@
 || `quantity` || numeric(20,4) || required, > 0 ||
 || `filled_quantity` || numeric(20,4) || required, default 0, between 0 and `quantity` — how much has been traded; remaining = `quantity − filled_quantity` (added in v04, after P7) ||
-|| `price` || numeric(18,6) || the limit price; for a market order, the market price when it was placed ||
+|| `price` || numeric(18,6) || optional — the limit price; for a market order, the market price when it was placed ||
 || `placed_at` || timestamptz || required, defaults to now ||
 || `executed_at` || timestamptz || optional, set when the order settles ||
@@ -139,6 +142,6 @@
 writes directly.
 
-'''Keys:''' candidate `{id}` — `{market_id, executed_at}` looks unique in
-principle, but two trades can share a timestamp, so it is not a safe key;
+'''Keys:''' candidate `{id}` — "market plus `executed_at`" looks unique in
+principle, but two trades on a market can share a timestamp, so it is not a safe key;
 primary key '''`id`''' (a plain auto-incrementing integer here rather than a
 UUID, because this is the highest-volume entity set and it is only ever read
@@ -146,5 +149,5 @@
 
 ||= Attribute =||= Type =||= Constraints =||
-|| `id` || integer || PK, required, auto-generated ||
+|| `id` || big integer || PK, required, auto-generated (`bigserial` in P2) ||
 || `executed_at` || timestamptz || required ||
 || `price` || numeric(18,6) || required, > 0 ||
@@ -166,10 +169,10 @@
 
 ||= Attribute =||= Type =||= Constraints =||
-|| `id` || integer || PK, required, auto-generated ||
+|| `id` || big integer || PK, required, auto-generated (`bigserial` in P2) ||
 || `event_type` || text || required, `placed`, `partially_filled`, `filled` or `cancelled` ||
 || `quantity` || numeric(20,4) || required — the ordered quantity for `placed`, the filled amount for a fill, the unfilled rest for `cancelled` ||
 || `price` || numeric(18,6) || optional — the order price, or the trade price for a fill ||
 || `status_after` || text || required, the order's status after the event ||
-|| `created_at` || timestamptz || required, defaults to now ||
+|| `created_at` || timestamptz || required, set automatically when the event is recorded (`clock_timestamp()`, so events inside one transaction keep their real order) ||
 
 ==== !MarketCandles ====
@@ -179,11 +182,12 @@
 screen refresh does not scale.
 
-'''Keys:''' candidates `{id}`, `{market_id, timeframe, candle_time}` — a market
-has exactly one candle per timeframe per time bucket; primary key '''`id`''', the
-composite is enforced as a uniqueness rule because it is the real-world
-constraint and it is what prevents duplicate candles.
-
-||= Attribute =||= Type =||= Constraints =||
-|| `id` || integer || PK, required, auto-generated ||
+'''Keys:''' candidate `{id}`; primary key '''`id`'''. '''Uniqueness rule:''' a market
+has exactly one candle per timeframe per time bucket, so the market a candle
+`Aggregates` together with `timeframe` and `candle_time` also identifies it.
+This is the real-world constraint that prevents duplicate candles. P2 enforces
+it as `UNIQUE(market_id, timeframe, candle_time)`.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || big integer || PK, required, auto-generated (`bigserial` in P2) ||
 || `timeframe` || text || required, `1m`, `5m`, `1h` or `1d` ||
 || `open`, `high`, `low`, `close` || numeric(18,6) || all required ||
@@ -196,7 +200,7 @@
 several lists ("long term", "watching today") and each needs its own name.
 
-'''Keys:''' candidate `{id}` — `{user_id, name}` would also work if list names
-were required to be unique per user, which the model does not impose, so it is
-not listed as a candidate key; primary key '''`id`'''.
+'''Keys:''' candidate `{id}`; primary key '''`id`'''. "Owner plus `name`" would
+also identify a list if names had to be unique per user, but the model does
+not require that, so there is no uniqueness rule here.
 
 ||= Attribute =||= Type =||= Constraints =||
@@ -205,59 +209,18 @@
 || `created_at` || timestamptz || required, defaults to now ||
 
-=== Relationships ===
-
-==== !QuotedOn — Cryptos (1) : Markets (N), total on Markets ====
-Ties a market to the asset it trades. One asset can be quoted in many markets;
-every market must have exactly one asset, hence total participation on the
-`Markets` side. No attributes.
-
-==== !PlacedOn — Markets (1) : Orders (N), total on Orders ====
-Records which market an order was placed on. Every order must name a market;
-a market may have no orders yet. No attributes.
-
-==== Places — Users (1) : Orders (N), total on Orders ====
-Records who placed an order. Every order belongs to exactly one user; a new
-user has no orders. No attributes.
-
-==== Records — Users (1) : Transactions (N), total on Transactions ====
-Attributes each ledger entry to a user. Every entry belongs to exactly one
-user. No attributes.
-
-==== Settles — Orders (1) : Transactions (N), partial on both sides ====
-Links a ledger entry to the order that caused it. Partial on the
-`Transactions` side because deposits have no originating order, and partial on
-the `Orders` side because an order that never executes never produces a
-ledger entry — which is why the corresponding column is nullable in P2. No
-attributes.
-
-==== Fills — Markets (1) : !MarketTrades (N), total on !MarketTrades ====
-Every executed trade happened on exactly one market. No attributes.
-
-==== !FillsBuy — Orders (1) : !MarketTrades (N), partial on both sides ====
-''Added in v04, after P7.'' The buy order a trade filled. An order can be
-filled by many trades (partial fills); a trade fills at most one buy order,
-and none when the simulated market was the buyer. No attributes.
-
-==== !FillsSell — Orders (1) : !MarketTrades (N), partial on both sides ====
-''Added in v04, after P7.'' The sell order a trade filled, symmetric to
-`FillsBuy`. A trade between two users' orders participates in both. No
-attributes.
-
-==== Logs — Orders (1) : !OrderEvents (N), total on !OrderEvents ====
-''Added in v04, after P7.'' Every event belongs to exactly one order. No
-attributes.
-
-==== Aggregates — Markets (1) : !MarketCandles (N), total on !MarketCandles ====
-Every candle summarises trades of exactly one market. No attributes.
-
-==== Owns — Users (1) : Watchlists (N), total on Watchlists ====
-Every watchlist belongs to exactly one user. No attributes.
-
-==== Holds — Users (M) : Cryptos (N), partial on both sides, '''with attributes''' ====
-A user's position in an asset. M:N because one user holds many assets and one
-asset is held by many users, and partial on both sides because a user may hold
-nothing and an asset may be held by nobody. Modeled as a relationship rather
-than an entity set because a position has no identity of its own — it is
-entirely described by ''which user'', ''which asset'', and how much.
+==== Holdings ====
+A user's position in one crypto asset: how much of it the user owns, how much
+of that is already promised to open sell orders, and at what average price it
+was accumulated. ''An entity set since v05'' (until v04 it was the M:N
+relationship `Holds`). A holding has its own identifier and its own
+lifecycle: it is created on the first buy, updated on every later fill, and
+the prototype reads and locks it as a unit (`SELECT … FOR UPDATE` on the sell
+path). It is linked to its owner through `Holds` and to its asset through
+`PositionIn`.
+
+'''Keys:''' candidate `{id}`; primary key '''`id`'''. '''Uniqueness rule:''' a user
+has at most one holding per crypto, so the user who `Holds` it together with
+the crypto it is a `PositionIn` also identifies a holding. P2 enforces this as
+`UNIQUE(user_id, crypto_id)`.
 
 `reserved_quantity` mirrors `available_balance`/`invested_balance` on `Users`:
@@ -270,17 +233,96 @@
 
 ||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
 || `quantity` || numeric(20,4) || required, ≥ 0 — total amount owned ||
 || `reserved_quantity` || numeric(20,4) || required, default 0, `0 ≤ reserved_quantity ≤ quantity` — committed to the user's own open sell orders, not yet removed from the position ||
-|| `avg_price` || numeric(18,6) || required, ≥ 0, '''derived''' (dashed ellipse) — the weighted average of the prices at which the position was accumulated; derivable from the buy history, stored anyway so unrealised P/L can be shown without replaying the whole ledger ||
+|| `avg_price` || numeric(18,6) || required, default 0, ≥ 0, '''derived''' (dashed ellipse) — the weighted average of the prices at which the position was accumulated; derivable from the buy history, stored anyway so unrealised P/L can be shown without replaying the whole ledger ||
 || `created_at` || timestamptz || required, defaults to now ||
 || `updated_at` || timestamptz || optional ||
 
-==== Contains — Watchlists (M) : Cryptos (N), partial on both sides, '''with attribute''' ====
-Which assets are on which watchlist. M:N: a list holds many assets, an asset
-appears on many lists. Partial on both sides — an empty list is valid and an
-asset need not be on any list.
-
-||= Attribute =||= Type =||= Constraints =||
+==== !WatchlistItems ====
+One asset placed on one watchlist. ''An entity set since v05'' (until v04 it was
+the M:N relationship `Contains`). It has its own identifier, and it is linked
+to its list through `Contains` and to its asset through `Lists`.
+
+'''Keys:''' candidate `{id}`; primary key '''`id`'''. '''Uniqueness rule:''' an asset
+appears at most once on a given list, so the watchlist that `Contains` an item
+together with the crypto it `Lists` also identifies the item. P2 enforces this
+as `UNIQUE(watchlist_id, crypto_id)`.
+
+||= Attribute =||= Type =||= Constraints =||
+|| `id` || UUID || PK, required ||
 || `added_at` || timestamptz || required, defaults to now — recorded so a list can be shown in the order the user built it ||
+
+=== Relationships ===
+
+==== !QuotedOn — Cryptos (1) : Markets (N), total on Markets ====
+Ties a market to the asset it trades. One asset can be quoted in many markets;
+every market must have exactly one asset, hence total participation on the
+`Markets` side. No attributes.
+
+==== !PlacedOn — Markets (1) : Orders (N), total on Orders ====
+Records which market an order was placed on. Every order must name a market;
+a market may have no orders yet. No attributes.
+
+==== Places — Users (1) : Orders (N), total on Orders ====
+Records who placed an order. Every order belongs to exactly one user; a new
+user has no orders. No attributes.
+
+==== Records — Users (1) : Transactions (N), total on Transactions ====
+Attributes each ledger entry to a user. Every entry belongs to exactly one
+user. No attributes.
+
+==== Settles — Orders (1) : Transactions (N), partial on both sides ====
+Links a ledger entry to the order that caused it. Partial on the
+`Transactions` side because deposits have no originating order, and partial on
+the `Orders` side because an order that never executes never produces a
+ledger entry — which is why the corresponding column is nullable in P2. No
+attributes.
+
+==== Fills — Markets (1) : !MarketTrades (N), total on !MarketTrades ====
+Every executed trade happened on exactly one market. No attributes.
+
+==== !FillsBuy — Orders (1) : !MarketTrades (N), partial on both sides ====
+''Added in v04, after P7.'' The buy order a trade filled. An order can be
+filled by many trades (partial fills); a trade fills at most one buy order,
+and none when the simulated market was the buyer. The role of `Orders` in this
+relationship is ''the buy order'' of the trade. No attributes.
+
+==== !FillsSell — Orders (1) : !MarketTrades (N), partial on both sides ====
+''Added in v04, after P7.'' The sell order a trade filled, symmetric to
+`FillsBuy`; the role of `Orders` here is ''the sell order'' of the trade. A
+trade between two users' orders participates in both. No attributes.
+
+==== Logs — Orders (1) : !OrderEvents (N), total on !OrderEvents ====
+''Added in v04, after P7.'' Every event belongs to exactly one order. No
+attributes.
+
+==== Aggregates — Markets (1) : !MarketCandles (N), total on !MarketCandles ====
+Every candle summarises trades of exactly one market. No attributes.
+
+==== Owns — Users (1) : Watchlists (N), total on Watchlists ====
+Every watchlist belongs to exactly one user. No attributes.
+
+==== Holds — Users (1) : Holdings (N), total on Holdings ====
+''1:N since v05.'' Every holding belongs to exactly one user. A user may hold
+nothing yet, so participation is partial on the `Users` side. No attributes.
+
+==== !PositionIn — Cryptos (1) : Holdings (N), total on Holdings ====
+''Added in v05.'' Every holding is a position in exactly one crypto asset. An
+asset may be held by nobody. No attributes.
+
+Together, `Holds` and `PositionIn` still say what the old M:N `Holds` said:
+a user can hold many assets and an asset can be held by many users. The
+difference is that the position is now a thing with its own identity, not
+just a pair. The rule "at most one holding per user and crypto" is stated
+under Holdings.
+
+==== Contains — Watchlists (1) : !WatchlistItems (N), total on !WatchlistItems ====
+''1:N since v05.'' Every watchlist item is on exactly one list. An empty list is
+valid, so participation is partial on the `Watchlists` side. No attributes.
+
+==== Lists — Cryptos (1) : !WatchlistItems (N), total on !WatchlistItems ====
+''Added in v05.'' Every watchlist item names exactly one crypto asset. An asset
+need not be on any list. No attributes.
 
 == Entity-Relationship Model History ==
@@ -300,5 +342,21 @@
   Nothing existing was removed or changed. See
   [wiki:AdvancedDatabaseDevelopment].
-  The diagram files are `ERModel_v04.xml` / `ERModel_v04.png`; earlier versions
+  The diagram files are `ERModel_v04.xml` / `ERModel_v04.png`.
+ * '''v05 — correction after review.''' The review of P2 found that two parts of the model were implemented differently in the database:
+   * `Contains` was an M:N relationship in the model, but `watchlist_items` has its own `id` primary key;
+   * `Holds` was an M:N relationship in the model, but `holdings` has its own `id` primary key.
+
+  An M:N relationship has no identifier of its own; its table's key is the pair
+  of participating keys. A table with its own `id` is the implementation of an
+  entity set. Every phase after P2 (the prototype, the reports and the P7
+  logic) already uses the database as it is. So the '''model''' was corrected to
+  match P2, not the other way round:
+   * `Holds` (M:N, with attributes) became the entity set `Holdings` (its former attributes plus `id`) with two 1:N relationships, `Holds` (Users → Holdings) and `PositionIn` (Cryptos → Holdings), both total on the `Holdings` side;
+   * `Contains` (M:N, with `added_at`) became the entity set `WatchlistItems` (`id`, `added_at`) with `Contains` (Watchlists → !WatchlistItems) and `Lists` (Cryptos → !WatchlistItems), both total on the `WatchlistItems` side;
+   * the former keys of the two relationships are kept as uniqueness rules ("one holding per user and crypto", "an asset at most once per list");
+   * the key descriptions of `Markets`, `MarketTrades`, `MarketCandles` and `Watchlists` no longer name foreign-key columns (`crypto_id`, `market_id`, `user_id`), which do not exist in an ER model;
+   * the diagram was redrawn on a grid with no overlapping attributes. In v04, `Watchlists.id` was hidden behind `added_at`, and several attributes of `Orders`, `Transactions`, `MarketTrades` and `MarketCandles` overlapped. The grid also makes it easier to compare the diagram with the P2 relational diagram.
+
+  The diagram files are `ERModel_v05.xml` / `ERModel_v05.png`; earlier versions
   are kept.
 
Index: docs/P1-ConceptualModel/wiki/ERModelAIUsage.md
===================================================================
--- docs/P1-ConceptualModel/wiki/ERModelAIUsage.md	(revision ef1c1c725137d93fa85292f43440214aaddcdf05)
+++ docs/P1-ConceptualModel/wiki/ERModelAIUsage.md	(revision 1549dae4501012cfe2bffe1c5e9bdfdfb9dd62bd)
@@ -13,5 +13,6 @@
 === Diagram ===
 
-`ERModel_v01.xml` / `ERModel_v01.png`.
+Current version: `ERModel_v05.xml` / `ERModel_v05.png` (see session 5 below). First
+version: `ERModel_v01.xml` / `ERModel_v01.png`.
 
 '''Declaration of how the diagram was produced.''' The initial model is the
@@ -305,2 +306,22 @@
 '''What I decided:''' to add the P7 structure to the ER model. The new elements are placed
 automatically, so the layout can be tidied by hand in TerraER.
+
+=== Session 5 — 2026-09-29 (Claude Opus 5.5): v05, correction after review ===
+
+'''Prompt (student, excerpt):''' I pasted the reviewer's comments that `Holds` and `Contains`
+are implemented differently in the database than in the model, with the suggestion to
+"correct only the Phase 1 model so that it matches Phase 2", and asked:
+
+> Can you take a look at this stuff? and fix them, but don't push anything just make the
+> changes requested and try to explain it to me to see if you understand the problem with
+> the solution
+
+'''Response (AI, summarised):'''
+
+ * Explained that an M:N relationship has no identifier of its own, while `holdings` and `watchlist_items` each have an `id` primary key, so the database treats them as entity sets.
+ * Changed the model to v05. `Holdings` (`id`, `quantity`, `reserved_quantity`, derived `avg_price`, `created_at`, `updated_at`) and `WatchlistItems` (`id`, `added_at`) became entity sets, with the 1:N relationships `Holds`, `PositionIn`, `Contains` and `Lists`, each total on the new entity's side. The old relationship keys are now stated as uniqueness rules. The key descriptions no longer name foreign-key columns.
+ * Generated `ERModel_v05.xml` / `ERModel_v05.png` from scratch with TerraER 3.11's own figure classes and writer (adapted from the v01 generator), on a grid, with no overlapping attributes. It was verified by reading the file back with TerraER's reader (184 figures) and by inspecting the rendered PNG.
+ * Updated [wiki:ERModel] (v05 sections and history entry).
+
+'''What I decided:''' to follow the reviewer's advice and change the model rather than the
+database, since every later phase already uses the database as it is.
