GitHubBlog

Search Documentation

Search for a page in the docs

Trading as Git

Every trade in OpenAlice follows a git-like workflow: stage operations, commit with a message, push to execute. If you use UTA, this is the required path for account mutation.

The point is approval and auditability. A trading desk does not let every proposed order go straight to the exchange; risk approval, execution authority, and post-trade records are separate concerns. Trading as Git gives a one-person desk the same shape: Alice can submit intent, a human approves execution, and the resulting history remains available for later analysis.

It also creates a clean architecture boundary. Alice can run where research and agent work are convenient, while UTA can run on trusted hardware that holds exchange keys. The submitter and approver are separated by the stage → commit → push wall, which is what makes future standalone UTA deployment possible.

The Analogy

GitTrading
git addStage an order (placeOrder, closePosition, modifyOrder, cancelOrder)
git commit -m "..."Bundle staged operations with a message, get an 8-char hash
git pushExecute — send orders to the broker (requires your approval)
git logReview commit history with hashes, timestamps, and results
git show <hash>Inspect a specific commit's operations and outcomes
git statusSee what's currently staged

Stage

Staging adds operations to the staging area without executing them. Alice stages operations through AI tools:

  • placeOrder — Stage a new order (buy/sell with order type, quantity, price)
  • closePosition — Stage closing an existing position (full or partial)
  • modifyOrder — Stage a change to a pending order
  • cancelOrder — Stage cancellation of a pending order

Multiple operations can be staged before committing. For example, Alice might stage closing one position and opening another in a single commit.

Commit

Committing bundles all staged operations with a descriptive message and generates an 8-char SHA-256 hash:

commit a3f8c1d2 — "Rotate from AAPL to NVDA based on AI momentum analysis"
  placeOrder: SELL 10 AAPL @ MKT
  placeOrder: BUY 5 NVDA @ LMT 135.00

At this point, nothing has been sent to the broker. The commit is prepared and waiting for approval.

Push

Push is the execution step — and it always requires your explicit approval. Calling tradingPush from Alice never executes directly: it returns a "pending approval" response that prompts you to approve from the Web UI. Once you approve, the system:

  1. Validates the push — the UTA checks the staged operations and account routing before broker contact
  2. Dispatches to the broker — approved operations are sent to the broker API
  3. Records results — each operation gets a status: submitted, filled, rejected, or cancelled
  4. Takes a snapshot — account state is captured for equity curve tracking
  5. Saves the commit — the full commit (operations + results + state) is persisted to disk

Optional push-time middleware can reject an operation before dispatch, but the main safety wall is the human approval step: no push approval, no broker execution.

Reject

Rejection comes from two directions, and they're distinct:

  • Alice discards her own stage — the tradingReject tool is the undo for a wrong stage, like git reset. Alice discards her staged (and committed-but-unpushed) operations herself; nothing is sent to the broker. If only a raw stage exists, it's committed transparently first so the recorded entry stays clean.
  • You reject a pending commit — when a commit is awaiting your approval, you turn it down from the Web UI instead of approving. This is the human's call at the push wall.

Either way the operations are recorded as user-rejected in the history, so Alice sees what was turned down and why, which informs future decisions.

commit b7e2f190 — "[rejected] Aggressive leveraged position — too much risk for current portfolio"
  placeOrder: BUY 100 TQQQ @ MKT (user-rejected)

Sync

After a push, orders may not be immediately filled — exchanges are asynchronous. The tradingSync tool checks the broker for order status updates:

  • Pending orders that have been filled get their fill price and quantity recorded
  • Cancelled or expired orders are marked accordingly
  • A sync commit is created with the updates
commit c4d9e0a1 — "[sync] 2 order(s) updated"
  synced → filled @135.20 (5 filled)

Reading History

Three tools let you inspect the trading history:

  • tradingLog — List recent commits with hashes, messages, and operation summaries. Filter by symbol to see all activity on a specific asset.
  • tradingShow — Inspect a specific commit by hash — see every operation, its result, and the account state at that point.
  • tradingStatus — See what's currently in the staging area and the head commit hash.

Example Conversation

You: Buy 10 shares of AAPL at market price.

Alice: I've staged a market buy order for 10 AAPL shares.

      Staging area:
      • placeOrder: BUY 10 AAPL @ MKT

      Committing as "Buy 10 AAPL — market order per user request"
      Commit hash: a3f8c1d2

      Ready to push. Shall I execute?

You: Yes, go ahead.

Alice: Pushed commit a3f8c1d2.
      • BUY 10 AAPL @ MKT → submitted (orderId: abc123)

      The order has been submitted to Alpaca. Let me sync to check
      if it's been filled...

      Synced: order abc123 filled @ $187.42

Why This Design?

The git workflow solves several problems:

  1. Auditability — Every decision has a hash, timestamp, and message. You can trace exactly what happened and why.
  2. Safety — The push approval step prevents accidental execution.
  3. Batching — Multiple related operations can be committed together as a logical unit.
  4. Async settlement — The sync step cleanly handles the gap between order submission and fill.
  5. AI learning — Rejected commits teach Alice what you don't want, improving future suggestions. Alice can also reject her own staged operations (tradingReject) when she catches a mistake before the push wall.

Next Steps