webull-openapi-python-sdk 2.0.4__py3-none-any.whl → 2.0.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- samples/__init__.py +1 -1
- samples/data/data_client.py +33 -1
- samples/screener/__init__.py +15 -0
- samples/screener/screener_client.py +118 -0
- samples/watchlist/__init__.py +13 -0
- samples/watchlist/watchlist_client.py +87 -0
- webull/__init__.py +1 -1
- webull/core/__init__.py +1 -1
- webull/core/utils/common.py +3 -1
- webull/data/__init__.py +1 -1
- webull/data/data_client.py +4 -0
- webull/data/quotes/instrument.py +77 -4
- webull/data/quotes/market_data.py +65 -3
- webull/data/quotes/screener.py +116 -0
- webull/data/quotes/watchlist.py +148 -0
- webull/data/request/get_analyst_rating_request.py +38 -0
- webull/data/request/get_analyst_target_price_request.py +38 -0
- webull/data/request/get_batch_historical_bars_request.py +19 -1
- webull/data/request/get_company_profile_request.py +38 -0
- webull/data/request/get_futures_instruments_request.py +6 -0
- webull/data/request/get_futures_product_class.py +24 -0
- webull/data/request/get_futures_products_request.py +3 -0
- webull/data/request/get_historical_bars_request.py +18 -0
- webull/data/request/get_noii_bars_request.py +55 -0
- webull/data/request/get_noii_snapshot_request.py +59 -0
- webull/data/request/screener/__init__.py +15 -0
- webull/data/request/screener/get_gainers_losers_request.py +109 -0
- webull/data/request/screener/get_most_active_request.py +110 -0
- webull/data/request/watchlist/__init__.py +13 -0
- webull/data/request/watchlist/add_watchlist_instruments_request.py +41 -0
- webull/data/request/watchlist/create_watchlist_request.py +39 -0
- webull/data/request/watchlist/delete_watchlist_request.py +30 -0
- webull/data/request/watchlist/get_watchlist_instruments_request.py +30 -0
- webull/data/request/watchlist/get_watchlist_request.py +22 -0
- webull/data/request/watchlist/remove_watchlist_instruments_request.py +40 -0
- webull/data/request/watchlist/update_watchlist_instruments_request.py +41 -0
- webull/data/request/watchlist/update_watchlist_request.py +48 -0
- webull/trade/__init__.py +1 -1
- {webull_openapi_python_sdk-2.0.4.dist-info → webull_openapi_python_sdk-2.0.6.dist-info}/METADATA +1 -1
- {webull_openapi_python_sdk-2.0.4.dist-info → webull_openapi_python_sdk-2.0.6.dist-info}/RECORD +44 -20
- {webull_openapi_python_sdk-2.0.4.dist-info → webull_openapi_python_sdk-2.0.6.dist-info}/WHEEL +0 -0
- {webull_openapi_python_sdk-2.0.4.dist-info → webull_openapi_python_sdk-2.0.6.dist-info}/licenses/LICENSE +0 -0
- {webull_openapi_python_sdk-2.0.4.dist-info → webull_openapi_python_sdk-2.0.6.dist-info}/licenses/NOTICE +0 -0
- {webull_openapi_python_sdk-2.0.4.dist-info → webull_openapi_python_sdk-2.0.6.dist-info}/top_level.txt +0 -0
samples/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.0.
|
|
1
|
+
__version__ = '2.0.6'
|
samples/data/data_client.py
CHANGED
|
@@ -112,4 +112,36 @@ if __name__ == '__main__':
|
|
|
112
112
|
|
|
113
113
|
res = data_client.instrument.get_futures_instrument_by_code("ES", Category.US_FUTURES.name, ContractType.MONTHLY.name)
|
|
114
114
|
if res.status_code == 200:
|
|
115
|
-
print('get_futures_instrument_by_code:', res.json())
|
|
115
|
+
print('get_futures_instrument_by_code:', res.json())
|
|
116
|
+
|
|
117
|
+
res = data_client.instrument.get_company_profile("AAPL", Category.US_STOCK.name)
|
|
118
|
+
if res.status_code == 200:
|
|
119
|
+
print('get_company_profile:', res.json())
|
|
120
|
+
|
|
121
|
+
res = data_client.instrument.get_analyst_target_price("AAPL", Category.US_STOCK.name)
|
|
122
|
+
if res.status_code == 200:
|
|
123
|
+
print('get_analyst_target_price:', res.json())
|
|
124
|
+
|
|
125
|
+
res = data_client.instrument.get_analyst_rating("AAPL", Category.US_STOCK.name)
|
|
126
|
+
if res.status_code == 200:
|
|
127
|
+
print('get_analyst_rating:', res.json())
|
|
128
|
+
|
|
129
|
+
# NOII (Net Order Imbalance Indicator) - Opening imbalance bars
|
|
130
|
+
res = data_client.market_data.get_noii_bars("AAPL", Category.US_STOCK.name, "PRE_OPEN")
|
|
131
|
+
if res.status_code == 200:
|
|
132
|
+
print('get_noii_bars (opening):', res.json())
|
|
133
|
+
|
|
134
|
+
# NOII - Closing imbalance bars
|
|
135
|
+
res = data_client.market_data.get_noii_bars("AAPL", Category.US_STOCK.name, "PRE_CLOSE")
|
|
136
|
+
if res.status_code == 200:
|
|
137
|
+
print('get_noii_bars (closing):', res.json())
|
|
138
|
+
|
|
139
|
+
# NOII Snapshot - Opening imbalance
|
|
140
|
+
res = data_client.market_data.get_noii_snapshot("AAPL", Category.US_STOCK.name, "PRE_OPEN")
|
|
141
|
+
if res.status_code == 200:
|
|
142
|
+
print('get_noii_snapshot (opening):', res.json())
|
|
143
|
+
|
|
144
|
+
# NOII Snapshot - Closing imbalance
|
|
145
|
+
res = data_client.market_data.get_noii_snapshot("AAPL", Category.US_STOCK.name, "PRE_CLOSE")
|
|
146
|
+
if res.status_code == 200:
|
|
147
|
+
print('get_noii_snapshot (closing):', res.json())
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Copyright 2022 Webull
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# coding=utf-8
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Copyright 2022 Webull
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# coding=utf-8
|
|
16
|
+
|
|
17
|
+
from webull.core.client import ApiClient
|
|
18
|
+
from webull.data.data_client import DataClient
|
|
19
|
+
|
|
20
|
+
optional_api_endpoint = "<api_endpoint>"
|
|
21
|
+
your_app_key = "<your_app_key>"
|
|
22
|
+
your_app_secret = "<your_app_secret>"
|
|
23
|
+
region_id = "<region_id>"
|
|
24
|
+
|
|
25
|
+
api_client = ApiClient(your_app_key, your_app_secret, region_id)
|
|
26
|
+
api_client.add_endpoint(region_id, optional_api_endpoint)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == '__main__':
|
|
30
|
+
data_client = DataClient(api_client)
|
|
31
|
+
|
|
32
|
+
# Get top gainers for today (stocks with highest price increase)
|
|
33
|
+
res = data_client.screener.get_gainers_losers(
|
|
34
|
+
rank_type="DAY_1",
|
|
35
|
+
category="US_STOCK",
|
|
36
|
+
sort_by="CHANGE_RATIO",
|
|
37
|
+
direction="DESC",
|
|
38
|
+
page_size=10
|
|
39
|
+
)
|
|
40
|
+
if res.status_code == 200:
|
|
41
|
+
print('get_gainers (day):', res.json())
|
|
42
|
+
|
|
43
|
+
# Get top losers for today (stocks with highest price decrease)
|
|
44
|
+
res = data_client.screener.get_gainers_losers(
|
|
45
|
+
rank_type="DAY_1",
|
|
46
|
+
category="US_STOCK",
|
|
47
|
+
sort_by="CHANGE_RATIO",
|
|
48
|
+
direction="ASC",
|
|
49
|
+
page_size=10
|
|
50
|
+
)
|
|
51
|
+
if res.status_code == 200:
|
|
52
|
+
print('get_losers (day):', res.json())
|
|
53
|
+
|
|
54
|
+
# Get pre-market movers
|
|
55
|
+
res = data_client.screener.get_gainers_losers(
|
|
56
|
+
rank_type="PRE_MARKET",
|
|
57
|
+
category="US_STOCK",
|
|
58
|
+
sort_by="CHANGE_RATIO",
|
|
59
|
+
direction="DESC",
|
|
60
|
+
page_size=20
|
|
61
|
+
)
|
|
62
|
+
if res.status_code == 200:
|
|
63
|
+
print('get_pre_market_movers:', res.json())
|
|
64
|
+
|
|
65
|
+
# Get 52-week top performers
|
|
66
|
+
res = data_client.screener.get_gainers_losers(
|
|
67
|
+
rank_type="WEEK_52",
|
|
68
|
+
category="US_STOCK",
|
|
69
|
+
sort_by="CHANGE_RATIO",
|
|
70
|
+
direction="DESC",
|
|
71
|
+
page_size=10
|
|
72
|
+
)
|
|
73
|
+
if res.status_code == 200:
|
|
74
|
+
print('get_52_week_top_performers:', res.json())
|
|
75
|
+
|
|
76
|
+
# Get most active stocks by volume
|
|
77
|
+
res = data_client.screener.get_most_active(
|
|
78
|
+
category="US_STOCK",
|
|
79
|
+
rank_type="VOLUME",
|
|
80
|
+
sort_by="VOLUME",
|
|
81
|
+
direction="DESC",
|
|
82
|
+
page_size=10
|
|
83
|
+
)
|
|
84
|
+
if res.status_code == 200:
|
|
85
|
+
print('get_most_active_by_volume:', res.json())
|
|
86
|
+
|
|
87
|
+
# Get stocks with unusual trading activity (high relative volume)
|
|
88
|
+
res = data_client.screener.get_most_active(
|
|
89
|
+
category="US_STOCK",
|
|
90
|
+
rank_type="RELATIVE_VOLUME_10D",
|
|
91
|
+
sort_by="RELATIVE_VOLUME_10D",
|
|
92
|
+
direction="DESC",
|
|
93
|
+
page_size=10
|
|
94
|
+
)
|
|
95
|
+
if res.status_code == 200:
|
|
96
|
+
print('get_unusual_volume_activity:', res.json())
|
|
97
|
+
|
|
98
|
+
# Get most active stocks by turnover amount
|
|
99
|
+
res = data_client.screener.get_most_active(
|
|
100
|
+
category="US_STOCK",
|
|
101
|
+
rank_type="TURNOVER",
|
|
102
|
+
sort_by="TURNOVER",
|
|
103
|
+
direction="DESC",
|
|
104
|
+
page_size=10
|
|
105
|
+
)
|
|
106
|
+
if res.status_code == 200:
|
|
107
|
+
print('get_most_active_by_turnover:', res.json())
|
|
108
|
+
|
|
109
|
+
# Get stocks with high price amplitude
|
|
110
|
+
res = data_client.screener.get_most_active(
|
|
111
|
+
category="US_STOCK",
|
|
112
|
+
rank_type="AMPLITUDE",
|
|
113
|
+
sort_by="AMPLITUDE",
|
|
114
|
+
direction="DESC",
|
|
115
|
+
page_size=10
|
|
116
|
+
)
|
|
117
|
+
if res.status_code == 200:
|
|
118
|
+
print('get_high_amplitude_stocks:', res.json())
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Copyright 2022 Webull
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Copyright 2022 Webull
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
# coding=utf-8
|
|
16
|
+
|
|
17
|
+
from webull.core.client import ApiClient
|
|
18
|
+
from webull.data.data_client import DataClient
|
|
19
|
+
|
|
20
|
+
optional_api_endpoint = "<api_endpoint>"
|
|
21
|
+
your_app_key = "<your_app_key>"
|
|
22
|
+
your_app_secret = "<your_app_secret>"
|
|
23
|
+
region_id = "<region_id>"
|
|
24
|
+
|
|
25
|
+
api_client = ApiClient(your_app_key, your_app_secret, region_id)
|
|
26
|
+
api_client.add_endpoint(region_id, optional_api_endpoint)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
if __name__ == '__main__':
|
|
30
|
+
data_client = DataClient(api_client)
|
|
31
|
+
|
|
32
|
+
# Get all watchlists
|
|
33
|
+
res = data_client.watchlist.get_watchlist()
|
|
34
|
+
if res.status_code == 200:
|
|
35
|
+
print('get_watchlist:', res.json())
|
|
36
|
+
|
|
37
|
+
# Create a new watchlist (max 20 watchlists, shared with retail)
|
|
38
|
+
res = data_client.watchlist.create_watchlist(name="Tech Stocks", sort=1)
|
|
39
|
+
if res.status_code == 200:
|
|
40
|
+
print('create_watchlist:', res.json())
|
|
41
|
+
watchlist_id = res.json().get("watchlist_id")
|
|
42
|
+
|
|
43
|
+
# Update the watchlist
|
|
44
|
+
res = data_client.watchlist.update_watchlist(
|
|
45
|
+
watchlist_id=watchlist_id,
|
|
46
|
+
name="My Favorites",
|
|
47
|
+
sort=2
|
|
48
|
+
)
|
|
49
|
+
if res.status_code == 200:
|
|
50
|
+
print('update_watchlist:', res.json())
|
|
51
|
+
|
|
52
|
+
# Add instruments to the watchlist (max 1000 instruments total)
|
|
53
|
+
instruments = [
|
|
54
|
+
{"symbol": "AAPL", "category": "US_STOCK", "sort": 1},
|
|
55
|
+
{"symbol": "TSLA", "category": "US_STOCK", "sort": 2}
|
|
56
|
+
]
|
|
57
|
+
res = data_client.watchlist.add_instruments(watchlist_id, instruments)
|
|
58
|
+
if res.status_code == 200:
|
|
59
|
+
print('add_instruments:', res.json())
|
|
60
|
+
|
|
61
|
+
# Get instruments in the watchlist
|
|
62
|
+
res = data_client.watchlist.get_instruments(watchlist_id)
|
|
63
|
+
if res.status_code == 200:
|
|
64
|
+
print('get_instruments:', res.json())
|
|
65
|
+
|
|
66
|
+
# Update instruments sort order
|
|
67
|
+
instruments = [
|
|
68
|
+
{"symbol": "AAPL", "category": "US_STOCK", "sort": 3},
|
|
69
|
+
{"symbol": "TSLA", "category": "US_STOCK", "sort": 1}
|
|
70
|
+
]
|
|
71
|
+
res = data_client.watchlist.update_instruments(watchlist_id, instruments)
|
|
72
|
+
if res.status_code == 200:
|
|
73
|
+
print('update_instruments:', res.json())
|
|
74
|
+
|
|
75
|
+
# Remove instruments from the watchlist
|
|
76
|
+
instruments = [
|
|
77
|
+
{"symbol": "AAPL", "category": "US_STOCK"},
|
|
78
|
+
{"symbol": "TSLA", "category": "US_STOCK"}
|
|
79
|
+
]
|
|
80
|
+
res = data_client.watchlist.remove_instruments(watchlist_id, instruments)
|
|
81
|
+
if res.status_code == 200:
|
|
82
|
+
print('remove_instruments:', res.json())
|
|
83
|
+
|
|
84
|
+
# Delete the watchlist (irreversible)
|
|
85
|
+
res = data_client.watchlist.delete_watchlist(watchlist_id)
|
|
86
|
+
if res.status_code == 200:
|
|
87
|
+
print('delete_watchlist:', res.json())
|
webull/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = '2.0.
|
|
1
|
+
__version__ = '2.0.6'
|
webull/core/__init__.py
CHANGED
webull/core/utils/common.py
CHANGED
|
@@ -72,6 +72,8 @@ def is_not_upgrade_api_host(host):
|
|
|
72
72
|
"pre-openapi-us-alb.webullbroker.com","pre-openapi-us-events.webullbroker.com",
|
|
73
73
|
"pre-openapi-alb.webullbroker.com","pre-openapi-events.webullbroker.com",
|
|
74
74
|
"us-openapi-alb.uat.webullbroker.com","us-openapi-events.uat.webullbroker.com",
|
|
75
|
-
"hk-openapi.uat.webullbroker.com", "hk-openapi-events-api.uat.webullbroker.com"
|
|
75
|
+
"hk-openapi.uat.webullbroker.com", "hk-openapi-events-api.uat.webullbroker.com",
|
|
76
|
+
"api.sandbox.webull.hk", "events-api.sandbox.webull.hk"
|
|
77
|
+
|
|
76
78
|
}
|
|
77
79
|
return host not in upgrade_hosts
|
webull/data/__init__.py
CHANGED
webull/data/data_client.py
CHANGED
|
@@ -23,6 +23,8 @@ from webull.data.quotes.event_market_data import EventMarketData
|
|
|
23
23
|
from webull.data.quotes.futures_market_data import FuturesMarketData
|
|
24
24
|
from webull.data.quotes.instrument import Instrument
|
|
25
25
|
from webull.data.quotes.market_data import MarketData
|
|
26
|
+
from webull.data.quotes.screener import Screener
|
|
27
|
+
from webull.data.quotes.watchlist import Watchlist
|
|
26
28
|
|
|
27
29
|
|
|
28
30
|
class DataClient:
|
|
@@ -34,6 +36,8 @@ class DataClient:
|
|
|
34
36
|
self.crypto_market_data = CryptoMarketData(api_client)
|
|
35
37
|
self.futures_market_data = FuturesMarketData(api_client)
|
|
36
38
|
self.event_market_data = EventMarketData(api_client)
|
|
39
|
+
self.screener = Screener(api_client)
|
|
40
|
+
self.watchlist = Watchlist(api_client)
|
|
37
41
|
|
|
38
42
|
def _init_logger(self, api_client):
|
|
39
43
|
# No logger configured, using default console and local file logging.
|
webull/data/quotes/instrument.py
CHANGED
|
@@ -12,6 +12,9 @@
|
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
14
|
from webull.data.common.category import Category
|
|
15
|
+
from webull.data.request.get_analyst_rating_request import GetAnalystRatingRequest
|
|
16
|
+
from webull.data.request.get_analyst_target_price_request import GetAnalystTargetPriceRequest
|
|
17
|
+
from webull.data.request.get_company_profile_request import GetCompanyProfileRequest
|
|
15
18
|
from webull.data.request.get_event_events_request import GetEventEventsRequest
|
|
16
19
|
from webull.data.request.get_event_instrument_request import GetEventInstrumentRequest
|
|
17
20
|
from webull.data.request.get_event_series_categories import GetEventCategoriesRequest
|
|
@@ -21,6 +24,7 @@ from webull.data.request.get_crypto_instruments_request import GetCryptoInstrume
|
|
|
21
24
|
from webull.data.request.get_futures_instruments_request import GetFuturesInstrumentsRequest
|
|
22
25
|
from webull.data.request.get_futures_products_request import GetFuturesProductsRequest
|
|
23
26
|
from webull.data.request.get_futures_instruments_by_code_request import GetFuturesInstrumentsByCodeRequest
|
|
27
|
+
from webull.data.request.get_futures_product_class import GetFuturesProductClassRequest
|
|
24
28
|
|
|
25
29
|
|
|
26
30
|
class Instrument:
|
|
@@ -68,32 +72,45 @@ class Instrument:
|
|
|
68
72
|
response = self.client.get_response(crypto_instruments_request)
|
|
69
73
|
return response
|
|
70
74
|
|
|
71
|
-
def get_futures_instrument(self, symbols, category):
|
|
75
|
+
def get_futures_instrument(self, symbols=None, category=Category.US_STOCK.name, code=None, status=None):
|
|
72
76
|
"""
|
|
73
77
|
Query the futures instrument information based on the futures contract symbol.
|
|
74
78
|
|
|
75
|
-
:param symbols: Futures contract symbol, such as: ESmain,ESM5.
|
|
76
79
|
:param category: Security type, enumeration.
|
|
80
|
+
:param symbols: Futures contract symbol, such as: ESmain,ESM5.
|
|
81
|
+
:param code: Futures contract code, such as: ES.
|
|
82
|
+
:param status: Tradable status.
|
|
77
83
|
"""
|
|
78
84
|
|
|
79
85
|
futures_instrument_request = GetFuturesInstrumentsRequest()
|
|
80
|
-
futures_instrument_request.set_symbols(symbols)
|
|
81
86
|
futures_instrument_request.set_category(category)
|
|
87
|
+
if symbols:
|
|
88
|
+
futures_instrument_request.set_symbols(symbols)
|
|
89
|
+
if code:
|
|
90
|
+
futures_instrument_request.set_code(code)
|
|
91
|
+
if status:
|
|
92
|
+
futures_instrument_request.set_status(status)
|
|
82
93
|
response = self.client.get_response(futures_instrument_request)
|
|
83
94
|
return response
|
|
84
95
|
|
|
85
|
-
def get_futures_products(self, category):
|
|
96
|
+
def get_futures_products(self, category, product_class_id=None):
|
|
86
97
|
"""
|
|
87
98
|
Query futures contract codes in batches based on security types.
|
|
88
99
|
|
|
89
100
|
:param category: Security type, enumeration.
|
|
101
|
+
:param product_class_id: Asset classification code, used to filter products of specific categories
|
|
90
102
|
"""
|
|
91
103
|
|
|
92
104
|
batch_futures_products_request = GetFuturesProductsRequest()
|
|
93
105
|
batch_futures_products_request.set_category(category)
|
|
106
|
+
if product_class_id:
|
|
107
|
+
batch_futures_products_request.set_product_class_id(product_class_id)
|
|
94
108
|
response = self.client.get_response(batch_futures_products_request)
|
|
95
109
|
return response
|
|
96
110
|
|
|
111
|
+
"""
|
|
112
|
+
Deprecated: This endpoint is deprecated, please use the get_futures_instrument endpoint
|
|
113
|
+
"""
|
|
97
114
|
def get_futures_instrument_by_code(self, code, category, contract_type=None):
|
|
98
115
|
"""
|
|
99
116
|
Query futures instrument information based on futures contract code.
|
|
@@ -113,6 +130,18 @@ class Instrument:
|
|
|
113
130
|
response = self.client.get_response(futures_instrument_request)
|
|
114
131
|
return response
|
|
115
132
|
|
|
133
|
+
def get_futures_product_class(self, category):
|
|
134
|
+
"""
|
|
135
|
+
Query futures product classes based on security types.
|
|
136
|
+
|
|
137
|
+
:param category: Security type, enumeration.
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
futures_product_class_request = GetFuturesProductClassRequest()
|
|
141
|
+
futures_product_class_request.set_category(category)
|
|
142
|
+
response = self.client.get_response(futures_product_class_request)
|
|
143
|
+
return response
|
|
144
|
+
|
|
116
145
|
def get_event_categories(self):
|
|
117
146
|
"""
|
|
118
147
|
Query event contract categories
|
|
@@ -187,4 +216,48 @@ class Instrument:
|
|
|
187
216
|
event_instrument_request.set_last_instrument_id(last_instrument_id)
|
|
188
217
|
event_instrument_request.set_page_size(page_size)
|
|
189
218
|
response = self.client.get_response(event_instrument_request)
|
|
219
|
+
return response
|
|
220
|
+
|
|
221
|
+
def get_company_profile(self, symbol, category=Category.US_STOCK.name):
|
|
222
|
+
"""
|
|
223
|
+
Get company profile for one instrument.
|
|
224
|
+
|
|
225
|
+
:param symbol: Security symbol, e.g., AAPL
|
|
226
|
+
:param category: Security type. Possible values: US_STOCK. Default is US_STOCK.
|
|
227
|
+
:return: Company profile including company name, establish date, CEO, employees,
|
|
228
|
+
address, profile description, industries, etc.
|
|
229
|
+
"""
|
|
230
|
+
request = GetCompanyProfileRequest()
|
|
231
|
+
request.set_symbol(symbol)
|
|
232
|
+
request.set_category(category)
|
|
233
|
+
response = self.client.get_response(request)
|
|
234
|
+
return response
|
|
235
|
+
|
|
236
|
+
def get_analyst_target_price(self, symbol, category=Category.US_STOCK.name):
|
|
237
|
+
"""
|
|
238
|
+
Get analyst target price for one instrument.
|
|
239
|
+
|
|
240
|
+
:param symbol: Security symbol, e.g., AAPL
|
|
241
|
+
:param category: Security type. Possible values: US_STOCK. Default is US_STOCK.
|
|
242
|
+
:return: Analyst target price including mean, low, high, median price and currency.
|
|
243
|
+
"""
|
|
244
|
+
request = GetAnalystTargetPriceRequest()
|
|
245
|
+
request.set_symbol(symbol)
|
|
246
|
+
request.set_category(category)
|
|
247
|
+
response = self.client.get_response(request)
|
|
248
|
+
return response
|
|
249
|
+
|
|
250
|
+
def get_analyst_rating(self, symbol, category=Category.US_STOCK.name):
|
|
251
|
+
"""
|
|
252
|
+
Get analyst rating for one instrument.
|
|
253
|
+
|
|
254
|
+
:param symbol: Security symbol, e.g., AAPL
|
|
255
|
+
:param category: Security type. Possible values: US_STOCK. Default is US_STOCK.
|
|
256
|
+
:return: Analyst rating including total number of analysts, buy/sell/hold counts,
|
|
257
|
+
strong buy count, under perform count, etc.
|
|
258
|
+
"""
|
|
259
|
+
request = GetAnalystRatingRequest()
|
|
260
|
+
request.set_symbol(symbol)
|
|
261
|
+
request.set_category(category)
|
|
262
|
+
response = self.client.get_response(request)
|
|
190
263
|
return response
|
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
from webull.data.common.category import Category
|
|
15
14
|
from webull.data.request.get_batch_historical_bars_request import BatchHistoricalBarsRequest
|
|
16
15
|
from webull.data.request.get_corp_action_request import GetCorpActionRequest
|
|
17
16
|
from webull.data.request.get_eod_bars_request import GetEodBarsRequest
|
|
18
17
|
from webull.data.request.get_footprint_request import GetFootprintRequest
|
|
19
18
|
from webull.data.request.get_historical_bars_request import GetHistoricalBarsRequest
|
|
19
|
+
from webull.data.request.get_noii_bars_request import GetNoiiBarsRequest
|
|
20
|
+
from webull.data.request.get_noii_snapshot_request import GetNoiiSnapshotRequest
|
|
20
21
|
from webull.data.request.get_quotes_request import GetQuotesRequest
|
|
21
22
|
from webull.data.request.get_snapshot_request import GetSnapshotRequest
|
|
22
23
|
from webull.data.request.get_tick_request import GetTickRequest
|
|
@@ -26,7 +27,7 @@ class MarketData:
|
|
|
26
27
|
def __init__(self, api_client):
|
|
27
28
|
self.client = api_client
|
|
28
29
|
|
|
29
|
-
def get_history_bar(self, symbol, category, timespan, count='200', real_time_required=None, trading_sessions=None):
|
|
30
|
+
def get_history_bar(self, symbol, category, timespan, count='200', real_time_required=None, trading_sessions=None, start_time=None, end_time=None):
|
|
30
31
|
"""
|
|
31
32
|
Returns to Instrument in the window aggregated data.
|
|
32
33
|
According to the last N K-lines of the stock code, it supports various granularity K-lines such as m1 and m5.
|
|
@@ -40,6 +41,8 @@ class MarketData:
|
|
|
40
41
|
:param real_time_required: Returns the latest trade quote data. By default, the most recent market data is returned.
|
|
41
42
|
:param trading_sessions: Specify trading session, multiple selections are allowed
|
|
42
43
|
By default, only intraday candlestick data is returned.
|
|
44
|
+
:param start_time: Start timestamp in milliseconds (Long). Optional.
|
|
45
|
+
:param end_time: End timestamp in milliseconds (Long). Delayed permission will auto-offset time. Optional.
|
|
43
46
|
"""
|
|
44
47
|
history_bar_request = GetHistoricalBarsRequest()
|
|
45
48
|
history_bar_request.set_symbol(symbol)
|
|
@@ -48,10 +51,12 @@ class MarketData:
|
|
|
48
51
|
history_bar_request.set_count(count)
|
|
49
52
|
history_bar_request.set_real_time_required(real_time_required)
|
|
50
53
|
history_bar_request.set_trading_sessions(trading_sessions)
|
|
54
|
+
history_bar_request.set_start_time(start_time)
|
|
55
|
+
history_bar_request.set_end_time(end_time)
|
|
51
56
|
response = self.client.get_response(history_bar_request)
|
|
52
57
|
return response
|
|
53
58
|
|
|
54
|
-
def get_batch_history_bar(self, symbols, category, timespan, count='200', real_time_required=None, trading_sessions=None):
|
|
59
|
+
def get_batch_history_bar(self, symbols, category, timespan, count='200', real_time_required=None, trading_sessions=None, start_time=None, end_time=None):
|
|
55
60
|
"""
|
|
56
61
|
Batch query K-line data for multiple symbols, returning aggregated data within the window.
|
|
57
62
|
According to the last N K-lines of the stock code, it supports various granularity K-lines such as m1 and m5.
|
|
@@ -65,6 +70,8 @@ class MarketData:
|
|
|
65
70
|
:param real_time_required: Returns the latest trade quote data. By default, the most recent market data is returned.
|
|
66
71
|
:param trading_sessions: Specify trading session, multiple selections are allowed
|
|
67
72
|
By default, only intraday candlestick data is returned.
|
|
73
|
+
:param start_time: Start timestamp in milliseconds (Long). Optional.
|
|
74
|
+
:param end_time: End timestamp in milliseconds (Long). Delayed permission will auto-offset time. Optional.
|
|
68
75
|
"""
|
|
69
76
|
history_bar_request = BatchHistoricalBarsRequest()
|
|
70
77
|
history_bar_request.set_symbols(symbols)
|
|
@@ -73,6 +80,8 @@ class MarketData:
|
|
|
73
80
|
history_bar_request.set_count(count)
|
|
74
81
|
history_bar_request.set_real_time_required(real_time_required)
|
|
75
82
|
history_bar_request.set_trading_sessions(trading_sessions)
|
|
83
|
+
history_bar_request.set_start_time(start_time)
|
|
84
|
+
history_bar_request.set_end_time(end_time)
|
|
76
85
|
response = self.client.get_response(history_bar_request)
|
|
77
86
|
return response
|
|
78
87
|
|
|
@@ -207,3 +216,56 @@ class MarketData:
|
|
|
207
216
|
footprint_request.set_trading_sessions(trading_sessions)
|
|
208
217
|
response = self.client.get_response(footprint_request)
|
|
209
218
|
return response
|
|
219
|
+
|
|
220
|
+
def get_noii_bars(self, symbol, category, imbalance_action_type):
|
|
221
|
+
"""
|
|
222
|
+
Query NOII (Net Order Imbalance Indicator) K-line data for a stock.
|
|
223
|
+
|
|
224
|
+
NOII data provides insight into market supply and demand during NASDAQ
|
|
225
|
+
opening and closing auctions, acting as a leading indicator for potential
|
|
226
|
+
price movements at key trading moments.
|
|
227
|
+
|
|
228
|
+
:param symbol: Security symbol, e.g., AAPL. Only single symbol query is supported.
|
|
229
|
+
:param category: Security category. Currently only US_STOCK is supported.
|
|
230
|
+
:param imbalance_action_type: Imbalance action type.
|
|
231
|
+
- PRE_OPEN: Opening imbalance
|
|
232
|
+
- PRE_CLOSE: Closing imbalance
|
|
233
|
+
:return: Response containing a list of NOII bar data with:
|
|
234
|
+
instrument_id, symbol, imbalance_time, imbalance_ref_price,
|
|
235
|
+
imbalance_near_price, imbalance_far_price, imbalance_action_type.
|
|
236
|
+
"""
|
|
237
|
+
request = GetNoiiBarsRequest()
|
|
238
|
+
request.set_symbol(symbol)
|
|
239
|
+
request.set_category(category)
|
|
240
|
+
request.set_imbalance_action_type(imbalance_action_type)
|
|
241
|
+
response = self.client.get_response(request)
|
|
242
|
+
return response
|
|
243
|
+
|
|
244
|
+
def get_noii_snapshot(self, symbol, category, imbalance_action_type):
|
|
245
|
+
"""
|
|
246
|
+
Query the latest NOII (Net Order Imbalance Indicator) snapshot for a stock.
|
|
247
|
+
|
|
248
|
+
Provides real-time NOII snapshot during US stock call auction phases to
|
|
249
|
+
determine market supply-demand relationship and expected match price.
|
|
250
|
+
|
|
251
|
+
NOII data is published only during call auction periods, updating every 5 seconds:
|
|
252
|
+
- Opening auction: 9:28 - 9:30 AM ET (2 minutes)
|
|
253
|
+
- Closing auction: 3:50 - 4:00 PM ET (10 minutes)
|
|
254
|
+
Outside these periods, historical data is returned.
|
|
255
|
+
|
|
256
|
+
:param symbol: Security symbol, e.g., AAPL. Only single symbol query is supported.
|
|
257
|
+
:param category: Security category. Currently only US_STOCK is supported.
|
|
258
|
+
:param imbalance_action_type: Imbalance action type.
|
|
259
|
+
- PRE_OPEN: Opening imbalance
|
|
260
|
+
- PRE_CLOSE: Closing imbalance
|
|
261
|
+
:return: Response containing NOII snapshot data with:
|
|
262
|
+
instrument_id, symbol, paired_shares, imbalance_shares, imbalance_side,
|
|
263
|
+
imbalance_ref_price, imbalance_near_price, imbalance_far_price,
|
|
264
|
+
imbalance_act_tp, imbalance_time, imbalance_var_indicator.
|
|
265
|
+
"""
|
|
266
|
+
request = GetNoiiSnapshotRequest()
|
|
267
|
+
request.set_symbol(symbol)
|
|
268
|
+
request.set_category(category)
|
|
269
|
+
request.set_imbalance_action_type(imbalance_action_type)
|
|
270
|
+
response = self.client.get_response(request)
|
|
271
|
+
return response
|