> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sory.pro/llms.txt
> Use this file to discover all available pages before exploring further.

# Adding a venue

> One file. Nothing else in SORY changes.

If a venue is not in the [supported list](/venues), you can add it yourself. It is one file, and nothing else in the package needs editing — if you find yourself changing anything else, that is a bug in SORY, not a gap in the template.

<Steps>
  <Step title="Generate the adapter" icon="download">
    ```bash theme={"dark"}
    sory scaffold-venue mynewvenue
    ```

    Writes a single file with the class, the capability declaration and the one hook most venues need.
  </Step>

  <Step title="Declare what it can do" icon="circle-check">
    ```python theme={"dark"}
    class MyNewVenue(ExchangeAdapter):
        exchange_id = "mynewvenue"

        capabilities = Capabilities(
            spot=True,
            spot_margin_short=False,
            swap=False,
            post_only=False,
        )
    ```

    Declare what you have **proven**, not what the venue's own API metadata claims. It is wrong in both directions often enough to be useless — that is why `time_in_force` starts at `GTC` only and why `spot_margin_short` starts `False`.
  </Step>

  <Step title="Translate anything unusual" icon="split">
    Most venues need nothing here. When one does, it is a parameter name:

    ```python theme={"dark"}
    def _order_params(self, order: VenueOrder) -> dict[str, Any]:
        params = super()._order_params(order)      # handles post_only, time_in_force
        if order.margin:
            params["allowBorrow"] = True           # this venue's word for it
        return params
    ```

    This is the only hook most adapters ever use. Everything else — sessions, book maintenance, rate limiting, rounding, error translation — comes from the base class.
  </Step>

  <Step title="Prove it works" icon="shield-check">
    ```bash theme={"dark"}
    sory test-venue mynewvenue
    ```

    Loads markets, subscribes to the book, and checks the things that quietly break routing: prices are `Decimal`, bids descend and asks ascend, the book is not crossed, rounding never rounds an amount **up**, and quantities are in base units rather than contracts.

    Add `--private` to include a real resting order, `fetch`, and `cancel` round trip, plus IOC and FOK if you declared them.
  </Step>

  <Step title="Register it" icon="plug">
    ```python theme={"dark"}
    from sory import SoryClient, default_registry

    registry = default_registry()
    registry.register("mynewvenue", MyNewVenue)

    config = {"symbol": "BTC/USDT", "exchanges": ["binance", "mynewvenue"], "registry": registry}
    ```

    From here it behaves like any other venue: it appears in the book, it gets routed to, and it is excluded with a reason when it goes quiet.
  </Step>
</Steps>

## The contract

An adapter provides these. `ExchangeAdapter` implements all of them, so a subclass usually overrides none.

| Method                                       | Purpose                                          |
| -------------------------------------------- | ------------------------------------------------ |
| `connect` / `close`                          | Open and close the venue session.                |
| `load_markets`                               | Instrument metadata, normalised to `MarketInfo`. |
| `watch_order_book`                           | Yield an immutable snapshot per tick.            |
| `watch_orders`                               | Stream order updates.                            |
| `create_order` / `cancel_order`              | Send and pull one order.                         |
| `fetch_open_orders` / `fetch_order`          | What is resting; what happened to one.           |
| `market`                                     | Cached `MarketInfo` for a symbol.                |
| `amount_to_precision` / `price_to_precision` | Round to the venue's lot and tick.               |

<Warning>
  `amount_to_precision` must **never round up**. Rounding an amount up sends more than was allocated — an over-fill nobody asked for. The conformance suite checks this explicitly.
</Warning>

## Running the checks yourself

The conformance suite ships inside the package, so it works from an installed copy:

```python theme={"dark"}
from sory import conformance, default_registry

report = await conformance.run(default_registry(), "mynewvenue", "BTC/USDT", private=False)
print(report.passed)
for check in report.checks:
    print(check)
```

## Regenerating the reference page

```bash theme={"dark"}
sory docs-venue mynewvenue
```

<Note>
  If a venue quotes order quantities in **contracts** rather than base units, it cannot be added safely without extra work — its numbers do not mean the same thing as the rest of the book, and an order could be sized orders of magnitude wrong. The conformance suite detects this and fails.
</Note>

<Card title="Or just ask" icon="mail" horizontal href="mailto:manu.de.cara@gmail.com">
  New venues are added on almost every release. Register your interest.
</Card>
