# Alpaca paper mandate executor

The Alpaca paper adapter runs on the executing party's machine. It routes signed orders to Alpaca's paper API, checks the existing Wever mandate registry, retains a durable evidence journal, and sends only signed chain-tip fingerprints to Wever Labs. The same principal approval, Ed25519 agent and broker keys, wallet signatures, version fingerprints and free emergency controls from trading mandates v1 apply.

Download [the executable](https://weverlabs.com/adapters/alpaca-paper/alpaca-paper.mjs) and [its SHA-256 manifest](https://weverlabs.com/adapters/alpaca-paper/manifest.json). The executable bundles its dependencies and includes their license notices. Use Node.js 24.12 or later; Node.js 22.13 is the minimum supported runtime. Run `node alpaca-paper.mjs --help` for commands.

## Configuration

Use a dedicated Alpaca paper account. The adapter pins trading requests to `https://paper-api.alpaca.markets` and data requests to `https://data.alpaca.markets`, with redirects disabled. Alpaca provides separate paper credentials. Place these in an owner-readable JSON file with `key` and `secret` properties and file mode 0600. Keep the broker's existing Ed25519 private key in a separate 0600 PEM file. Retain both on the executor host.

A local config JSON contains:

```json
{
  "mandate": "replace with the complete approved mandate object",
  "approval": "replace with its wallet approval or broker attestation object",
  "broker_key_file": "./broker-private.pem",
  "credentials_file": "./alpaca-paper-credentials.json",
  "state_directory": "./private-executor-state"
}
```

Bind `mandate.principal.account_id` to the Alpaca paper account ID. Set venues to `["alpaca-paper"]`. Assets use US stock symbols or `BTC-USD`, which maps to Alpaca `BTC/USD`. Approve and register the exact mandate through the existing issue tool. Only the principal's wallet signature or an actual broker login attestation activates it. Installing the adapter or possessing API credentials does not create principal approval. Issue and amendment retain the existing $2.00 fee; status, halt, revoke and witnessing remain free.

`node alpaca-paper.mjs check config.json` verifies the bound account and queries its mandate status. It performs no order submission.

## Signed orders and execution

The order envelope uses the existing `wever.trading-mandate.v1` signing context. Its payload contains kind `order`, id, mandate_fingerprint, venue, asset, side, size, price, order_type, reduce_only and sent_at. Quantities and USD values are integer millionths, and times are UTC Unix seconds. The agent signs the complete payload with the key bound in the mandate.

Run `node alpaca-paper.mjs submit config.json signed-order.json` for one order. New exposure uses limit orders with a price bound, funded from cash and limited to long positions. US equities use whole shares, cent prices and regular trading hours. BTC-USD supports fractional quantities. Sell orders are reduce-only and reserve against the broker's remaining long quantity. The workload permits four outstanding orders and six submissions per minute across the account. Each order also obeys its signed mandate's smaller limits.

Checks include the account binding, agent signature, exact mandate version, live registry, current broker positions, resting orders, quote provenance and freshness, asset and venue, allowed order type, validity, position caps, total cap, cash, leverage and daily loss. Full-fill valuations use the more conservative of the current ask and signed limit price. Pending buys reserve exposure and cash; pending exits reserve held quantity. A 50-basis-point cost reserve and bid/ask adverse-price allowance are included before routing. Reserves for observed fills remain charged through that UTC day, including while broker fee postings lag. They can conservatively overlap losses already included in account equity. The first adapter supports cash-funded exposure even when a mandate permits higher leverage.

Daily loss uses Alpaca's equity history at midnight UTC and current account equity, including broker-booked realized and unrealized losses and fees. The maximum observed loss remains latched for that UTC day. Missing baseline data, an incomplete activity page, or cash-adjustment activity blocks new risk until the account snapshot can be reconciled. Portfolio history is requested with continuous intraday reporting. A newly created account can establish its inception baseline when Alpaca confirms it was created during the current UTC day and its positions, open orders and complete activity list are empty. That baseline persists through restarts. Quotes and broker snapshots have a five-second freshness limit. Current account state, valid signatures and bounded quantities still apply to reduce-only exits after expiry or during registry outages.

## Worker, halt and recovery

Run `node alpaca-paper.mjs run config.json` under the executor host's process supervisor. It polls every five seconds and processes a private filesystem inbox. To enqueue work while it runs, use `node alpaca-paper.mjs enqueue config.json request.json`, where the request contains `action` (`order`, `halt` or `amend`) and `input` (the corresponding signed order, signed halt, or approved version). Halt requests take priority over orders in the inbox. The worker processes at most one new order per cycle.

A separate SQLite lock permits one executor writer. The order intent and hash-chained evidence commit with full synchronization before the network submission. Alpaca receives a stable client order ID derived from account, mandate and caller order ID. A timeout or process crash triggers lookup by that same ID. Recovery never submits an ambiguous order again. An unresolved intent holds subsequent orders until its venue status can be established. The executor reconciles partial fills, terminal outcomes and cancellations after a restart.

A signed halt persists the local brake before cancellation or registry requests. Failed registry writes and cancellations remain pending and are retried after restart. The broker can renew the delivery signature for its already-recorded halt without changing the mandate's authority. Registry halt, revoke or replacement causes cancellation requests for all of the executor's resting orders. Expiry or registry outage cancels risk-increasing orders while preserving authenticated reduce-only exits. Cancellation remains pending until Alpaca reports a terminal outcome; fills that win the cancellation race remain in broker-held positions and evidence. Status polling, network timeouts and broker cancellation acknowledgments determine observed halt latency.

Use `node alpaca-paper.mjs halt config.json signed-halt.json` when the worker is stopped, or enqueue the halt while it runs. This adapter's halt keeps existing positions and uses `close_positions:false`. Resume requires a separately registered, principal-approved amendment. Use `amend config.json approved-version.json`, or enqueue it. Outstanding orders must have confirmed terminal outcomes before the new version activates locally.

The state directory contains `evidence.sqlite`, its SQLite recovery files, the process lock, inbox and processed results. Keep the complete directory on durable storage. `node alpaca-paper.mjs verify-evidence config.json` independently recomputes the stored sequence and hash links. A witness outage leaves the records intact and retries the latest chain tip on the next poll. Wever receives the mandate ID, sequence, current tip and previous witnessed tip, with a broker signature.

## Verification and operating scope

The automated suite exercises the paper transport, pre-routing rejection, reservations, signature/account binding, expiry exits, registry outage, halt cancellation, durable restart, lost-response reconciliation, version amendments, witness recovery and the single-writer lock. Test records are synthetic acceptance. Connecting an actual Alpaca paper account adds broker-hosted paper execution evidence, still separate from real-money trading.

A supported first run is: bind an approved mandate to a dedicated paper account; submit a small permitted limit; reject an oversized order before routing; place a non-marketable resting order; halt and confirm cancellation; restart and reconcile the same client IDs; read the live Wever status and independently verify the local evidence chain. Preserve account credentials and order evidence locally.

References: [Alpaca paper trading](https://docs.alpaca.markets/us/docs/paper-trading), [orders](https://docs.alpaca.markets/us/docs/working-with-orders), [portfolio history](https://docs.alpaca.markets/us/reference/getaccountportfoliohistory-1), [stock quotes](https://docs.alpaca.markets/us/reference/stocklatestquotes-1), [crypto quotes](https://docs.alpaca.markets/us/reference/cryptolatestquotes-1).
