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)

ValueDescription
ExerciseExercise the option before expiration
ExpireWaive 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

ParameterTypeRequiredDescription
accountstringYesTrading account
contractIdlongYesOption contract ID
typestringYesExercise type: Exercise / Expire
quantitydoubleYesExercise quantity (> 0)
executingDatestringRequired for ExerciseExecution date, format yyyy-MM-dd
isForcebooleanRequired for ExerciseWhether to force exercise
itmRateIntegerNoNullable. The check path applies no local default, range restriction, or exercise-type restriction; a supplied value is passed through for the check
secretKeystringNoTrader key for institutional/Prime accounts

Response (OptionExerciseCheckItem)

FieldTypeDescription
availableQuantitydoubleExercisable quantity
positiondoubleCurrent option position
stkPositiondoubleCurrent underlying stock position
stkPositionChangedoubleStock position change after exercise
stkPositionBeforedoubleStock position before exercise
stkPositionAfterdoubleStock position after exercise
symbolstringUnderlying 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

ParameterTypeRequiredDescription
accountstringYesTrading account
typestringYesExercise type: Exercise / Expire
secretKeystringNoTrader key for institutional/Prime accounts

Returns (OptionExercisePositionPageItem)

Pagination wrapper containing:

FieldTypeDescription
pageNumIntegerCurrent page number, starting from 1
pageSizeIntegerPage size
itemCountIntegerTotal record count
pageCountIntegerTotal page count
itemsList<OptionExercisePositionItem>Position list

OptionExercisePositionItem fields

FieldTypeDescription
contractIdlongOption contract ID
symbolstringOption contract symbol
stkSymbolstringUnderlying stock symbol
expireDatestringExpiry date, format yyyy-MM-dd
strikestringStrike price
callPutstringCALL / PUT
marketstringMarket
accountIdlongAccount ID
positiondoublePosition quantity
availableQuantitydoubleExercisable 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
  • executingDate and isForce are only applicable to Exercise type
  • itmRate is only applicable to Expire type
  • To cancel after a successful submission, use the cancel exercise request API

Parameters (Exercise type)

ParameterTypeRequiredDescription
accountstringYesTrading account
contractIdlongYesOption contract ID
quantitydoubleYesExercise quantity
executingDatestringYesExecution date, format yyyy-MM-dd
isForcebooleanYesWhether to force exercise
secretKeystringNoTrader key for institutional/Prime accounts

Parameters (Expire type)

ParameterTypeRequiredDescription
accountstringYesTrading account
contractIdlongYesOption contract ID
quantitydoubleYesWaive quantity
itmRateintNoITM rate threshold; range 0–10, defaults to 0 when omitted. Do not send an explicit null value
secretKeystringNoTrader 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

ParameterTypeRequiredDescription
accountstringYesTrading account
pageIntegerNoPage number; must be at least 1 when provided
sizeIntegerNoPage size; must be 1–100 when provided
statusstringNoStatus filter: New / Cancel / Success / Fail
typestringNoType filter: Exercise / Expire
symbolstringNoUnderlying symbol filter
orderBystringNoSort field: symbol / expire_date / strike / is_call
secretKeystringNoTrader 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)

FieldTypeDescription
pageNumIntegerCurrent page number, starting from 1
pageSizeIntegerPage size
itemCountIntegerTotal record count
pageCountIntegerTotal page count
itemsList<OptionExerciseRecordItem>Exercise record list

OptionExerciseRecordItem fields

FieldTypeDescription
idlongExercise record ID
contractIdlongOption contract ID
symbolstringOption contract symbol
stkSymbolstringUnderlying stock symbol
expireDatestringExpiry date
strikestringStrike price
callPutstringCALL / PUT
typestringExercise / Expire
requestQuantitydoubleRequested quantity
quantitydoubleActual exercised quantity
statusstringRequest status: New / Cancel / Success / Fail
executingDatestringExecution date
itmRateintITM rate
isForcebooleanForce exercise flag
reasonstringRejection reason (if any)
accountIdlongAccount 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

ParameterTypeRequiredDescription
accountstringYesTrading account
idlongYesExercise record ID (from OptionExerciseRecordRequest)
secretKeystringNoTrader 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.


Did this page help you?