# Time-in-Force Specification

Order execution policies following Betfair's model.

## Time-in-Force Types

| Type | Betfair Name | Description |
|------|--------------|-------------|
| `Gtc` | (default) | Good-til-Cancelled: rest unmatched portion |
| `FillOrKill` | `FILL_OR_KILL` | Match immediately in full or cancel entirely |

## GTC (Good-til-Cancelled)

Default behavior. The order:
1. Matches against available liquidity at valid prices
2. Any unmatched remainder rests in the book
3. Remains until explicitly cancelled, lapsed, matched out, or market-level cancel flow

## Fill-or-Kill (FOK)

Aggressive execution policy:

1. Check if **full quantity** can be matched immediately
2. If yes: execute all matches, order is `ExecutionComplete`
3. If no: reject order immediately, no partial fills

### Optional: Minimum Fill Size

`FillOrKill` supports optional minimum fill:
- If specified, at least `min_fill` must be matchable
- Remainder after min fill is cancelled (not rested)

```rust
FillOrKill {
    // Exchange orders: stake units
    // Binary orders: share units
    min_fill: Option<Quantity>,  // None = must fill entire order
}
```

**Examples:**

| Order Qty | Min Fill | Available | Result |
|----------|----------|-----------|--------|
| 100 | None | 100 | Filled 100 |
| 100 | None | 80 | Rejected |
| 100 | Some(50) | 80 | Filled 80, cancelled 20 |
| 100 | Some(50) | 40 | Rejected |

## Validation

Before matching a FOK order:

```
available_qty = sum of matchable liquidity at order's price or better
// same-account resting orders are excluded from available_qty
required = min_fill.unwrap_or(order.qty)

if available_qty < required:
    reject("WOULD_NOT_FILL_FOK")
else:
    match now
    if matched < order.qty:
        emit cancel cause FOK_REMAINDER
```

For `min_fill = None`, `required = order.qty` so the check enforces full-fill-or-reject.

## Events

FOK orders emit standard events:
- Exchange odds: `OrderAccepted` + `TradeMatched`* on success
- Binary yes: `BinaryOrderAccepted` + `BinaryTradeMatched`* on success
- Rejection: command returns `Response::Rejected { reason: WOULD_NOT_FILL_FOK }` and emits no book event

If `min_fill` is used and partial cancellation occurs:
- `OrderAccepted`/`BinaryOrderAccepted` + match events + `OrderCancelled { cancel_cause: FokRemainder }`

## Implementation Notes

1. FOK requires a "dry run" check before committing any matches
2. The check must account for self-trade prevention (can't match own orders)
3. Price improvement: FOK at price X can match at better prices
4. Multiple price levels may be swept to fill the order
