Skip to content

Commit cc3b186

Browse files
author
方佳
committed
Merge branch 'main_merge_250116' into 'main'
[OpenAPI]: Add support for stock short selling and single-leg options See merge request webull/openapi-java-sdk!11
2 parents babc3ad + d5e26af commit cc3b186

28 files changed

Lines changed: 974 additions & 88 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
<groupId>com.webull.openapi</groupId>
2222
<artifactId>webull-java-sdk</artifactId>
2323
<packaging>pom</packaging>
24-
<version>0.2.10</version>
24+
<version>0.2.11</version>
2525

2626
<name>webull-java-sdk</name>
2727
<url>https://github.com/webull-inc/openapi-java-sdk/</url>

webull-java-sdk-core/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<parent>
2020
<groupId>com.webull.openapi</groupId>
2121
<artifactId>webull-java-sdk</artifactId>
22-
<version>0.2.10</version>
22+
<version>0.2.11</version>
2323
</parent>
2424

2525
<modelVersion>4.0.0</modelVersion>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright 2022 Webull
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.webull.openapi.common.dict;
17+
18+
public enum ComboType {
19+
20+
/** Simple Order **/
21+
NORMAL,
22+
23+
/** Master Order */
24+
MASTER,
25+
26+
/** Stop Loss Order **/
27+
STOP_LOSS,
28+
29+
/** Take Profit Order **/
30+
STOP_PROFIT,
31+
32+
/** One Triggers Other Order **/
33+
OTO,
34+
35+
/** One Cancels Other Order **/
36+
OCO,
37+
38+
/** One Triggers a One Cancels Other Order **/
39+
OTOCO
40+
41+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright 2022 Webull
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.webull.openapi.common.dict;
17+
18+
public enum OptionStrategy {
19+
20+
/** Single option **/
21+
SINGLE,
22+
23+
/** Buy writes **/
24+
COVERED_STOCK,
25+
26+
/** Straddle **/
27+
STRADDLE,
28+
29+
/** Strangle **/
30+
STRANGLE,
31+
32+
/** Vertical **/
33+
VERTICAL,
34+
35+
/** Calendar **/
36+
CALENDAR,
37+
38+
/** Butterfly **/
39+
BUTTERFLY,
40+
41+
/** Condor **/
42+
CONDOR,
43+
44+
/** Collar with stock **/
45+
COLLAR_WITH_STOCK,
46+
47+
/** Iron butterfly **/
48+
IRON_BUTTERFLY,
49+
50+
/** Iron condor **/
51+
IRON_CONDOR,
52+
53+
/** Diagonal **/
54+
DIAGONAL
55+
56+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright 2022 Webull
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.webull.openapi.common.dict;
17+
18+
public enum OptionType {
19+
20+
/** PUT **/
21+
PUT,
22+
23+
/** CALL **/
24+
CALL,
25+
26+
}

webull-java-sdk-core/src/main/java/com/webull/openapi/config/ProjectReaderHelper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ private ProjectReaderHelper() {
2424

2525
private static final String APPLICATION_VERSION = "application.version";
2626

27-
private static final String DEFAULT_APPLICATION_VERSION = "0.2.10";
27+
private static final String DEFAULT_APPLICATION_VERSION = "0.2.11";
2828

2929
private static final String APPLICATION_NAME = "application.name";
3030

webull-java-sdk-example/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<parent>
2020
<groupId>com.webull.openapi</groupId>
2121
<artifactId>webull-java-sdk</artifactId>
22-
<version>0.2.10</version>
22+
<version>0.2.11</version>
2323
</parent>
2424

2525
<modelVersion>4.0.0</modelVersion>

webull-java-sdk-example/src/main/java/com/webull/openapi/example/trade/TradeApi.java

Lines changed: 85 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
package com.webull.openapi.example.trade;
22

3-
import com.webull.openapi.common.dict.*;
3+
import com.webull.openapi.common.dict.ComboType;
4+
import com.webull.openapi.common.dict.EntrustType;
5+
import com.webull.openapi.common.dict.InstrumentSuperType;
6+
import com.webull.openapi.common.dict.Markets;
7+
import com.webull.openapi.common.dict.OptionStrategy;
8+
import com.webull.openapi.common.dict.OptionType;
9+
import com.webull.openapi.common.dict.OrderSide;
10+
import com.webull.openapi.common.dict.OrderTIF;
11+
import com.webull.openapi.common.dict.OrderType;
412
import com.webull.openapi.example.config.Env;
513
import com.webull.openapi.execption.ClientException;
614
import com.webull.openapi.execption.ServerException;
@@ -10,19 +18,26 @@
1018
import com.webull.openapi.trade.api.TradeApiService;
1119
import com.webull.openapi.trade.api.http.TradeHttpApiService;
1220
import com.webull.openapi.trade.api.request.StockOrder;
13-
import com.webull.openapi.trade.api.response.*;
21+
import com.webull.openapi.trade.api.request.v2.OptionOrder;
22+
import com.webull.openapi.trade.api.request.v2.OptionOrderItem;
23+
import com.webull.openapi.trade.api.request.v2.OptionOrderItemLeg;
1424
import com.webull.openapi.trade.api.response.Account;
1525
import com.webull.openapi.trade.api.response.AccountDetail;
1626
import com.webull.openapi.trade.api.response.AccountPositions;
27+
import com.webull.openapi.trade.api.response.BalanceBase;
1728
import com.webull.openapi.trade.api.response.InstrumentInfo;
1829
import com.webull.openapi.trade.api.response.Order;
1930
import com.webull.openapi.trade.api.response.OrderResponse;
2031
import com.webull.openapi.trade.api.response.Orders;
32+
import com.webull.openapi.trade.api.response.TradableInstruments;
2133
import com.webull.openapi.trade.api.response.TradeCalendar;
34+
import com.webull.openapi.trade.api.response.v2.PreviewOrderResponse;
35+
import com.webull.openapi.trade.api.response.v2.TradeOrderResponse;
2236
import com.webull.openapi.utils.CollectionUtils;
2337
import com.webull.openapi.utils.GUID;
2438
import com.webull.openapi.utils.StringUtils;
2539

40+
import java.util.ArrayList;
2641
import java.util.List;
2742

2843
public class TradeApi {
@@ -111,6 +126,74 @@ public static void main(String[] args) {
111126
TradableInstruments tradeableInstruments = apiService.getTradeableInstruments("", 10);
112127
logger.info("Tradeable instruments info: {}", tradeableInstruments);
113128

129+
130+
131+
// Options
132+
// For option order inquiries, please use the V2 query interface: TradeHttpApiV2Service.getOrderDetails(accountId, clientOrderId).
133+
OptionOrderItemLeg optionOrderItemLeg = new OptionOrderItemLeg();
134+
optionOrderItemLeg.setSide(OrderSide.BUY.name());
135+
optionOrderItemLeg.setQuantity("1");
136+
optionOrderItemLeg.setSymbol("AAPL");
137+
optionOrderItemLeg.setStrikePrice("250");
138+
optionOrderItemLeg.setInitExpDate("2025-08-15");
139+
optionOrderItemLeg.setInstrumentType(InstrumentSuperType.OPTION.name());
140+
optionOrderItemLeg.setOptionType(OptionType.CALL.name());
141+
optionOrderItemLeg.setMarket(Markets.US.name());
142+
List<OptionOrderItemLeg> optionOrderItemLegList = new ArrayList<>();
143+
optionOrderItemLegList.add(optionOrderItemLeg);
144+
OptionOrderItem optionOrderItem = new OptionOrderItem();
145+
optionOrderItem.setClientOrderId(GUID.get());
146+
optionOrderItem.setComboType(ComboType.NORMAL.name());
147+
optionOrderItem.setOptionStrategy(OptionStrategy.SINGLE.name());
148+
optionOrderItem.setSide(OrderSide.BUY.name());
149+
optionOrderItem.setOrderType(OrderType.LIMIT.name());
150+
optionOrderItem.setTimeInForce(OrderTIF.GTC.name());
151+
optionOrderItem.setLimitPrice("2");
152+
optionOrderItem.setQuantity("1");
153+
optionOrderItem.setEntrustType(EntrustType.QTY.name());
154+
optionOrderItem.setOrders(optionOrderItemLegList);
155+
List<OptionOrderItem> optionOrderItemList = new ArrayList<>();
156+
optionOrderItemList.add(optionOrderItem);
157+
OptionOrder optionOrder = new OptionOrder();
158+
optionOrder.setNewOrders(optionOrderItemList);
159+
160+
logger.info("previewOptionRequest: {}", optionOrder);
161+
PreviewOrderResponse previewOptionResponse = apiService.previewOption(accountId, optionOrder);
162+
logger.info("previewOptionResponse: {}", previewOptionResponse);
163+
164+
logger.info("placeOptionRequest: {}", optionOrder);
165+
TradeOrderResponse placeOptionResponse = apiService.placeOption(accountId, optionOrder);
166+
logger.info("placeOptionResponse: {}", placeOptionResponse);
167+
Thread.sleep(5000L);
168+
169+
// This code is only applicable for single-leg options modification operations.
170+
OptionOrderItemLeg optionReplaceItemLeg = new OptionOrderItemLeg();
171+
optionReplaceItemLeg.setQuantity("2");
172+
optionReplaceItemLeg.setClientOrderId(optionOrderItem.getClientOrderId());
173+
List<OptionOrderItemLeg> optionReplaceItemLegList = new ArrayList<>();
174+
optionReplaceItemLegList.add(optionReplaceItemLeg);
175+
OptionOrderItem optionReplaceItem = new OptionOrderItem();
176+
optionReplaceItem.setClientOrderId(optionOrderItem.getClientOrderId());
177+
optionReplaceItem.setLimitPrice("3");
178+
optionReplaceItem.setQuantity("2");
179+
optionReplaceItem.setOrders(optionReplaceItemLegList);
180+
List<OptionOrderItem> optionReplaceItemList = new ArrayList<>();
181+
optionReplaceItemList.add(optionReplaceItem);
182+
OptionOrder optionReplace = new OptionOrder();
183+
optionReplace.setModifyOrders(optionReplaceItemList);
184+
185+
logger.info("replaceOptionRequest: {}", optionReplace);
186+
TradeOrderResponse replaceOptionResponse = apiService.replaceOption(accountId, optionReplace);
187+
logger.info("replaceOptionResponse: {}", replaceOptionResponse);
188+
Thread.sleep(5000L);
189+
190+
OptionOrder cancelTradeOption = new OptionOrder();
191+
cancelTradeOption.setClientOrderId(optionOrderItem.getClientOrderId());
192+
193+
logger.info("cancelOptionRequest: {}", cancelTradeOption);
194+
TradeOrderResponse cancelOptionResponse = apiService.cancelOption(accountId, cancelTradeOption);
195+
logger.info("cancelOptionResponse: {}", cancelOptionResponse);
196+
114197
} catch (ClientException ex) {
115198
logger.error("Client error", ex);
116199
} catch (ServerException ex) {

webull-java-sdk-example/src/main/java/com/webull/openapi/example/trade/TradeV2Api.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public static void main(String[] args) {
7676

7777
PreviewOrderResponse previewOrderResponse = apiService.previewOrder(accountId, tradeOrder);
7878
logger.info("previewOrderResponse: {}", previewOrderResponse);
79-
placeOne.setClientOrderId(GUID.get());
79+
String clientOrderId = GUID.get();
80+
placeOne.setClientOrderId(clientOrderId);
8081
TradeOrderResponse tradePlaceOrderResponse = apiService.placeOrder(accountId, tradeOrder);
8182
logger.info("tradePlaceOrderResponse: {}", tradePlaceOrderResponse);
8283
Thread.sleep(1000L);
@@ -96,8 +97,13 @@ public static void main(String[] args) {
9697
TradeOrderResponse tradeCancelOrderResponse = apiService.cancelOrder(accountId, cancelTradeOrder);
9798
logger.info("tradeCancelOrderResponse: {}", tradeCancelOrderResponse);
9899

99-
List<OrderHistory> tradeOrderItems = apiService.listOrders(accountId, 10, "2024-09-25", "034Q784G9K6DT0KHKA8S000000");
100+
List<OrderHistory> tradeOrderItems = apiService.listOrders(accountId, 10, "2024-09-25", null, null);
100101
logger.info("tradeOrderItems: {}", tradeOrderItems);
102+
103+
// Replace with the client_order_id to be queried.
104+
OrderHistory orderDetailResponse = apiService.getOrderDetails(accountId, clientOrderId);
105+
logger.info("orderDetailResponse: {}", orderDetailResponse);
106+
101107
} catch (ClientException ex) {
102108
logger.error("Client error", ex);
103109
} catch (ServerException ex) {

webull-java-sdk-grpc/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<parent>
2020
<groupId>com.webull.openapi</groupId>
2121
<artifactId>webull-java-sdk</artifactId>
22-
<version>0.2.10</version>
22+
<version>0.2.11</version>
2323
</parent>
2424

2525
<modelVersion>4.0.0</modelVersion>

0 commit comments

Comments
 (0)