Option Exercise
Overview
The option exercise APIs are available since v0.4.2 and provide the following capabilities:
- Exercise check: Estimate the underlying stock position change after exercise or waive
- Query exercisable positions: Get the list of option positions eligible for exercise/waive requests
- Submit exercise request: Submit an early exercise or early waive request
- Query exercise records: Paginated query of submitted exercise request history
- Cancel exercise request: Cancel a pending exercise request
Exercise Types (OptionExerciseType)
| Value | Description |
|---|---|
Exercise | Early exercise — exercise the option before expiry |
Expire | Early waive — voluntarily waive the right to exercise before expiry |
Exercise Check
Request class: OptionExerciseCheckRequest
Estimates the underlying stock position change after exercise or waive. Call this before submitting to confirm 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 | int | No | ITM rate threshold 0–10 (Expire only) |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Returns (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
// 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, ITM rate optional)
OptionExerciseCheckRequest expireCheck =
OptionExerciseCheckRequest.buildRequest(account, contractId, OptionExerciseType.Expire)
.setQuantity(1.0)
.setItmRate(5);
OptionExerciseCheckResponse expireResp = client.execute(expireCheck);Response example
{
"availableQuantity": 10.0,
"position": 10.0,
"stkPosition": 300.0,
"stkPositionChange": -100.0,
"stkPositionBefore": 300.0,
"stkPositionAfter": 200.0,
"symbol": "AAPL"
}Query Exercisable Positions
Request class: OptionExercisePositionRequest
Returns the list of option positions eligible for exercise or waive requests.
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 | int | Current page number |
| pageSize | int | Page size |
| itemCount | int | Total record count |
| pageCount | int | 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
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());
}Response example
{
"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
}
]
}Submit Exercise Request
Request class: OptionExerciseSubmitRequest
Submits an early exercise or early waive request.
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 0–10 |
| secretKey | string | No | Trader key for institutional/Prime accounts |
Example
// Early exercise
OptionExerciseSubmitRequest exerciseRequest =
OptionExerciseSubmitRequest.buildExerciseRequest(
account, contractId, 1.0, "2025-06-20", false);
OptionExerciseSubmitResponse exerciseResp = client.execute(exerciseRequest);
System.out.println(exerciseResp.isSuccess() ? "Submitted successfully" : "Error: " + exerciseResp.getMessage());
// Early waive
OptionExerciseSubmitRequest expireRequest =
OptionExerciseSubmitRequest.buildExpireRequest(account, contractId, 1.0, null);
OptionExerciseSubmitResponse expireResp = client.execute(expireRequest);
System.out.println(expireResp.isSuccess() ? "Submitted successfully" : "Error: " + expireResp.getMessage());Query Exercise Records
Request class: OptionExerciseRecordRequest
Returns paginated exercise/waive request records.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| account | string | Yes | Trading account |
| page | int | Yes | Page number, starts from 1 |
| size | int | Yes | Page size, 1–100 |
| 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 |
Returns (OptionExerciseRecordPageItem)
Pagination wrapper; items is List<OptionExerciseRecordItem>.
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
// Basic query
OptionExerciseRecordRequest request =
OptionExerciseRecordRequest.buildRequest(account, 1, 20);
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());
}
}
// With filters
OptionExerciseRecordRequest filtered =
OptionExerciseRecordRequest.buildRequest(account, 1, 20)
.setType(OptionExerciseType.Exercise.name())
.setOrderBy("symbol");Response example
{
"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
}
]
}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
OptionExerciseCancelRequest request =
OptionExerciseCancelRequest.buildRequest(account, recordId);
OptionExerciseCancelResponse response = client.execute(request);
System.out.println(response.isSuccess() ? "Cancelled successfully" : "Error: " + response.getMessage());