Skill: kevin1chun/robinhood-for-agents (version 0.6.1)

--- name: robinhood-for-agents description: Trade stocks, options, and crypto on Robinhood — dual mode (MCP tools or TypeScript client). homepage: https://github.com/kevin1chun/robinhood-for-agents allowed-tools: mcp__robinhood-for-agents__* install: - kind: node package: robinhood-for-agents bins: [robinhood-for-agents] requires: bins: [bun, google-chrome] metadata: {"credentials":"OAuth tokens stored in OS keychain via Bun.secrets (macOS Keychain Services, Linux libsecret, Windows Credential Manager). No tokens on disk. Browser login captures tokens via Playwright intercepting network traffic — no DOM interaction. Tokens expire ~24h.","chrome":"Required only for initial login (bunx robinhood-for-agents login). Not needed for subsequent API calls."} --- # robinhood-for-agents AI-native Robinhood trading interface. **No MCP server required** — this skill works standalone via the TypeScript client API and `bun`. ## How to Use Run Robinhood operations by executing TypeScript code with `bun`. The `robinhood-for-agents` npm package provides a full client library — just import it and call methods: ```bash bun -e ' import { getClient } from "robinhood-for-agents"; const rh = getClient(); await rh.restoreSession(); // call any method, print results as JSON const holdings = await rh.buildHoldings(); console.log(JSON.stringify(holdings, null, 2)); ' ``` See [client-api.md](client-api.md) for all available methods and signatures. > **MCP users:** If you have the `robinhood-for-agents` MCP server configured, you may use MCP tools instead. See [reference.md](reference.md) for tool parameters. MCP is optional — the client API above does everything the MCP tools do. ## CRITICAL SAFETY RULES 1. **Always confirm before placing any order** — show order preview, get explicit "yes" 2. **Show current price** before order confirmation so user knows the cost 3. **Never place orders without user confirmation** 4. **Fund transfers and bank operations are BLOCKED** — refuse these requests 5. **Never place bulk cancel operations** — cancel orders one at a time ### BLOCKED Operations (never use) - Bulk cancel operations - Fund transfers (withdraw/deposit) - Bank unlinking ## Routing | User Intent | Domain File | Example Triggers | |---|---|---| | Auth / login / connect | [setup.md](setup.md) | "setup robinhood", "connect to robinhood", "robinhood login" | | Portfolio / holdings / positions | [portfolio.md](portfolio.md) | "show my portfolio", "my holdings", "account summary" | | Stock research / analysis | [research.md](research.md) | "research AAPL", "analyze TSLA", "due diligence on NVDA" | | Buy / sell / orders / cancel | [trade.md](trade.md) | "buy 10 shares of AAPL", "sell my TSLA", "cancel my order" | | Options / calls / puts / chains | [options.md](options.md) | "show AAPL options", "SPX calls", "0DTE options", "covered calls" | Read the corresponding domain file for detailed workflow instructions. ## Authentication Prerequisite Before any data-fetching or trading operation, verify the session is active: ```bash bun -e 'import { getClient } from "robinhood-for-agents"; const rh = getClient(); await rh.restoreSession(); console.log("ok");' ``` If it throws, follow [setup.md](setup.md) to authenticate. ## Client Method Inventory | Method | Category | Description | |---|---|---| | `restoreSession()` | Auth | Restore/validate session (throws if not authenticated) | | `getAccountProfile()` | Account | Account details and preferences | | `getAccounts()` | Account | All brokerage accounts | | `buildHoldings(opts?)` | Portfolio | Holdings with P&L, equity, buying power | | `getCryptoPositions()` | Crypto | Crypto holdings | | `getCryptoQuote(symbol)` | Crypto | Current crypto price | | `getQuotes(symbols)` | Research | Stock quotes (price, bid/ask, P/E) | | `getFundamentals(symbols)` | Research | Market cap, 52-week range, sector | | `getNews(symbol)` | Research | Recent news articles | | `getRatings(symbol)` | Research | Analyst buy/hold/sell ratings | | `getEarnings(symbol)` | Research | Quarterly EPS history | | `getStockHistoricals(symbols, opts?)` | Research | OHLCV price history | | `findInstruments(query)` | Research | Search stocks by keyword | | `getChains(symbol)` | Options | Option chain expirations | | `findTradableOptions(symbol, opts?)` | Options | Option instruments by expiration/strike/type | | `getOptionMarketData(symbol, exp, strike, type)` | Options | Greeks and pricing | | `getIndexValue(symbol)` | Options | Current index value (SPX, NDX, etc.) | | `getMovers()` | Markets | Top market movers | | `orderStock(symbol, qty, side, opts?)` | Trading | Place stock order | | `orderOption(symbol, legs, price, qty, dir, opts?)` | Trading | Place option order | | `orderCrypto(symbol, side, amount, opts?)` | Trading | Place crypto order | | `getAllStockOrders()` / `getOpenStockOrders()` | Trading | View stock orders | | `cancelStockOrder(id)` | Trading | Cancel stock order | | `getStockOrder(id)` | Trading | Check order fill status | ## Important Notes - **Do NOT use `phoenix.robinhood.com`** — use `api.robinhood.com` endpoints only - Multi-account is first-class: always ask which account when multiple exist - Session tokens expire ~24h; the client auto-refreshes before requiring re-auth

path: reference.md
content: # MCP Tools Reference

## Auth

### robinhood_check_session
Check if a Robinhood session is active.

**Parameters:** none

**Response:** `{ "status": "logged_in" | "not_authenticated" }`

### robinhood_browser_login
Open Chrome for browser-based Robinhood login. Captures OAuth tokens automatically.

**Parameters:** none

### robinhood_get_account
Get account details, profile, and investment preferences.

**Parameters:**
- `info_type` (enum: "all", "account", "user", "investment", default: "all")

**Response:**
```json
{
  "account": { "account_number": "123", "buying_power": "2000.00" },
  "user": { "username": "[REDACTED_SECRET]", "first_name": "John" },
  "investment": { "risk_tolerance": "moderate" }
}
```

## Account & Portfolio

### robinhood_get_accounts
Get all brokerage accounts (multi-account support).

**Parameters:** none

**Response:**
```json
{
  "accounts": [{ "account_number": "123", "type": "cash", "cash": "1000.00", "buying_power": "2000.00" }]
}
```

### robinhood_get_portfolio
Get complete portfolio: positions with P&L, equity, buying power, cash.

**Parameters:**
- `account_number` (string, optional) — specific account
- `with_dividends` (boolean, default: false) — include dividend info

**Response:**
```json
{
  "holdings": {
    "AAPL": {
      "price": "150.00", "quantity": "10", "average_buy_price": "120.00",
      "equity": "1500.00", "percent_change": "25.0", "name": "Apple"
    }
  },
  "summary": {
    "equity": "15000.00", "market_value": "14000.00", "cash": "1000.00",
    "buying_power": "2000.00", "crypto_buying_power": "500.00"
  }
}
```

## Crypto

### robinhood_get_crypto
Get crypto positions or a quote.

**Parameters:**
- `info_type` (enum: "positions", "quote", default: "positions")
- `symbol` (string, required when `info_type: "quote"`)

## Research

### robinhood_get_stock_quote
Get quote and fundamentals. Also works for index symbols (SPX, NDX, VIX, RUT, XSP).

**Parameters:**
- `symbols` (string, required) — comma-separated, e.g. "AAPL" or "AAPL,MSFT"

**Response:**
```json
{
  "AAPL": {
    "quote": { "last_trade_price": "150.00", "bid_price": "149.90", "ask_price": "150.10", "previous_close": "148.00", "pe_ratio": "25.5" },
    "fundamentals": { "market_cap": "2500000000000", "dividend_yield": "0.55", "high_52_weeks": "180.00", "low_52_weeks": "120.00" }
  }
}
```

### robinhood_get_news
Get news, analyst ratings, and earnings.

**Parameters:**
- `symbol` (string, required)

**Response:**
```json
{
  "news": [{ "title": "...", "source": "...", "published_at": "...", "url": "..." }],
  "ratings": { "summary": { "num_buy_ratings": 20, "num_hold_ratings": 5, "num_sell_ratings": 2 } },
  "earnings": [{ "year": 2025, "quarter": 1, "eps": { "estimate": "1.50", "actual": "1.55" } }]
}
```

### robinhood_get_historicals
Get OHLCV price history.

**Parameters:**
- `symbols` (string, required) — comma-separated
- `interval` (enum: "5minute", "10minute", "hour", "day", "week", default: "day")
- `span` (enum: "day", "week", "month", "3month", "year", "5year", default: "month")
- `bounds` (enum: "regular", "extended", "trading", default: "regular")

### robinhood_search
Search stocks by keyword or browse by market category.

**Parameters:**
- `query` (string, required) — search keyword (ignored if tag provided)
- `tag` (string, optional) — e.g., "technology", "most-popular-under-25"

## Options

### robinhood_get_options
Get options chain with greeks for a stock or index symbol.

**Parameters:**
- `symbol` (string, required) — stock or index ticker
- `expiration_date` (string, optional) — "YYYY-MM-DD"
- `strike_price` (number, optional) — filter by strike
- `option_type` (enum: "call", "put", optional)
- `max_strikes` (number, optional) — limit to N strikes nearest ATM

**Response (equity):**
```json
{
  "chain_info": { "id": "chain-uuid", "symbol": "AAPL", "expiration_dates": ["2025-01-17", "2025-02-21"] },
  "options": [{ "id": "option-uuid", "type": "call", "strike_price": "150.0000", "expiration_date": "2025-01-17" }],
  "market_data": [{ "adjusted_mark_price": "3.50", "delta": "0.5500", "gamma": "0.0300", "theta": "-0.0500", "vega": "0.2000", "implied_volatility": "0.3000", "open_interest": 15000, "volume": 5000 }]
}
```

**Response (index — additional field):**
```json
{ "index_value": { "value": "5700.00", "symbol": "SPX" }, "chain_info": { "symbol": "SPXW" }, "options": [...] }
```

**Notes:**
- `market_data` only included when all three filters (`expiration_date`, `strike_price`, `option_type`) are set.
- `index_value` only for index symbols.
- Chain auto-selected by `expiration_date`. SPXW (daily, PM-settled) is default; SPX monthly (AM-settled) for monthly-only dates.

## Orders

### robinhood_place_stock_order
**Parameters:**
- `symbol` (string, required), `side` ("buy"/"sell"), `quantity` (number, supports fractional)
- `limit_price` (number, optional), `stop_price` (number, optional)
- `trail_amount` (number, optional), `trail_type` ("percentage"/"amount", default: "percentage")
- `account_number` (string, required), `time_in_force` ("gtc"/"gfd", default: "gtc"), `extended_hours` (boolean)

### robinhood_place_option_order
**Parameters:**
- `symbol` (string, required), `legs` (array of `{ expiration_date, strike, option_type, side, position_effect, ratio_quantity }`)
- `price` (number, required), `quantity` (number), `direction` ("debit"/"credit")
- `stop_price` (number, optional), `time_in_force` ("gtc"/"gfd"/"ioc"/"opg", default: "gfd")
- `account_number` (string, required)

### robinhood_place_crypto_order
**Parameters:**
- `symbol` (string, required), `side` ("buy"/"sell")
- `amount_or_quantity` (number), `amount_in` ("quantity"/"price", default: "quantity")
- `order_type` ("market"/"limit", default: "market"), `limit_price` (number, optional)

### robinhood_get_orders
**Parameters:**
- `order_type` ("stock"/"option"/"crypto", default: "stock")
- `status` ("open"/"all", default: "all")
- `account_number` (string, optional), `limit` (number, default: 50)

### robinhood_cancel_order
**Parameters:**
- `order_id` (string, required), `order_type` ("stock"/"option"/"crypto", default: "stock")

### robinhood_get_order_status
**Parameters:**
- `order_id` (string, required), `order_type` ("stock"/"option"/"crypto", default: "stock")

## Markets

### robinhood_get_movers
Get top movers by category.

**Parameters:**
- `direction` (enum: "up", "down", optional)


path: setup.md
content: # Setup — Authentication Workflow

### Step 1: Check Session
```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
try { await rh.restoreSession(); console.log("logged_in"); }
catch { console.log("not_authenticated"); }
'
```
If `logged_in` — already authenticated, stop. Otherwise continue.

### Step 2: Browser Login
```bash
bunx robinhood-for-agents login
```
This opens Chrome to the real Robinhood website:
1. Chrome opens to robinhood.com/login
2. User enters email and password
3. Robinhood handles MFA natively (push notification, SMS, etc.)
4. Token captured automatically and saved securely
5. Chrome closes when login is complete

### Step 3: Verify
```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();
const acct = await rh.getAccountProfile();
console.log(JSON.stringify(acct, null, 2));
'
```
Confirm to the user that authentication is complete.

## Security Warning
After successful login, **always** remind the user:

> **Robinhood OAuth tokens are stored in the OS keychain (macOS Keychain Services, Linux libsecret, Windows Credential Manager) via Bun.secrets. No tokens are written to disk. Tokens expire after ~24 hours. Anyone with access to this machine's keychain can read them.**

## Notes
- No credentials (username/password) pass through the tool layer — login happens on the real Robinhood website
- Requires Google Chrome installed on the system
- Tokens expire after ~24h; the client auto-refreshes before requiring re-auth


path: portfolio.md
content: # Portfolio — Holdings, P&L, Account Summary

### Fetch Portfolio Data

```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();

const [holdings, accounts, crypto] = await Promise.all([
  rh.buildHoldings(),
  rh.getAccounts(),
  rh.getCryptoPositions(),
]);
console.log(JSON.stringify({ holdings, accounts, crypto }, null, 2));
'
```

### Enrich (Optional)
For crypto positions, get current prices:
```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();
const btc = await rh.getCryptoQuote("BTC");
console.log(JSON.stringify(btc, null, 2));
'
```

## Multi-Account Support
`getAccounts()` returns all accounts. To get portfolio for a specific account:
```typescript
rh.buildHoldings({ accountNumber: "ACCT_ID" })
```

## Output Format
Present results as a formatted table:
- Account summary: account number, type, portfolio value, cash, buying power
- Per-holding: Symbol, Name, Shares, Price, Avg Cost, Equity, P&L %, Allocation %
- Separate sections for stocks and crypto
- Summary line: Total holdings value, day change

## Key Response Fields
**`holdings`** — per ticker: `price`, `quantity`, `average_buy_price`, `equity`, `percent_change`, `intraday_percent_change`, `equity_change`, `name`

**`summary`**: `equity`, `market_value`, `cash`, `buying_power`, `crypto_buying_power`, `cash_available_for_withdrawal`

For all client methods, see [client-api.md](client-api.md).


path: trade.md
content: # Trade — Order Placement & Management

**CRITICAL: Safety rules in SKILL.md apply to ALL operations below. Always confirm with the user before placing any order.**

## Order Flow

### Step 1: Resolve Account
```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();
const accounts = await rh.getAccounts();
console.log(JSON.stringify(accounts, null, 2));
'
```
If multiple accounts, **ask the user which account to use**. Never pick on their behalf.

### Step 2: Parse the Request
Extract from the user's message:
- Symbol (e.g., AAPL, BTC)
- Side (buy/sell)
- Quantity or dollar amount
- Order type (market/limit/stop) and prices
- Asset type (stock/option/crypto)

### Step 3: Show Confirmation
Get current price, then present an order preview:
```
Order Preview:
  Action: BUY 10 shares of AAPL
  Type: Market order
  Current price: $150.00
  Estimated cost: ~$1,500.00
  Account: <account_number>

Proceed? (yes/no)
```
Wait for the user to explicitly confirm.

### Step 4: Place Order (after user confirms)

## Stock Orders

```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();
const order = await rh.orderStock("AAPL", 10, "buy", { limitPrice: 150.0, accountNumber: "ACCT" });
console.log(JSON.stringify(order, null, 2));
'
```

Options: `{ limitPrice, stopPrice, trailAmount, trailType, accountNumber, timeInForce, extendedHours }`

- Market order: omit `limitPrice` and `stopPrice`
- Limit order: set `limitPrice`
- Stop-limit: set both `stopPrice` and `limitPrice`
- Trailing stop: set `trailAmount` + `trailType` ("percentage" or "price")

## Option Orders

```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();
const order = await rh.orderOption("AAPL", [
  { expirationDate: "2026-04-17", strike: 200, optionType: "call", side: "buy", positionEffect: "open" }
], 3.50, 1, "debit", { accountNumber: "ACCT" });
console.log(JSON.stringify(order, null, 2));
'
```

For spreads, pass multiple legs. `direction` is "debit" for net-buy, "credit" for net-sell.

## Crypto Orders

```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();
// Buy 0.5 BTC
const order = await rh.orderCrypto("BTC", "buy", 0.5);
// Buy $100 of BTC
const order2 = await rh.orderCrypto("BTC", "buy", 100, { amountIn: "price" });
console.log(JSON.stringify(order, null, 2));
'
```

Options: `{ amountIn?: "quantity" | "price"; limitPrice?: number }`

## Order Management

### View Orders
```typescript
const allOrders = await rh.getAllStockOrders();
const openOrders = await rh.getOpenStockOrders();
// Also: getAllOptionOrders(), getOpenOptionOrders(), getAllCryptoOrders(), getOpenCryptoOrders()
```

### Cancel Order
```typescript
await rh.cancelStockOrder("order-uuid");
// Also: cancelOptionOrder(), cancelCryptoOrder()
```

### Monitor Order
```typescript
const order = await rh.getStockOrder("order-uuid");
// Also: getOptionOrder(), getCryptoOrder()
```

For all client methods, see [client-api.md](client-api.md).


path: research.md
content: # Research — Stock Analysis

### Fetch Data (parallel)

```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();

const [quotes, fundamentals, news, ratings, earnings, historicals] = await Promise.all([
  rh.getQuotes("AAPL"),
  rh.getFundamentals("AAPL"),
  rh.getNews("AAPL"),
  rh.getRatings("AAPL"),
  rh.getEarnings("AAPL"),
  rh.getStockHistoricals("AAPL", { interval: "day", span: "year" }),
]);
console.log(JSON.stringify({ quotes, fundamentals, news, ratings, earnings, historicals }, null, 2));
'
```

To search by keyword: `await rh.findInstruments("artificial intelligence")`

Index symbols (SPX, NDX, VIX, RUT, XSP) also work with `getQuotes()` — returns the current index value.

## Key Data Fields
- **Quote**: `last_trade_price`, `bid_price`, `ask_price`, `previous_close`, `pe_ratio`
- **Fundamentals**: `market_cap`, `pe_ratio`, `dividend_yield`, `high_52_weeks`, `low_52_weeks`, `description`, `ceo`, `sector`
- **Ratings**: `summary.num_buy_ratings`, `summary.num_hold_ratings`, `summary.num_sell_ratings`
- **Earnings**: `eps.estimate`, `eps.actual`, `year`, `quarter`
- **Historicals**: Array of `{ begins_at, open_price, close_price, high_price, low_price, volume }`

## Output Structure
1. **Company Overview**: Name, sector, industry, market cap, description
2. **Price Data**: Current price, 52-week range, position within range
3. **Valuation**: P/E ratio, dividend yield
4. **Analyst Ratings**: Buy/Hold/Sell consensus
5. **Recent Earnings**: Last 4 quarters EPS (estimate vs actual)
6. **News**: Top 5 recent headlines
7. **Price Trend**: Summary of recent price action from historicals

For all client methods, see [client-api.md](client-api.md).


path: options.md
content: # Options — Chain Analysis & Index Options

## Fetching Options Data

```bash
bun -e '
import { getClient } from "robinhood-for-agents";
const rh = getClient();
await rh.restoreSession();

const chain = await rh.getChains("AAPL");
console.log("Expirations:", chain.expiration_dates);

const options = await rh.findTradableOptions("AAPL", { expirationDate: "2026-04-17", optionType: "call" });
console.log(JSON.stringify(options.map(o => ({ strike: o.strike_price, exp: o.expiration_date, type: o.type })), null, 2));
'
```

For greeks and pricing:
```typescript
const data = await rh.getOptionMarketData("AAPL", "2026-04-17", 200, "call");
// => [{ adjusted_mark_price, delta, gamma, theta, vega, implied_volatility, open_interest, volume }]
```

## Common Workflows

### View Available Expirations
```typescript
const chain = await rh.getChains("AAPL");
// chain.expiration_dates => ["2026-04-17", "2026-05-15", ...]
```

### Full Chain for a Date
```typescript
const options = await rh.findTradableOptions("AAPL", { expirationDate: "2026-04-17" });
```

### Specific Option with Greeks
```typescript
const data = await rh.getOptionMarketData("AAPL", "2026-04-17", 200, "call");
```

### Covered Call Screening
1. Get holdings: `await rh.buildHoldings()`
2. For each stock with 100+ shares, fetch OTM calls 30-45 DTE
3. Calculate annualized premium yield from market data

### Open Option Positions
```typescript
const positions = await rh.getOpenOptionPositions();
```

## Index Options (SPX, NDX, VIX, RUT, XSP)

Index options work the same — just pass the index symbol (e.g. `"SPX"`). The client auto-detects index symbols.

**Chain selection**: Indexes like SPX have two chains:
- **SPXW** — daily expirations (0DTE, 1DTE, weeklies), PM-settled
- **SPX** — monthly expirations only (3rd Friday), AM-settled

The client auto-selects based on `expirationDate`. SPXW (more expirations) is default.

**Index value**:
```typescript
const spx = await rh.getIndexValue("SPX");
// => { value: "5700.00", symbol: "SPX" }
```

**Key differences**: European-style (exercise at expiration only), cash-settled (no stock delivery).

## Key Data Fields

**Option instrument**: `strike_price`, `expiration_date`, `type` (call/put), `state`, `tradability`

**Market data (greeks)**: `adjusted_mark_price`, `delta`, `gamma`, `theta`, `vega`, `rho`, `implied_volatility`, `open_interest`, `volume`, `chance_of_profit_long`, `chance_of_profit_short`

## Placing Option Orders
Before placing, get accounts and ask which to use. See [trade.md](trade.md) for the full option order flow.

## Output Format
Present as a table: Strike | Type | Bid | Ask | Last | Delta | IV | Volume | OI | Prob Profit

For all client methods, see [client-api.md](client-api.md).


path: client-api.md
content: # TypeScript Client API

Methods from `robinhood-for-agents` for programmatic access without MCP.

## Quick Start

```typescript
import { RobinhoodClient, getClient } from "robinhood-for-agents";

const rh = getClient(); // singleton
await rh.restoreSession();
```

All methods are `async`. Multi-account is first-class: account-scoped methods accept `accountNumber`.

## MCP Tool → Client Method Mapping

| MCP Tool | Client Method |
|----------|--------------|
| `robinhood_check_session` | `restoreSession()` |
| `robinhood_get_account` | `getAccountProfile(accountNumber?)` |
| `robinhood_get_accounts` | `getAccounts(opts?)` |
| `robinhood_get_portfolio` | `buildHoldings(opts?)` |
| `robinhood_get_crypto` (positions) | `getCryptoPositions()` |
| `robinhood_get_crypto` (quote) | `getCryptoQuote(symbol)` |
| `robinhood_get_stock_quote` | `getQuotes(symbols)` + `getFundamentals(symbols)` |
| `robinhood_get_news` | `getNews(symbol)` + `getRatings(symbol)` + `getEarnings(symbol)` |
| `robinhood_get_historicals` | `getStockHistoricals(symbols, opts?)` |
| `robinhood_search` | `findInstruments(query)` |
| `robinhood_get_options` (chain) | `getChains(symbol, opts?)` |
| `robinhood_get_options` (instruments) | `findTradableOptions(symbol, opts?)` |
| `robinhood_get_options` (greeks) | `getOptionMarketData(symbol, expDate, strike, type)` |
| `robinhood_get_options` (index value) | `getIndexValue(symbol)` |
| `robinhood_place_stock_order` | `orderStock(symbol, quantity, side, opts?)` |
| `robinhood_place_option_order` | `orderOption(symbol, legs, price, quantity, direction, opts?)` |
| `robinhood_place_crypto_order` | `orderCrypto(symbol, side, amount, opts?)` |
| `robinhood_get_orders` (stock) | `getAllStockOrders()` / `getOpenStockOrders()` |
| `robinhood_get_orders` (option) | `getAllOptionOrders()` / `getOpenOptionOrders()` |
| `robinhood_get_orders` (crypto) | `getAllCryptoOrders()` / `getOpenCryptoOrders()` |
| `robinhood_cancel_order` | `cancelStockOrder(id)` / `cancelOptionOrder(id)` / `cancelCryptoOrder(id)` |
| `robinhood_get_order_status` | `getStockOrder(id)` / `getOptionOrder(id)` / `getCryptoOrder(id)` |

## Portfolio Methods

### `buildHoldings(opts?): Promise<Record<string, Holding>>`
```typescript
const holdings = await rh.buildHoldings({ withDividends: true });
// => { "AAPL": { price, quantity, average_buy_price, equity, percent_change, name, ... } }
```
Options: `{ accountNumber?: string; withDividends?: boolean }`

### `getAccounts(opts?): Promise<Account[]>`
```typescript
const accounts = await rh.getAccounts();
```

### `getPortfolioProfile(accountNumber?): Promise<Portfolio>`
```typescript
const portfolio = await rh.getPortfolioProfile();
// => { equity, market_value, ... }
```

### `getCryptoPositions(): Promise<CryptoPosition[]>`
### `getCryptoQuote(symbol): Promise<CryptoQuote>`
```typescript
const btc = await rh.getCryptoQuote("BTC");
// => { mark_price, ask_price, bid_price, symbol, ... }
```

## Research Methods

### `getQuotes(symbols): Promise<Quote[]>`
Accepts single symbol or array. Returns `last_trade_price`, `bid_price`, `ask_price`, `previous_close`, `pe_ratio`.

### `getFundamentals(symbols): Promise<Fundamental[]>`
Returns `market_cap`, `pe_ratio`, `dividend_yield`, `high_52_weeks`, `low_52_weeks`, `description`, `ceo`, `sector`.

### `getStockHistoricals(symbols, opts?): Promise<StockHistorical[]>`
```typescript
const hist = await rh.getStockHistoricals("AAPL", { interval: "day", span: "year", bounds: "regular" });
// => [{ symbol, historicals: [{ begins_at, open_price, close_price, high_price, low_price, volume }] }]
```

### `getNews(symbol): Promise<News[]>`
### `getRatings(symbol): Promise<Rating>`
### `getEarnings(symbol): Promise<Earnings[]>`
### `findInstruments(query): Promise<Instrument[]>`

## Options Methods

### `getChains(symbol, opts?): Promise<OptionChain>`
Works for equities and indexes (SPX, NDX, VIX, RUT, XSP). For indexes with multiple chains, pass `expirationDate` to select. Defaults to SPXW.
```typescript
const chain = await rh.getChains("AAPL");
// => { id, expiration_dates: [...], ... }
```

### `findTradableOptions(symbol, opts?): Promise<OptionInstrument[]>`
```typescript
const calls = await rh.findTradableOptions("AAPL", {
  expirationDate: "2026-04-17", strikePrice: 200, optionType: "call"
});
```

### `getOptionMarketData(symbol, expirationDate, strikePrice, optionType): Promise<OptionMarketData[]>`
```typescript
const data = await rh.getOptionMarketData("AAPL", "2026-04-17", 200, "call");
// => [{ adjusted_mark_price, delta, gamma, theta, vega, implied_volatility, open_interest, volume, ... }]
```

### `getIndexValue(symbol): Promise<IndexValue | null>`
```typescript
const spx = await rh.getIndexValue("SPX");
// => { value: "5700.00", symbol: "SPX" } or null for non-index
```

### `getOpenOptionPositions(accountNumber?): Promise<OptionPosition[]>`

## Order Methods

**Safety**: Always confirm with the user before calling any order method.

### `orderStock(symbol, quantity, side, opts?)`
```typescript
await rh.orderStock("AAPL", 10, "buy");                          // market
await rh.orderStock("AAPL", 10, "buy", { limitPrice: 150.0 });   // limit
await rh.orderStock("AAPL", 10, "sell", { stopPrice: 145.0, limitPrice: 144.0 }); // stop-limit
await rh.orderStock("AAPL", 10, "sell", { trailAmount: 5, trailType: "percentage" }); // trailing stop
```
Options: `{ limitPrice, stopPrice, trailAmount, trailType, accountNumber, timeInForce, extendedHours }`

### `orderOption(symbol, legs, price, quantity, direction, opts?)`
```typescript
// Single call
await rh.orderOption("AAPL", [
  { expirationDate: "2026-04-17", strike: 200, optionType: "call", side: "buy", positionEffect: "open" }
], 3.50, 1, "debit");

// Bull call spread
await rh.orderOption("AAPL", [
  { expirationDate: "2026-04-17", strike: 200, optionType: "call", side: "buy", positionEffect: "open" },
  { expirationDate: "2026-04-17", strike: 210, optionType: "call", side: "sell", positionEffect: "open" },
], 2.50, 1, "debit");
```

### `orderCrypto(symbol, side, quantityOrPrice, opts?)`
```typescript
await rh.orderCrypto("BTC", "buy", 0.5);                           // buy 0.5 BTC
await rh.orderCrypto("BTC", "buy", 100, { amountIn: "price" });    // buy $100 of BTC
await rh.orderCrypto("BTC", "buy", 0.5, { limitPrice: 60000 });    // limit buy
```
Options: `{ amountIn?: "quantity" | "price"; limitPrice?: number; timeInForce?: string }`

### Order Queries
```typescript
const allOrders = await rh.getAllStockOrders();
const openOrders = await rh.getOpenStockOrders();
const order = await rh.getStockOrder("order-uuid");
```

### Cancel Orders
```typescript
await rh.cancelStockOrder("order-uuid");
await rh.cancelOptionOrder("order-uuid");
await rh.cancelCryptoOrder("order-uuid");
```


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)