Skip to content

Commit 538c321

Browse files
author
方佳
committed
Merge branch 'main_260314_merge' into 'main'
feat: Support GTD ordering, add market interface to event contracts See merge request webull/webull-openapi-python-sdk!17
2 parents 27d399d + d62865a commit 538c321

13 files changed

Lines changed: 255 additions & 15 deletions

‎samples/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '2.0.0'
1+
__version__ = '2.0.1'

‎samples/data/data_client_event.py‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
from webull.data.common.timespan import Timespan
1415

1516
# coding=utf-8
1617

@@ -35,11 +36,19 @@
3536
if __name__ == '__main__':
3637
data_client = DataClient(api_client)
3738

39+
res = data_client.instrument.get_event_categories()
40+
if res.status_code == 200:
41+
print('get_event_categories:', res.json())
42+
3843
res = data_client.instrument.get_event_series("ECONOMICS")
3944
if res.status_code == 200:
4045
print('get_event_series:', res.json())
4146

42-
res = data_client.instrument.get_event_instrument("KXGDP")
47+
res = data_client.instrument.get_event_events("KXRATECUTCOUNT")
48+
if res.status_code == 200:
49+
print('get_event_events:', res.json())
50+
51+
res = data_client.instrument.get_event_instrument("KXRATECUTCOUNT")
4352
if res.status_code == 200:
4453
print('get_event_instrument:', res.json())
4554

@@ -49,4 +58,12 @@
4958

5059
res = data_client.event_market_data.get_event_depth("KXRATECUTCOUNT-25DEC31-T10", Category.US_EVENT.name)
5160
if res.status_code == 200:
52-
print('get_event_depth:', res.json())
61+
print('get_event_depth:', res.json())
62+
63+
res = data_client.event_market_data.get_event_bars("KXRATECUTCOUNT-25DEC31-T10", Timespan.M1, Category.US_EVENT.name, 200, False)
64+
if res.status_code == 200:
65+
print('get_event_bars:', res.json())
66+
67+
res = data_client.event_market_data.get_event_tick("KXRATECUTCOUNT-25DEC31-T10", Category.US_EVENT.name, 30)
68+
if res.status_code == 200:
69+
print('get_event_tick:', res.json())

‎webull/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '2.0.0'
1+
__version__ = '2.0.1'

‎webull/core/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__ = '2.0.0'
1+
__version__ = '2.0.1'
22

33
import logging
44

‎webull/data/__init__.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# coding=utf-8
22

3-
__version__ = '2.0.0'
3+
__version__ = '2.0.1'

‎webull/data/quotes/event_market_data.py‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
from webull.data.common.category import Category
15+
from webull.data.request.get_event_bars_request import GetEventBarsRequest
1516
from webull.data.request.get_event_depth_request import GetEventDepthRequest
1617
from webull.data.request.get_event_snapshot_request import GetEventSnapshotRequest
18+
from webull.data.request.get_event_tick_request import GetEventTickRequest
19+
1720

1821
class EventMarketData:
1922
def __init__(self, api_client):
@@ -47,4 +50,43 @@ def get_event_depth(self, symbol, category=Category.US_EVENT.name, depth=10):
4750
quote_request.set_category(category)
4851
quote_request.set_depth(depth)
4952
response = self.client.get_response(quote_request)
53+
return response
54+
55+
def get_event_bars(self, symbols, timespan, category=Category.US_EVENT.name, count=200, real_time_required=False):
56+
"""
57+
Get the current order book for a specific event instrument.
58+
The order book shows all active bid orders for both yes and no sides of a binary market.
59+
It returns yes bids and no bids only (no asks are returned). Price unit is based on usd_cent.
60+
61+
:param symbols: Symbol of the event market, supports JSON array format, multiple symbols separated by commas; maximum 100 symbols per query.
62+
:param timespan:K-line time granularity.
63+
:param category: default is US_EVENT, currently only US_EVENT is supported.
64+
:param count: Number of entries, default 200 entries, maximum 1200 entries.
65+
:param real_time_required: Does it include the latest data? The k-line that has not been finalized is not included by default. It is false and only used for minutes.
66+
"""
67+
quote_request = GetEventBarsRequest()
68+
quote_request.set_symbols(symbols)
69+
quote_request.set_category(category)
70+
quote_request.set_timespan(timespan)
71+
quote_request.set_count(count)
72+
quote_request.set_real_time_required(real_time_required)
73+
response = self.client.get_response(quote_request)
74+
return response
75+
76+
77+
def get_event_tick(self, symbol, category=Category.US_EVENT.name, count=30):
78+
"""
79+
Detailed transaction records, including transaction time, price, quantity,
80+
and transaction direction. Data is sorted in reverse chronological order,
81+
with the most recent transaction record first.
82+
83+
:param symbol:Symbol of the event market.
84+
:param category: default is US_EVENT, currently only US_EVENT is supported.
85+
:param count: Number of entries, default 30 entries, maximum 1200 entries.
86+
"""
87+
quote_request = GetEventTickRequest()
88+
quote_request.set_symbol(symbol)
89+
quote_request.set_category(category)
90+
quote_request.set_count(count)
91+
response = self.client.get_response(quote_request)
5092
return response

‎webull/data/quotes/instrument.py‎

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414
from webull.data.common.category import Category
15+
from webull.data.request.get_event_events_request import GetEventEventsRequest
1516
from webull.data.request.get_event_instrument_request import GetEventInstrumentRequest
17+
from webull.data.request.get_event_series_categories import GetEventCategoriesRequest
1618
from webull.data.request.get_event_series_request import GetEventSeriesRequest
1719
from webull.data.request.get_instruments_request import GetInstrumentsRequest
1820
from webull.data.request.get_crypto_instruments_request import GetCryptoInstrumentsRequest
@@ -111,7 +113,15 @@ def get_futures_instrument_by_code(self, code, category, contract_type=None):
111113
response = self.client.get_response(futures_instrument_request)
112114
return response
113115

114-
def get_event_series(self, category, last_instrument_id=None, page_size=500):
116+
def get_event_categories(self):
117+
"""
118+
Query event contract categories
119+
"""
120+
event_categories_request = GetEventCategoriesRequest()
121+
response = self.client.get_response(event_categories_request)
122+
return response
123+
124+
def get_event_series(self, category=None, symbols=None, last_series_id=None, page_size=500):
115125
"""
116126
Retrieve multiple series with specified filters.
117127
A series represents a template for recurring events that follow the same format and rules (e.g., “Monthly Jobs Report” ).
@@ -120,30 +130,57 @@ def get_event_series(self, category, last_instrument_id=None, page_size=500):
120130
:param category: The category which this series belongs to.Allowed values:
121131
ECONOMICS, FINANCIALS, POLITICS, ENTERTAINMENT, SCIENCE_TECHNOLOGY,
122132
CLIMATE_WEATHER, TRANSPORTATION, CRYPTO, SPORTS
123-
:param last_instrument_id: Last series id for pagination.
133+
:param symbols: Symbol of the event series, supports JSON array format, multiple symbols separated by commas; maximum 100 symbols per query.
134+
:param last_series_id: Last series id for pagination.
124135
:param page_size: Page size, default 500.
125136
"""
126137

127138
event_series_request = GetEventSeriesRequest()
128-
event_series_request.set_category(category)
129-
if last_instrument_id:
130-
event_series_request.set_last_instrument_id(last_instrument_id)
139+
if category:
140+
event_series_request.set_category(category)
141+
if symbols:
142+
event_series_request.set_symbols(symbols)
143+
if last_series_id:
144+
event_series_request.set_last_series_id(last_series_id)
131145
event_series_request.set_page_size(page_size)
132146
response = self.client.get_response(event_series_request)
133147
return response
134148

135-
def get_event_instrument(self, series_symbol, expiration_date_after=None, last_instrument_id=None, page_size=500):
149+
def get_event_events(self, series_symbol, symbols=None, status=None):
150+
"""
151+
Query event contract events
152+
153+
:param series_symbol: Series Symbol that identifies this series.
154+
:param symbols: Symbol of the event events, supports JSON array format, multiple symbols separated by commas; maximum 100 symbols per query.
155+
:param status: Event status (optional, defaults to querying tradable/valid events).
156+
"""
157+
event_events_request = GetEventEventsRequest()
158+
event_events_request.set_series_symbol(series_symbol)
159+
if symbols:
160+
event_events_request.set_symbols(symbols)
161+
if status:
162+
event_events_request.set_status(status)
163+
response = self.client.get_response(event_events_request)
164+
return response
165+
166+
def get_event_instrument(self, series_symbol, event_symbol=None, symbols=None, expiration_date_after=None, last_instrument_id=None, page_size=500):
136167
"""
137168
Retrieve profile information for event contract markets based on the series symbol.
138169
139170
:param series_symbol: Symbol that identifies this series.
171+
:param event_symbol: Symbol of the event events.
172+
:param symbols: Symbol of the event market, supports JSON array format, multiple symbols separated by commas; maximum 100 symbols per query.
140173
:param expiration_date_after: Used to filter items whose expiration date is later than a specified date; the default selection is the current day (inclusive).
141-
:param last_instrument_id: Last series id for pagination.
174+
:param last_instrument_id: Last instrument id for pagination.
142175
:param page_size: Page size, default 500.
143176
"""
144177

145178
event_instrument_request = GetEventInstrumentRequest()
146179
event_instrument_request.set_series_symbol(series_symbol)
180+
if event_symbol:
181+
event_instrument_request.set_event_symbol(event_symbol)
182+
if symbols:
183+
event_instrument_request.set_symbols(symbols)
147184
if expiration_date_after:
148185
event_instrument_request.set_expiration_date_after(expiration_date_after)
149186
if last_instrument_id:
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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.request import ApiRequest
18+
19+
20+
class GetEventBarsRequest(ApiRequest):
21+
def __init__(self):
22+
ApiRequest.__init__(self, "/openapi/market-data/event/bars", version='v2', method="GET", query_params={})
23+
24+
def set_symbols(self, symbols):
25+
if isinstance(symbols, str):
26+
self.add_query_param("symbols", symbols)
27+
elif isinstance(symbols, list):
28+
self.add_query_param("symbols", ",".join(symbols))
29+
30+
def set_category(self, category):
31+
self.add_query_param("category", category)
32+
33+
def set_timespan(self, timespan):
34+
if timespan:
35+
self.add_query_param("timespan", timespan)
36+
37+
def set_count(self, count):
38+
if count:
39+
self.add_query_param("count", count)
40+
41+
def set_real_time_required(self, real_time_required):
42+
if real_time_required:
43+
self.add_query_param("real_time_required", real_time_required)
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
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.request import ApiRequest
18+
19+
class GetEventEventsRequest(ApiRequest):
20+
def __init__(self):
21+
ApiRequest.__init__(self, "/openapi/instrument/event/events", version='v2', method="GET", query_params={})
22+
23+
def set_series_symbol(self, series_symbol):
24+
self.add_query_param("series_symbol", series_symbol)
25+
26+
def set_symbols(self, symbols):
27+
if isinstance(symbols, str):
28+
self.add_query_param("symbols", symbols)
29+
elif isinstance(symbols, list):
30+
self.add_query_param("symbols", ",".join(symbols))
31+
32+
def set_status(self, status):
33+
self.add_query_param("status", status)

‎webull/data/request/get_event_instrument_request.py‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ def __init__(self):
2323
def set_series_symbol(self, series_symbol):
2424
self.add_query_param("series_symbol", series_symbol)
2525

26+
def set_event_symbol(self, event_symbol):
27+
self.add_query_param("event_symbol", event_symbol)
28+
29+
def set_symbols(self, symbols):
30+
if isinstance(symbols, str):
31+
self.add_query_param("symbols", symbols)
32+
elif isinstance(symbols, list):
33+
self.add_query_param("symbols", ",".join(symbols))
34+
2635
def set_expiration_date_after(self, expiration_date_after):
2736
self.add_query_param("expiration_date_after", expiration_date_after)
2837

0 commit comments

Comments
 (0)