webull-openapi-python-sdk 1.0.7__py3-none-any.whl → 1.0.9__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 CHANGED
@@ -1 +1 @@
1
- __version__ = '1.0.7'
1
+ __version__ = '1.0.9'
@@ -74,6 +74,10 @@ if __name__ == '__main__':
74
74
  if res.status_code == 200:
75
75
  print('get_tick:', res.json())
76
76
 
77
+ res = data_client.market_data.get_footprint("AAPL", Category.US_STOCK.name, Timespan.S5.name)
78
+ if res.status_code == 200:
79
+ print('get_footprint:', res.json())
80
+
77
81
  res = data_client.market_data.get_quotes("AAPL", Category.US_STOCK.name, depth=1, overnight_required=True)
78
82
  if res.status_code == 200:
79
83
  print('get_quotes:', res.json())
@@ -94,6 +98,10 @@ if __name__ == '__main__':
94
98
  if res.status_code == 200:
95
99
  print('get_futures_snapshot:', res.json())
96
100
 
101
+ res = data_client.futures_market_data.get_futures_footprint("SILZ5,6BM6", Category.US_FUTURES.name, Timespan.S5.name)
102
+ if res.status_code == 200:
103
+ print('get_futures_footprint:', res.json())
104
+
97
105
  res = data_client.instrument.get_futures_products(Category.US_FUTURES.name)
98
106
  if res.status_code == 200:
99
107
  print('get_futures_products:', res.json())
@@ -208,7 +208,38 @@ if __name__ == '__main__':
208
208
  if res.status_code == 200:
209
209
  print('get master order detail res:', res.json())
210
210
 
211
-
211
+ # batch place order
212
+ batch_place_orders = [
213
+ {
214
+ "combo_type": "NORMAL",
215
+ "client_order_id": uuid.uuid4().hex,
216
+ "instrument_type": "EQUITY",
217
+ "market": "US",
218
+ "symbol": "AAPL",
219
+ "order_type": "MARKET",
220
+ "entrust_type": "QTY",
221
+ "support_trading_session": "CORE",
222
+ "time_in_force": "DAY",
223
+ "side": "BUY",
224
+ "quantity": "1"
225
+ },
226
+ {
227
+ "combo_type": "NORMAL",
228
+ "client_order_id": uuid.uuid4().hex,
229
+ "instrument_type": "EQUITY",
230
+ "market": "US",
231
+ "symbol": "TESL",
232
+ "order_type": "MARKET",
233
+ "entrust_type": "QTY",
234
+ "support_trading_session": "CORE",
235
+ "time_in_force": "DAY",
236
+ "side": "BUY",
237
+ "quantity": "1"
238
+ }
239
+ ]
240
+ res = trade_client.order_v3.batch_place_order(account_id, batch_place_orders)
241
+ if res.status_code == 200:
242
+ print('batch place normal equity order res:', res.json())
212
243
 
213
244
 
214
245
  # ============================================================
webull/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.0.7'
1
+ __version__ = '1.0.9'
webull/core/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
- __version__ = '1.0.7'
1
+ __version__ = '1.0.9'
2
2
 
3
3
  import logging
4
4
 
webull/data/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  # coding=utf-8
2
2
 
3
- __version__ = '1.0.7'
3
+ __version__ = '1.0.9'
@@ -16,6 +16,8 @@
16
16
 
17
17
  from webull.core.common.easy_enum import EasyEnum
18
18
  class Timespan(EasyEnum):
19
+ S5 = (12, "5 Second")
20
+ S15= (13, "15 Second")
19
21
  M1 = (1, "1 minute")
20
22
  M5 = (2, "5 minute")
21
23
  M15 = (3, "15 minute")
@@ -11,8 +11,8 @@
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
-
15
-
14
+ from webull.data.common.category import Category
15
+ from webull.data.request.get_futures_footprint_request import GetFuturesFootprintRequest
16
16
  from webull.data.request.get_futures_historical_bars_request import GetFuturesHistoricalBarsRequest
17
17
  from webull.data.request.get_futures_snapshot_request import GetFuturesSnapshotRequest
18
18
  from webull.data.request.get_futures_depth_request import GetFuturesDepthRequest
@@ -86,4 +86,26 @@ class FuturesMarketData:
86
86
  tick_request.set_category(category)
87
87
  tick_request.set_count(count)
88
88
  response = self.client.get_response(tick_request)
89
+ return response
90
+
91
+ def get_futures_footprint(self, symbols, category, timespan, count=None,
92
+ real_time_required=None, trading_sessions=None):
93
+ """
94
+ Search the futures footprint based on the list of futures codes and futures types.
95
+
96
+ :param symbols: Futures Securities symbol, such as: BITH6,BITF26.
97
+ :param category: Security type, enumeration.
98
+ :param timespan: Time granularity.
99
+ :param count: Number of entries: 200 by default, maximum 1200.
100
+ :param real_time_required: Whether to include the latest data or candlestick charts that are not yet finalized. The default is false, meaning they are not included. This option is only used for minute candlestick charts.
101
+ :param trading_sessions: RTH: During trading hours, PRE: Before trading hours, ATH: After trading hours. Default: RTH.
102
+ """
103
+ footprint_request = GetFuturesFootprintRequest()
104
+ footprint_request.set_symbols(symbols)
105
+ footprint_request.set_category(category)
106
+ footprint_request.set_timespan(timespan)
107
+ footprint_request.set_count(count)
108
+ footprint_request.set_real_time_required(real_time_required)
109
+ footprint_request.set_trading_sessions(trading_sessions)
110
+ response = self.client.get_response(footprint_request)
89
111
  return response
@@ -11,9 +11,11 @@
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
14
15
  from webull.data.request.get_batch_historical_bars_request import BatchHistoricalBarsRequest
15
16
  from webull.data.request.get_corp_action_request import GetCorpActionRequest
16
17
  from webull.data.request.get_eod_bars_request import GetEodBarsRequest
18
+ from webull.data.request.get_footprint_request import GetFootprintRequest
17
19
  from webull.data.request.get_historical_bars_request import GetHistoricalBarsRequest
18
20
  from webull.data.request.get_quotes_request import GetQuotesRequest
19
21
  from webull.data.request.get_snapshot_request import GetSnapshotRequest
@@ -183,3 +185,25 @@ class MarketData:
183
185
  eod_corp_action_request.set_last_update_time(last_update_time)
184
186
  response = self.client.get_response(eod_corp_action_request)
185
187
  return response
188
+
189
+ def get_footprint(self, symbols, category, timespan, count=None,
190
+ real_time_required=None, trading_sessions=None):
191
+ """
192
+ Search the footprint based on the list of security codes and security types.
193
+
194
+ :param symbols: Securities symbol, such as: 00700,00981.
195
+ :param category: Security type, enumeration.
196
+ :param timespan: Time granularity.
197
+ :param count: Number of entries: 200 by default, maximum 1200.
198
+ :param real_time_required: Whether to include the latest data or candlestick charts that are not yet finalized. The default is false, meaning they are not included. This option is only used for minute candlestick charts.
199
+ :param trading_sessions: RTH: During trading hours, PRE: Before trading hours, ATH: After trading hours. Default: RTH.
200
+ """
201
+ footprint_request = GetFootprintRequest()
202
+ footprint_request.set_symbols(symbols)
203
+ footprint_request.set_category(category)
204
+ footprint_request.set_timespan(timespan)
205
+ footprint_request.set_count(count)
206
+ footprint_request.set_real_time_required(real_time_required)
207
+ footprint_request.set_trading_sessions(trading_sessions)
208
+ response = self.client.get_response(footprint_request)
209
+ return response
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
13
13
 
14
14
 
15
15
 
16
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rmessage.proto\"Z\n\x05\x42\x61sic\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\x12\x11\n\ttimestamp\x18\x03 \x01(\t\x12\x17\n\x0ftrading_session\x18\x04 \x01(\t\"\xb6\x01\n\x08Snapshot\x12\x15\n\x05\x62\x61sic\x18\x01 \x01(\x0b\x32\x06.Basic\x12\x12\n\ntrade_time\x18\x02 \x01(\t\x12\r\n\x05price\x18\x03 \x01(\t\x12\x0c\n\x04open\x18\x04 \x01(\t\x12\x0c\n\x04high\x18\x05 \x01(\t\x12\x0b\n\x03low\x18\x06 \x01(\t\x12\x11\n\tpre_close\x18\x07 \x01(\t\x12\x0e\n\x06volume\x18\x08 \x01(\t\x12\x0e\n\x06\x63hange\x18\t \x01(\t\x12\x14\n\x0c\x63hange_ratio\x18\n \x01(\t\"L\n\x05Quote\x12\x15\n\x05\x62\x61sic\x18\x01 \x01(\x0b\x32\x06.Basic\x12\x15\n\x04\x61sks\x18\x02 \x03(\x0b\x32\x07.AskBid\x12\x15\n\x04\x62ids\x18\x03 \x03(\x0b\x32\x07.AskBid\"X\n\x04Tick\x12\x15\n\x05\x62\x61sic\x18\x01 \x01(\x0b\x32\x06.Basic\x12\x0c\n\x04time\x18\x02 \x01(\t\x12\r\n\x05price\x18\x03 \x01(\t\x12\x0e\n\x06volume\x18\x04 \x01(\t\x12\x0c\n\x04side\x18\x05 \x01(\t\"U\n\x06\x41skBid\x12\r\n\x05price\x18\x01 \x01(\t\x12\x0c\n\x04size\x18\x02 \x01(\t\x12\x15\n\x05order\x18\x03 \x03(\x0b\x32\x06.Order\x12\x17\n\x06\x62roker\x18\x04 \x03(\x0b\x32\x07.Broker\"#\n\x05Order\x12\x0c\n\x04mpid\x18\x01 \x01(\t\x12\x0c\n\x04size\x18\x02 \x01(\t\"#\n\x06\x42roker\x12\x0b\n\x03\x62id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\tb\x06proto3')
16
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rmessage.proto\"Z\n\x05\x42\x61sic\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x15\n\rinstrument_id\x18\x02 \x01(\t\x12\x11\n\ttimestamp\x18\x03 \x01(\t\x12\x17\n\x0ftrading_session\x18\x04 \x01(\t\"\xd6\x03\n\x08Snapshot\x12\x15\n\x05\x62\x61sic\x18\x01 \x01(\x0b\x32\x06.Basic\x12\x12\n\ntrade_time\x18\x02 \x01(\t\x12\r\n\x05price\x18\x03 \x01(\t\x12\x0c\n\x04open\x18\x04 \x01(\t\x12\x0c\n\x04high\x18\x05 \x01(\t\x12\x0b\n\x03low\x18\x06 \x01(\t\x12\x11\n\tpre_close\x18\x07 \x01(\t\x12\x0e\n\x06volume\x18\x08 \x01(\t\x12\x0e\n\x06\x63hange\x18\t \x01(\t\x12\x14\n\x0c\x63hange_ratio\x18\n \x01(\t\x12\x16\n\x0e\x65xt_trade_time\x18\x0b \x01(\t\x12\x11\n\text_price\x18\x0c \x01(\t\x12\x10\n\x08\x65xt_high\x18\r \x01(\t\x12\x0f\n\x07\x65xt_low\x18\x0e \x01(\t\x12\x12\n\next_volume\x18\x0f \x01(\t\x12\x12\n\next_change\x18\x10 \x01(\t\x12\x18\n\x10\x65xt_change_ratio\x18\x11 \x01(\t\x12\x16\n\x0eovn_trade_time\x18\x12 \x01(\t\x12\x11\n\tovn_price\x18\x13 \x01(\t\x12\x10\n\x08ovn_high\x18\x14 \x01(\t\x12\x0f\n\x07ovn_low\x18\x15 \x01(\t\x12\x12\n\novn_volume\x18\x16 \x01(\t\x12\x12\n\novn_change\x18\x17 \x01(\t\x12\x18\n\x10ovn_change_ratio\x18\x18 \x01(\t\"L\n\x05Quote\x12\x15\n\x05\x62\x61sic\x18\x01 \x01(\x0b\x32\x06.Basic\x12\x15\n\x04\x61sks\x18\x02 \x03(\x0b\x32\x07.AskBid\x12\x15\n\x04\x62ids\x18\x03 \x03(\x0b\x32\x07.AskBid\"X\n\x04Tick\x12\x15\n\x05\x62\x61sic\x18\x01 \x01(\x0b\x32\x06.Basic\x12\x0c\n\x04time\x18\x02 \x01(\t\x12\r\n\x05price\x18\x03 \x01(\t\x12\x0e\n\x06volume\x18\x04 \x01(\t\x12\x0c\n\x04side\x18\x05 \x01(\t\"U\n\x06\x41skBid\x12\r\n\x05price\x18\x01 \x01(\t\x12\x0c\n\x04size\x18\x02 \x01(\t\x12\x15\n\x05order\x18\x03 \x03(\x0b\x32\x06.Order\x12\x17\n\x06\x62roker\x18\x04 \x03(\x0b\x32\x07.Broker\"#\n\x05Order\x12\x0c\n\x04mpid\x18\x01 \x01(\t\x12\x0c\n\x04size\x18\x02 \x01(\t\"#\n\x06\x42roker\x12\x0b\n\x03\x62id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\tb\x06proto3')
17
17
 
18
18
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
19
19
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'message_pb2', globals())
@@ -23,15 +23,15 @@ if _descriptor._USE_C_DESCRIPTORS == False:
23
23
  _BASIC._serialized_start=17
24
24
  _BASIC._serialized_end=107
25
25
  _SNAPSHOT._serialized_start=110
26
- _SNAPSHOT._serialized_end=292
27
- _QUOTE._serialized_start=294
28
- _QUOTE._serialized_end=370
29
- _TICK._serialized_start=372
30
- _TICK._serialized_end=460
31
- _ASKBID._serialized_start=462
32
- _ASKBID._serialized_end=547
33
- _ORDER._serialized_start=549
34
- _ORDER._serialized_end=584
35
- _BROKER._serialized_start=586
36
- _BROKER._serialized_end=621
26
+ _SNAPSHOT._serialized_end=580
27
+ _QUOTE._serialized_start=582
28
+ _QUOTE._serialized_end=658
29
+ _TICK._serialized_start=660
30
+ _TICK._serialized_end=748
31
+ _ASKBID._serialized_start=750
32
+ _ASKBID._serialized_end=835
33
+ _ORDER._serialized_start=837
34
+ _ORDER._serialized_end=872
35
+ _BROKER._serialized_start=874
36
+ _BROKER._serialized_end=909
37
37
  # @@protoc_insertion_point(module_scope)
@@ -21,22 +21,40 @@ from webull.data.quotes.subscribe.basic_result import BasicResult
21
21
  class SnapshotResult:
22
22
  def __init__(self, pb_snapshot):
23
23
  self.basic = BasicResult(pb_snapshot.basic)
24
+ self.last_trade_time = int(pb_snapshot.trade_time) if pb_snapshot.trade_time else None
25
+ self.price = Decimal(pb_snapshot.price) if pb_snapshot.price else None
24
26
  self.open = Decimal(pb_snapshot.open) if pb_snapshot.open else None
25
27
  self.high = Decimal(pb_snapshot.high) if pb_snapshot.high else None
26
28
  self.low = Decimal(pb_snapshot.low) if pb_snapshot.low else None
27
- self.price = Decimal(pb_snapshot.price) if pb_snapshot.price else None
28
- self.pre_close = Decimal(
29
- pb_snapshot.pre_close) if pb_snapshot.pre_close else None
30
- self.volume = Decimal(
31
- pb_snapshot.volume) if pb_snapshot.volume else None
32
- self.change = Decimal(
33
- pb_snapshot.change) if pb_snapshot.change else None
34
- self.change_ratio = Decimal(
35
- pb_snapshot.change_ratio) if pb_snapshot.change_ratio else None
29
+ self.pre_close = Decimal(pb_snapshot.pre_close) if pb_snapshot.pre_close else None
30
+ self.close = Decimal(pb_snapshot.open) if pb_snapshot.open else None
31
+ self.volume = Decimal(pb_snapshot.volume) if pb_snapshot.volume else None
32
+ self.change = Decimal(pb_snapshot.change) if pb_snapshot.change else None
33
+ self.change_ratio = Decimal(pb_snapshot.change_ratio) if pb_snapshot.change_ratio else None
34
+ self.ext_trade_time = int(pb_snapshot.ext_trade_time) if pb_snapshot.ext_trade_time else None
35
+ self.ext_price = Decimal(pb_snapshot.ext_price) if pb_snapshot.ext_price else None
36
+ self.ext_high = Decimal(pb_snapshot.ext_high) if pb_snapshot.ext_high else None
37
+ self.ext_low = Decimal(pb_snapshot.ext_low) if pb_snapshot.ext_low else None
38
+ self.ext_volume = Decimal(pb_snapshot.ext_volume) if pb_snapshot.ext_volume else None
39
+ self.ext_change = Decimal(pb_snapshot.ext_change) if pb_snapshot.ext_change else None
40
+ self.ext_change_ratio = Decimal(pb_snapshot.ext_change_ratio) if pb_snapshot.ext_change_ratio else None
41
+ self.ovn_trade_time = int(pb_snapshot.ovn_trade_time) if pb_snapshot.ovn_trade_time else None
42
+ self.ovn_price = Decimal(pb_snapshot.ovn_price) if pb_snapshot.ovn_price else None
43
+ self.ovn_high = Decimal(pb_snapshot.ovn_high) if pb_snapshot.ovn_high else None
44
+ self.ovn_low = Decimal(pb_snapshot.ovn_low) if pb_snapshot.ovn_low else None
45
+ self.ovn_volume = Decimal(pb_snapshot.ovn_volume) if pb_snapshot.ovn_volume else None
46
+ self.ovn_change = Decimal(pb_snapshot.ovn_change) if pb_snapshot.ovn_change else None
47
+ self.ovn_change_ratio = Decimal(pb_snapshot.ovn_change_ratio) if pb_snapshot.ovn_change_ratio else None
36
48
 
37
49
  def get_basic(self):
38
50
  return self.basic
39
51
 
52
+ def get_last_trade_time(self):
53
+ return self.last_trade_time
54
+
55
+ def get_price(self):
56
+ return self.price
57
+
40
58
  def get_open(self):
41
59
  return self.open
42
60
 
@@ -46,12 +64,12 @@ class SnapshotResult:
46
64
  def get_low(self):
47
65
  return self.low
48
66
 
49
- def get_price(self):
50
- return self.price
51
-
52
67
  def get_pre_close(self):
53
68
  return self.pre_close
54
69
 
70
+ def get_close(self):
71
+ return self.close
72
+
55
73
  def get_volume(self):
56
74
  return self.volume
57
75
 
@@ -61,9 +79,55 @@ class SnapshotResult:
61
79
  def get_change_ratio(self):
62
80
  return self.change_ratio
63
81
 
82
+ def get_ext_trade_time(self):
83
+ return self.ext_trade_time
84
+
85
+ def get_ext_price(self):
86
+ return self.ext_price
87
+
88
+ def get_ext_high(self):
89
+ return self.ext_high
90
+
91
+ def get_ext_low(self):
92
+ return self.ext_low
93
+
94
+ def get_ext_volume(self):
95
+ return self.ext_volume
96
+
97
+ def get_ext_change(self):
98
+ return self.ext_change
99
+
100
+ def get_ext_change_ratio(self):
101
+ return self.ext_change_ratio
102
+
103
+ def get_ovn_trade_time(self):
104
+ return self.ovn_trade_time
105
+
106
+ def get_ovn_price(self):
107
+ return self.ovn_price
108
+
109
+ def get_ovn_high(self):
110
+ return self.ovn_high
111
+
112
+ def get_ovn_low(self):
113
+ return self.ovn_low
114
+
115
+ def get_ovn_volume(self):
116
+ return self.ovn_volume
117
+
118
+ def get_ovn_change(self):
119
+ return self.ovn_change
120
+
121
+ def get_ovn_change_ratio(self):
122
+ return self.ovn_change_ratio
123
+
64
124
  def __repr__(self):
65
- return "%s, open:%s, high:%s, low:%s, price:%s, pre_close:%s, volume:%s, change:%s, change_ratio:%s" \
66
- % (self.basic, self.open, self.high, self.low, self.price, self.pre_close, self.volume, self.change, self.change_ratio)
125
+ attrs = ['last_trade_time', 'price', 'open', 'high', 'low', 'pre_close', 'close', 'volume', 'change', 'change_ratio']
126
+ ext_attrs = [f"ext_{name}" for name in ['trade_time', 'price', 'high', 'low', 'volume', 'change', 'change_ratio']]
127
+ ovn_attrs = [f"ovn_{name}" for name in ['trade_time', 'price', 'high', 'low', 'volume', 'change', 'change_ratio']]
128
+ all_attrs = attrs + ext_attrs + ovn_attrs
129
+ attr_str = ', '.join(f"{name}:{getattr(self, name)}" for name in all_attrs)
130
+ return f"{self.basic}, {attr_str}"
67
131
 
68
132
  def __str__(self):
69
133
  return self.__repr__()
@@ -0,0 +1,45 @@
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
+ from webull.core.request import ApiRequest
17
+
18
+ class GetFootprintRequest(ApiRequest):
19
+ def __init__(self):
20
+ ApiRequest.__init__(self, "/openapi/market-data/stock/footprint", version='v2', method="GET", query_params={})
21
+
22
+ def set_symbols(self, symbols):
23
+ if isinstance(symbols, str):
24
+ self.add_query_param("symbols", symbols)
25
+ elif isinstance(symbols, list):
26
+ self.add_query_param("symbols", ",".join(symbols))
27
+
28
+ def set_category(self, category):
29
+ self.add_query_param("category", category)
30
+
31
+ def set_timespan(self, timespan):
32
+ if timespan:
33
+ self.add_query_param("timespan", timespan)
34
+
35
+ def set_count(self, count):
36
+ if count:
37
+ self.add_query_param("count", count)
38
+
39
+ def set_real_time_required(self, real_time_required):
40
+ if real_time_required:
41
+ self.add_query_param("real_time_required", real_time_required)
42
+
43
+ def set_trading_sessions(self, trading_sessions):
44
+ if trading_sessions:
45
+ self.add_query_param("trading_sessions", trading_sessions)
@@ -0,0 +1,45 @@
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
+ from webull.core.request import ApiRequest
17
+
18
+ class GetFuturesFootprintRequest(ApiRequest):
19
+ def __init__(self):
20
+ ApiRequest.__init__(self, "/openapi/market-data/futures/footprint", version='v2', method="GET", query_params={})
21
+
22
+ def set_symbols(self, symbols):
23
+ if isinstance(symbols, str):
24
+ self.add_query_param("symbols", symbols)
25
+ elif isinstance(symbols, list):
26
+ self.add_query_param("symbols", ",".join(symbols))
27
+
28
+ def set_category(self, category):
29
+ self.add_query_param("category", category)
30
+
31
+ def set_timespan(self, timespan):
32
+ if timespan:
33
+ self.add_query_param("timespan", timespan)
34
+
35
+ def set_count(self, count):
36
+ if count:
37
+ self.add_query_param("count", count)
38
+
39
+ def set_real_time_required(self, real_time_required):
40
+ if real_time_required:
41
+ self.add_query_param("real_time_required", real_time_required)
42
+
43
+ def set_trading_sessions(self, trading_sessions):
44
+ if trading_sessions:
45
+ self.add_query_param("trading_sessions", trading_sessions)
webull/trade/__init__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '1.0.7'
1
+ __version__ = '1.0.9'
@@ -0,0 +1,52 @@
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
+ import json
15
+ # coding=utf-8
16
+
17
+ from webull.core.request import ApiRequest
18
+
19
+
20
+ class BatchPlaceOrderRequest(ApiRequest):
21
+ def __init__(self):
22
+ super().__init__("/openapi/trade/order/batch-place", version='v2', method="POST", body_params={})
23
+
24
+ def set_account_id(self, account_id):
25
+ self.add_body_params("account_id", account_id)
26
+
27
+ def set_batch_orders(self, batch_orders):
28
+ self.add_body_params("batch_orders", batch_orders)
29
+
30
+ def add_custom_headers_from_order(self, batch_orders):
31
+ if not batch_orders:
32
+ return
33
+
34
+ if isinstance(batch_orders, list) and batch_orders[0]:
35
+ first_order = batch_orders[0]
36
+ leg_list = first_order.get("legs")
37
+ if leg_list is not None and isinstance(leg_list, list):
38
+ for sub_leg in leg_list:
39
+ if (sub_leg and isinstance(sub_leg, dict)
40
+ and sub_leg.get("instrument_type") == "OPTION"):
41
+ instrument_type = sub_leg.get("instrument_type")
42
+ market = sub_leg.get("market")
43
+ category = market + "_" + instrument_type
44
+ if category is not None:
45
+ self.add_header("category", category)
46
+ return
47
+
48
+ market = first_order.get("market")
49
+ instrument_type = first_order.get("instrument_type")
50
+ category = market + "_" + instrument_type
51
+ if category is not None:
52
+ self.add_header("category", category)
@@ -14,6 +14,7 @@
14
14
  # coding=utf-8
15
15
  from webull.trade.request.v3.preview_order_request import PreviewOrderRequest
16
16
  from webull.trade.request.v3.place_order_request import PlaceOrderRequest
17
+ from webull.trade.request.v3.batch_place_order_request import BatchPlaceOrderRequest
17
18
  from webull.trade.request.v3.replace_order_request import ReplaceOrderRequest
18
19
  from webull.trade.request.v3.cancel_order_request import CancelOrderRequest
19
20
  from webull.trade.request.v3.get_order_detail_request import OrderDetailRequest
@@ -50,6 +51,18 @@ class OrderOperationV3:
50
51
  response = self.client.get_response(place_order_request)
51
52
  return response
52
53
 
54
+ def batch_place_order(self, account_id, batch_orders):
55
+ """
56
+ This interface is currently supported only for Webull US.
57
+ Support for other regions will be available in future updates.
58
+ """
59
+ batch_place_order_request = BatchPlaceOrderRequest()
60
+ batch_place_order_request.set_account_id(account_id=account_id)
61
+ batch_place_order_request.set_batch_orders(batch_orders=batch_orders)
62
+ batch_place_order_request.add_custom_headers_from_order(batch_orders)
63
+ response = self.client.get_response(batch_place_order_request)
64
+ return response
65
+
53
66
  def replace_order(self, account_id, modify_orders, client_combo_order_id=None):
54
67
  """
55
68
  This interface is currently supported only for Webull US.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: webull-openapi-python-sdk
3
- Version: 1.0.7
3
+ Version: 1.0.9
4
4
  Summary: Webull Python SDK.
5
5
  Home-page:
6
6
  Author: Webull
@@ -1,10 +1,10 @@
1
- samples/__init__.py,sha256=Th6FPUfmw3s94879QiaD_OgzmQyEFPOnYrMVoQqee8Y,22
1
+ samples/__init__.py,sha256=mg2kb865UYMe9zOkU2VcRPfv-5zzU182OL3t45SXXWk,22
2
2
  samples/account/__init__.py,sha256=eoZ6GfifbqhMLNzjlqRDVil-yyBkOmVN9ujSgJWNBlY,15
3
3
  samples/account/account_client.py,sha256=vwh-nI_JnjwcIeOr1sQPMzG8pAqZwliUusE49ZmYE3s,1796
4
4
  samples/assets/__init__.py,sha256=eoZ6GfifbqhMLNzjlqRDVil-yyBkOmVN9ujSgJWNBlY,15
5
5
  samples/assets/assets_client.py,sha256=p9LS2Td3gbUMkHn4LD_9RMCFuaQRUbsKvG4PhZBGJDc,1974
6
6
  samples/data/__init__.py,sha256=eoZ6GfifbqhMLNzjlqRDVil-yyBkOmVN9ujSgJWNBlY,15
7
- samples/data/data_client.py,sha256=rH91Yj7oIF6dBOOzF99cUn_12cgDLkw02SNIQM2nB1o,4868
7
+ samples/data/data_client.py,sha256=8FR5ZOY8jWCGfN3XohzyvLdFxYv-TdqfWRKw3E827WY,5248
8
8
  samples/data/data_streaming_client.py,sha256=IdCUNdfo2_dR9OLgWZuIc9U9s-0-uNjwqkf9aLoG-44,4088
9
9
  samples/data/data_streaming_client_async.py,sha256=o_u1ch8JdbcYnLCvDCCUzO-Z1IG7BUKncu_GB_kCbOs,4443
10
10
  samples/order/__init__.py,sha256=eoZ6GfifbqhMLNzjlqRDVil-yyBkOmVN9ujSgJWNBlY,15
@@ -13,10 +13,10 @@ samples/order/order_stock_client.py,sha256=hYwVwVFVERk-YS7gRcW-LuGfAvcF8VJHZs1qw
13
13
  samples/trade/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  samples/trade/trade_client.py,sha256=LyWSvZJH4ByCkRORqP9WdkXfx65A2b6fhc9_GzL8DOM,6258
15
15
  samples/trade/trade_client_v2.py,sha256=IO-zmRiUnCmIetTdiYunPh8jVK2VaPrOR77Dwvz1auY,10771
16
- samples/trade/trade_client_v3.py,sha256=JcgblJMYL4X5P8BP0TQEgP3nqDBQWGor2WzhU96f_h8,15464
16
+ samples/trade/trade_client_v3.py,sha256=70f4VJYWcSJP3ppA8mRAoftJqjRTn5GTeGZck8eLCTg,16526
17
17
  samples/trade/trade_event_client.py,sha256=uOx9EwFaves2yaTNm13BHpYC0IHXSoBL8BWPbDLeFw4,2469
18
- webull/__init__.py,sha256=Th6FPUfmw3s94879QiaD_OgzmQyEFPOnYrMVoQqee8Y,22
19
- webull/core/__init__.py,sha256=JOXhdxQYuIkQibSKfZ3BBnLJJfch1qMGlPwyIVRRq1k,225
18
+ webull/__init__.py,sha256=mg2kb865UYMe9zOkU2VcRPfv-5zzU182OL3t45SXXWk,22
19
+ webull/core/__init__.py,sha256=MSNIk2XHGC6pQer-Z5tjWyHUXb0Wi1O1Vnn93JEPa5A,225
20
20
  webull/core/client.py,sha256=OE_ghPA558eE85MmaU_I3Tg0j-osCQFChTk-6dy4OW0,16398
21
21
  webull/core/compat.py,sha256=HDis0D271oQ6OCpA7ViX10NJdhfXdoBfzx6nuV3vrnI,3114
22
22
  webull/core/headers.py,sha256=7aMt3_YtaL9Yhqj2T1g7ESQgkI78SAXIk7hMX5U5FgE,2019
@@ -186,7 +186,7 @@ webull/core/vendored/requests/packages/urllib3/util/ssl_.py,sha256=aRUKc1WIyS-sU
186
186
  webull/core/vendored/requests/packages/urllib3/util/timeout.py,sha256=sAyiBBds7eOk1oM3ulvVMWZiqx1B743puHqK92XwBcY,10325
187
187
  webull/core/vendored/requests/packages/urllib3/util/url.py,sha256=_CgqbyNrQWubrv_y5aWhuutz3mnbj1cvTUe4VYbGYWA,7367
188
188
  webull/core/vendored/requests/packages/urllib3/util/wait.py,sha256=0FHS8R3OrMU-97XWt8AxuUStkSGXTct9CfOwY_fWn7U,5971
189
- webull/data/__init__.py,sha256=qJOTnMZHsC7a5W3ojnkVnl82XCnV6QdQQDpZO3aEy2Y,38
189
+ webull/data/__init__.py,sha256=16Et8WoO5VLLeKZR62v51Ah41JMXVyb5jk5AlVyFpvU,38
190
190
  webull/data/data_client.py,sha256=JGouoFd37-sxpP6GyOJ0rRw7UuBmXqoIcis0jiRGJPQ,1871
191
191
  webull/data/data_streaming_client.py,sha256=hYqrdKTeIB3Xmp7LMjMwN1XE6Y7bKXX0y-lGX1ty6W4,3870
192
192
  webull/data/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -200,7 +200,7 @@ webull/data/common/expiration_cycle.py,sha256=f1yyOVBnw8jQX16t_QIhyWgfAsaQn8asjd
200
200
  webull/data/common/instrument_status.py,sha256=T8lMZxvhwV-19XprrvbajEfGQ9gaWVjf0p0UASrCxSQ,789
201
201
  webull/data/common/option_type.py,sha256=E4lzZJS-6iX167l6b3mMhWUbNVD0joPxwqGL_mnOGRI,705
202
202
  webull/data/common/subscribe_type.py,sha256=2EpBsPXCDjx5q25GonbUur2upQFfGvT6dcSYQ3BolyY,745
203
- webull/data/common/timespan.py,sha256=Mg-dnvIWclVZRhIkjDiGzRlnOK457PWZ8sY5I8NXRBA,938
203
+ webull/data/common/timespan.py,sha256=Yjr35Zjhj6qyW1k_pnXkDjm6fWWZ-vs44F_gMWCYCKU,991
204
204
  webull/data/internal/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
205
205
  webull/data/internal/default_retry_policy.py,sha256=g94o5LKtbB5XoDiZWHp7yKGOWTTTOT89bz1ZSlT79mI,3307
206
206
  webull/data/internal/exceptions.py,sha256=qtInXjns6ce6KQTtJOxz8M4bywuOJe2sNSAwGJqTWDs,1800
@@ -210,21 +210,21 @@ webull/data/internal/quotes_payload_decoder.py,sha256=x2XGYDu4wSdc1LLrcIo3BXeb5j
210
210
  webull/data/internal/quotes_topic.py,sha256=kG4RZTjj01U0e54qoOrJHlLrPeBzXekySasm2uoyXVo,1138
211
211
  webull/data/quotes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
212
212
  webull/data/quotes/crypto_market_data.py,sha256=UQlxUz0GntvwcRS-Vh_h7cXbhQ045MqPlG5AhWUoQI4,3063
213
- webull/data/quotes/futures_market_data.py,sha256=cS_VMbVsqz8JGF1zM3Hc5fQBR-30yoRM30jIw8HBD3A,4131
213
+ webull/data/quotes/futures_market_data.py,sha256=fc9giYNy1LcdLHOJV31zMbPBKtWDH8kBW5xRFgHzQUA,5596
214
214
  webull/data/quotes/instrument.py,sha256=4mrL8VEftiPmbEl_7qdpnrgFDuty54tb6C9j_Hh8iME,5089
215
- webull/data/quotes/market_data.py,sha256=6Md4a30byQiJuglKP0EJW28LCYPCHgJmD1NEAkNocUA,9907
215
+ webull/data/quotes/market_data.py,sha256=5HjzLQje1F7OxasRrjNPZ2d-tkuYJ-aDMZj3fVEO6cI,11329
216
216
  webull/data/quotes/market_streaming_data.py,sha256=cI9xxGpKV_KDS8cgh9azHifBji0yeSuKmH7Jxaqij38,3139
217
217
  webull/data/quotes/subscribe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
218
218
  webull/data/quotes/subscribe/ask_bid_result.py,sha256=EWu5dFMb_BwFGYPLe-f9uCD8_Ftl1wguhpU1qXi2zaY,1552
219
219
  webull/data/quotes/subscribe/basic_result.py,sha256=l9pxGlt8HLHwE3plq_6J0OPZ_X4ZjjRfa1f9nExu2dE,1450
220
220
  webull/data/quotes/subscribe/broker_result.py,sha256=E6pM0Ydr6tU_bPSOeyu1KJf7oYgbO-lIXLIdJQANH4I,1013
221
- webull/data/quotes/subscribe/message_pb2.py,sha256=I6scR0qacKJWWhBdZq9tvCzSYUXZ9-TuPwpAmnp-FgY,2570
221
+ webull/data/quotes/subscribe/message_pb2.py,sha256=JimxZN9hCEvt_NF0eYRNZJttEsCAc3bWAelE5Tva7yM,3136
222
222
  webull/data/quotes/subscribe/order_result.py,sha256=bqLjRzCDK0jpQBMm00QxfgV-SPg04lOLYxc8SgpkFDw,912
223
223
  webull/data/quotes/subscribe/payload_type.py,sha256=nacQubAzKjutfddNdilckpsbamCUt6nrBnzrxgMOrWQ,674
224
224
  webull/data/quotes/subscribe/quote_decoder.py,sha256=vTDKi3TaQ79ODTydVcEEiJR2g0fQLPf5hUOqo7Mi1gw,1016
225
225
  webull/data/quotes/subscribe/quote_result.py,sha256=2SoRzSGANphAut1jleNnfZtUhpqqbELRcs1biu440p8,1442
226
226
  webull/data/quotes/subscribe/snapshot_decoder.py,sha256=dukBHXa971LHp9oPkgQ4mqL_8yIAU5XSlUIUjpMz2NY,1045
227
- webull/data/quotes/subscribe/snapshot_result.py,sha256=T46uw-hxmWDCJdhXfFsdSn3UtE50Bsc3oYJ9rYS1f6o,2311
227
+ webull/data/quotes/subscribe/snapshot_result.py,sha256=U-YPGAVklcCsXZsp-9TPUUIfvqEgbPsou4Mhkkbxzp8,5077
228
228
  webull/data/quotes/subscribe/tick_decoder.py,sha256=Qb__nJth2vsDMk2bWfNxY-mUGTUPzSZPO-ukHVxq80g,1008
229
229
  webull/data/quotes/subscribe/tick_result.py,sha256=i2-4ZD1GK5EI3NhxkhSmUXfKnkBMjrwVBzLoDUY95OU,1467
230
230
  webull/data/request/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -234,7 +234,9 @@ webull/data/request/get_crypto_historical_bars_request.py,sha256=FKIp2hB2fPbkMLx
234
234
  webull/data/request/get_crypto_instruments_request.py,sha256=GwOA9oPBH4qNg7yR-lVjrRSGZDF5zfRUBS4PegKLcjk,1549
235
235
  webull/data/request/get_crypto_snapshot_request.py,sha256=W-z9nuBu2RaXqy07zFVHMQs9GP5Hc55vOWWYKoibWVA,1136
236
236
  webull/data/request/get_eod_bars_request.py,sha256=CwbyXeAE-iPKu43zNxcekSw5qOlfEwZsztFxCQvAXuQ,1234
237
+ webull/data/request/get_footprint_request.py,sha256=MnbKhhe7QMkKqyTxmXl-ztDl5l_3kkFhT1vtql82K3Y,1664
237
238
  webull/data/request/get_futures_depth_request.py,sha256=d6Tl-75pcJlvX6-beAdko15o8hDhdB-486uxH8AeGIk,1083
239
+ webull/data/request/get_futures_footprint_request.py,sha256=I0l-SlXBKqY61Oxq1zn1EWwLY79euuEoUcrvCzPJlA8,1673
238
240
  webull/data/request/get_futures_historical_bars_request.py,sha256=QwvJq33wkJ-_KLZutkh3Z55gQyCDTRkCPwc9UyYcvKU,1330
239
241
  webull/data/request/get_futures_instruments_by_code_request.py,sha256=9WjmisgOtzSim-3umKu_2NaATPZBFQxU-3HQ-jBHU1U,1319
240
242
  webull/data/request/get_futures_instruments_request.py,sha256=3i1B0v0jhQxx3ETN2Jiu-3aoitUWFN6QfwGNnBfK8eo,1136
@@ -248,7 +250,7 @@ webull/data/request/get_snapshot_request.py,sha256=OD2PiaxmBCboFDaU8DFTwvfNd2zOb
248
250
  webull/data/request/get_tick_request.py,sha256=rUHhQgC8Z_6ensLyCkg3DDK55SlEi0Bc_dhpCIIspDs,1366
249
251
  webull/data/request/subscribe_request.py,sha256=dm93Q5Q4gigAMqAobolaYYSs3wM6QddPUZOjEtJsX-8,1471
250
252
  webull/data/request/unsubscribe_request.py,sha256=hQA4mYM64PgmQEA2otl47-3nCXqjsSY_weFA3_wNbMM,1446
251
- webull/trade/__init__.py,sha256=GIukrVnl8Ykjex2rUbxdz2Ov1PRc_MomFmxwSzRJH9w,21
253
+ webull/trade/__init__.py,sha256=mu4LFHUATfA8gJh1jUgMKeIXEjlhbQqTC5UyMGu-2Gs,21
252
254
  webull/trade/trade_client.py,sha256=_6lH4KO-jKgKWU28fWNsc9-KEHto-WvaP0gT96BJ_dw,2184
253
255
  webull/trade/trade_events_client.py,sha256=4a7qupeT3dKJRKBQqXNhCai6ENzX6PA4yjTDHHxPR0w,8892
254
256
  webull/trade/common/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -310,6 +312,7 @@ webull/trade/request/v2/preview_order_request.py,sha256=gRld4FcpBFQk7X24hzgs5lmM
310
312
  webull/trade/request/v2/replace_option_request.py,sha256=0S86ToPdfZlZmf85jBQ39a1RkQ8wY7FJZA4hdxmyjN0,1189
311
313
  webull/trade/request/v2/replace_order_request.py,sha256=rptKekCa6uSj1rzg8TT7jnuMVCDquhev6naPESqpihU,1193
312
314
  webull/trade/request/v3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
315
+ webull/trade/request/v3/batch_place_order_request.py,sha256=QW6EZ-mZVTdLVbzJsr0VxA5Bca4hRgAq9_x6N9xVjnk,2115
313
316
  webull/trade/request/v3/cancel_order_request.py,sha256=x3_5w-0_qwN6CjW2yuM4oLd51QuuTtXNVKZQ23MYscs,1024
314
317
  webull/trade/request/v3/get_order_detail_request.py,sha256=jYuU8vHdE0fkXZdHqyuZ-rnhHUlQ9Qo5r7FvzmCfEKE,1000
315
318
  webull/trade/request/v3/get_order_history_request.py,sha256=iCZEUs6JHOlRuA-u1zL1QvfD8h7gaEg1TR0X4mWxIVo,1304
@@ -326,10 +329,10 @@ webull/trade/trade/v2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
326
329
  webull/trade/trade/v2/account_info_v2.py,sha256=IGY_BGTrZ0h7yQ_nDodNtmKen9gXW6heUFb7VLRQ9bY,2142
327
330
  webull/trade/trade/v2/order_operation_v2.py,sha256=m54RH2j45CBBWEnqe4KxrsltAF44XKtPMT4kv8t7djQ,12745
328
331
  webull/trade/trade/v3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
329
- webull/trade/trade/v3/order_opration_v3.py,sha256=4OTodBrcfyRuZOMXodNNHjCtsQxCV-5JQXEFBB1S_cE,6738
330
- webull_openapi_python_sdk-1.0.7.dist-info/licenses/LICENSE,sha256=ALOnsLtb1aHxmDJg3-oMi0BO-i-cjfyZaOBfnnavKMc,11359
331
- webull_openapi_python_sdk-1.0.7.dist-info/licenses/NOTICE,sha256=X5TApte6CPV10b96Cb70IRLusXmiRmK_R-dB-1tQM_I,2018
332
- webull_openapi_python_sdk-1.0.7.dist-info/METADATA,sha256=oSynjgWvR3nGCvWHQRUO10aUeW6zUHrwEYsZNW3O4a0,702
333
- webull_openapi_python_sdk-1.0.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
334
- webull_openapi_python_sdk-1.0.7.dist-info/top_level.txt,sha256=h8pEjNDGWS2ZUZ2vYFpUShoMQT0ZRIQaD57QJWD8_aI,15
335
- webull_openapi_python_sdk-1.0.7.dist-info/RECORD,,
332
+ webull/trade/trade/v3/order_opration_v3.py,sha256=_L10--m_XhoMe8YeYjQXVvRoTAWoRRzLU59UeneyMrU,7428
333
+ webull_openapi_python_sdk-1.0.9.dist-info/licenses/LICENSE,sha256=ALOnsLtb1aHxmDJg3-oMi0BO-i-cjfyZaOBfnnavKMc,11359
334
+ webull_openapi_python_sdk-1.0.9.dist-info/licenses/NOTICE,sha256=X5TApte6CPV10b96Cb70IRLusXmiRmK_R-dB-1tQM_I,2018
335
+ webull_openapi_python_sdk-1.0.9.dist-info/METADATA,sha256=I4Ohkx7rljnJeBfQ0goKx42vBTbF48Kp4aSWQF3xEcM,702
336
+ webull_openapi_python_sdk-1.0.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
337
+ webull_openapi_python_sdk-1.0.9.dist-info/top_level.txt,sha256=h8pEjNDGWS2ZUZ2vYFpUShoMQT0ZRIQaD57QJWD8_aI,15
338
+ webull_openapi_python_sdk-1.0.9.dist-info/RECORD,,