Option Exercise
Overview
The option exercise APIs support the following operations:
- Exercise check: Estimate the change in the underlying stock position after exercise or waiver
- Query exercisable positions: List option positions eligible for exercise or waiver requests
- Submit exercise request: Submit an early-exercise request or waive the right to exercise before expiration
- Query exercise records: Retrieve submitted exercise requests with pagination
- Cancel exercise request: Cancel a pending exercise request
Option exercise is available for Prime accounts only.
Exercise Types (OptionExerciseType)
| Value | Description |
|---|---|
Exercise | Exercise the option before expiration |
Expire | Waive exercise rights before expiration |
Exercise Check
Request class: OptionExerciseCheckRequest
Estimates the change in the underlying stock position after exercise or waiver. Call this endpoint before submitting an exercise request to verify the expected result.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| contractId | long | Yes | Option contract ID |
| type | string | Yes | Exercise type: Exercise / Expire |
| quantity | double | Yes | Exercise quantity (> 0) |
| executingDate | string | Required for Exercise | Execution date, format yyyy-MM-dd |
| isForce | boolean | Required for Exercise | Whether to force exercise |
| itmRate | Integer | No | Nullable. The check path applies no local default, range restriction, or exercise-type restriction; a supplied value is passed through for the check |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Response (OptionExerciseCheckItem)
| Field | Type | Description |
|---|---|---|
| availableQuantity | double | Exercisable quantity |
| position | double | Current option position |
| stkPosition | double | Current underlying stock position |
| stkPositionChange | double | Stock position change after exercise |
| stkPositionBefore | double | Stock position before exercise |
| stkPositionAfter | double | Stock position after exercise |
| symbol | string | Underlying stock symbol |
Example
String account = "YOUR_PRIME_ACCOUNT";
Long contractId = 1684414425L;
// Exercise check (Exercise type — quantity, executingDate, isForce required)
OptionExerciseCheckRequest request =
OptionExerciseCheckRequest.buildRequest(account, contractId, OptionExerciseType.Exercise)
.setQuantity(1.0)
.setExecutingDate("2025-06-20")
.setIsForce(false);
OptionExerciseCheckResponse response = client.execute(request);
if (response.isSuccess()) {
OptionExerciseCheckItem item = response.getItem();
System.out.println("availableQuantity=" + item.getAvailableQuantity()
+ " stkPositionBefore=" + item.getStkPositionBefore()
+ " stkPositionAfter=" + item.getStkPositionAfter());
} else {
System.out.println("Error: " + response.getMessage());
}
// Exercise check (Expire type: quantity required, itmRate nullable)
OptionExerciseCheckRequest expireCheck =
OptionExerciseCheckRequest.buildRequest(account, contractId, OptionExerciseType.Expire)
.setQuantity(1.0)
.setItmRate(5);
OptionExerciseCheckResponse expireResp = client.execute(expireCheck);Example Response
{
"availableQuantity": 10.0,
"position": 10.0,
"stkPosition": 300.0,
"stkPositionChange": -100.0,
"stkPositionBefore": 300.0,
"stkPositionAfter": 200.0,
"symbol": "AAPL"
}Rate Limit
The base rate limit is 60 requests/min.
Query Exercisable Positions
Request class: OptionExercisePositionRequest
Returns option positions eligible for requests to exercise or waive exercise rights.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| type | string | Yes | Exercise type: Exercise / Expire |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Returns (OptionExercisePositionPageItem)
Pagination wrapper containing:
| Field | Type | Description |
|---|---|---|
| pageNum | Integer | Current page number, starting from 1 |
| pageSize | Integer | Page size |
| itemCount | Integer | Total record count |
| pageCount | Integer | Total page count |
| items | List<OptionExercisePositionItem> | Position list |
OptionExercisePositionItem fields
| Field | Type | Description |
|---|---|---|
| contractId | long | Option contract ID |
| symbol | string | Option contract symbol |
| stkSymbol | string | Underlying stock symbol |
| expireDate | string | Expiry date, format yyyy-MM-dd |
| strike | string | Strike price |
| callPut | string | CALL / PUT |
| market | string | Market |
| accountId | long | Account ID |
| position | double | Position quantity |
| availableQuantity | double | Exercisable quantity |
Example
String account = "YOUR_PRIME_ACCOUNT";
OptionExercisePositionRequest request =
OptionExercisePositionRequest.buildRequest(account, OptionExerciseType.Exercise);
OptionExercisePositionResponse response = client.execute(request);
if (response.isSuccess()) {
OptionExercisePositionPageItem page = response.getItem();
System.out.println("itemCount=" + page.getItemCount());
for (OptionExercisePositionItem item : page.getItems()) {
System.out.println("contractId=" + item.getContractId()
+ " symbol=" + item.getSymbol()
+ " expireDate=" + item.getExpireDate()
+ " availableQty=" + item.getAvailableQuantity());
}
} else {
System.out.println("Error: " + response.getMessage());
}Example Response
{
"itemCount": 4,
"pageNum": 1,
"pageSize": 10,
"pageCount": 1,
"items": [
{
"contractId": 1684414425,
"symbol": "AAPL",
"stkSymbol": "AAPL",
"expireDate": "2026-04-17",
"strike": "280.0",
"callPut": "PUT",
"market": "US",
"accountId": 600021133765,
"position": 10.0,
"availableQuantity": 10.0
}
]
}Rate Limit
The base rate limit is 60 requests/min.
Submit Exercise Request
Request class: OptionExerciseSubmitRequest
Submits a request to exercise early or waive exercise rights before expiration.
Note
- Call the exercise check API first to confirm the position impact before submitting
executingDateandisForceare only applicable toExercisetypeitmRateis only applicable toExpiretype- To cancel after a successful submission, use the cancel exercise request API
Parameters (Exercise type)
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| contractId | long | Yes | Option contract ID |
| quantity | double | Yes | Exercise quantity |
| executingDate | string | Yes | Execution date, format yyyy-MM-dd |
| isForce | boolean | Yes | Whether to force exercise |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Parameters (Expire type)
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| contractId | long | Yes | Option contract ID |
| quantity | double | Yes | Waive quantity |
| itmRate | int | No | ITM rate threshold; range 0–10, defaults to 0 when omitted. Do not send an explicit null value |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Example
String account = "YOUR_PRIME_ACCOUNT";
Long contractId = 1684414425L;
// Early exercise
OptionExerciseSubmitRequest exerciseRequest =
OptionExerciseSubmitRequest.buildExerciseRequest(
account, contractId, 1.0, "2025-06-20", false);
OptionExerciseSubmitResponse exerciseResp = client.execute(exerciseRequest);
System.out.println(exerciseResp.isSuccess() ? "OpenAPI call succeeded" : "OpenAPI call failed: " + exerciseResp.getMessage());
// Waive exercise rights before expiration
OptionExerciseSubmitRequest expireRequest =
OptionExerciseSubmitRequest.buildExpireRequest(account, contractId, 1.0, 5);
OptionExerciseSubmitResponse expireResp = client.execute(expireRequest);
System.out.println(expireResp.isSuccess() ? "OpenAPI call succeeded" : "OpenAPI call failed: " + expireResp.getMessage());isSuccess(), code, and message confirm only whether the OpenAPI call succeeded. They do not confirm final business processing of the exercise request. Query exercise records after submission to confirm its status and result.
Rate Limit
The base rate limit is 60 requests/min.
Query Exercise Records
Request class: OptionExerciseRecordRequest
Returns paginated records of requests to exercise or waive exercise rights.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| page | Integer | No | Page number; must be at least 1 when provided |
| size | Integer | No | Page size; must be 1–100 when provided |
| status | string | No | Status filter: New / Cancel / Success / Fail |
| type | string | No | Type filter: Exercise / Expire |
| symbol | string | No | Underlying symbol filter |
| orderBy | string | No | Sort field: symbol / expire_date / strike / is_call |
| secretKey | string | No | Trader key for institutional/Prime accounts |
buildRequest(account, page, size) requires the page and size argument positions in that order, but either value may be null to omit it. This documentation does not infer defaults for omitted pagination values. When non-null, page must be at least 1 and size must be 1–100.
Returns (OptionExerciseRecordPageItem)
| Field | Type | Description |
|---|---|---|
| pageNum | Integer | Current page number, starting from 1 |
| pageSize | Integer | Page size |
| itemCount | Integer | Total record count |
| pageCount | Integer | Total page count |
| items | List<OptionExerciseRecordItem> | Exercise record list |
OptionExerciseRecordItem fields
| Field | Type | Description |
|---|---|---|
| id | long | Exercise record ID |
| contractId | long | Option contract ID |
| symbol | string | Option contract symbol |
| stkSymbol | string | Underlying stock symbol |
| expireDate | string | Expiry date |
| strike | string | Strike price |
| callPut | string | CALL / PUT |
| type | string | Exercise / Expire |
| requestQuantity | double | Requested quantity |
| quantity | double | Actual exercised quantity |
| status | string | Request status: New / Cancel / Success / Fail |
| executingDate | string | Execution date |
| itmRate | int | ITM rate |
| isForce | boolean | Force exercise flag |
| reason | string | Rejection reason (if any) |
| accountId | long | Account ID |
Example
String account = "YOUR_PRIME_ACCOUNT";
// Omit pagination values; retain the page and size argument positions
OptionExerciseRecordRequest request =
OptionExerciseRecordRequest.buildRequest(account, null, null);
OptionExerciseRecordResponse response = client.execute(request);
if (response.isSuccess()) {
OptionExerciseRecordPageItem page = response.getItem();
System.out.println("itemCount=" + page.getItemCount() + " pageCount=" + page.getPageCount());
for (OptionExerciseRecordItem item : page.getItems()) {
System.out.println("id=" + item.getId() + " type=" + item.getType()
+ " status=" + item.getStatus());
}
}
// Specify pagination and filters
OptionExerciseRecordRequest filtered =
OptionExerciseRecordRequest.buildRequest(account, 1, 20)
.setType(OptionExerciseType.Exercise.name())
.setOrderBy("symbol");Example Response
{
"itemCount": 19,
"pageNum": 1,
"pageSize": 10,
"pageCount": 2,
"items": [
{
"id": 315,
"contractId": 2701923713,
"symbol": "AAPL",
"stkSymbol": "AAPL",
"expireDate": "2026-06-05",
"strike": "305.0",
"callPut": "PUT",
"type": "Exercise",
"requestQuantity": 1.0,
"quantity": 0.0,
"status": "Cancel",
"executingDate": "2026-06-01",
"itmRate": 0,
"isForce": false,
"reason": "Cancelled by manual",
"accountId": 600021133765
}
]
}Rate Limit
The base rate limit is 60 requests/min.
Cancel Exercise Request
Request class: OptionExerciseCancelRequest
Cancels a pending exercise request.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| id | long | Yes | Exercise record ID (from OptionExerciseRecordRequest) |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Example
String account = "YOUR_PRIME_ACCOUNT";
Long recordId = 315L; // Obtain this from the query exercise records API
OptionExerciseCancelRequest request =
OptionExerciseCancelRequest.buildRequest(account, recordId);
OptionExerciseCancelResponse response = client.execute(request);
System.out.println(response.isSuccess() ? "Cancellation call succeeded" : "Error: " + response.getMessage());isSuccess(), code, and message confirm only whether the OpenAPI call succeeded. They do not confirm final business processing of the cancellation. Query exercise records afterward to confirm the request status and result.
Rate Limit
The base rate limit is 60 requests/min.
Updated about 1 month ago
