# `Bourse.Order.Sanity`
[🔗](https://github.com/ZenHive/bourse/blob/main/lib/bourse/order/sanity.ex#L1)

Pre-submit order validation against market metadata.

Checks order shape, exchange order-type support, market limits, tick-size
precision, and optional price deviation before an order is submitted.

Unified `Bourse.create_order` and `Bourse.edit_order` calls opt in with
`sanity: true`. The default is `false` so existing callers retain the
exchange's validation contract; validation is skipped when markets have not
been loaded with `Bourse.load_markets/1`.

## Options

- `:has` — the exchange capability map, used to reject unsupported order types.
- `:partial` — when `true`, an absent `amount` or `price` is treated as a field
  that is not being changed rather than a missing required field. The unified
  path sets this for `edit_order`, which carries only the changed fields.
- `:reference_price` / `:deviation_threshold` — opt into the price-deviation warning.
- `:warnings` — `:strict` promotes warnings to errors.

# `reason`

```elixir
@type reason() :: {atom(), String.t()}
```

# `result`

```elixir
@type result() ::
  {:ok, map()}
  | {:ok, map(), [reason()]}
  | {:error, {:sanity_check, [reason()]}}
```

# `check_amount`

```elixir
@spec check_amount(any(), map() | nil, keyword()) :: :ok | {:error, String.t()}
```

Validates order amount against market limits and precision.

# `check_cost`

```elixir
@spec check_cost(any(), any(), map() | nil) :: :ok | {:error, String.t()}
```

Validates order notional against market cost limits.

# `check_order_type`

```elixir
@spec check_order_type(
  any(),
  keyword()
) :: :ok | {:error, String.t()}
```

Validates order type and optional exchange capability support.

# `check_price`

```elixir
@spec check_price(any(), String.t() | nil, map() | nil, keyword()) ::
  :ok | {:error, String.t()}
```

Validates order price against order type, market limits, and precision.

# `check_price_deviation`

```elixir
@spec check_price_deviation(any(), any(), keyword()) :: :ok | {:warning, String.t()}
```

Warns when price deviates beyond the configured reference-price threshold.

# `check_side`

```elixir
@spec check_side(any()) :: :ok | {:error, String.t()}
```

Validates order side.

# `check_symbol`

```elixir
@spec check_symbol(any(), map()) :: :ok | {:error, String.t()}
```

Validates order symbol against market metadata.

# `validate`

```elixir
@spec validate(map() | Bourse.Order.Builder.t(), map() | nil, keyword()) :: result()
```

Runs all applicable sanity checks and collects every hard failure.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
