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

# Equity Trading

> Trade stocks and ETFs with the same engine, pipeline, and risk system used for prediction markets.

# Equity Trading

Horizon supports equities as a first-class asset class. The same engine, risk pipeline, feed system, and persistence layer work for stocks — the only differences are `Side.Long` instead of `Side.Yes`/`Side.No`, and price ranges that aren't limited to 0-1.

## Quick Start

```python theme={null}
import horizon as hz

def fair_value(ctx: hz.Context) -> float:
    return ctx.feeds["aapl"].price

def quoter(ctx: hz.Context, fair: float) -> list[hz.Quote]:
    spread = fair * 0.001  # 10bps spread
    return [hz.Quote(bid=fair - spread/2, ask=fair + spread/2, size=10)]

hz.run(
    name="aapl_mm",
    exchange=hz.Alpaca(paper=True),
    markets=[hz.Market(id="AAPL", exchange="alpaca", ticker="AAPL", asset_class="equity")],
    feeds={"aapl": hz.AlpacaFeed(symbols=["AAPL"])},
    pipeline=[fair_value, quoter],
    risk=hz.Risk.equity(max_position=100, max_notional=50_000),
    mode="live",
)
```

## What's Different from Prediction Markets

|                 | Prediction Markets                    | Equities                          |
| --------------- | ------------------------------------- | --------------------------------- |
| **Side**        | `Side.Yes` / `Side.No`                | `Side.Long`                       |
| **Price range** | 0.01 - 0.99                           | 0.01 - 100,000                    |
| **Risk preset** | `Risk()`                              | `Risk.equity()`                   |
| **Token IDs**   | Yes (Polymarket)                      | None                              |
| **Exchanges**   | Polymarket, Kalshi, Limitless         | Alpaca, IBKR                      |
| **Discovery**   | `discover_markets("polymarket", ...)` | `discover_markets("alpaca", ...)` |

Everything else is the same: pipeline composition, risk checks, order management, position tracking, persistence, monitoring, backtesting.

## Side.Long

Equities don't have Yes/No outcomes. The `Side.Long` variant represents a directional position:

```python theme={null}
from horizon import Side, OrderSide, OrderRequest

# Buy 10 shares of AAPL at $175
req = OrderRequest(
    market_id="AAPL",
    side=Side.Long,
    order_side=OrderSide.Buy,
    size=10,
    price=175.50,
)

# Sell to close
req = OrderRequest(
    market_id="AAPL",
    side=Side.Long,
    order_side=OrderSide.Sell,
    size=10,
    price=180.00,
)
```

The position tracker, risk pipeline, and P\&L calculations all handle `Side.Long` the same way they handle `Side.Yes` — buy increases position, sell decreases it.

## Risk Configuration

`Risk.equity()` provides defaults appropriate for stock trading:

```python theme={null}
risk = hz.Risk.equity(
    max_position=1000,       # max shares per symbol (default: 1000)
    max_notional=100_000,    # max portfolio value (default: 100,000)
    max_drawdown_pct=5,      # kill switch trigger (default: 5%)
    max_order_size=500,      # max single order size (default: 500)
    price_min=0.01,          # minimum valid price (default: 0.01)
    price_max=100_000,       # maximum valid price (default: 100,000)
)
```

The key difference from `Risk()` is `price_max`. Prediction market prices are bounded 0-1; stock prices aren't. The Rust risk pipeline uses `price_min`/`price_max` from the config, so the same validation code works for both.

## Market Discovery

Find stocks via Alpaca or IBKR:

```python theme={null}
import horizon as hz

# Search Alpaca for equities
stocks = hz.discover_markets(exchange="alpaca", query="AAPL", limit=10)
for s in stocks:
    print(f"{s.ticker}: {s.name}")

# Search IBKR
contracts = hz.discover_markets(exchange="ibkr", query="AAPL", limit=10)
```

### CLI Discovery

```bash theme={null}
horizon discover "AAPL" --exchange alpaca
horizon discover "apple" --exchange ibkr
```

## Market Object

Equity markets use optional fields for asset class metadata:

```python theme={null}
market = hz.Market(
    id="AAPL",
    name="Apple Inc.",
    exchange="alpaca",
    ticker="AAPL",
    asset_class="equity",
)

# Options contracts use additional fields
option = hz.Market(
    id="AAPL230120C00150000",
    name="AAPL Jan 2023 150 Call",
    exchange="ibkr",
    ticker="AAPL",
    asset_class="option",
    underlying="AAPL",
    strike_price=150.0,
    option_type="call",
    multiplier=100.0,
)
```

| Field          | Used For        | Example                            |
| -------------- | --------------- | ---------------------------------- |
| `asset_class`  | Instrument type | `"equity"`, `"option"`, `"crypto"` |
| `underlying`   | Derivatives     | `"AAPL"` for an AAPL option        |
| `strike_price` | Options         | `150.0`                            |
| `option_type`  | Options         | `"call"` or `"put"`                |
| `multiplier`   | Contracts       | `100.0` for US equity options      |

All fields are optional and default to `None`. Prediction markets ignore them.

## Feeds

Alpaca provides real-time equity data via WebSocket:

```python theme={null}
feeds = {
    "aapl": hz.AlpacaFeed(symbols=["AAPL"]),
    "spy": hz.AlpacaFeed(symbols=["SPY", "QQQ"]),
}
```

Multi-symbol feeds create per-symbol snapshots keyed as `{feed_name}:{SYMBOL}`:

```python theme={null}
ctx.feeds["spy:SPY"].price   # SPY last trade
ctx.feeds["spy:QQQ"].price   # QQQ last trade
ctx.feeds["spy:SPY"].bid     # SPY best bid
ctx.feeds["spy:SPY"].ask     # SPY best ask
```

## CLI Tools

The `equity` CLI group provides market data tools:

```bash theme={null}
horizon equity quote AAPL              # stock quote
horizon equity search "tech"           # search stocks
horizon equity options-chain AAPL      # options chain
horizon equity greeks SPY              # Greek exposure
horizon equity iv-surface TSLA         # IV term structure
horizon equity screener --sector tech  # stock screener
```

These use [Unusual Whales](/providers/unusual-whales) as the data source when `UNUSUAL_WHALES_API_KEY` is set.

## Multi-Asset Strategies

Combine prediction markets and equities in one strategy:

```python theme={null}
hz.run(
    name="cross_asset",
    exchanges=[
        hz.Polymarket(private_key="0x..."),
        hz.Alpaca(paper=True),
    ],
    markets=[
        hz.Market(id="will-fed-cut-rates", exchange="polymarket"),
        hz.Market(id="TLT", exchange="alpaca", asset_class="equity"),
    ],
    feeds={
        "rates": hz.PolymarketBook("will-fed-cut-rates"),
        "tlt": hz.AlpacaFeed(symbols=["TLT"]),
    },
    pipeline=[cross_asset_strategy],
    risk=hz.Risk(max_position=100, price_min=0.01, price_max=1000),
)
```

Orders route to the correct exchange based on `market.exchange`. The engine tracks positions and P\&L across all exchanges in a single book.

## What Works the Same

These features work identically for equities and prediction markets:

* **Pipeline composition**: chain functions, automatic signature introspection
* **Risk pipeline**: all 8 checks (kill switch, price/size, position, notional, drawdown, rate limit, dedup)
* **Order management**: submit, cancel, amend, bracket orders, stop-loss, take-profit
* **Position tracking**: real-time P\&L, exposure calculations
* **Persistence**: SQLite crash recovery, fill journal, position snapshots
* **Monitoring**: Prometheus metrics, alerts, TUI dashboard
* **Backtesting**: `hz.backtest()` with the same pipeline
* **Autonomous fund**: FundManager, strategy lifecycle, oversight loop
