bt-api-base 0.15.1__tar.gz
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.
- bt_api_base-0.15.1/LICENSE +21 -0
- bt_api_base-0.15.1/PKG-INFO +536 -0
- bt_api_base-0.15.1/README.md +501 -0
- bt_api_base-0.15.1/pyproject.toml +90 -0
- bt_api_base-0.15.1/setup.cfg +4 -0
- bt_api_base-0.15.1/src/bt_api_base/__init__.py +7 -0
- bt_api_base-0.15.1/src/bt_api_base/_compat.py +29 -0
- bt_api_base-0.15.1/src/bt_api_base/_plugin_shims.py +28 -0
- bt_api_base-0.15.1/src/bt_api_base/_version.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/auth_config.py +171 -0
- bt_api_base-0.15.1/src/bt_api_base/balance_utils.py +99 -0
- bt_api_base-0.15.1/src/bt_api_base/cache.py +212 -0
- bt_api_base-0.15.1/src/bt_api_base/config_loader.py +288 -0
- bt_api_base-0.15.1/src/bt_api_base/connection_pool.py +247 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/__init__.py +45 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/accounts/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/accounts/account.py +182 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/auto_init_mixin.py +63 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/balances/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/balances/balance.py +260 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/bars/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/bars/bar.py +90 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/exchanges/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/exchanges/exchange_data.py +89 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/fundingrates/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/fundingrates/funding_rate.py +122 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/greeks/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/greeks/greeks.py +63 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/incomes/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/incomes/income.py +77 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/instrument.py +177 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/liquidations/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/liquidations/liquidation.py +61 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/markprices/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/markprices/mark_price.py +70 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/orderbooks/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/orderbooks/orderbook.py +94 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/orders/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/orders/order.py +290 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/positions/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/positions/position.py +196 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/requestdatas/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/requestdatas/request_data.py +173 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/symbols/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/symbols/symbol.py +125 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/tickers/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/tickers/ticker.py +169 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/timers/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/timers/timer.py +15 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/trades/__init__.py +5 -0
- bt_api_base-0.15.1/src/bt_api_base/containers/trades/trade.py +151 -0
- bt_api_base-0.15.1/src/bt_api_base/core/__init__.py +46 -0
- bt_api_base-0.15.1/src/bt_api_base/core/async_context.py +475 -0
- bt_api_base-0.15.1/src/bt_api_base/core/dependency_injection.py +261 -0
- bt_api_base-0.15.1/src/bt_api_base/core/interfaces.py +325 -0
- bt_api_base-0.15.1/src/bt_api_base/core/services.py +609 -0
- bt_api_base-0.15.1/src/bt_api_base/error.py +432 -0
- bt_api_base-0.15.1/src/bt_api_base/event_bus.py +136 -0
- bt_api_base-0.15.1/src/bt_api_base/exceptions.py +359 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/__init__.py +18 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/abstract_feed.py +305 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/base_stream.py +116 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/capability.py +110 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/connection_mixin.py +71 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/feed.py +633 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/http_client.py +304 -0
- bt_api_base-0.15.1/src/bt_api_base/feeds/my_websocket_app.py +324 -0
- bt_api_base-0.15.1/src/bt_api_base/functions/__init__.py +7 -0
- bt_api_base-0.15.1/src/bt_api_base/functions/async_base.py +132 -0
- bt_api_base-0.15.1/src/bt_api_base/functions/calculate_time.py +131 -0
- bt_api_base-0.15.1/src/bt_api_base/functions/log_message.py +124 -0
- bt_api_base-0.15.1/src/bt_api_base/functions/utils.py +301 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/__init__.py +22 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/adapters/__init__.py +42 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/adapters/base.py +56 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/adapters/plugin_adapter.py +81 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/models.py +53 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/protocol.py +39 -0
- bt_api_base-0.15.1/src/bt_api_base/gateway/registrar.py +37 -0
- bt_api_base-0.15.1/src/bt_api_base/instrument_manager.py +122 -0
- bt_api_base-0.15.1/src/bt_api_base/logging_factory.py +109 -0
- bt_api_base-0.15.1/src/bt_api_base/plugins/__init__.py +19 -0
- bt_api_base-0.15.1/src/bt_api_base/plugins/errors.py +17 -0
- bt_api_base-0.15.1/src/bt_api_base/plugins/loader.py +229 -0
- bt_api_base-0.15.1/src/bt_api_base/plugins/protocol.py +16 -0
- bt_api_base-0.15.1/src/bt_api_base/rate_limiter.py +304 -0
- bt_api_base-0.15.1/src/bt_api_base/registry.py +274 -0
- bt_api_base-0.15.1/src/bt_api_base/security.py +209 -0
- bt_api_base-0.15.1/src/bt_api_base/utils/__init__.py +3 -0
- bt_api_base-0.15.1/src/bt_api_base/utils/time.py +29 -0
- bt_api_base-0.15.1/src/bt_api_base/websocket/__init__.py +41 -0
- bt_api_base-0.15.1/src/bt_api_base/websocket/exchange_adapters.py +488 -0
- bt_api_base-0.15.1/src/bt_api_base/websocket_manager.py +594 -0
- bt_api_base-0.15.1/src/bt_api_base.egg-info/PKG-INFO +536 -0
- bt_api_base-0.15.1/src/bt_api_base.egg-info/SOURCES.txt +122 -0
- bt_api_base-0.15.1/src/bt_api_base.egg-info/dependency_links.txt +1 -0
- bt_api_base-0.15.1/src/bt_api_base.egg-info/requires.txt +25 -0
- bt_api_base-0.15.1/src/bt_api_base.egg-info/top_level.txt +2 -0
- bt_api_base-0.15.1/tests/test_async_context.py +96 -0
- bt_api_base-0.15.1/tests/test_async_context_quality.py +99 -0
- bt_api_base-0.15.1/tests/test_auto_init_mixin.py +76 -0
- bt_api_base-0.15.1/tests/test_cache.py +341 -0
- bt_api_base-0.15.1/tests/test_calculate_time.py +168 -0
- bt_api_base-0.15.1/tests/test_config_loader_quality.py +51 -0
- bt_api_base-0.15.1/tests/test_dependency_injection.py +55 -0
- bt_api_base-0.15.1/tests/test_error.py +466 -0
- bt_api_base-0.15.1/tests/test_event_bus.py +243 -0
- bt_api_base-0.15.1/tests/test_exceptions.py +648 -0
- bt_api_base-0.15.1/tests/test_exchange_data.py +101 -0
- bt_api_base-0.15.1/tests/test_instrument.py +156 -0
- bt_api_base-0.15.1/tests/test_logging_factory.py +88 -0
- bt_api_base-0.15.1/tests/test_package_metadata.py +11 -0
- bt_api_base-0.15.1/tests/test_protocol_conformance.py +278 -0
- bt_api_base-0.15.1/tests/test_quality_batch_v4.py +287 -0
- bt_api_base-0.15.1/tests/test_registry.py +149 -0
- bt_api_base-0.15.1/tests/test_request_data.py +92 -0
- bt_api_base-0.15.1/tests/test_security.py +217 -0
- bt_api_base-0.15.1/tests/test_services.py +279 -0
- bt_api_base-0.15.1/tests/test_services_quality.py +86 -0
- bt_api_base-0.15.1/tests/test_stage0_infrastructure.py +706 -0
- bt_api_base-0.15.1/tests/test_thread_safety.py +430 -0
- bt_api_base-0.15.1/tests/test_time.py +37 -0
- bt_api_base-0.15.1/tests/test_timer.py +41 -0
- bt_api_base-0.15.1/tests/test_utils.py +181 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 cloudQuant
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,536 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bt_api_base
|
|
3
|
+
Version: 0.15.1
|
|
4
|
+
Summary: Shared base abstractions for bt_api plugins
|
|
5
|
+
Author-email: cloudQuant <yunjinqi@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cloudQuant/bt_api_py
|
|
8
|
+
Project-URL: Repository, https://github.com/cloudQuant/bt_api_py
|
|
9
|
+
Requires-Python: >=3.9
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: numpy>=1.26.0
|
|
13
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
14
|
+
Requires-Dist: requests>=2.31.0
|
|
15
|
+
Requires-Dist: websocket-client>=1.6.0
|
|
16
|
+
Requires-Dist: pyyaml>=6.0
|
|
17
|
+
Requires-Dist: pandas>=2.0.0
|
|
18
|
+
Requires-Dist: aiohttp>=3.9.0
|
|
19
|
+
Requires-Dist: packaging>=24.0
|
|
20
|
+
Requires-Dist: spdlog>=2.0.0
|
|
21
|
+
Requires-Dist: pytz>=2023.3
|
|
22
|
+
Requires-Dist: python-rapidjson>=1.10
|
|
23
|
+
Requires-Dist: httpx>=0.27.0
|
|
24
|
+
Requires-Dist: pyzmq>=26.0.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0.0
|
|
26
|
+
Requires-Dist: websockets>=12.0
|
|
27
|
+
Requires-Dist: typing-extensions>=4.8.0
|
|
28
|
+
Requires-Dist: eval-type-backport>=0.2.0; python_version < "3.10"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
31
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
32
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
33
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
# bt_api_base
|
|
37
|
+
|
|
38
|
+
[](https://pypi.org/project/bt_api_base/)
|
|
39
|
+
[](https://pypi.org/project/bt_api_base/)
|
|
40
|
+
[](https://opensource.org/licenses/MIT)
|
|
41
|
+
[](https://github.com/cloudQuant/bt_api_base/actions)
|
|
42
|
+
[](https://bt-api-base.readthedocs.io/)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## English | [中文](#中文)
|
|
47
|
+
|
|
48
|
+
### Overview
|
|
49
|
+
|
|
50
|
+
`bt_api_base` is the **canonical shared base package** for the [bt_api](https://github.com/cloudQuant/bt_api_py) plugin ecosystem. It provides a standardized foundation that all exchange plugins (Binance, OKX, HTX, CTP, Interactive Brokers, etc.) depend on — without needing to import from the main application.
|
|
51
|
+
|
|
52
|
+
This package is the **core runtime dependency** for every `bt_api_xx` exchange plugin. It abstracts away the complexity of multi-exchange integration, letting plugin authors focus purely on exchange-specific API semantics.
|
|
53
|
+
|
|
54
|
+
### Architecture
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
bt_api_base/
|
|
58
|
+
├── src/bt_api_base/
|
|
59
|
+
│ ├── registry.py # ExchangeRegistry — plugin registration system
|
|
60
|
+
│ ├── event_bus.py # EventBus — pub/sub event dispatcher
|
|
61
|
+
│ ├── websocket_manager.py # WebSocketManager — connection pooling & auto-reconnect
|
|
62
|
+
│ ├── cache.py # SimpleCache, ExchangeInfoCache, MarketDataCache
|
|
63
|
+
│ ├── rate_limiter.py # SlidingWindowLimiter, FixedWindowLimiter, RateLimiter
|
|
64
|
+
│ ├── exceptions.py # Full exception hierarchy (20+ exception types)
|
|
65
|
+
│ ├── config_loader.py # Pydantic-based YAML config validation
|
|
66
|
+
│ ├── security.py # Authentication & request signing utilities
|
|
67
|
+
│ ├── balance_utils.py # Balance normalization helpers
|
|
68
|
+
│ ├── logging_factory.py # Structured logging setup
|
|
69
|
+
│ ├── feeds/ # AbstractVenueFeed protocol & AsyncWrapperMixin
|
|
70
|
+
│ ├── containers/ # Instrument, Tick, OrderBook, Bar, Order, Position, Balance...
|
|
71
|
+
│ ├── gateway/ # BaseGatewayAdapter, PluginGatewayAdapter
|
|
72
|
+
│ ├── plugins/ # PluginInfo, PluginLoader, PluginProtocol
|
|
73
|
+
│ └── core/ # AsyncTaskGroup, DependencyInjection, Interfaces, Services
|
|
74
|
+
├── tests/ # Comprehensive unit & integration tests
|
|
75
|
+
└── docs/ # API documentation
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Core Features
|
|
79
|
+
|
|
80
|
+
#### 1. Exchange Registry (Plugin System)
|
|
81
|
+
|
|
82
|
+
The `ExchangeRegistry` implements a **Registry Pattern** for plug-and-play exchange support:
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
from bt_api_base.registry import ExchangeRegistry
|
|
86
|
+
|
|
87
|
+
# Global singleton (backward compatible)
|
|
88
|
+
ExchangeRegistry.register_feed("BINANCE___SPOT", BinanceSpotFeed)
|
|
89
|
+
feed = ExchangeRegistry.create_feed("BINANCE___SPOT", data_queue)
|
|
90
|
+
|
|
91
|
+
# Isolated instance (for testing)
|
|
92
|
+
registry = ExchangeRegistry.create_isolated()
|
|
93
|
+
registry.register_feed("TEST___SPOT", MockFeed)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### 2. Event Bus
|
|
97
|
+
|
|
98
|
+
Publish/subscribe event dispatcher with **Queue mode** (existing behavior) and **Callback mode** (for CTP SPI / IB EWrapper callback-driven APIs):
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
from bt_api_base.event_bus import EventBus, ErrorHandlerMode
|
|
102
|
+
|
|
103
|
+
bus = EventBus(error_mode=ErrorHandlerMode.LOG)
|
|
104
|
+
|
|
105
|
+
bus.on("order_filled", lambda data: print(f"Order filled: {data}"))
|
|
106
|
+
bus.on("tick_update", lambda data: update_chart(data))
|
|
107
|
+
|
|
108
|
+
errors = bus.emit("order_filled", {"order_id": "123", "filled": 0.5})
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### 3. WebSocket Manager
|
|
112
|
+
|
|
113
|
+
Connection pooling with **auto-reconnect**, **backpressure handling**, and **subscription limiting**:
|
|
114
|
+
|
|
115
|
+
```python
|
|
116
|
+
from bt_api_base.websocket_manager import WebSocketManager, WebSocketConfig
|
|
117
|
+
|
|
118
|
+
config = WebSocketConfig(
|
|
119
|
+
url="wss://stream.binance.com:9443/ws",
|
|
120
|
+
exchange_name="BINANCE___SPOT",
|
|
121
|
+
max_connections=5,
|
|
122
|
+
heartbeat_interval=30.0,
|
|
123
|
+
reconnect_interval=5.0,
|
|
124
|
+
max_reconnect_attempts=10,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
manager = WebSocketManager()
|
|
128
|
+
await manager.add_exchange(config)
|
|
129
|
+
|
|
130
|
+
subscription_id = await manager.subscribe(
|
|
131
|
+
exchange_name="BINANCE___SPOT",
|
|
132
|
+
topic="ticker",
|
|
133
|
+
symbol="BTCUSDT",
|
|
134
|
+
callback=on_ticker_update,
|
|
135
|
+
)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
#### 4. Caching System
|
|
139
|
+
|
|
140
|
+
Three-tier caching with TTL support and thread-safe operations:
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
from bt_api_base.cache import SimpleCache, ExchangeInfoCache, MarketDataCache, cached
|
|
144
|
+
|
|
145
|
+
# Manual cache
|
|
146
|
+
cache = SimpleCache(default_ttl=300.0, max_size=10000)
|
|
147
|
+
cache.set("key", value, ttl=60)
|
|
148
|
+
value = cache.get("key")
|
|
149
|
+
|
|
150
|
+
# Decorator-based caching
|
|
151
|
+
@cached(ttl=60)
|
|
152
|
+
def fetch_exchange_info():
|
|
153
|
+
return requests.get("/api/v3/exchangeInfo").json()
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### 5. Rate Limiter
|
|
157
|
+
|
|
158
|
+
Supports **sliding window**, **fixed window**, and **token bucket** rate limiting with endpoint-level glob matching and weight mapping:
|
|
159
|
+
|
|
160
|
+
```python
|
|
161
|
+
from bt_api_base.rate_limiter import RateLimiter, RateLimitRule, RateLimitType, RateLimitScope
|
|
162
|
+
|
|
163
|
+
rules = [
|
|
164
|
+
RateLimitRule(name="global", type=RateLimitType.SLIDING_WINDOW,
|
|
165
|
+
interval=60, limit=1200, scope=RateLimitScope.GLOBAL),
|
|
166
|
+
RateLimitRule(name="order", type=RateLimitType.FIXED_WINDOW,
|
|
167
|
+
interval=1, limit=10, scope=RateLimitScope.ENDPOINT,
|
|
168
|
+
endpoint="/api/v3/order*",
|
|
169
|
+
weight_map={"POST": 10, "DELETE": 5, "GET": 1}),
|
|
170
|
+
]
|
|
171
|
+
|
|
172
|
+
limiter = RateLimiter(rules)
|
|
173
|
+
|
|
174
|
+
with limiter:
|
|
175
|
+
# Rate-limited request
|
|
176
|
+
response = requests.post("/api/v3/order", json=order_data)
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### 6. Configuration System
|
|
180
|
+
|
|
181
|
+
Pydantic-based YAML config validation with full schema checking:
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from bt_api_base.config_loader import load_exchange_config, ExchangeConfig
|
|
185
|
+
|
|
186
|
+
config = load_exchange_config("binance.yaml")
|
|
187
|
+
# Returns ExchangeConfig with validated fields
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
#### 7. Comprehensive Exception Hierarchy
|
|
191
|
+
|
|
192
|
+
20+ exception types with predicate functions for error classification:
|
|
193
|
+
|
|
194
|
+
```python
|
|
195
|
+
from bt_api_base.exceptions import (
|
|
196
|
+
BtApiError, ExchangeNotFoundError, AuthenticationError,
|
|
197
|
+
RateLimitError, OrderError, is_network_error, is_user_recoverable
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
try:
|
|
201
|
+
feed.make_order(...)
|
|
202
|
+
except RateLimitError as e:
|
|
203
|
+
wait_time = e.retry_after
|
|
204
|
+
except OrderError as e:
|
|
205
|
+
log.error(f"Order failed: {e}")
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### 8. Feed Protocol & Async Wrapper
|
|
209
|
+
|
|
210
|
+
Standardized `AbstractVenueFeed` protocol ensuring all exchange plugins implement a consistent interface:
|
|
211
|
+
|
|
212
|
+
```python
|
|
213
|
+
from bt_api_base.feeds.abstract_feed import AbstractVenueFeed, AsyncWrapperMixin
|
|
214
|
+
|
|
215
|
+
# All exchange feeds implement:
|
|
216
|
+
# - get_tick, get_depth, get_kline, make_order, cancel_order, get_balance, get_position...
|
|
217
|
+
# - async_* versions for each operation
|
|
218
|
+
# - connect, disconnect, is_connected
|
|
219
|
+
# - capabilities property
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Supported Exchanges
|
|
223
|
+
|
|
224
|
+
All exchange plugins in the bt_api ecosystem depend on bt_api_base:
|
|
225
|
+
|
|
226
|
+
| Exchange Plugin | Repository | Status |
|
|
227
|
+
|----------------|------------|--------|
|
|
228
|
+
| Binance | [bt_api_binance](https://github.com/cloudQuant/bt_api_binance) | ✅ |
|
|
229
|
+
| OKX | [bt_api_okx](https://github.com/cloudQuant/bt_api_okx) | ✅ |
|
|
230
|
+
| HTX | [bt_api_htx](https://github.com/cloudQuant/bt_api_htx) | ✅ |
|
|
231
|
+
| CTP (China Futures) | [bt_api_ctp](https://github.com/cloudQuant/bt_api_ctp) | ✅ |
|
|
232
|
+
| Interactive Brokers | [bt_api_ib_web](https://github.com/cloudQuant/bt_api_ib_web) | ✅ |
|
|
233
|
+
| Gemini | [bt_api_gemini](https://github.com/cloudQuant/bt_api_gemini) | ✅ |
|
|
234
|
+
| Bybit | [bt_api_bybit](https://github.com/cloudQuant/bt_api_bybit) | ✅ |
|
|
235
|
+
| Gate.io | [bt_api_gateio](https://github.com/cloudQuant/bt_api_gateio) | ✅ |
|
|
236
|
+
| MetaTrader 5 | [bt_api_mt5](https://github.com/cloudQuant/bt_api_mt5) | ✅ |
|
|
237
|
+
|
|
238
|
+
*And 54+ more exchange plugins...*
|
|
239
|
+
|
|
240
|
+
### Installation
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
pip install bt_api_base
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Or install from source:
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
git clone https://github.com/cloudQuant/bt_api_base
|
|
250
|
+
cd bt_api_base
|
|
251
|
+
pip install -e .
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
For development:
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
pip install -e ".[dev]"
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
### Requirements
|
|
261
|
+
|
|
262
|
+
- Python 3.9+
|
|
263
|
+
- pydantic >= 2.0
|
|
264
|
+
- numpy >= 1.26
|
|
265
|
+
- requests >= 2.31
|
|
266
|
+
- websocket-client >= 1.6
|
|
267
|
+
- aiohttp >= 3.9
|
|
268
|
+
- websockets >= 12.0
|
|
269
|
+
- pyyaml >= 6.0
|
|
270
|
+
|
|
271
|
+
### Online Documentation
|
|
272
|
+
|
|
273
|
+
| Resource | Link |
|
|
274
|
+
|----------|------|
|
|
275
|
+
| English Docs | https://bt-api-base.readthedocs.io/ |
|
|
276
|
+
| Chinese Docs | https://bt-api-base.readthedocs.io/zh/latest/ |
|
|
277
|
+
| GitHub Repository | https://github.com/cloudQuant/bt_api_base |
|
|
278
|
+
| Issue Tracker | https://github.com/cloudQuant/bt_api_base/issues |
|
|
279
|
+
| PyPI Package | https://pypi.org/project/bt_api_base/ |
|
|
280
|
+
| Main Project (bt_api_py) | https://github.com/cloudQuant/bt_api_py |
|
|
281
|
+
|
|
282
|
+
### License
|
|
283
|
+
|
|
284
|
+
MIT License - see [LICENSE](LICENSE) for details.
|
|
285
|
+
|
|
286
|
+
### Support
|
|
287
|
+
|
|
288
|
+
- Report bugs via [GitHub Issues](https://github.com/cloudQuant/bt_api_base/issues)
|
|
289
|
+
- Email: yunjinqi@gmail.com
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
## 中文
|
|
294
|
+
|
|
295
|
+
### 概述
|
|
296
|
+
|
|
297
|
+
`bt_api_base` 是 [bt_api](https://github.com/cloudQuant/bt_api_py) 插件生态系统的**标准共享基础包**。它为所有交易所插件(Binance、OKX、HTX、CTP、Interactive Brokers 等)提供标准化的基础依赖,让插件作者无需从主应用包导入,即可获得所有核心功能。
|
|
298
|
+
|
|
299
|
+
这个包是**每个 `bt_api_xx` 交易所插件的核心运行时依赖**。它将多交易所集成的复杂性抽象化,让插件作者专注于交易所特定的 API 语义。
|
|
300
|
+
|
|
301
|
+
### 架构
|
|
302
|
+
|
|
303
|
+
```
|
|
304
|
+
bt_api_base/
|
|
305
|
+
├── src/bt_api_base/
|
|
306
|
+
│ ├── registry.py # ExchangeRegistry — 插件注册系统
|
|
307
|
+
│ ├── event_bus.py # EventBus — 发布/订阅事件分发器
|
|
308
|
+
│ ├── websocket_manager.py # WebSocketManager — 连接池与自动重连
|
|
309
|
+
│ ├── cache.py # SimpleCache, ExchangeInfoCache, MarketDataCache
|
|
310
|
+
│ ├── rate_limiter.py # SlidingWindowLimiter, FixedWindowLimiter, RateLimiter
|
|
311
|
+
│ ├── exceptions.py # 完整异常层次结构(20+ 异常类型)
|
|
312
|
+
│ ├── config_loader.py # 基于 Pydantic 的 YAML 配置验证
|
|
313
|
+
│ ├── security.py # 认证与请求签名工具
|
|
314
|
+
│ ├── balance_utils.py # 余额规范化辅助函数
|
|
315
|
+
│ ├── logging_factory.py # 结构化日志配置
|
|
316
|
+
│ ├── feeds/ # AbstractVenueFeed 协议和 AsyncWrapperMixin
|
|
317
|
+
│ ├── containers/ # Instrument, Tick, OrderBook, Bar, Order, Position, Balance...
|
|
318
|
+
│ ├── gateway/ # BaseGatewayAdapter, PluginGatewayAdapter
|
|
319
|
+
│ ├── plugins/ # PluginInfo, PluginLoader, PluginProtocol
|
|
320
|
+
│ └── core/ # AsyncTaskGroup, DependencyInjection, Interfaces, Services
|
|
321
|
+
├── tests/ # 综合单元测试和集成测试
|
|
322
|
+
└── docs/ # API 文档
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### 核心功能
|
|
326
|
+
|
|
327
|
+
#### 1. 交易所注册表(插件系统)
|
|
328
|
+
|
|
329
|
+
`ExchangeRegistry` 实现**注册表模式**,支持插件式交易所接入:
|
|
330
|
+
|
|
331
|
+
```python
|
|
332
|
+
from bt_api_base.registry import ExchangeRegistry
|
|
333
|
+
|
|
334
|
+
# 全局单例(向后兼容)
|
|
335
|
+
ExchangeRegistry.register_feed("BINANCE___SPOT", BinanceSpotFeed)
|
|
336
|
+
feed = ExchangeRegistry.create_feed("BINANCE___SPOT", data_queue)
|
|
337
|
+
|
|
338
|
+
# 隔离实例(用于测试)
|
|
339
|
+
registry = ExchangeRegistry.create_isolated()
|
|
340
|
+
registry.register_feed("TEST___SPOT", MockFeed)
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
#### 2. 事件总线
|
|
344
|
+
|
|
345
|
+
支持 **Queue 模式**(现有行为)和 **Callback 模式**(适配 CTP SPI / IB EWrapper 等回调驱动 API)的发布/订阅事件分发器:
|
|
346
|
+
|
|
347
|
+
```python
|
|
348
|
+
from bt_api_base.event_bus import EventBus, ErrorHandlerMode
|
|
349
|
+
|
|
350
|
+
bus = EventBus(error_mode=ErrorHandlerMode.LOG)
|
|
351
|
+
|
|
352
|
+
bus.on("order_filled", lambda data: print(f"订单成交: {data}"))
|
|
353
|
+
bus.on("tick_update", lambda data: update_chart(data))
|
|
354
|
+
|
|
355
|
+
errors = bus.emit("order_filled", {"order_id": "123", "filled": 0.5})
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### 3. WebSocket 管理器
|
|
359
|
+
|
|
360
|
+
支持**自动重连**、**背压处理**和**订阅限制**的连接池:
|
|
361
|
+
|
|
362
|
+
```python
|
|
363
|
+
from bt_api_base.websocket_manager import WebSocketManager, WebSocketConfig
|
|
364
|
+
|
|
365
|
+
config = WebSocketConfig(
|
|
366
|
+
url="wss://stream.binance.com:9443/ws",
|
|
367
|
+
exchange_name="BINANCE___SPOT",
|
|
368
|
+
max_connections=5,
|
|
369
|
+
heartbeat_interval=30.0,
|
|
370
|
+
reconnect_interval=5.0,
|
|
371
|
+
max_reconnect_attempts=10,
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
manager = WebSocketManager()
|
|
375
|
+
await manager.add_exchange(config)
|
|
376
|
+
|
|
377
|
+
subscription_id = await manager.subscribe(
|
|
378
|
+
exchange_name="BINANCE___SPOT",
|
|
379
|
+
topic="ticker",
|
|
380
|
+
symbol="BTCUSDT",
|
|
381
|
+
callback=on_ticker_update,
|
|
382
|
+
)
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
#### 4. 缓存系统
|
|
386
|
+
|
|
387
|
+
三层缓存系统,支持 TTL 和线程安全操作:
|
|
388
|
+
|
|
389
|
+
```python
|
|
390
|
+
from bt_api_base.cache import SimpleCache, ExchangeInfoCache, MarketDataCache, cached
|
|
391
|
+
|
|
392
|
+
# 手动缓存
|
|
393
|
+
cache = SimpleCache(default_ttl=300.0, max_size=10000)
|
|
394
|
+
cache.set("key", value, ttl=60)
|
|
395
|
+
value = cache.get("key")
|
|
396
|
+
|
|
397
|
+
# 装饰器缓存
|
|
398
|
+
@cached(ttl=60)
|
|
399
|
+
def fetch_exchange_info():
|
|
400
|
+
return requests.get("/api/v3/exchangeInfo").json()
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
#### 5. 限流器
|
|
404
|
+
|
|
405
|
+
支持**滑动窗口**、**固定窗口**和**令牌桶**限流,端点级 glob 匹配和权重映射:
|
|
406
|
+
|
|
407
|
+
```python
|
|
408
|
+
from bt_api_base.rate_limiter import RateLimiter, RateLimitRule, RateLimitType, RateLimitScope
|
|
409
|
+
|
|
410
|
+
rules = [
|
|
411
|
+
RateLimitRule(name="global", type=RateLimitType.SLIDING_WINDOW,
|
|
412
|
+
interval=60, limit=1200, scope=RateLimitScope.GLOBAL),
|
|
413
|
+
RateLimitRule(name="order", type=RateLimitType.FIXED_WINDOW,
|
|
414
|
+
interval=1, limit=10, scope=RateLimitScope.ENDPOINT,
|
|
415
|
+
endpoint="/api/v3/order*",
|
|
416
|
+
weight_map={"POST": 10, "DELETE": 5, "GET": 1}),
|
|
417
|
+
]
|
|
418
|
+
|
|
419
|
+
limiter = RateLimiter(rules)
|
|
420
|
+
|
|
421
|
+
with limiter:
|
|
422
|
+
# 限流请求
|
|
423
|
+
response = requests.post("/api/v3/order", json=order_data)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### 6. 配置系统
|
|
427
|
+
|
|
428
|
+
基于 Pydantic 的 YAML 配置验证,支持完整 Schema 检查:
|
|
429
|
+
|
|
430
|
+
```python
|
|
431
|
+
from bt_api_base.config_loader import load_exchange_config, ExchangeConfig
|
|
432
|
+
|
|
433
|
+
config = load_exchange_config("binance.yaml")
|
|
434
|
+
# 返回经过字段验证的 ExchangeConfig
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
#### 7. 完整异常层次结构
|
|
438
|
+
|
|
439
|
+
20+ 异常类型,带错误分类谓词函数:
|
|
440
|
+
|
|
441
|
+
```python
|
|
442
|
+
from bt_api_base.exceptions import (
|
|
443
|
+
BtApiError, ExchangeNotFoundError, AuthenticationError,
|
|
444
|
+
RateLimitError, OrderError, is_network_error, is_user_recoverable
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
try:
|
|
448
|
+
feed.make_order(...)
|
|
449
|
+
except RateLimitError as e:
|
|
450
|
+
wait_time = e.retry_after
|
|
451
|
+
except OrderError as e:
|
|
452
|
+
log.error(f"订单失败: {e}")
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
#### 8. Feed 协议和异步封装
|
|
456
|
+
|
|
457
|
+
标准化的 `AbstractVenueFeed` 协议,确保所有交易所插件实现一致接口:
|
|
458
|
+
|
|
459
|
+
```python
|
|
460
|
+
from bt_api_base.feeds.abstract_feed import AbstractVenueFeed, AsyncWrapperMixin
|
|
461
|
+
|
|
462
|
+
# 所有交易所 feeds 都实现:
|
|
463
|
+
# - get_tick, get_depth, get_kline, make_order, cancel_order, get_balance, get_position...
|
|
464
|
+
# - 各操作的 async_* 版本
|
|
465
|
+
# - connect, disconnect, is_connected
|
|
466
|
+
# - capabilities 属性
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
### 支持的交易所
|
|
470
|
+
|
|
471
|
+
bt_api 生态系统中所有交易所插件都依赖 bt_api_base:
|
|
472
|
+
|
|
473
|
+
| 交易所插件 | 仓库 | 状态 |
|
|
474
|
+
|----------------|------------|--------|
|
|
475
|
+
| Binance | [bt_api_binance](https://github.com/cloudQuant/bt_api_binance) | ✅ |
|
|
476
|
+
| OKX | [bt_api_okx](https://github.com/cloudQuant/bt_api_okx) | ✅ |
|
|
477
|
+
| HTX (火币) | [bt_api_htx](https://github.com/cloudQuant/bt_api_htx) | ✅ |
|
|
478
|
+
| CTP (中国期货) | [bt_api_ctp](https://github.com/cloudQuant/bt_api_ctp) | ✅ |
|
|
479
|
+
| Interactive Brokers | [bt_api_ib_web](https://github.com/cloudQuant/bt_api_ib_web) | ✅ |
|
|
480
|
+
| Gemini | [bt_api_gemini](https://github.com/cloudQuant/bt_api_gemini) | ✅ |
|
|
481
|
+
| Bybit | [bt_api_bybit](https://github.com/cloudQuant/bt_api_bybit) | ✅ |
|
|
482
|
+
| Gate.io | [bt_api_gateio](https://github.com/cloudQuant/bt_api_gateio) | ✅ |
|
|
483
|
+
| MetaTrader 5 | [bt_api_mt5](https://github.com/cloudQuant/bt_api_mt5) | ✅ |
|
|
484
|
+
|
|
485
|
+
*以及 54+ 更多交易所插件...*
|
|
486
|
+
|
|
487
|
+
### 安装
|
|
488
|
+
|
|
489
|
+
```bash
|
|
490
|
+
pip install bt_api_base
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
或从源码安装:
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
git clone https://github.com/cloudQuant/bt_api_base
|
|
497
|
+
cd bt_api_base
|
|
498
|
+
pip install -e .
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
开发安装:
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
pip install -e ".[dev]"
|
|
505
|
+
```
|
|
506
|
+
|
|
507
|
+
### 系统要求
|
|
508
|
+
|
|
509
|
+
- Python 3.9+
|
|
510
|
+
- pydantic >= 2.0
|
|
511
|
+
- numpy >= 1.26
|
|
512
|
+
- requests >= 2.31
|
|
513
|
+
- websocket-client >= 1.6
|
|
514
|
+
- aiohttp >= 3.9
|
|
515
|
+
- websockets >= 12.0
|
|
516
|
+
- pyyaml >= 6.0
|
|
517
|
+
|
|
518
|
+
### 在线文档
|
|
519
|
+
|
|
520
|
+
| 资源 | 链接 |
|
|
521
|
+
|----------|------|
|
|
522
|
+
| 英文文档 | https://bt-api-base.readthedocs.io/ |
|
|
523
|
+
| 中文文档 | https://bt-api-base.readthedocs.io/zh/latest/ |
|
|
524
|
+
| GitHub 仓库 | https://github.com/cloudQuant/bt_api_base |
|
|
525
|
+
| 问题反馈 | https://github.com/cloudQuant/bt_api_base/issues |
|
|
526
|
+
| PyPI 包 | https://pypi.org/project/bt_api_base/ |
|
|
527
|
+
| 主项目 (bt_api_py) | https://github.com/cloudQuant/bt_api_py |
|
|
528
|
+
|
|
529
|
+
### 许可证
|
|
530
|
+
|
|
531
|
+
MIT 许可证 - 详见 [LICENSE](LICENSE)。
|
|
532
|
+
|
|
533
|
+
### 技术支持
|
|
534
|
+
|
|
535
|
+
- 通过 [GitHub Issues](https://github.com/cloudQuant/bt_api_base/issues) 反馈问题
|
|
536
|
+
- 邮箱: yunjinqi@gmail.com
|