Skip to content

Commit

Permalink
Merge branch 'main_merge_250116' into 'main'
Browse files Browse the repository at this point in the history
[OpenAPI]: Add support for stock short selling and single-leg options

See merge request webull/openapi-python-sdk!9
  • Loading branch information
方佳 committed Jan 17, 2025
2 parents ce59799 + ecb1829 commit 1cc418d
Show file tree
Hide file tree
Showing 25 changed files with 601 additions and 19 deletions.
2 changes: 1 addition & 1 deletion webull-python-sdk-core/webullsdkcore/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "0.1.10"
__version__ = "0.1.11"

import logging

Expand Down
4 changes: 2 additions & 2 deletions webull-python-sdk-demos/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
LONG_DESCRIPTION = fp.read()

requires = [
"webull-python-sdk-mdata==0.1.10",
"webull-python-sdk-trade==0.1.10"
"webull-python-sdk-mdata==0.1.11",
"webull-python-sdk-trade==0.1.11"
]

setup_args = {
Expand Down
47 changes: 47 additions & 0 deletions webull-python-sdk-demos/tests/trade/request/test_cancel_option.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2022 Webull
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import unittest

from webullsdkcore.client import ApiClient
from webullsdkcore.exception.exceptions import ServerException
from webullsdktrade.request.v2.cancel_option_request import CancelOptionRequest

optional_api_endpoint = "<api_endpoint>"
optional_api_region_id = "<api_region_id>"
your_app_key = "<your_app_key>"
your_app_secret = "<your_app_secret>"
account_id = "<your_account_id>"
api_client = ApiClient(your_app_key, your_app_secret)
api_client.add_endpoint(optional_api_region_id, optional_api_endpoint)

client_order_id = "e1890d630d5542b48fe50d82e0d7b13f"

class TestOptionOperation(unittest.TestCase):
def test_preview_order(self):
request = CancelOptionRequest()
request.set_endpoint(optional_api_endpoint)
request.set_account_id(account_id)
request.set_client_order_id(client_order_id)
post_body = request.get_body_params()
print(json.dumps(post_body, indent=4))
params = request.get_query_params()
print(params)

try:
response = api_client.get_response(request)
print(response.json())

except ServerException as se:
print(se.get_error_code(), ":", se.get_error_msg())
74 changes: 74 additions & 0 deletions webull-python-sdk-demos/tests/trade/request/test_place_option.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Copyright 2022 Webull
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import unittest
import uuid

from webullsdkcore.client import ApiClient
from webullsdkcore.exception.exceptions import ServerException
from webullsdktrade.request.v2.place_option_request import PlaceOptionRequest

optional_api_endpoint = "<api_endpoint>"
optional_api_region_id = "<api_region_id>"
your_app_key = "<your_app_key>"
your_app_secret = "<your_app_secret>"
account_id = "<your_account_id>"
api_client = ApiClient(your_app_key, your_app_secret)
api_client.add_endpoint(optional_api_region_id, optional_api_endpoint)

client_order_id = uuid.uuid4().hex
new_orders = [
{
"client_order_id": client_order_id,
"combo_type": "NORMAL",
"order_type": "LIMIT",
"quantity": "1",
"limit_price": "11.25",
"option_strategy": "SINGLE",
"side": "BUY",
"time_in_force": "GTC",
"entrust_type": "QTY",
"orders": [
{
"side": "BUY",
"quantity": "1",
"symbol": "AAPL",
"strike_price": "250.0",
"init_exp_date": "2025-08-15",
"instrument_type": "OPTION",
"option_type": "CALL",
"market": "US"
}
]
}
]


class TestOptionOperation(unittest.TestCase):
def test_preview_order(self):
request = PlaceOptionRequest()
request.set_endpoint(optional_api_endpoint)
request.set_account_id(account_id)
request.set_new_orders(new_orders)
post_body = request.get_body_params()
print(json.dumps(post_body, indent=4))
params = request.get_query_params()
print(params)

try:
response = api_client.get_response(request)
print(response.json())

except ServerException as se:
print(se.get_error_code(), ":", se.get_error_msg())
75 changes: 75 additions & 0 deletions webull-python-sdk-demos/tests/trade/request/test_preview_option.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright 2022 Webull
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import unittest
import uuid

from webullsdkcore.client import ApiClient
from webullsdkcore.exception.exceptions import ServerException
from webullsdktrade.request.v2.preview_option_request import PreviewOptionRequest


optional_api_endpoint = "<api_endpoint>"
optional_api_region_id = "<api_region_id>"
your_app_key = "<your_app_key>"
your_app_secret = "<your_app_secret>"
account_id = "<your_account_id>"
api_client = ApiClient(your_app_key, your_app_secret)
api_client.add_endpoint(optional_api_region_id, optional_api_endpoint)

client_order_id = uuid.uuid4().hex
new_orders = [
{
"client_order_id": client_order_id,
"combo_type": "NORMAL",
"order_type": "LIMIT",
"quantity": "1",
"limit_price": "11.25",
"option_strategy": "SINGLE",
"side": "BUY",
"time_in_force": "DAY",
"entrust_type": "QTY",
"orders": [
{
"side": "BUY",
"quantity": "1",
"symbol": "AAPL",
"strike_price": "250.0",
"init_exp_date": "2025-08-15",
"instrument_type": "OPTION",
"option_type": "CALL",
"market": "US"
}
]
}
]


class TestOptionOperation(unittest.TestCase):
def test_preview_order(self):
request = PreviewOptionRequest()
request.set_endpoint(optional_api_endpoint)
request.set_account_id(account_id)
request.set_new_orders(new_orders)
post_body = request.get_body_params()
print(json.dumps(post_body, indent=4))
params = request.get_query_params()
print(params)

try:
response = api_client.get_response(request)
print(response.json())

except ServerException as se:
print(se.get_error_code(), ":", se.get_error_msg())
62 changes: 62 additions & 0 deletions webull-python-sdk-demos/tests/trade/request/test_replace_option.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Copyright 2022 Webull
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import unittest

from webullsdkcore.client import ApiClient
from webullsdkcore.exception.exceptions import ServerException
from webullsdktrade.request.v2.replace_option_request import ReplaceOptionRequest


optional_api_endpoint = "<api_endpoint>"
optional_api_region_id = "<api_region_id>"
your_app_key = "<your_app_key>"
your_app_secret = "<your_app_secret>"
account_id = "<your_account_id>"
api_client = ApiClient(your_app_key, your_app_secret)
api_client.add_endpoint(optional_api_region_id, optional_api_endpoint)

client_order_id = "e1890d630d5542b48fe50d82e0d7b13f"
modify_orders = [
{
"client_order_id": client_order_id,
"quantity": "2",
"limit_price": "11.3",
"orders": [
{
"client_order_id": client_order_id,
"quantity": "2"
}
]
}
]


class TestOptionOperation(unittest.TestCase):
def test_preview_order(self):
request = ReplaceOptionRequest()
request.set_endpoint(optional_api_endpoint)
request.set_account_id(account_id)
request.set_modify_orders(modify_orders)
post_body = request.get_body_params()
print(json.dumps(post_body, indent=4))
params = request.get_query_params()
print(params)

try:
response = api_client.get_response(request)
print(response.json())

except ServerException as se:
print(se.get_error_code(), ":", se.get_error_msg())
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2022 Webull
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import json
import unittest

from webullsdkcore.client import ApiClient
from webullsdkcore.exception.exceptions import ServerException
from webullsdktrade.request.v2.get_order_detail_request import OrderDetailRequest


optional_api_endpoint = "<api_endpoint>"
optional_api_region_id = "<api_region_id>"
your_app_key = "<your_app_key>"
your_app_secret = "<your_app_secret>"
account_id = "<your_account_id>"
api_client = ApiClient(your_app_key, your_app_secret)
api_client.add_endpoint(optional_api_region_id, optional_api_endpoint)

# Replace with the client_order_id to be queried.
client_order_id = "<your_client_order_id>"

class TestOrderOperation(unittest.TestCase):
def test_order_open(self):
request = OrderDetailRequest()
request.set_endpoint(optional_api_endpoint)
request.set_account_id(account_id)
request.set_client_order_id(client_order_id)
params = request.get_query_params()
print(params)
try:
response = api_client.get_response(request)
print(json.dumps(response.json(), indent=4))

except ServerException as se:
print(se.get_error_code(), ":", se.get_error_msg())
Loading

0 comments on commit 1cc418d

Please sign in to comment.