# Webull Openapi

> Trade stocks, options, futures, crypto, and event contracts on Webull. Query real-time and historical market data. Manage accounts and positions. Supports US and HK regions with configurable risk controls.

- **Type:** Skill
- **Install:** `agentstack add skill-webull-inc-webull-agent-skills-webull-openapi-skills`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [webull-inc](https://agentstack.voostack.com/s/webull-inc)
- **Installs:** 0
- **Category:** [Finance & Payments](https://agentstack.voostack.com/c/finance-and-payments)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [webull-inc](https://github.com/webull-inc)
- **Source:** https://github.com/webull-inc/webull-agent-skills/tree/main/webull_openapi_skills

## Install

```sh
agentstack add skill-webull-inc-webull-agent-skills-webull-openapi-skills
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Webull OpenAPI Skill

This skill lets you interact with Webull's trading platform through natural language. You can place orders, check market data, query account info, and manage positions — all via the official Webull Python SDK.

## What You Can Do

- **Trade**: Place, preview, modify, and cancel orders for stocks, options, futures, crypto, and event contracts
- **Market Data**: Get real-time snapshots, historical bars, tick data, quotes, and order flow for all asset classes
- **Accounts**: List accounts, check balances, view positions
- **Instruments**: Look up stock, crypto, futures, and event contract instruments

## Safety Rules

**All order-mutating operations require user confirmation before execution.**

Mutating actions: `place`, `replace`, `cancel`, `batch-place`, `algo-place`, `option-place`, `option-replace`, `option-strategy-place`, `futures-place`, `futures-replace`, `crypto-place`, `event-place`, `event-replace`.

Before executing any of these operations, the AI must:
1. Display a clear summary of the operation to the user, including:
   - Action type (place / replace / cancel)
   - Symbol, side, order type, quantity, price
   - Account being used
2. Explicitly ask the user to confirm (e.g., "Confirm this order? [Yes/No]")
3. Only proceed after receiving explicit user approval

Read-only operations (`account-list`, `balance`, `position`, `open`, `history`, `detail`, `instrument-*`, all `market-data` actions) do not require confirmation and can be executed immediately.

---

## Quick Examples

> **Python command:** Use `python3` on macOS/Linux, `python` on Windows. Examples below use `python3`.

> **Passing order JSON:** Prefer `--order-file ` (write JSON to a temp file first) over `--order-json ''`. Inline JSON with `--order-json` is fragile across shells — Windows bash, PowerShell, and some macOS terminals mangle quotes and escapes. Using `--order-file` avoids all shell quoting issues.

```bash
# Check your accounts
python3 scripts/cli.py trading --action account-list

# Get AAPL stock price
python3 scripts/cli.py market-data --action stock-snapshot --symbols AAPL

# Get account balance
python3 scripts/cli.py trading --action balance --account-id 

# Place a limit buy order (recommended: use --order-file)
# First write JSON to a file, then pass it:
#   echo '{"symbol":"AAPL","side":"BUY","order_type":"LIMIT","limit_price":180,"quantity":10,"instrument_type":"EQUITY","market":"US","time_in_force":"DAY","entrust_type":"QTY","support_trading_session":"CORE","combo_type":"NORMAL"}' > /tmp/order.json
#   python3 scripts/cli.py trading --action place --account-id  --order-file /tmp/order.json
#
# Alternative (inline, may fail on some shells):
python3 scripts/cli.py trading --action place --account-id  \
  --order-json '{"symbol":"AAPL","side":"BUY","order_type":"LIMIT","limit_price":180,"quantity":10,"instrument_type":"EQUITY","market":"US","time_in_force":"DAY","entrust_type":"QTY","support_trading_session":"CORE","combo_type":"NORMAL"}'

# Cancel an order
python3 scripts/cli.py trading --action cancel --account-id  --client-order-id 
```

## CLI Entry Point

```
python3 scripts/cli.py [--env-file PATH] [--verbose-sdk-log]  --action  [options]
```

Three modules: `trading`, `market-data`, `auth`.

---

## Module: trading

Instrument queries, account/asset operations, and all order operations.

### Instrument Queries

| Action | Description | Key Options |
|--------|-------------|-------------|
| `instrument-stock` | Stock/ETF instrument info | `--symbols AAPL,TSLA` |
| `instrument-crypto` | Crypto instrument info | `--symbols BTCUSD` |
| `instrument-futures-products` | Futures product codes | `--category US_FUTURES` |
| `instrument-futures-list` | Futures instruments by symbol | `--symbols ESM6` |
| `instrument-futures-by-code` | Futures by product code | `--code ES` |
| `instrument-event-series` | Event contract series | `--page-size 50` |
| `instrument-event-list` | Event instruments by series | `--series-symbol ` |
| `instrument-event-categories` | Event contract categories | |
| `instrument-event-events` | Events within a series | `--series-symbol ` |

### Account & Asset

| Action | Description | Key Options |
|--------|-------------|-------------|
| `account-list` | List all linked accounts | |
| `balance` | Account balance | `--account-id ` |
| `position` | Account positions | `--account-id ` |

### Stock Orders

| Action | Description |
|--------|-------------|
| `place` | Place stock order (single, non-combo) |
| `preview` | Preview order without submitting |
| `replace` | Modify existing stock order |
| `batch-place` | Combo orders (OTO/OCO/OTOCO) — US only |
| `algo-place` | Algorithmic order (TWAP/VWAP/POV) — US only |

### Option Orders

| Action | Description |
|--------|-------------|
| `option-place` | Place single-leg option order |
| `option-preview` | Preview option order |
| `option-replace` | Modify option order |
| `option-strategy-place` | Multi-leg strategy (VERTICAL, STRADDLE, etc.) — US only |

### Futures / Crypto / Event Orders (US only)

| Action | Description |
|--------|-------------|
| `futures-place` | Place futures order |
| `futures-replace` | Modify futures order |
| `crypto-place` | Place crypto order (no replace supported) |
| `event-place` | Place event contract order |
| `event-replace` | Modify event contract order |

### Order Management

| Action | Description | Key Options |
|--------|-------------|-------------|
| `cancel` | Cancel an order | `--account-id`, `--client-order-id` |
| `open` | List open/pending orders | `--account-id` |
| `history` | Order history | `--account-id` |
| `detail` | Single order detail | `--account-id`, `--client-order-id` |
| `local-check` | Risk check only (no API call) | `--order-json` |

---

### Order JSON Format

Orders are passed via `--order-json` (inline string) or `--order-file` (path to a JSON file). **`--order-file` is strongly recommended** to avoid shell quoting issues.

> **Important:** The `place` and `replace` actions accept **different** JSON fields. Do NOT use `place` fields for `replace` — the CLI spreads JSON keys directly into the function, so unexpected fields cause errors.

> **`client_order_id` / `client_combo_order_id` rules:** Max 32 characters, must be alphanumeric only (letters and digits, no hyphens/underscores/special chars), and must be unique per account. If not provided, the system auto-generates one.

---

#### Place Order JSON (for `place`, `preview`)

> **Type note:** Stock place CLI does `float()` conversion internally, so strings technically work — but for consistency and to avoid issues, always use **number** types for numeric fields.

| Field | Required | JSON Type | Values / Description |
|-------|----------|-----------|----------------------|
| `combo_type` | Yes | string | `NORMAL` (single order). For combo: `MASTER`, `STOP_PROFIT`, `STOP_LOSS`, `OTO`, `OCO`, `OTOCO` |
| `symbol` | Yes | string | Ticker symbol, e.g. `AAPL`, `00700`, `BTCUSD`, `ESZ5` |
| `instrument_type` | Yes | string | `EQUITY`, `OPTION`, `FUTURES`, `CRYPTO`, `EVENT` |
| `market` | Yes | string | `US`, `HK`, `CN` |
| `side` | Yes | string | `BUY`, `SELL`, `SHORT` |
| `order_type` | Yes | string | See [Order Types by Market](#order-types-by-market) below |
| `time_in_force` | Yes | string | See [Time in Force](#time-in-force) below |
| `quantity` | Conditional | number (float) | Number of shares/contracts. Required when `entrust_type=QTY`. e.g. `10` — NOT `"10"` |
| `entrust_type` | Yes | string | `QTY` (by quantity) or `AMOUNT` (fractional shares / crypto by dollar amount) |
| `limit_price` | Conditional | number (float) | Required for `LIMIT`, `STOP_LOSS_LIMIT` orders, e.g. `180` — NOT `"180"` |
| `stop_price` | Conditional | number (float) | Required for `STOP_LOSS`, `STOP_LOSS_LIMIT` orders |
| `support_trading_session` | US stocks | string | `CORE` (regular hours), `ALL` (extended hours), `NIGHT` (night session) |
| `total_cash_amount` | Conditional | number (float) | Required when `entrust_type=AMOUNT` (US fractional shares / crypto) |
| `trailing_type` | Conditional | string | Required for `TRAILING_STOP_LOSS`: `AMOUNT` or `PERCENTAGE` |
| `trailing_stop_step` | Conditional | number (float) | Required for `TRAILING_STOP_LOSS`: trail amount or percentage (0.01 = 1%) |
| `sender_sub_id` | No (HK broker) | string | Broker user UUID for third-party transactions (HK region, institutional only) |
| `no_party_ids` | No (HK broker) | array | BCAN party identifiers for HK stock orders (institutional only). See below |

> **`quantity` vs `total_cash_amount`:** These two fields are mutually exclusive.
> - When `entrust_type=QTY`: provide `quantity` (number of shares/contracts)
> - When `entrust_type=AMOUNT`: provide `total_cash_amount` (dollar amount for fractional shares / crypto)
> - Do NOT provide both at the same time.

Stock limit buy example:
```json
{
  "symbol": "AAPL",
  "side": "BUY",
  "order_type": "LIMIT",
  "limit_price": 180,
  "quantity": 10,
  "instrument_type": "EQUITY",
  "market": "US",
  "time_in_force": "DAY",
  "entrust_type": "QTY",
  "support_trading_session": "CORE",
  "combo_type": "NORMAL"
}
```

HK stock order example (with BCAN, institutional/broker only):
```json
{
  "symbol": "00700",
  "side": "BUY",
  "order_type": "ENHANCED_LIMIT",
  "limit_price": 350,
  "quantity": 100,
  "instrument_type": "EQUITY",
  "market": "HK",
  "time_in_force": "DAY",
  "entrust_type": "QTY",
  "combo_type": "NORMAL",
  "sender_sub_id": "",
  "no_party_ids": [
    {
      "party_id": "ABC123.2568",
      "party_id_source": "D",
      "party_role": "3"
    }
  ]
}
```

`no_party_ids` array item fields:

| Field | Required | Description |
|-------|----------|-------------|
| `party_id` | Yes | BCAN ID, format: `CE_NUMBER.BCAN` e.g. `ABC123.2568` |
| `party_id_source` | Yes | Always `"D"` (Proprietary/Custom Code) |
| `party_role` | Yes | Always `"3"` (Client ID / BCAN Field) |

---

#### Option Place JSON (for `option-place`, `option-preview`)

> **⚠️ Type-sensitive:** Option place uses `**o` spread — JSON types must match function signatures exactly. `quantity` must be **integer**, `strike_price`/`limit_price`/`stop_price` must be **number** (float), not strings.

| Field | Required | JSON Type | Values / Description |
|-------|----------|-----------|----------------------|
| `symbol` | Yes | string | Underlying symbol, e.g. `AAPL` |
| `instrument_type` | Yes | string | `OPTION` |
| `option_type` | Yes | string | `CALL` or `PUT` |
| `strike_price` | Yes | number (float) | Strike price, e.g. `220.00` — NOT `"220.00"` |
| `expiration_date` | Yes | string | Expiration date, format `yyyy-MM-dd`, e.g. `"2026-06-19"` |
| `side` | Yes | string | `BUY`, `SELL`, `SHORT` |
| `order_type` | Yes | string | `MARKET`, `LIMIT`, `STOP_LOSS`, `STOP_LOSS_LIMIT` |
| `time_in_force` | Yes | string | `DAY`, `GTC`. Sell-side only supports `DAY` |
| `quantity` | Yes | number (int) | Number of contracts, e.g. `1` — NOT `"1"` |
| `limit_price` | Conditional | number (float) | Required for `LIMIT` orders, e.g. `11.25` — NOT `"11.25"` |
| `stop_price` | Conditional | number (float) | Required for `STOP_LOSS` orders |
| `position_intent` | No | string | Position strategy (US only). `BUY_TO_OPEN`, `BUY_TO_CLOSE`, `SELL_TO_OPEN`, `SELL_TO_CLOSE`. Must match `side` |
| `sender_sub_id` | No (HK broker) | string | Broker user UUID (HK region, institutional only). No BCAN needed for options |

Option single-leg example:
```json
{
  "symbol": "AAPL",
  "instrument_type": "OPTION",
  "option_type": "CALL",
  "strike_price": 220.00,
  "expiration_date": "2026-06-19",
  "side": "BUY",
  "order_type": "LIMIT",
  "limit_price": 11.25,
  "quantity": 1,
  "time_in_force": "DAY",
  "position_intent": "BUY_TO_OPEN"
}
```

---

#### Option Strategy Place JSON (for `option-strategy-place`)

> **⚠️ Type-sensitive:** Same as option-place — numeric fields must be numbers, not strings.

| Field | Required | JSON Type | Values / Description |
|-------|----------|-----------|----------------------|
| `strategy` | Yes | string | `VERTICAL`, `STRADDLE`, `STRANGLE`, `BUTTERFLY`, `CONDOR`, `CALENDAR`, `DIAGONAL`, `IRON_BUTTERFLY`, `IRON_CONDOR`, `COLLAR_WITH_STOCK`, `COVERED_STOCK` |
| `symbol` | Yes | string | Underlying symbol |
| `order_type` | Yes | string | `LIMIT`, `MARKET` |
| `time_in_force` | Yes | string | `DAY`, `GTC` |
| `quantity` | No | number (int) | Number of contracts per leg |
| `limit_price` | Conditional | number (float) | Net debit/credit price for the strategy |
| `legs` | Yes | array | Array of leg objects (see below) |

Each leg object:

| Field | Required | JSON Type | Values |
|-------|----------|-----------|--------|
| `side` | Yes | string | `BUY`, `SELL` |
| `quantity` | Yes | string | Contracts for this leg |
| `symbol` | Yes | string | Underlying symbol |
| `strike_price` | Yes | string | Strike price |
| `option_expire_date` | Yes | string | `yyyy-MM-dd` |
| `instrument_type` | Yes | string | `OPTION` |
| `option_type` | Yes | string | `CALL` or `PUT` |
| `market` | Yes | string | `US` |

---

#### Futures Place JSON (for `futures-place`)

> **⚠️ Type-sensitive:** Futures place uses `**o` spread — `quantity`/`limit_price`/`stop_price` must be **number** (float), not strings.

| Field | Required | JSON Type | Values / Description |
|-------|----------|-----------|----------------------|
| `symbol` | Yes | string | Futures symbol, e.g. `ESZ5`, `NQM6` |
| `side` | Yes | string | `BUY`, `SELL` |
| `order_type` | Yes | string | `MARKET`, `LIMIT`, `STOP_LOSS`, `STOP_LOSS_LIMIT`, `TRAILING_STOP_LOSS` |
| `time_in_force` | Yes | string | `DAY`, `GTC` |
| `quantity` | Yes | number (float) | Number of contracts, e.g. `1` — NOT `"1"` |
| `limit_price` | Conditional | number (float) | Required for `LIMIT`, `STOP_LOSS_LIMIT` |
| `stop_price` | Conditional | number (float) | Required for `STOP_LOSS`, `STOP_LOSS_LIMIT` |

Futures example:
```json
{
  "symbol": "ESZ5",
  "side": "BUY",
  "order_type": "LIMIT",
  "limit_price": 4500,
  "quantity": 1,
  "time_in_force": "DAY"
}
```

---

#### Crypto Place JSON (for `crypto-place`)

> **⚠️ Type-sensitive:** Crypto place uses `**o` spread — `quantity`/`limit_price`/`stop_price`/`total_cash_amount` must be **number** (float), not strings.

| Field | Required | JSON Type | Values / Description |
|-------|----------|-----------|----------------------|
| `symbol` | Yes | string | e.g. `BTCUSD`, `ETHUSD` |
| `side` | Yes | string | `BUY`, `SELL` |
| `order_type` | Yes | string | `MARKET` (tif **must** be `IOC`), `LIMIT` (tif `DAY`/`GTC`), `STOP_LOSS_LIMIT` (tif `DAY`/`GTC`) |
| `time_in_force` | Yes | string | `IOC` (only for `MARKET`), `DAY` or `GTC` (for `LIMIT`/`STOP_LOSS_LIMIT`) |
| `entrust_type` | Yes | string | `QTY` or `AMOUNT` |
| `quantity` | Conditional | number (float) | Required when `entrust_type=QTY`. Supports up to 8 decimal places |
| `total_cash_amount` | Conditional | number (float) | Required when `entrust_type=AMOUNT` |
| `limit_price` | Conditional | number (float) | Required for `LIMIT`, `STOP_LOSS_LIMIT` |
| `stop_price` | Conditional | number (float) | Required for `STOP_LOSS_LIMIT` |

> Note: Crypto does NOT support replace (modify) orders. When selling, position must not fall below $2.

Crypto example:
```json
{
  "symbol": "BTCUSD",
  "side": "BUY",
  "order_type": "LIMIT",
  "limit_price": 80000,
  "quantity": 0.003,
  "time_in_force": "DAY",
  "entrust_type": "QTY"
}
```

---

#### Event Contract Place JSON (for `event-place`)

> **⚠️ Type-sensitive:** Event place uses `**o` spread — `quantity` and `limit_price` must be **number** (float), not strings.

| Field | Required | JSON Type | Values / Description |
|-------|----------|-----------|----------------------|
| `symbol` | Yes | string | Event contract symbol |
| `side` | Yes | string | `BUY`, `SELL` |
| `quantity` | Yes | number (float) | Number of contracts. Accepts 0-2 decimal places |
| `limit_price`

…

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [webull-inc](https://github.com/webull-inc)
- **Source:** [webull-inc/webull-agent-skills](https://github.com/webull-inc/webull-agent-skills)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-webull-inc-webull-agent-skills-webull-openapi-skills
- Seller: https://agentstack.voostack.com/s/webull-inc
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
