webull-openapi-python-sdk 1.0.3__py3-none-any.whl → 1.0.5__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.
Files changed (48) hide show
  1. samples/__init__.py +1 -1
  2. samples/data/data_client.py +27 -0
  3. samples/trade/trade_client_v3.py +420 -0
  4. samples/trade/trade_event_client.py +3 -1
  5. webull/__init__.py +1 -1
  6. webull/core/__init__.py +1 -1
  7. webull/core/data/endpoints.json +1 -1
  8. webull/data/__init__.py +1 -1
  9. webull/data/common/category.py +3 -2
  10. webull/data/common/contract_type.py +20 -0
  11. webull/data/data_client.py +4 -0
  12. webull/data/quotes/crypto_market_data.py +58 -0
  13. webull/data/quotes/futures_market_data.py +89 -0
  14. webull/data/quotes/instrument.py +79 -2
  15. webull/data/quotes/market_data.py +0 -2
  16. webull/data/request/get_crypto_historical_bars_request.py +40 -0
  17. webull/data/request/get_crypto_instruments_request.py +44 -0
  18. webull/data/request/get_crypto_snapshot_request.py +31 -0
  19. webull/data/request/get_futures_depth_request.py +32 -0
  20. webull/data/request/get_futures_historical_bars_request.py +36 -0
  21. webull/data/request/get_futures_instruments_by_code_request.py +36 -0
  22. webull/data/request/get_futures_instruments_request.py +31 -0
  23. webull/data/request/get_futures_products_request.py +25 -0
  24. webull/data/request/get_futures_snapshot_request.py +31 -0
  25. webull/data/request/get_futures_tick_request.py +31 -0
  26. webull/data/request/get_instruments_request.py +13 -1
  27. webull/trade/__init__.py +1 -1
  28. webull/trade/common/category.py +2 -3
  29. webull/trade/request/v2/palce_order_request.py +5 -3
  30. webull/trade/request/v2/place_option_request.py +7 -7
  31. webull/trade/request/v2/place_order_request.py +4 -6
  32. webull/trade/request/v3/__init__.py +0 -0
  33. webull/trade/request/v3/cancel_order_request.py +28 -0
  34. webull/trade/request/v3/get_order_detail_request.py +26 -0
  35. webull/trade/request/v3/get_order_history_request.py +35 -0
  36. webull/trade/request/v3/get_order_open_request.py +29 -0
  37. webull/trade/request/v3/place_order_request.py +56 -0
  38. webull/trade/request/v3/preview_order_request.py +31 -0
  39. webull/trade/request/v3/replace_order_request.py +31 -0
  40. webull/trade/trade/v3/__init__.py +0 -0
  41. webull/trade/trade/v3/order_opration_v3.py +134 -0
  42. webull/trade/trade_client.py +2 -0
  43. {webull_openapi_python_sdk-1.0.3.dist-info → webull_openapi_python_sdk-1.0.5.dist-info}/METADATA +1 -1
  44. {webull_openapi_python_sdk-1.0.3.dist-info → webull_openapi_python_sdk-1.0.5.dist-info}/RECORD +48 -24
  45. {webull_openapi_python_sdk-1.0.3.dist-info → webull_openapi_python_sdk-1.0.5.dist-info}/WHEEL +0 -0
  46. {webull_openapi_python_sdk-1.0.3.dist-info → webull_openapi_python_sdk-1.0.5.dist-info}/licenses/LICENSE +0 -0
  47. {webull_openapi_python_sdk-1.0.3.dist-info → webull_openapi_python_sdk-1.0.5.dist-info}/licenses/NOTICE +0 -0
  48. {webull_openapi_python_sdk-1.0.3.dist-info → webull_openapi_python_sdk-1.0.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,89 @@
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
+
16
+ from webull.data.request.get_futures_historical_bars_request import GetFuturesHistoricalBarsRequest
17
+ from webull.data.request.get_futures_snapshot_request import GetFuturesSnapshotRequest
18
+ from webull.data.request.get_futures_depth_request import GetFuturesDepthRequest
19
+ from webull.data.request.get_futures_tick_request import GetFuturesTickRequest
20
+
21
+ class FuturesMarketData:
22
+ def __init__(self, api_client):
23
+ self.client = api_client
24
+
25
+ def get_futures_history_bars(self, symbols, category, timespan, count='200', real_time_required=None):
26
+ """
27
+ Batch query K-line data for multiple futures symbols, returning aggregated data within the window.
28
+ According to the last N K-lines of the futures code, it supports various granularity K-lines such as m1 and m5.
29
+
30
+ :param symbols: List of futures security codes
31
+ :param category: Security type, enumeration
32
+ :param timespan: K-line interval
33
+ :param count: Number of K-lines to return, default is 200, maximum is 1200
34
+ :param real_time_required: Returns the latest trade quote data. By default, the most recent market data is returned.
35
+ """
36
+ history_bar_request = GetFuturesHistoricalBarsRequest()
37
+ history_bar_request.set_symbols(symbols)
38
+ history_bar_request.set_category(category)
39
+ history_bar_request.set_timespan(timespan)
40
+ history_bar_request.set_count(count)
41
+ history_bar_request.set_real_time_required(real_time_required)
42
+ response = self.client.get_response(history_bar_request)
43
+ return response
44
+
45
+ def get_futures_snapshot(self, symbols, category):
46
+ """
47
+ Query the latest futures market snapshots in batches according to the futures code list.
48
+
49
+ :param symbols: List of futures security codes; for example: single: ESZ3 multiple: ESZ3,NQZ3;
50
+ For each request,up to 100 symbols can be subscribed
51
+ :param category: Security type, enumeration.
52
+ """
53
+ snapshot_request = GetFuturesSnapshotRequest()
54
+ snapshot_request.set_symbols(symbols)
55
+ snapshot_request.set_category(category)
56
+ response = self.client.get_response(snapshot_request)
57
+ return response
58
+
59
+ def get_futures_depth(self, symbol, category, depth=None):
60
+ """
61
+ Query the depth quote of futures according to the futures code list.
62
+
63
+ :param symbol: Futures securities code
64
+ :param category: Security type, enumeration.
65
+ :param depth: Retrieve bid/ask depth
66
+ Level 1 contains only the top 1 bid/ask level.
67
+ Level 2 becomes effective, with 10 levels by default. For U.S. futures, Level 2 supports up to 50 levels.
68
+ """
69
+ quote_request = GetFuturesDepthRequest()
70
+ quote_request.set_symbol(symbol)
71
+ quote_request.set_category(category)
72
+ quote_request.set_depth(depth)
73
+ response = self.client.get_response(quote_request)
74
+ return response
75
+
76
+ def get_futures_tick(self, symbol, category, count='200'):
77
+ """
78
+ Query tick-by-tick transaction of futures according to the futures code list.
79
+
80
+ :param symbol: Futures securities code
81
+ :param category: Security type, enumeration.
82
+ :param count: The number of lines: the default is 30, and the maximum limit is 1200
83
+ """
84
+ tick_request = GetFuturesTickRequest()
85
+ tick_request.set_symbol(symbol)
86
+ tick_request.set_category(category)
87
+ tick_request.set_count(count)
88
+ response = self.client.get_response(tick_request)
89
+ return response
@@ -11,23 +11,100 @@
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
-
14
+ from webull.data.common.category import Category
15
15
  from webull.data.request.get_instruments_request import GetInstrumentsRequest
16
+ from webull.data.request.get_crypto_instruments_request import GetCryptoInstrumentsRequest
17
+ from webull.data.request.get_futures_instruments_request import GetFuturesInstrumentsRequest
18
+ from webull.data.request.get_futures_products_request import GetFuturesProductsRequest
19
+ from webull.data.request.get_futures_instruments_by_code_request import GetFuturesInstrumentsByCodeRequest
16
20
 
17
21
 
18
22
  class Instrument:
19
23
  def __init__(self, api_client):
20
24
  self.client = api_client
21
25
 
22
- def get_instrument(self, symbols, category):
26
+ def get_instrument(self, symbols=None, category=Category.US_STOCK.name, status=None, last_instrument_id=None,
27
+ page_size=1000):
23
28
  """
24
29
  Query the underlying information according to the security symbol list and security type.
25
30
 
26
31
  :param symbols: Securities symbol, such as: 00700,00981.
27
32
  :param category: Security type, enumeration.
33
+ :param status: Tradable status.
34
+ :param last_instrument_id: Last instrument id for pagination.
35
+ :param page_size: Page size, default 1000.
28
36
  """
29
37
  instruments_request = GetInstrumentsRequest()
30
38
  instruments_request.set_symbols(symbols)
31
39
  instruments_request.set_category(category)
40
+ instruments_request.set_status(status)
41
+ instruments_request.set_last_instrument_id(last_instrument_id)
42
+ instruments_request.set_page_size(page_size)
32
43
  response = self.client.get_response(instruments_request)
33
44
  return response
45
+
46
+ def get_crypto_instrument(self, symbols=None, status=None, last_instrument_id=None,
47
+ category=Category.US_CRYPTO.name, page_size=1000):
48
+ """
49
+ Query the crypto underlying information according to the security symbol.
50
+ :param symbols: Securities symbol, such as: BTCUSD,ETHUSD.
51
+ :param status: Tradable status.
52
+ :param last_instrument_id: Last instrument id for pagination.
53
+ :param category: (str, required) Instrument type.
54
+ Possible values: ["US_CRYPTO"]
55
+ Example: "US_CRYPTO"
56
+ :param page_size: Page size, default 1000.
57
+ """
58
+ crypto_instruments_request = GetCryptoInstrumentsRequest()
59
+ crypto_instruments_request.set_symbols(symbols)
60
+ crypto_instruments_request.set_category(category)
61
+ crypto_instruments_request.set_status(status)
62
+ crypto_instruments_request.set_last_instrument_id(last_instrument_id)
63
+ crypto_instruments_request.set_page_size(page_size)
64
+ response = self.client.get_response(crypto_instruments_request)
65
+ return response
66
+
67
+ def get_futures_instrument(self, symbols, category):
68
+ """
69
+ Query the futures instrument information based on the futures contract symbol.
70
+
71
+ :param symbols: Futures contract symbol, such as: ESmain,ESM5.
72
+ :param category: Security type, enumeration.
73
+ """
74
+
75
+ futures_instrument_request = GetFuturesInstrumentsRequest()
76
+ futures_instrument_request.set_symbols(symbols)
77
+ futures_instrument_request.set_category(category)
78
+ response = self.client.get_response(futures_instrument_request)
79
+ return response
80
+
81
+ def get_futures_products(self, category):
82
+ """
83
+ Query futures contract codes in batches based on security types.
84
+
85
+ :param category: Security type, enumeration.
86
+ """
87
+
88
+ batch_futures_products_request = GetFuturesProductsRequest()
89
+ batch_futures_products_request.set_category(category)
90
+ response = self.client.get_response(batch_futures_products_request)
91
+ return response
92
+
93
+ def get_futures_instrument_by_code(self, code, category, contract_type=None):
94
+ """
95
+ Query futures instrument information based on futures contract code.
96
+
97
+ :param code: Futures contract code, such as: ES.
98
+ :param category: Security type, enumeration.
99
+ :param contract_type: Contract type, values include
100
+ - MONTHLY: Regular monthly contract
101
+ - MAIN: Main continuous contract
102
+ """
103
+
104
+ futures_instrument_request = GetFuturesInstrumentsByCodeRequest()
105
+ futures_instrument_request.set_codes(code)
106
+ futures_instrument_request.set_category(category)
107
+ if contract_type:
108
+ futures_instrument_request.set_contract_type(contract_type)
109
+ response = self.client.get_response(futures_instrument_request)
110
+ return response
@@ -18,8 +18,6 @@ from webull.data.request.get_historical_bars_request import GetHistoricalBarsReq
18
18
  from webull.data.request.get_quotes_request import GetQuotesRequest
19
19
  from webull.data.request.get_snapshot_request import GetSnapshotRequest
20
20
  from webull.data.request.get_tick_request import GetTickRequest
21
- from webull.data.request.subscribe_request import SubscribeRequest
22
- from webull.data.request.unsubscribe_request import UnsubcribeRequest
23
21
 
24
22
 
25
23
  class MarketData:
@@ -0,0 +1,40 @@
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
+
19
+ class GetCryptoHistoricalBarsRequest(ApiRequest):
20
+ def __init__(self):
21
+ ApiRequest.__init__(self, "/openapi/market-data/crypto/bars", version='v2', method="GET", query_params={})
22
+
23
+ def set_symbols(self, symbols):
24
+ if isinstance(symbols, str):
25
+ self.add_query_param("symbols", symbols)
26
+ elif isinstance(symbols, list):
27
+ self.add_query_param("symbols", ",".join(symbols))
28
+
29
+ def set_category(self, category):
30
+ self.add_query_param("category", category)
31
+
32
+ def set_timespan(self, timespan):
33
+ self.add_query_param("timespan", timespan)
34
+
35
+ def set_count(self, count='200'):
36
+ self.add_query_param("count", count)
37
+
38
+ def set_real_time_required(self, real_time_required):
39
+ if real_time_required:
40
+ self.add_query_param("real_time_required", real_time_required)
@@ -0,0 +1,44 @@
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 GetCryptoInstrumentsRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/instrument/crypto/list", 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
+ if category:
32
+ self.add_query_param("category", category)
33
+
34
+ def set_status(self, status):
35
+ if status:
36
+ self.add_query_param("status", status)
37
+
38
+ def set_last_instrument_id(self, last_instrument_id):
39
+ if last_instrument_id:
40
+ self.add_query_param("last_instrument_id", last_instrument_id)
41
+
42
+ def set_page_size(self, page_size):
43
+ if page_size:
44
+ self.add_query_param("page_size", page_size)
@@ -0,0 +1,31 @@
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 GetCryptoSnapshotRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/market-data/crypto/snapshot", 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)
@@ -0,0 +1,32 @@
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 GetFuturesDepthRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/market-data/futures/depth", version='v2', method="GET", query_params={})
23
+
24
+ def set_symbol(self, symbol):
25
+ self.add_query_param("symbol", symbol)
26
+
27
+ def set_category(self, category):
28
+ self.add_query_param("category", category)
29
+
30
+ def set_depth(self, depth):
31
+ if depth:
32
+ self.add_query_param("depth", depth)
@@ -0,0 +1,36 @@
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 GetFuturesHistoricalBarsRequest(ApiRequest):
19
+ def __init__(self):
20
+ ApiRequest.__init__(self, "/openapi/market-data/futures/bars", version='v2', method="GET", body_params={})
21
+
22
+ def set_symbols(self, symbol):
23
+ self.add_query_param("symbols", symbol)
24
+
25
+ def set_category(self, category):
26
+ self.add_query_param("category", category)
27
+
28
+ def set_timespan(self, timespan):
29
+ self.add_query_param("timespan", timespan)
30
+
31
+ def set_count(self, count='200'):
32
+ self.add_query_param("count", count)
33
+
34
+ def set_real_time_required(self, real_time_required):
35
+ if real_time_required:
36
+ self.add_query_param("real_time_required", real_time_required)
@@ -0,0 +1,36 @@
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 GetFuturesInstrumentsByCodeRequest(ApiRequest):
20
+ def __init__(self):
21
+ ApiRequest.__init__(self, "/openapi/instrument/futures/by-code", version='v2', method="GET", query_params={})
22
+
23
+ def set_codes(self, code):
24
+ self.add_query_param("code", code)
25
+
26
+ def set_category(self, category):
27
+ self.add_query_param("category", category)
28
+
29
+ def set_contract_type(self, contract_type):
30
+ """
31
+ Set the contract type for the futures instruments.
32
+ contract_type: Contract type, values include
33
+ - MONTHLY: Regular monthly contract
34
+ - MAIN: Main continuous contract
35
+ """
36
+ self.add_query_param("contract_type", contract_type)
@@ -0,0 +1,31 @@
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 GetFuturesInstrumentsRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/instrument/futures/list", 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)
@@ -0,0 +1,25 @@
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 GetFuturesProductsRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/instrument/futures/products", version='v2', method="GET", query_params={})
23
+
24
+ def set_category(self, category):
25
+ self.add_query_param("category", category)
@@ -0,0 +1,31 @@
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 GetFuturesSnapshotRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/market-data/futures/snapshot", 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)
@@ -0,0 +1,31 @@
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 GetFuturesTickRequest(ApiRequest):
21
+ def __init__(self):
22
+ ApiRequest.__init__(self, "/openapi/market-data/futures/tick", version='v2', method="GET", query_params={})
23
+
24
+ def set_symbol(self, symbol):
25
+ self.add_query_param("symbol", symbol)
26
+
27
+ def set_category(self, category):
28
+ self.add_query_param("category", category)
29
+
30
+ def set_count(self, count):
31
+ self.add_query_param("count", count)
@@ -27,4 +27,16 @@ class GetInstrumentsRequest(ApiRequest):
27
27
  self.add_query_param("symbols", ",".join(symbols))
28
28
 
29
29
  def set_category(self, category):
30
- self.add_query_param("category", category)
30
+ self.add_query_param("category", category)
31
+
32
+ def set_status(self, status):
33
+ if status:
34
+ self.add_query_param("status", status)
35
+
36
+ def set_last_instrument_id(self, last_instrument_id):
37
+ if last_instrument_id:
38
+ self.add_query_param("last_instrument_id", last_instrument_id)
39
+
40
+ def set_page_size(self, page_size):
41
+ if page_size:
42
+ self.add_query_param("page_size", page_size)
webull/trade/__init__.py CHANGED
@@ -1,2 +1,2 @@
1
- __version__ = "1.0.3"
1
+ __version__ = "1.0.5"
2
2
 
@@ -21,9 +21,8 @@ class Category(EasyEnum):
21
21
  US_STOCK = (1, 'US STOCK')
22
22
  US_OPTION = (2, 'US OPTION')
23
23
  HK_STOCK = (3, 'HK STOCK')
24
- CRYPTO = (4, 'CRYPTO')
25
24
  US_ETF = (5, 'US ETF')
26
25
  HK_ETF = (6, 'HK ETF')
27
26
  CN_STOCK = (7, "CN STOCK")
28
- NFT = (8, "NFT")
29
- US_CFDONSTOCK = (8, "US CFDON STOCK")
27
+ US_CRYPTO = (8, "US CRYPTO")
28
+ US_FUTURES = (12, "US FUTURES")
@@ -37,8 +37,10 @@ class PlaceOrderRequest(ApiRequest):
37
37
  if not new_orders:
38
38
  return
39
39
 
40
- if not isinstance(new_orders, (list, tuple)):
41
- market = new_orders.get("market")
42
- category = market + "_" + "STOCK"
40
+ if isinstance(new_orders, list) and new_orders[0]:
41
+ first_order = new_orders[0]
42
+ instrument_type = first_order.get("instrument_type")
43
+ market = first_order.get("market")
44
+ category = market + "_" + instrument_type
43
45
  if category is not None:
44
46
  self.add_header("category", category)
@@ -37,13 +37,13 @@ class PlaceOptionRequest(ApiRequest):
37
37
 
38
38
  if isinstance(new_orders, list) and new_orders[0]:
39
39
  first_order = new_orders[0]
40
- orders_list = first_order.get("orders", [])
41
- if isinstance(orders_list, list):
42
- for sub_order in orders_list:
43
- if (sub_order and isinstance(sub_order, dict)
44
- and sub_order.get("instrument_type") == "OPTION"):
45
- instrument_type = sub_order.get("instrument_type")
46
- market = sub_order.get("market")
40
+ leg_list = first_order.get("legs", [])
41
+ if isinstance(leg_list, list):
42
+ for sub_leg in leg_list:
43
+ if (sub_leg and isinstance(sub_leg, dict)
44
+ and sub_leg.get("instrument_type") == "OPTION"):
45
+ instrument_type = sub_leg.get("instrument_type")
46
+ market = sub_leg.get("market")
47
47
  category = market + "_" + instrument_type
48
48
  if category is not None:
49
49
  self.add_header("category", category)
@@ -19,9 +19,6 @@ from webull.core.request import ApiRequest
19
19
  class PlaceOrderRequest(ApiRequest):
20
20
  def __init__(self):
21
21
  super().__init__("/openapi/trade/stock/order/place", version='v2', method="POST", body_params={})
22
- self._new_orders = []
23
- self._current_order = {}
24
- self.add_body_params("new_orders", self._new_orders)
25
22
 
26
23
  def set_new_orders(self, new_orders):
27
24
  self.add_body_params("new_orders", new_orders)
@@ -37,8 +34,9 @@ class PlaceOrderRequest(ApiRequest):
37
34
  if not new_orders:
38
35
  return
39
36
 
40
- if not isinstance(new_orders, (list, tuple)):
41
- market = new_orders.get("market")
37
+ if isinstance(new_orders, list) and new_orders[0]:
38
+ first_order = new_orders[0]
39
+ market = first_order.get("market")
42
40
  category = market + "_" + "STOCK"
43
41
  if category is not None:
44
- self.add_header("category", category)
42
+ self.add_header("category", category)
File without changes