> For the complete documentation index, see [llms.txt](https://dev.strixlab.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://dev.strixlab.io/typescript-sdk/portfolio.md).

# Portfolio & Positions

All of these require [HMAC credentials](/http-and-websocket-api/authentication.md) and are always scoped to the calling account.

### Balances — the one to poll

```ts
const { cashBalance, availableBalance, usdcOnHold, positions } = await client.portfolio.balances();

availableBalance;   // "842.15" — USDC spendable after open-buy holds
usdcOnHold;         // "157.85" — reserved by your resting bids
positions;          // [{ tokenId, marketId, shareAmount, onHoldShareAmount, … }]
```

{% hint style="success" %}
**Use `balances()` in a quoting loop.** It returns spendable cash and share counts and nothing else. `summary()` and `positions()` replay your entire trade ledger to compute P\&L — correct for a dashboard, expensive to call every requote.
{% endhint %}

### Summary — with P\&L

```ts
const s = await client.portfolio.summary();

s.cashBalance;        // USDC in the wallet
s.availableBalance;   // after holds
s.positionsValue;     // marked-to-market value of open positions
s.totalBalance;
s.realizedPnl;        // may be null
s.unrealizedPnl;
s.totalPnl;
s.pnlStatus;          // 'reconciled' | 'unavailable'
s.accountReturn;
s.accountReturnStatus;// 'complete' | 'syncing'
s.asOf;               // ISO timestamp of the calculation
```

{% hint style="info" %}
Check `pnlStatus` before displaying P\&L. `'unavailable'` means the ledger could not be fully reconciled for this account yet (for example, positions transferred in from outside the platform have no cost basis) — the balance figures are still correct.
{% endhint %}

### Positions

```ts
const positions   = await client.portfolio.positions();
const forOneMkt   = await client.portfolio.positionsForMarket(marketId);

for (const p of positions) {
  console.log(`${p.outcomeName}: ${p.shareAmount} @ avg ${p.averagePrice} → ${p.currentValue}`);
}
```

{% hint style="danger" %}
**Match positions by `tokenId`, not `outcomeId`.** `outcomeId` is the outcome row's database id; `tokenId` is the ERC-1155 token you traded. The settled share count is `shareAmount` (mirrored as `balance`), and `onHoldShareAmount` is locked by an in-flight settlement.
{% endhint %}

Positions are indexed from on-chain state, so they lag a fill by roughly 30 seconds to two minutes. The [`position.update`](/typescript-sdk/websockets.md#your-orders-and-fills) WebSocket event bridges that gap with an optimistic delta the moment a trade settles — treat it as provisional and let the indexed value win.

### History

```ts
const trades      = await client.portfolio.trades({ limit: 100 });
const deposits    = await client.portfolio.deposits({ limit: 50 });
const withdrawals = await client.portfolio.withdrawals({ limit: 50 });
```

{% code title="Trade" %}

```ts
interface Trade {
  id: string;
  side: 'BUY' | 'SELL';
  outcomeName: string;
  marketId: string;
  marketTitle: string;
  price: string;
  quantity: string;
  total: string;
  txHash: string | null;
  createdAt: string;
}
```

{% endcode %}

## Conditional token operations

A complete outcome set is always worth exactly $1, so you can convert between USDC and shares without touching the order book at all. These are on-chain operations — each returns a transaction hash and takes a few seconds to confirm.

{% tabs %}
{% tab title="Split" %}

```ts
// $100 USDC → 100 YES + 100 NO
const { txHash } = await client.positions.split({
  eventId,
  marketId,      // required for multi-outcome events, optional for binary
  amount: 100,   // USDC
});
```

Market makers use this to manufacture two-sided inventory instead of buying each leg.
{% endtab %}

{% tab title="Merge" %}

```ts
// 100 YES + 100 NO → $100 USDC
const { txHash } = await client.positions.merge({
  eventId,
  marketId,
  amount: 100,   // shares of each side
});
```

The way to unwind a fully hedged book without paying the spread twice.
{% endtab %}

{% tab title="Redeem" %}

```ts
// After resolution: winning shares → $1.00 each
const { txHash } = await client.positions.redeem({ marketId });
```

Only callable once the market has resolved. Losing shares are simply worth nothing.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Splitting is not free money — you end up holding both sides, and you carry the inventory risk of whichever leg you later sell. What it buys you is instant, spread-free two-sided inventory.
{% endhint %}

### Referrals

```ts
const { code, total, completed, pending } = await client.referrals.me();
```

Returns your referral code (creating one on first call) and how many sign-ups it has produced.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://dev.strixlab.io/typescript-sdk/portfolio.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
