# Markets

> Markets, events, filters, and cursor pagination.

Source: https://docs.stxapp.io/sdks/typescript/markets/

## Markets

```ts
import { STX } from "@stxapp/stx-typescript";

const client = new STX();
const page = await client.markets({ status: "open", limit: 5 });
for (const market of page) {
  console.log(market.symbol, "last", market.last_traded_price, "bid", market.bids?.[0]?.price);
}
console.log("more pages:", page.hasMore);
```

| Option | Meaning |
|---|---|
| `marketIds`, `eventIds` | One id or a list |
| `status` | One or a list, lowercase, e.g. `"open"`; see [Market status](/concepts/market-status/) |
| `trading` | `true` for only the markets accepting orders now, `false` for only those that are not |
| `sports`, `competitions` | One or a list |
| `sortBy`, `sortDirection` | e.g. `sortBy: "event_start"`, `sortDirection: "desc"` |
| `limit`, `cursor` | Page size and the cursor from the previous page |

Filters combine with AND; a list filter matches any of its values. `client.market(id)` fetches one market and throws `STXNotFoundException` when there is none.

## Pagination

A list method returns one `Page`: `page.items`, `page.cursor` (`null` on the last page), `page.hasMore` and `page.length`. A `Page` is iterable. To walk every page, use the `iter*` twin, which follows the cursor for you:

```ts
import { STX } from "@stxapp/stx-typescript";

const client = new STX();

let market;
for await (const m of client.iterMarkets({ trading: true, sortBy: "event_start", sortDirection: "desc" })) {
  if (m.event_status === "scheduled") {
    market = m;
    break;
  }
}
console.log(market?.market_id, market?.symbol, market?.max_price);
```

`trading: true` returns only the markets that accept orders now.

Or page by hand:

```ts
let page = await client.markets({ status: "open", limit: 100 });
while (true) {
  for (const m of page) console.log(m.symbol);
  if (!page.hasMore) break;
  page = await client.markets({ status: "open", limit: 100, cursor: page.cursor! });
}
```

## Events

```ts
const events = await client.events({ limit: 10 });
for (const e of events) console.log(e.event_id, e.title, e.status);

for await (const e of client.iterEvents({ promoted: true })) console.log(e.title);
```

`events()` filters on `eventIds`, `sports`, `competitions`, `eventTypes`, `title`, `status` and `promoted`, and sorts with `sortBy` and `sortDirection`.

## Creating markets

An app that STX has granted the `markets.write` scope can create player-prop markets on scheduled events, from an address on its IP allow-list. See [Creating markets](https://docs.stxapp.io/isv/creating-markets/) for the setup and the full list of outcomes.

```ts
import { AppScopes, OAuthClient } from "@stxapp/stx-typescript/oauth";
import { Stats } from "@stxapp/stx-typescript";

const oauth = new OAuthClient({ clientId, clientSecret });
const stx = oauth.appClient([AppScopes.EVENTS, AppScopes.MARKETS_WRITE]);

const roster = await stx.eventPlayers(eventId);
const player = roster.teams[0].players[0];

const results = await stx.createMarkets(eventId, [
  { playerId: player.player_id, stat: Stats.Basketball.POINTS, line: 18.5 },
  { playerId: player.player_id, stat: Stats.Basketball.REBOUNDS, line: 4.5 },
]);
for (const r of results) console.log(r.status, r.status === "rejected" ? r.reason : r.market_id);
```

- **Lines** must be positive and end in `.5`: `18.5` is accepted; `18`, `18.25`, `0` and `"18.5"` come back `rejected` with `invalid_line`.
- **Stats**: an event accepts the stats `eventPlayers()` (or `statsFor(event)`) returns for it. `Stats` lists them by sport for autocomplete.
- **Results** come back one per market, in order: `created`, `exists` (already listed, same `market_id`) or `rejected` with a `reason`. Resending is safe.
- **`validate: true`** checks players, stats and lines before sending, and returns failures as `rejected` without a request. It reads the event's players, so the token also needs `events`.
- Up to `MAX_MARKETS_PER_REQUEST` (25) markets per call; more throws `TypeError` before sending.

## Live prices

`bids` and `offers` are a snapshot of the top of the book. To follow prices as they move, stream them; see [WebSockets](/sdks/typescript/websockets/).
