# Open Orderbook

This is the simplest and most obvious strategy a relayer can use. The relayer accepts and broadcasts orders where the `taker` field is equal to `0x0000000000000000000000000000000000000000`. Any trader with access to all of an order's parameters is able to fill the order by signing a transaction locally and sending it to an Ethereum node.

## Example

Alice submits orderA to sell 1 WETH in exchange for 1000 ZRX to relayer Charlie. Bob sees the order on Charlie's orderbook and calls `fillOrder(orderA, 1000)` using his own local node. Bob's 1000 ZRX are exchanged for Alice's 1 WETH.

## Rationale

This is arguably the cheapest and most trustless strategy to implement. In addition, orders on an open orderbook are easily accessible to third parties. This comes with numerous benefits, including:

-   Orders are able to be shared across relayers.
-   External dApps can use these orders for liquidity.
-   External smart contracts can use these orders for liquidity.

## Limitations

As trading throughput increases, it becomes increasingly likely that multiple traders will attempt to fill the same order (either intentionally or accidentally). This strategy benefits the most from the ability of relayers and traders to quickly and reliably monitor the pending transaction pool.

---

# Matching

A relayer may chose to accept and broadcast orders where the `taker` field is equal to an address controlled by the relayer. When the relayer receives two orders on opposite sides of the market with overlapping prices, the relayer can call `batchFillOrders` or `batchFillOrKillOrders` to atomically match both orders.

## Example

Alice submits orderA to sell 1 WETH in exchange for 1000 ZRX to relayer Charlie. Bob submits orderB to sell 1000 ZRX in exchange for 1 WETH to Charlie. Charlie calls `batchFillOrKillOrders(orderA, 1000, orderB, 1)`, exchanging Alice's 1 WETH for Bob's 1000 ZRX.

## Rationale

This strategy removes the primary race condition from the matching process. Traders cannot accidentally or intentionally attempt to fill the same order since only the relayer is allowed to fill each order. The relayer also knows when orders are matched before anyone else and can update the orderbook as soon as the transaction is submitted, allowing for a more real-time trading experience. This strategy also moves all gas costs to the relayer and can potentially provide a better UX for traders.

## Limitations

Centralized matching has a few downsides, most notably:

-   It adds an element of trust. Relayers are not forced to match orders and are only incentivized by fees and/or arbitrage opportunities.
-   In v1.0.0, relayers using this strategy must have a sufficient balance to fill the first order submitted in `batchFillOrders` or `batchFillOrKillOrders`. This limitation will be removed in later versions of the protocol with the addition of an [atomic matching function](https://github.com/0xProject/ZEIPs/issues/2).
-   It is difficult to implement a market order with the intention of executing against multiple orders, since the market order would need to be broken down into multiple orders of different prices, each with their own signature. The addition of an [order types parameter](https://github.com/0xProject/ZEIPs/issues/4) may be able to remedy this issue.
-   Since orders cannot yet be [generated by smart contracts](https://github.com/0xProject/ZEIPs/issues/1), this strategy is limited in its ability to work with third party dApps.

---

# Quote Provider

A relayer can provide its own liquidity by simply broadcasting an intent to trade (unsigned order). Traders can submit a signed order with the specified rate to the relayer (optionally, the `taker` field can be the relayer's address), who can then choose to fill the order using owned tokens or external liquidity.

## Example

Relayer Charlie says that he is willing to buy ZRX at a rate of 1000 ZRX per WETH. Alice sends orderA to sell 10000 ZRX in exchange for 10 WETH to Charlie. Charlie calls `fillOrder(orderA, 10000)`, exchanging his 10 WETH for Alice's 10000 ZRX.

## Rationale

Since this strategy does not require any commitments to be made until the trader agrees to a rate, any arbitrary off-chain negotiation process can occur before an order is signed. Once an order is signed, the relayer also has the option of hedging with external liquidity, so the relayer does not necessarily need as large reserves as with the [reserve manager](https://github.com/0xProject/wiki/blob/master/relayer-strategies/Reserve-Manager.md) strategy.

## Limitations

After a trader signs an order, the relayer is in no way obligated to fill that order (although the relayer may suffer a loss of reputation). The relayer also still needs some token reserves to utilize this strategy until the addition of an [atomic matching function](https://github.com/0xProject/ZEIPs/issues/2) to the protocol.

---

# Reserve Manager

A relayer can provide its own liquidity by frequently posting large orders with short expiration times where the `taker` field is equal to `0x0000000000000000000000000000000000000000`. This can be used separately from or in conjunction with the [open orderbook](https://github.com/0xProject/wiki/blob/master/relayer-strategies/Open-Orderbook.md) strategy.

## Example

Relayer Alice broadcasts orderA to sell 100 WETH in exchange for 100000 ZRX that expires in 45 seconds. Bob calls `fillOrder(orderA, 1000)`, exchanging his 1000 ZRX for Alice's 1 WETH. Charlie calls `fillOrder(orderA, 2000)`, exchanging his 2000 ZRX for Alice's 2 WETH.

## Rationale

This strategy can be used by large market makers who are willing to reliably provide liquidity to traders. Note that orders can be broadcasted through any arbitrary communication channel, so this strategy can be implemented off-chain, through event logs, or on-chain if desired.

## Limitations

This strategy suffers from the same limitations as the open orderbook model, although the likelihood of a race occuring becomes smaller as order sizes grow. In addition, it requires the relayer to hold large reserves of tokens in order to make markets.
