# Data Model

PaperMarket keeps all simulation state off chain in a relational database.\
The data model is intentionally small and focused. It only stores what is needed to reconstruct a user’s virtual trading history against Polymarket markets.

At a high level the model is built around six core concepts

* user identities and authentication
* a per user virtual cash balance
* lightweight metadata for Polymarket markets and tokens
* simulated orders
* simulated trades (fills)
* aggregated positions per user and per token

Everything else in the application is derived from these entities.

### Core principles

The data model follows a few simple rules

* **Per user isolation**\
  Each user has their own account, cash balance, orders, trades and positions. There is no shared pool of state between users.
* **Off chain only**\
  The database stores simulation state only. It never stores private keys, real USDC balances or any on chain state.
* **Polymarket referenced by id**\
  Markets and tokens are referenced by stable identifiers and slugs taken from Polymarket. The database never tries to duplicate full Polymarket state.
* **Append only trading history**\
  Trade records are append-only. Orders are created once and only their status and derived fields are updated; the original intent stays visible. Cash balances and positions are derived from trades and explicit balance top-up events, not edited arbitrarily.

These principles keep the model simple, auditable and closely aligned with how Polymarket itself structures markets and tokens.

### Users and authentication

Each simulation account corresponds to a single user record.

A user record holds

* a stable internal identifier
* login credentials (email and password hash)
* basic metadata such as display name and timestamps

Authentication is handled entirely on the server side.\
The database only stores what is required to verify a login and link all other records (cash, orders, trades, positions) to the correct user id.

No wallet addresses or on chain identities are required to use PaperMarket.\
The system treats a “user” as an off chain simulation identity.

### Virtual cash balance

Every user has a single virtual cash balance used for all simulated trades.

Conceptually the balance table is a one to one extension of the user

* one row per user
* a numeric field that holds virtual dollars available for trading

The starting value is a fixed amount configured by the application (for example 10 000 virtual dollars).\
From that point the balance is updated only by the simulation engine

* buys decrease the balance by executed notional
* sells increase the balance by executed notional
* explicit top ups reset the balance back to the starting amount without touching orders or trades

There are no deposits, withdrawals or links to real money systems in the data model.

### Market metadata and Polymarket references

PaperMarket needs a way to remember which Polymarket markets a user has touched without copying the full market definition on every request.

For that it uses a small metadata entity keyed by Polymarket token id.\
A row typically stores

* the token id used in Polymarket APIs
* the human readable question text
* the canonical URL of the market on Polymarket
* event and market slugs used to reconstruct links

This table acts as a local index of “markets the simulation has seen”.\
Orders, trades and positions refer to markets by token id rather than embedding full JSON blobs of Polymarket responses.

If Polymarket changes how it exposes markets, the integration layer is updated, but the internal references remain stable as long as token ids stay consistent.

### Orders

Orders represent user intent in the simulation.

Each order record captures

* the user who placed it
* the target token (YES or NO) for a specific Polymarket market
* side (buy or sell)
* size requested by the user
* order type (for example market or limit)
* time in force behaviour (for example immediate or cancel vs. good till cancel)
* any limit price specified
* timestamps and a status field (open, partially filled, filled, canceled)

Orders are written once when the user submits a trade intent.\
The matching logic then attaches trade records to an order and updates its status, but the original intent does not change.

Importantly, orders in this table exist only inside PaperMarket.\
They are not forwarded to Polymarket and do not correspond to on chain orders.

### Trades (fills)

Trades are the atomic execution records produced by the simulation engine.

For each filled piece of an order the system creates a trade row with

* user reference
* order reference
* token reference
* side (buy or sell)
* executed size
* execution price
* notional value (size × price)
* timestamp

A single order can generate multiple trade records if it matches against several price levels in the Polymarket order book.\
Trades are append only and never edited after creation.

All portfolio level quantities — positions, average entry, realized cash impact — are computed from the set of trades, not from the orders themselves.

### Positions

Positions are aggregated views of trades per user and per token.

Conceptually a position row answers the question\
“what is this user’s net exposure to this Polymarket token right now?”

For each combination of user and token the position record stores

* net size after summing all buys and sells
* derived statistics such as average entry price for the remaining size

The model enforces that for a given user and token there is at most one active position row.\
If the net size returns to zero, the position can be treated as flat, but the underlying trades remain in history.

Short selling is not supported in the simulation, so net size is never negative. Sell orders that would drive the net size below zero are rejected before simulation.

### Relationships and invariants

The core entities are wired together through simple relationships

* a user has exactly one cash balance row
* a user has zero or more orders and trades
* a user has zero or more positions
* an order belongs to exactly one user and can have zero or more trades
* a trade belongs to exactly one order and one user
* a position is uniquely identified by `(user, token)` and can be recomputed from all trades for that pair

From these relationships the application can always reconstruct

* what a user tried to do (orders)
* what actually happened in the simulation (trades)
* where they stand now (positions and cash balance)

By keeping the data model small, relational and append oriented, PaperMarket can provide a realistic paper trading environment on top of Polymarket data without mirroring or duplicating any on chain state.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://papermarket.gitbook.io/papermarket/technical/data-model.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
