Code Along: Manual Orders

Place orders by hand with hz.connect(), no pipeline needed

Not everything needs a pipeline. Sometimes you just want to buy 10 shares of AAPL and check your balance. hz.connect() gives you a direct handle to a venue — paper or live — with simple buy/sell/flatten methods.

This is the imperative API. No strategies, no signals, no risk checks, no portfolio optimization. Just you and the order book.

Step 1. Connect to a paper venue

python
import horizon as hz

ex = hz.connect("paper", initial_cash_usd=100_000)

That’s it. ex is an ImperativeClient connected to a paper trading venue with $100k starting cash. No API keys, no broker accounts. Everything runs locally.

Step 2. Place a limit buy

python
order = ex.buy("AAPL", qty=10, limit=185.0)
print(order)
VenueOrder(id='p1', market_id='AAPL', side='buy', quantity=10, price=185.0, status='new')

This places a limit order to buy 10 shares of AAPL at $185. The order gets ID p1 (paper venue IDs are p1, p2, p3, …).

The order status is new — it’s resting in the paper venue’s book. In a backtest, the run loop ticks prices through the venue and fills matching orders. In standalone imperative use like this, limit orders sit forever until you cancel them or feed a crossing price.

For immediate fills, use market orders:

python
order = ex.buy("AAPL", qty=10, market=True)
print(order.status)  # "filled"

Market orders fill immediately at the last known price plus slippage.

Step 3. Sell some back

python
sell_order = ex.sell("AAPL", qty=5, limit=190.0)
print(sell_order)
VenueOrder(id='p2', market_id='AAPL', side='sell', quantity=5, price=190.0, status='new')

If the buy from step 2 was a market order and filled, you now hold 10 shares and have a resting sell for 5 of them.

Step 4. Check your state

python
# What positions do I hold?
positions = ex.positions()
for p in positions:
    print(f"  {p.market_id}: {p.quantity} shares")

# How much cash do I have?
balance = ex.balance()
print(f"Cash: ${balance.available_usd:,.2f}")

# What orders are still resting?
orders = ex.open_orders()
for o in orders:
    print(f"  {o.id}: {o.side} {o.quantity} {o.market_id} @ {o.price}")

# What fills happened?
fills = ex.fills()
for fill in fills:
    print(f"  Filled: {fill.side} {fill.quantity} {fill.market_id} @ {fill.price}")
  • ex.positions() returns a list of VenuePosition objects — everything you currently hold.
  • ex.balance() returns a VenueCapital object with available_usd, total_usd, etc.
  • ex.open_orders() returns all resting (unfilled) orders.
  • ex.fills() drains the fill queue — once you read them, they’re consumed.

Step 5. Close a position

python
# Close all AAPL
ex.flatten("AAPL")
print(ex.positions())  # AAPL is gone

flatten() sends a market order in the opposite direction of your current position. If you’re long 10 shares, it sells 10 at market.

Step 6. The nuclear option

python
# Close everything, all markets
ex.flatten_all()

Flattens every position across every market. Use when you want to go completely flat.

Step 7. Context manager (recommended)

The cleanest pattern wraps everything in a with block. close() is called automatically on exit:

python
with hz.connect("paper", initial_cash_usd=100_000) as ex:
    ex.buy("AAPL", qty=10, market=True)
    ex.buy("MSFT", qty=5, market=True)

    print("Positions:", ex.positions())
    print("Balance:", ex.balance())

    ex.flatten_all()
    print("After flatten:", ex.positions())

Step 8. Other asset classes

The imperative API has helpers for prediction markets, perpetuals, and options:

python
with hz.connect("paper", initial_cash_usd=100_000) as ex:
    # Prediction markets
    ex.buy_prediction(
        market="polymarket:trump-2028",
        qty=100,
        limit=0.45,
        side="yes",
    )

    # Perpetual futures
    ex.buy_perp(
        "hyperliquid:BTC-PERP",
        qty=0.1,
        leverage=3,
        limit=95_000,
    )

    # Options
    ex.buy_option(
        underlying="AAPL",
        strike=180,
        expiry="2025-01-17",
        right="call",
        qty=5,
        limit=3.50,
    )

Each helper sets the appropriate asset class metadata so the venue knows how to handle the order.

Step 9. Modify and cancel

python
with hz.connect("paper", initial_cash_usd=100_000) as ex:
    order = ex.buy("AAPL", qty=10, limit=180.0)

    # Change price and quantity
    ex.amend(order.id, new_quantity=20, new_price=179.0)

    # Cancel a specific order
    ex.cancel(order.id)

    # Cancel all orders on a market
    ex.cancel_all(market_id="AAPL")

    # Cancel everything
    ex.cancel_all()

When to use this vs hz.run()

The imperative API and the pipeline serve different purposes:

hz.connect()hz.run()
SignalsNone. You decide what to trade.Strategy emits signals.
SizingYou pick the quantity.Kelly/Carver/EqualWeight decides.
Risk checksNone. No stops, no drawdown guards.Full risk pipeline.
AttributionNone. No per-strategy tracking.Per-strategy P&L attribution.
Best forManual trading, scripts, one-off ordersSystematic strategies, backtests

If you want the full pipeline — features, signals, risk enforcement, portfolio optimization — use hz.run(). If you want to place a specific order right now and don’t need any of that machinery, use hz.connect().

Full file

python
# manual_orders.py
import horizon as hz


def main():
    with hz.connect("paper", initial_cash_usd=100_000) as ex:
        # Buy some stocks
        ex.buy("AAPL", qty=10, market=True)
        ex.buy("MSFT", qty=5, market=True)
        ex.buy("NVDA", qty=3, market=True)

        # Check state
        print("=" * 50)
        print("POSITIONS")
        for p in ex.positions():
            print(f"  {p.market_id}: {p.quantity} shares")

        print()
        print(f"BALANCE: ${ex.balance().available_usd:,.2f}")

        # Partial sell
        ex.sell("AAPL", qty=5, market=True)
        print()
        print("After selling 5 AAPL:")
        for p in ex.positions():
            print(f"  {p.market_id}: {p.quantity} shares")

        # Flatten one name
        ex.flatten("MSFT")
        print()
        print("After flattening MSFT:")
        for p in ex.positions():
            print(f"  {p.market_id}: {p.quantity} shares")

        # Flatten everything
        ex.flatten_all()
        print()
        print("After flatten_all:")
        print(f"  Positions: {len(ex.positions())}")
        print(f"  Balance: ${ex.balance().available_usd:,.2f}")


if __name__ == "__main__":
    main()

Expected output

==================================================
POSITIONS
  AAPL: 10 shares
  MSFT: 5 shares
  NVDA: 3 shares

BALANCE: $9x,xxx.xx

After selling 5 AAPL:
  AAPL: 5 shares
  MSFT: 5 shares
  NVDA: 3 shares

After flattening MSFT:
  AAPL: 5 shares
  NVDA: 3 shares

After flatten_all:
  Positions: 0
  Balance: $~100,000

Exact dollar amounts depend on the paper venue’s simulated prices.

Next