> For the complete documentation index, see [llms.txt](https://docs.lighter.xyz/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.lighter.xyz/developers/binary-options/trading-and-fees.md).

# Trading and fees

Place binary options orders, calculate fees, and handle market-specific restrictions.

Binary options use the same `CreateOrder`, `ModifyOrder` and `CancelOrder` transactions and the same SDK / WASM signer calls as other markets. Pass the binary options `market_id` and:

{% hint style="info" %}
For the current binary options discovery methods and response models, use [lighter-sdk 1.1.8](https://pypi.org/project/lighter-sdk/1.1.8/) or newer, or [lighter-go v1.0.12](https://github.com/elliottech/lighter-go/releases/tag/v1.0.12) or newer. Python 1.1.8 also fixes the `boPnl` authorization header. The standard create, modify and cancel order flow is unchanged; discover binary options market IDs through `events`.

The shared-library signer uses signed 64-bit market indices (`int64`). If you call it directly from C/C++ or a custom FFI binding, use a `.h` file and bindings that match your signer library. Update declarations that still use `int cMarketIndex` to `long long int cMarketIndex`, as shown in the [current signer header](https://github.com/elliottech/lighter-python/blob/v1.1.8/lighter/signers/lighter-signer-linux-amd64.h#L158).

See the [Python binary options examples](https://github.com/elliottech/lighter-python/tree/v1.1.8/examples/binary-options), especially [create\_order\_from\_event.py](https://github.com/elliottech/lighter-python/blob/v1.1.8/examples/binary-options/create_order_from_event.py), for market discovery through `events` followed by `create_order`.
{% endhint %}

| Parameter      | Binary options                                                                        |
| -------------- | ------------------------------------------------------------------------------------- |
| `price`        | Integer price ticks: `51` = `0.51` USDC. Must be `> 0` and `< settlement_cap` (`100`) |
| `baseAmount`   | Integer shares × 10^`size_decimals`: `1000000` = `100.0000` shares                    |
| `isAsk`        | `0` buy = Up, `1` sell = Down                                                         |
| `orderType`    | `0` Limit or `1` Market only                                                          |
| `timeInForce`  | `0` IOC · `1` Good-till-time · `2` Post-only                                          |
| `reduceOnly`   | Must be `0`                                                                           |
| `triggerPrice` | Must be `0` (no stop / take-profit / TWAP)                                            |

## Place an order

### Python

Use an initialized `SignerClient` from [Signing transactions](/developers/integration-guides/signing-transactions.md). Set `MARKET_ID` to a current binary options market ID from [Discover markets](/developers/binary-options/discover-markets.md).

```python
tx, tx_hash, err = await client.create_order(
    market_index=MARKET_ID,      # market_id from /api/v1/events
    client_order_index=1234,
    base_amount=1000000,         # 100.0000 shares
    price=51,                    # 0.51 USDC per Up share
    is_ask=False,                # buy = Up
    order_type=client.ORDER_TYPE_LIMIT,
    time_in_force=client.ORDER_TIME_IN_FORCE_GOOD_TILL_TIME,
    reduce_only=False,
    order_expiry=client.DEFAULT_28_DAY_ORDER_EXPIRY,
)
```

### TypeScript (WASM)

This snippet uses the signer and submission helpers from the [TypeScript quickstart](/developers/getting-started/quickstart-typescript.md).

```typescript
const tx = check(lighter.SignCreateOrder(
  MARKET_ID, clientOrderIndex, 1000000, 51, 0 /* buy = Up */, 0 /* limit */, 1 /* GTT */,
  0, 0, orderExpiry,
  0, 0, 0,                    // integrator account, taker fee, maker fee
  0, 0, 0, nonce, API_KEY_INDEX, ACCOUNT_INDEX,
));
await sendTx(tx);
```

## Order rules

* Create and modify requests must pass the same trading-window, frozen-book and price-cap checks: `start_timestamp ≤ block time ≤ end_timestamp`, `is_frozen = false`, and `0 < price < settlement_cap`. A `start_timestamp` of `0` means trading can start from listing. Cancellation is allowed outside the trading window.
* For resting orders, buy cost is `P × size` and sell cost is `(1 − P) × size`, where `P` is the Up price in USDC and `size` is shares. The USDC reserve is calculated **per market** as `max(Σ buy costs − Down shares held × 1.00, Σ sell costs − Up shares held × 1.00, 0)`. Buy and sell requirements are not added together; existing shares offset the opposite side. IOC and market orders are funded at fill time.
* The `min_quote_amount` check uses **`P × size` for both buys and sells**, even though opening a Down position costs `(1 − P) × size`. Read both minimums from [events](https://docs.lighter.xyz/api/binary-options). For example, mainnet markets checked on October 19, 2026 have `min_base_amount = 5` shares and `min_quote_amount = 0.000001` USDC. A 5-share sell at `P = 0.02` has an Up notional of 0.10 USDC and passes that quote minimum; its Down cost is 4.90 USDC. In this configuration the 5-share base minimum is the binding minimum. Also respect `order_quote_limit`.
* A market order's `price` is the worst acceptable Up price, as on other markets.
* Public pool and insurance fund accounts cannot trade binary options.

## Errors

| Code    | Message                                                  | Cause                                                                      |
| ------- | -------------------------------------------------------- | -------------------------------------------------------------------------- |
| `21618` | invalid order type for market                            | Stop, take-profit, TWAP or `reduceOnly = 1`                                |
| `21631` | market is outside its trading window                     | Create or modify request before `start_timestamp` or after `end_timestamp` |
| `21632` | order price must be below the full payout                | Create or modify request with `price ≥ settlement_cap`                     |
| `21638` | order book is frozen                                     | Create or modify request while the operator has frozen the market          |
| `21752` | pools are not allowed to trade in binary options markets | Public pool / insurance fund account                                       |

## Orders and trades

[accountActiveOrders](https://docs.lighter.xyz/api/orders), [accountInactiveOrders](https://docs.lighter.xyz/api/orders) and [trades](https://docs.lighter.xyz/api/orders) accept `market_type=bo` (`all` by default) and work with a binary options `market_id`. Trades carry `market_kind: "bo"`. Settlement records use `type: "market-settlement"`; see [Positions and settlement](/developers/binary-options/positions-and-settlement.md#settlement).

[recentTrades](https://docs.lighter.xyz/api/orders) returns an empty list once a binary options market has settled. Use [trades](https://docs.lighter.xyz/api/orders) with `market_id` for historical fills and settlement records. [exchangeStats](https://docs.lighter.xyz/api/info) includes binary options symbols such as `ETH-UPDOWN-…`; filter its market entries by symbol when separating market types.

## Fees

Each market has a maximum `taker_fee` and `maker_fee` (Up/Down series: taker **1%**, maker **0%**). Both sides pay in USDC on the trade notional, scaled by the trade price and by the account's binary options fee multiplier:

```
fee = marketFee × bo_fee_rate × size × P × (1 − P)
```

Use decimal rates in the formula: `marketFee = 0.01` for a 1% market fee. `P` is the Up price in USDC (`0.51`, not `51` price ticks).

* `size × P` is the Up-price notional in USDC. Opening Down costs `(1 − P) × size`; resting-order reserves follow the per-market rule above. Use the same fee formula for both sides.
* `(1 − P)` makes fees smaller as the outcome becomes certain: highest at `P = 0.50`, near zero at `0.01` and `0.99`.
* `bo_fee_rate` is the account's multiplier, the product of its binary options volume tier and LIT staking tier, `1` by default.

Binary options fees are separate from the perps/spot [account tiers](/developers/reference/account-types.md). [feeTiers](https://docs.lighter.xyz/api/binary-options) with `filter=bo` returns the `bo_tiers` (by trailing volume) and `staking_tiers` tables; [accountLimits](https://docs.lighter.xyz/api/account) returns the account's `bo_user_tier_name` and `bo_fee_rate`. Read the current tables from the endpoint instead of hard-coding volume thresholds or staking discounts.

```shell
curl "https://mainnet.zklighter.elliot.ai/api/v1/feeTiers?filter=bo"
```

### Fees in trade responses

In trade JSON, `taker_fee` / `maker_fee` are the **effective rate** in fee ticks (`1e6` = 100%): with `bo_fee_rate = 1`, a 1% market taker fee on a fill at `0.51` shows as `taker_fee: 4900` (`10000 × (1 − 0.51)`), i.e. `51.00 × 0.49% = 0.2499` USDC on 100 shares.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.lighter.xyz/developers/binary-options/trading-and-fees.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
