Skip to content

feat: add order history tool - #17

Merged
jack-arturo merged 3 commits into
mainfrom
feat/order-history
May 22, 2026
Merged

feat: add order history tool#17
jack-arturo merged 3 commits into
mainfrom
feat/order-history

Conversation

@jack-arturo

Copy link
Copy Markdown
Member

Summary

Adds robinhood_get_order_history, a read-only tool that wraps robin_stocks.orders.get_all_stock_orders() to surface executed buy/sell history — the trades that built the current positions. Fills a gap: the server could show what you hold now, but not what you bought or sold to get there.

What it returns

Curated rows (newest first), never a raw API dump:

  • symbol, side, state, quantity, filled_quantity, average_price, type, created_at, last_transaction_at
  • executions[] — per-fill price/quantity/timestamp detail

Design notes

  • Symbol resolution. Orders are keyed by instrument URL, not ticker. Resolved via get_symbol_by_url, cached in a module-level _symbol_url_cache (instrument→symbol mappings are immutable, so no TTL). Distinct URLs resolve once per call; an unresolvable instrument falls back to symbol: None rather than failing the whole response.
  • state filter. state="executed" (default) filters on a non-empty executions list, catching both filled and partially_filled — a literal state == "filled" check would silently drop partial fills. state="all" returns cancelled/queued/rejected rows too.
  • Cheap symbol filter. When provided, resolves ticker→URL first via the existing _validate_symbol_instrument and matches on instrument, skipping per-row resolution.
  • start_date passes straight through to the API for server-side trimming; limit slices most-recent-first.
  • Read-only mandate held. Only the read endpoint is wrapped — the cancel_* siblings in rh.orders are never exposed.

Lands the server at 14 tools, still within the comfort ceiling.

Tests

TestGetOrderHistory — 12 new tests, written test-first (TDD): curated rows, distinct-URL resolution dedup, executed vs all state filtering, symbol filter, limit + ordering, start_date passthrough, unresolvable instrument, empty/non-list responses, input validation.

Verified locally: ruff check clean, ruff format --check clean, 59 tests pass (47 existing + 12 new).

Add `robinhood_get_order_history`, a read-only tool that wraps
`robin_stocks.orders.get_all_stock_orders()` to surface executed
buy/sell history — the trades that built the current positions.

- Curated rows (symbol, side, state, quantity, filled quantity,
  average price, type, timestamps, per-fill executions), never a
  raw API dump.
- Instrument-URL → ticker resolution via `get_symbol_by_url`, cached
  in a module-level `_symbol_url_cache` (instrument→symbol mappings
  are immutable, so no TTL). Distinct URLs resolve once per call;
  unresolvable instruments fall back to `symbol: None` rather than
  failing the whole response.
- `state="executed"` (default) filters on a non-empty `executions`
  list, catching both `filled` and `partially_filled`; `state="all"`
  returns cancelled/queued/rejected rows too.
- Optional `symbol` filter resolves ticker→URL first and matches on
  `instrument`, skipping per-row resolution. `start_date` passes
  through to the API for server-side trimming. `limit` slices most
  recent first.
- Wraps only the read endpoint — the `cancel_*` siblings in
  `rh.orders` are never exposed, consistent with the no-trading rule.

Lands the server at 14 tools, still within the comfort ceiling.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 22, 2026 18:03

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new read-only MCP tool to surface Robinhood stock order history (buys/sells) as curated, symbol-resolved rows with per-fill execution details, filling the gap between “current positions” and “how you got there”.

Changes:

  • Implement get_order_history in tools.py, including instrument-URL→symbol resolution with a module-level cache and filtering options (symbol, state, limit, start_date).
  • Register the new tool in the FastMCP server and expose it in server.json, plus update README docs.
  • Add a dedicated TestGetOrderHistory test suite and related fixtures/helpers.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/test_tools.py Adds TestGetOrderHistory plus cache-reset fixture and order-shaped test helpers.
src/robinhood_mcp/tools.py Implements order history retrieval, curation, filtering, sorting, and symbol-resolution caching.
src/robinhood_mcp/server.py Registers the new robinhood_get_order_history MCP tool and wires it to get_order_history.
server.json Adds the new tool to published MCP server metadata.
README.md Documents trade history usage and adds the tool to the tool table.
CLAUDE.md Updates the architecture overview (tool count).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/robinhood_mcp/tools.py Outdated
Comment thread src/robinhood_mcp/tools.py Outdated
Comment thread CLAUDE.md Outdated
Comment thread server.json
Addresses GitHub Copilot review on PR #17.

- Add `_raw_executions()` helper that normalizes an order's `executions`
  field to a list of dicts, tolerating malformed (non-list) API data.
  Used by both `_order_payload` and the `state="executed"` filter so a
  non-list value can no longer crash `_order_payload` (it iterated the
  raw value directly) and no longer slips past the executed filter as a
  truthy non-list. One definition keeps filter and payload consistent.
- server.json: add the missing `robinhood_get_position` entry so the
  published tool metadata matches the registered tool surface (14 tools).
- CLAUDE.md: correct the architecture comment to 14 tool implementations.

Adds a regression test for malformed `executions` values.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment thread src/robinhood_mcp/tools.py
Comment thread src/robinhood_mcp/tools.py
The module-level symbol cache only stores successful instrument->symbol
lookups, so an unresolvable URL shared by many order rows re-hit the API
once per row. Resolve each distinct instrument URL once per call via a
local map, keeping the no-TTL module cache for successful lookups.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jack-arturo
jack-arturo merged commit 889f821 into main May 22, 2026
9 checks passed
@jack-arturo
jack-arturo deleted the feat/order-history branch May 22, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants