Trading API Getting Started
This guide walks you through making your first trade using the Webull SDK. By the end, you'll have placed, modified, and cancelled a stock order.
Prerequisites
- Webull SDK installed (SDKs and Tools)
- App Key and App Secret (Getting Started)
- An Account ID (retrieved in Step 1 below)
Step 1: Retrieve Your Account List
Before placing any orders, you need your Account ID.
- Python
- Java
from webull.core.client import ApiClient
from webull.trade.trade_client import TradeClient
api_client = ApiClient("<your_app_key>", "<your_app_secret>", "us")
api_client.add_endpoint("us", "<api_endpoint>")
trade_client = TradeClient(api_client)
res = trade_client.account_v2.get_account_list()
if res.status_code == 200:
print("Accounts:", res.json())
import com.webull.openapi.core.http.HttpApiConfig;
import com.webull.openapi.trade.TradeClientV2;
HttpApiConfig config = HttpApiConfig.builder()
.appKey("<your_app_key>")
.appSecret("<your_app_secret>")
.regionId("us")
.endpoint("<api_endpoint>")
.build();
TradeClientV2 client = new TradeClientV2(config);
System.out.println("Accounts: " + client.getAccountList());
Save the account_id from the response — you'll need it for all subsequent calls.
Step 2: Place a Stock Order
Place a simple limit order to buy 1 share:
- Python
- Java
import uuid
client_order_id = uuid.uuid4().hex
new_orders = [
{
"combo_type": "NORMAL",
"client_order_id": client_order_id,
"symbol": "AAPL",
"instrument_type": "EQUITY",
"market": "US",
"order_type": "LIMIT",
"limit_price": "180",
"quantity": "1",
"support_trading_session": "CORE",
"side": "BUY",
"time_in_force": "DAY",
"entrust_type": "QTY"
}
]
res = trade_client.order_v2.place_order(account_id, new_orders)
if res.status_code == 200:
print("Order placed:", res.json())
import com.webull.openapi.core.common.dict.*;
import com.webull.openapi.core.utils.GUID;
import com.webull.openapi.trade.request.v2.TradeOrder;
import com.webull.openapi.trade.request.v2.TradeOrderItem;
String accountId = "<your_account_id>";
String clientOrderId = GUID.get();
TradeOrder tradeOrder = new TradeOrder();
List<TradeOrderItem> newOrders = new ArrayList<>();
TradeOrderItem order = new TradeOrderItem();
order.setClientOrderId(clientOrderId);
order.setComboType(ComboType.NORMAL.name());
order.setSymbol("AAPL");
order.setInstrumentType(InstrumentSuperType.EQUITY.name());
order.setMarket("US");
order.setOrderType(OrderType.LIMIT.name());
order.setQuantity("1");
order.setLimitPrice("180");
order.setSupportTradingSession("CORE");
order.setSide(OrderSide.BUY.name());
order.setTimeInForce(OrderTIF.DAY.name());
order.setEntrustType(EntrustType.QTY.name());
newOrders.add(order);
tradeOrder.setNewOrders(newOrders);
var response = client.placeOrder(accountId, tradeOrder);
System.out.println("Order placed: " + response);
Step 3: Modify the Order
Change the price or quantity of an open order:
- Python
- Java
modify_orders = [
{
"client_order_id": client_order_id,
"quantity": "2",
"limit_price": "179"
}
]
res = trade_client.order_v2.replace_order(account_id, modify_orders)
if res.status_code == 200:
print("Order modified:", res.json())
TradeOrder replaceOrder = new TradeOrder();
List<TradeOrderItem> modifyOrders = new ArrayList<>();
TradeOrderItem modifyItem = new TradeOrderItem();
modifyItem.setClientOrderId(clientOrderId);
modifyItem.setLimitPrice("179");
modifyItem.setQuantity("2");
modifyOrders.add(modifyItem);
replaceOrder.setModifyOrders(modifyOrders);
var replaceResponse = client.replaceOrder(accountId, replaceOrder);
System.out.println("Order modified: " + replaceResponse);
Step 4: Cancel the Order
- Python
- Java
res = trade_client.order_v2.cancel_order(account_id, client_order_id)
if res.status_code == 200:
print("Order cancelled:", res.json())
TradeOrder cancelOrder = new TradeOrder();
cancelOrder.setClientOrderId(clientOrderId);
var cancelResponse = client.cancelOrder(accountId, cancelOrder);
System.out.println("Order cancelled: " + cancelResponse);
Step 5: Subscribe to Order Status Updates
Monitor order status changes in real time via gRPC streaming:
- Python
- Java
from webull.trade.events.types import ORDER_STATUS_CHANGED, EVENT_TYPE_ORDER
from webull.trade.trade_events_client import TradeEventsClient
def on_event(event_type, subscribe_type, payload, raw_message):
if EVENT_TYPE_ORDER == event_type and ORDER_STATUS_CHANGED == subscribe_type:
print("Order update:", payload)
events_client = TradeEventsClient("<your_app_key>", "<your_app_secret>", "us")
events_client.on_events_message = on_event
events_client.do_subscribe(["<your_account_id>"])
import com.webull.openapi.trade.events.subscribe.*;
import com.webull.openapi.trade.events.subscribe.message.*;
ITradeEventClient eventClient = ITradeEventClient.builder()
.appKey("<your_app_key>")
.appSecret("<your_app_secret>")
.regionId("us")
.onMessage(response -> {
System.out.println("Order update: " + response.getPayload());
})
.build();
SubscribeRequest request = new SubscribeRequest("<your_account_id>");
ISubscription subscription = eventClient.subscribe(request);
subscription.blockingAwait();
tip
For the production environment, use events-api.webull.com as the event endpoint. For the test environment, use us-openapi-events.uat.webullbroker.com.
Sample Project
Download the complete Trading API demo project with examples covering account management, order placement, and position queries:
What's Next
- Accounts — Query balances and positions
- Orders — Stock and options order types, combo orders, and advanced strategies
- Futures — Futures contract trading
- Crypto — Crypto trading
- Event Contracts — Binary outcome event trading