chub-dev 0.1.0 → 0.1.2-beta.0
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.
- package/README.md +55 -0
- package/bin/chub-mcp +2 -0
- package/dist/airtable/docs/database/javascript/DOC.md +1437 -0
- package/dist/airtable/docs/database/python/DOC.md +1735 -0
- package/dist/amplitude/docs/analytics/javascript/DOC.md +1282 -0
- package/dist/amplitude/docs/analytics/python/DOC.md +1199 -0
- package/dist/anthropic/docs/claude-api/javascript/DOC.md +503 -0
- package/dist/anthropic/docs/claude-api/python/DOC.md +389 -0
- package/dist/asana/docs/tasks/DOC.md +1396 -0
- package/dist/assemblyai/docs/transcription/DOC.md +1043 -0
- package/dist/atlassian/docs/confluence/javascript/DOC.md +1347 -0
- package/dist/atlassian/docs/confluence/python/DOC.md +1604 -0
- package/dist/auth0/docs/identity/javascript/DOC.md +968 -0
- package/dist/auth0/docs/identity/python/DOC.md +1199 -0
- package/dist/aws/docs/s3/javascript/DOC.md +1773 -0
- package/dist/aws/docs/s3/python/DOC.md +1807 -0
- package/dist/binance/docs/trading/javascript/DOC.md +1315 -0
- package/dist/binance/docs/trading/python/DOC.md +1454 -0
- package/dist/braintree/docs/gateway/javascript/DOC.md +1278 -0
- package/dist/braintree/docs/gateway/python/DOC.md +1179 -0
- package/dist/chromadb/docs/embeddings-db/javascript/DOC.md +1263 -0
- package/dist/chromadb/docs/embeddings-db/python/DOC.md +1707 -0
- package/dist/clerk/docs/auth/javascript/DOC.md +1220 -0
- package/dist/clerk/docs/auth/python/DOC.md +274 -0
- package/dist/cloudflare/docs/workers/javascript/DOC.md +918 -0
- package/dist/cloudflare/docs/workers/python/DOC.md +994 -0
- package/dist/cockroachdb/docs/distributed-db/DOC.md +1500 -0
- package/dist/cohere/docs/llm/DOC.md +1335 -0
- package/dist/datadog/docs/monitoring/javascript/DOC.md +1740 -0
- package/dist/datadog/docs/monitoring/python/DOC.md +1815 -0
- package/dist/deepgram/docs/speech/javascript/DOC.md +885 -0
- package/dist/deepgram/docs/speech/python/DOC.md +685 -0
- package/dist/deepl/docs/translation/javascript/DOC.md +887 -0
- package/dist/deepl/docs/translation/python/DOC.md +944 -0
- package/dist/deepseek/docs/llm/DOC.md +1220 -0
- package/dist/directus/docs/headless-cms/javascript/DOC.md +1128 -0
- package/dist/directus/docs/headless-cms/python/DOC.md +1276 -0
- package/dist/discord/docs/bot/javascript/DOC.md +1090 -0
- package/dist/discord/docs/bot/python/DOC.md +1130 -0
- package/dist/elasticsearch/docs/search/DOC.md +1634 -0
- package/dist/elevenlabs/docs/text-to-speech/javascript/DOC.md +336 -0
- package/dist/elevenlabs/docs/text-to-speech/python/DOC.md +552 -0
- package/dist/firebase/docs/auth/DOC.md +1015 -0
- package/dist/gemini/docs/genai/javascript/DOC.md +691 -0
- package/dist/gemini/docs/genai/python/DOC.md +555 -0
- package/dist/github/docs/octokit/DOC.md +1560 -0
- package/dist/google/docs/bigquery/javascript/DOC.md +1688 -0
- package/dist/google/docs/bigquery/python/DOC.md +1503 -0
- package/dist/hubspot/docs/crm/javascript/DOC.md +1805 -0
- package/dist/hubspot/docs/crm/python/DOC.md +2033 -0
- package/dist/huggingface/docs/transformers/DOC.md +948 -0
- package/dist/intercom/docs/messaging/javascript/DOC.md +1844 -0
- package/dist/intercom/docs/messaging/python/DOC.md +1797 -0
- package/dist/jira/docs/issues/javascript/DOC.md +1420 -0
- package/dist/jira/docs/issues/python/DOC.md +1492 -0
- package/dist/kafka/docs/streaming/javascript/DOC.md +1671 -0
- package/dist/kafka/docs/streaming/python/DOC.md +1464 -0
- package/dist/landingai-ade/docs/api/DOC.md +620 -0
- package/dist/landingai-ade/docs/sdk/python/DOC.md +489 -0
- package/dist/landingai-ade/docs/sdk/typescript/DOC.md +542 -0
- package/dist/landingai-ade/skills/SKILL.md +489 -0
- package/dist/launchdarkly/docs/feature-flags/javascript/DOC.md +1191 -0
- package/dist/launchdarkly/docs/feature-flags/python/DOC.md +1671 -0
- package/dist/linear/docs/tracker/DOC.md +1554 -0
- package/dist/livekit/docs/realtime/javascript/DOC.md +303 -0
- package/dist/livekit/docs/realtime/python/DOC.md +163 -0
- package/dist/mailchimp/docs/marketing/DOC.md +1420 -0
- package/dist/meilisearch/docs/search/DOC.md +1241 -0
- package/dist/microsoft/docs/onedrive/javascript/DOC.md +1421 -0
- package/dist/microsoft/docs/onedrive/python/DOC.md +1549 -0
- package/dist/mongodb/docs/atlas/DOC.md +2041 -0
- package/dist/notion/docs/workspace-api/javascript/DOC.md +1435 -0
- package/dist/notion/docs/workspace-api/python/DOC.md +1400 -0
- package/dist/okta/docs/identity/javascript/DOC.md +1171 -0
- package/dist/okta/docs/identity/python/DOC.md +1401 -0
- package/dist/openai/docs/chat/javascript/DOC.md +407 -0
- package/dist/openai/docs/chat/python/DOC.md +568 -0
- package/dist/paypal/docs/checkout/DOC.md +278 -0
- package/dist/pinecone/docs/sdk/javascript/DOC.md +984 -0
- package/dist/pinecone/docs/sdk/python/DOC.md +1395 -0
- package/dist/plaid/docs/banking/javascript/DOC.md +1163 -0
- package/dist/plaid/docs/banking/python/DOC.md +1203 -0
- package/dist/playwright-community/skills/login-flows/SKILL.md +108 -0
- package/dist/postmark/docs/transactional-email/DOC.md +1168 -0
- package/dist/prisma/docs/orm/javascript/DOC.md +1419 -0
- package/dist/prisma/docs/orm/python/DOC.md +1317 -0
- package/dist/qdrant/docs/vector-search/javascript/DOC.md +1221 -0
- package/dist/qdrant/docs/vector-search/python/DOC.md +1653 -0
- package/dist/rabbitmq/docs/message-queue/javascript/DOC.md +1193 -0
- package/dist/rabbitmq/docs/message-queue/python/DOC.md +1243 -0
- package/dist/razorpay/docs/payments/javascript/DOC.md +1219 -0
- package/dist/razorpay/docs/payments/python/DOC.md +1330 -0
- package/dist/redis/docs/key-value/javascript/DOC.md +1851 -0
- package/dist/redis/docs/key-value/python/DOC.md +2054 -0
- package/dist/registry.json +2817 -0
- package/dist/replicate/docs/model-hosting/DOC.md +1318 -0
- package/dist/resend/docs/email/DOC.md +1271 -0
- package/dist/salesforce/docs/crm/javascript/DOC.md +1241 -0
- package/dist/salesforce/docs/crm/python/DOC.md +1183 -0
- package/dist/search-index.json +1 -0
- package/dist/sendgrid/docs/email-api/javascript/DOC.md +371 -0
- package/dist/sendgrid/docs/email-api/python/DOC.md +656 -0
- package/dist/sentry/docs/error-tracking/javascript/DOC.md +1073 -0
- package/dist/sentry/docs/error-tracking/python/DOC.md +1309 -0
- package/dist/shopify/docs/storefront/DOC.md +457 -0
- package/dist/slack/docs/workspace/javascript/DOC.md +933 -0
- package/dist/slack/docs/workspace/python/DOC.md +271 -0
- package/dist/square/docs/payments/javascript/DOC.md +1855 -0
- package/dist/square/docs/payments/python/DOC.md +1728 -0
- package/dist/stripe/docs/api/DOC.md +1727 -0
- package/dist/stripe/docs/payments/DOC.md +1726 -0
- package/dist/stytch/docs/auth/javascript/DOC.md +1813 -0
- package/dist/stytch/docs/auth/python/DOC.md +1962 -0
- package/dist/supabase/docs/client/DOC.md +1606 -0
- package/dist/twilio/docs/messaging/python/DOC.md +469 -0
- package/dist/twilio/docs/messaging/typescript/DOC.md +946 -0
- package/dist/vercel/docs/platform/DOC.md +1940 -0
- package/dist/weaviate/docs/vector-db/javascript/DOC.md +1268 -0
- package/dist/weaviate/docs/vector-db/python/DOC.md +1388 -0
- package/dist/zendesk/docs/support/javascript/DOC.md +2150 -0
- package/dist/zendesk/docs/support/python/DOC.md +2297 -0
- package/package.json +22 -6
- package/skills/get-api-docs/SKILL.md +84 -0
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +12 -1
- package/src/commands/feedback.js +150 -0
- package/src/commands/get.js +83 -42
- package/src/commands/search.js +7 -0
- package/src/index.js +43 -17
- package/src/lib/analytics.js +90 -0
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +69 -6
- package/src/lib/config.js +8 -3
- package/src/lib/identity.js +99 -0
- package/src/lib/registry.js +103 -20
- package/src/lib/telemetry.js +86 -0
- package/src/mcp/server.js +177 -0
- package/src/mcp/tools.js +251 -0
|
@@ -0,0 +1,1454 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: trading
|
|
3
|
+
description: "Binance API Python coding guidelines for trading using official libraries and SDKs"
|
|
4
|
+
metadata:
|
|
5
|
+
languages: "python"
|
|
6
|
+
versions: "3.12.0"
|
|
7
|
+
updated-on: "2026-03-02"
|
|
8
|
+
source: maintainer
|
|
9
|
+
tags: "binance,trading,crypto,exchange,api"
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Binance API Python Coding Guidelines
|
|
13
|
+
|
|
14
|
+
You are a Binance API coding expert. Help me with writing code using the Binance API calling the official libraries and SDKs.
|
|
15
|
+
|
|
16
|
+
You can find the official documentation here:
|
|
17
|
+
https://developers.binance.com/docs/binance-spot-api-docs
|
|
18
|
+
|
|
19
|
+
## Golden Rule: Use the Correct and Current SDK
|
|
20
|
+
|
|
21
|
+
Always use the official Binance Connector for Python, which is the standard library for all Binance Spot API interactions. Do not use unofficial or third-party libraries.
|
|
22
|
+
|
|
23
|
+
- **Library Name:** Binance Connector Python
|
|
24
|
+
- **PyPI Package:** `binance-connector`
|
|
25
|
+
- **Alternative Official Packages:** `binance-sdk-spot` (newer modular package), `binance-futures-connector`, `binance-pay-connector`
|
|
26
|
+
- **Unofficial Libraries:** `python-binance`, `binance.py` (not recommended for production)
|
|
27
|
+
|
|
28
|
+
**Installation:**
|
|
29
|
+
|
|
30
|
+
- **Correct:** `pip install binance-connector`
|
|
31
|
+
- **Alternative:** `pip install binance-sdk-spot` (for newer modular approach)
|
|
32
|
+
|
|
33
|
+
**APIs and Usage:**
|
|
34
|
+
|
|
35
|
+
- **Correct:** `from binance.spot import Spot`
|
|
36
|
+
- **Correct:** `client = Spot(api_key='...', api_secret='...')`
|
|
37
|
+
- **Correct:** `client.account()` for account information
|
|
38
|
+
- **Correct:** `client.new_order()` for placing orders
|
|
39
|
+
- **Incorrect:** Using unofficial packages like `python-binance`
|
|
40
|
+
- **Incorrect:** Direct HTTP requests without using the connector
|
|
41
|
+
|
|
42
|
+
## Installation
|
|
43
|
+
|
|
44
|
+
Install the official Binance connector for Python:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install binance-connector
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For Python 3.9 or later, you can also use the modular SDK:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install binance-sdk-spot
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Environment Variables:**
|
|
57
|
+
|
|
58
|
+
Set your API credentials as environment variables:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
export BINANCE_API_KEY='your_api_key_here'
|
|
62
|
+
export BINANCE_API_SECRET='your_api_secret_here'
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or create a `.env` file:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
BINANCE_API_KEY=your_api_key_here
|
|
69
|
+
BINANCE_API_SECRET=your_api_secret_here
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Load environment variables in Python:
|
|
73
|
+
|
|
74
|
+
```python
|
|
75
|
+
import os
|
|
76
|
+
from dotenv import load_dotenv
|
|
77
|
+
|
|
78
|
+
load_dotenv()
|
|
79
|
+
|
|
80
|
+
api_key = os.getenv('BINANCE_API_KEY')
|
|
81
|
+
api_secret = os.getenv('BINANCE_API_SECRET')
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Initialization
|
|
85
|
+
|
|
86
|
+
The `binance-connector` library requires creating a `Spot` instance for all API calls.
|
|
87
|
+
|
|
88
|
+
### Basic Initialization (Public Endpoints)
|
|
89
|
+
|
|
90
|
+
For public market data endpoints that don't require authentication:
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from binance.spot import Spot
|
|
94
|
+
|
|
95
|
+
# Public endpoints only (no authentication)
|
|
96
|
+
client = Spot()
|
|
97
|
+
|
|
98
|
+
# Use client for public data
|
|
99
|
+
exchange_info = client.exchange_info()
|
|
100
|
+
print(exchange_info)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Authenticated Initialization (HMAC)
|
|
104
|
+
|
|
105
|
+
For trading and account endpoints:
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
import os
|
|
109
|
+
from binance.spot import Spot
|
|
110
|
+
|
|
111
|
+
api_key = os.getenv('BINANCE_API_KEY')
|
|
112
|
+
api_secret = os.getenv('BINANCE_API_SECRET')
|
|
113
|
+
|
|
114
|
+
# Authenticated client with HMAC
|
|
115
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
116
|
+
|
|
117
|
+
# Use client for authenticated endpoints
|
|
118
|
+
account_info = client.account()
|
|
119
|
+
print(account_info)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### RSA/ED25519 Authentication
|
|
123
|
+
|
|
124
|
+
For enhanced security using RSA or ED25519 private keys:
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
from binance.spot import Spot
|
|
128
|
+
|
|
129
|
+
api_key = os.getenv('BINANCE_API_KEY')
|
|
130
|
+
|
|
131
|
+
# Read private key from file
|
|
132
|
+
with open('/path/to/private_key.pem', 'r') as f:
|
|
133
|
+
private_key = f.read()
|
|
134
|
+
|
|
135
|
+
# Initialize with RSA key
|
|
136
|
+
client = Spot(
|
|
137
|
+
api_key=api_key,
|
|
138
|
+
private_key=private_key,
|
|
139
|
+
private_key_pass='your_passphrase' # Optional
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
# For ED25519 keys, the connector auto-detects the key type
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Client Configuration Options
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from binance.spot import Spot
|
|
149
|
+
|
|
150
|
+
client = Spot(
|
|
151
|
+
api_key=api_key,
|
|
152
|
+
api_secret=api_secret,
|
|
153
|
+
base_url='https://api.binance.com', # Default base URL
|
|
154
|
+
timeout=10, # Request timeout in seconds
|
|
155
|
+
proxies=None, # Proxy configuration
|
|
156
|
+
show_limit_usage=False, # Show rate limit usage in response
|
|
157
|
+
show_header=False # Include response headers
|
|
158
|
+
)
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### Testnet Configuration
|
|
162
|
+
|
|
163
|
+
For testing without real funds:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from binance.spot import Spot
|
|
167
|
+
|
|
168
|
+
client = Spot(
|
|
169
|
+
api_key=api_key,
|
|
170
|
+
api_secret=api_secret,
|
|
171
|
+
base_url='https://testnet.binance.vision'
|
|
172
|
+
)
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
### Proxy Configuration
|
|
176
|
+
|
|
177
|
+
For requests through a proxy:
|
|
178
|
+
|
|
179
|
+
```python
|
|
180
|
+
from binance.spot import Spot
|
|
181
|
+
|
|
182
|
+
proxies = {
|
|
183
|
+
'http': 'http://username:password@proxy.example.com:8080',
|
|
184
|
+
'https': 'https://username:password@proxy.example.com:8080'
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
client = Spot(
|
|
188
|
+
api_key=api_key,
|
|
189
|
+
api_secret=api_secret,
|
|
190
|
+
proxies=proxies
|
|
191
|
+
)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### Logging Configuration
|
|
195
|
+
|
|
196
|
+
Enable logging for debugging:
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
import logging
|
|
200
|
+
from binance.spot import Spot
|
|
201
|
+
from binance.lib.utils import config_logging
|
|
202
|
+
|
|
203
|
+
# Configure logging
|
|
204
|
+
config_logging(logging, logging.DEBUG)
|
|
205
|
+
|
|
206
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
207
|
+
|
|
208
|
+
# All API calls will now be logged
|
|
209
|
+
account_info = client.account()
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Market Data Endpoints
|
|
213
|
+
|
|
214
|
+
Market data endpoints provide access to public trading information without authentication.
|
|
215
|
+
|
|
216
|
+
### Exchange Information
|
|
217
|
+
|
|
218
|
+
Get exchange trading rules and symbol information:
|
|
219
|
+
|
|
220
|
+
```python
|
|
221
|
+
from binance.spot import Spot
|
|
222
|
+
|
|
223
|
+
client = Spot()
|
|
224
|
+
|
|
225
|
+
# Get all exchange information
|
|
226
|
+
exchange_info = client.exchange_info()
|
|
227
|
+
print(exchange_info)
|
|
228
|
+
|
|
229
|
+
# Get specific symbol information
|
|
230
|
+
exchange_info = client.exchange_info(symbol='BTCUSDT')
|
|
231
|
+
print(exchange_info)
|
|
232
|
+
|
|
233
|
+
# Get information for multiple symbols
|
|
234
|
+
exchange_info = client.exchange_info(symbols=['BTCUSDT', 'ETHUSDT'])
|
|
235
|
+
print(exchange_info)
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
### Order Book (Depth)
|
|
239
|
+
|
|
240
|
+
Get current order book for a symbol:
|
|
241
|
+
|
|
242
|
+
```python
|
|
243
|
+
# Get order book with default limit (100)
|
|
244
|
+
depth = client.depth('BTCUSDT')
|
|
245
|
+
print(depth)
|
|
246
|
+
|
|
247
|
+
# Get order book with specific limit (5, 10, 20, 50, 100, 500, 1000, 5000)
|
|
248
|
+
depth = client.depth('BTCUSDT', limit=10)
|
|
249
|
+
print(depth)
|
|
250
|
+
|
|
251
|
+
# Access bids and asks
|
|
252
|
+
bids = depth['bids']
|
|
253
|
+
asks = depth['asks']
|
|
254
|
+
print(f"Best Bid: {bids[0]}")
|
|
255
|
+
print(f"Best Ask: {asks[0]}")
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
### Recent Trades
|
|
259
|
+
|
|
260
|
+
Get recent trades for a symbol:
|
|
261
|
+
|
|
262
|
+
```python
|
|
263
|
+
# Get recent trades (default limit: 500)
|
|
264
|
+
trades = client.trades('BTCUSDT')
|
|
265
|
+
print(trades)
|
|
266
|
+
|
|
267
|
+
# Get specific number of recent trades
|
|
268
|
+
trades = client.trades('BTCUSDT', limit=100)
|
|
269
|
+
print(trades)
|
|
270
|
+
|
|
271
|
+
# Process trades
|
|
272
|
+
for trade in trades:
|
|
273
|
+
print(f"Price: {trade['price']}, Qty: {trade['qty']}, Time: {trade['time']}")
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
### Historical Trades
|
|
277
|
+
|
|
278
|
+
Get older trades (requires API key):
|
|
279
|
+
|
|
280
|
+
```python
|
|
281
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
282
|
+
|
|
283
|
+
# Get historical trades
|
|
284
|
+
historical_trades = client.historical_trades('BTCUSDT', limit=100)
|
|
285
|
+
print(historical_trades)
|
|
286
|
+
|
|
287
|
+
# Get trades from specific ID
|
|
288
|
+
historical_trades = client.historical_trades('BTCUSDT', limit=100, fromId=28457)
|
|
289
|
+
print(historical_trades)
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
### Aggregate Trades
|
|
293
|
+
|
|
294
|
+
Get compressed, aggregate trades:
|
|
295
|
+
|
|
296
|
+
```python
|
|
297
|
+
# Get recent aggregate trades
|
|
298
|
+
agg_trades = client.agg_trades('BTCUSDT')
|
|
299
|
+
print(agg_trades)
|
|
300
|
+
|
|
301
|
+
# Get aggregate trades with time range
|
|
302
|
+
agg_trades = client.agg_trades(
|
|
303
|
+
'BTCUSDT',
|
|
304
|
+
startTime=1609459200000,
|
|
305
|
+
endTime=1609545600000,
|
|
306
|
+
limit=1000
|
|
307
|
+
)
|
|
308
|
+
print(agg_trades)
|
|
309
|
+
|
|
310
|
+
# Get aggregate trades from specific ID
|
|
311
|
+
agg_trades = client.agg_trades('BTCUSDT', fromId=28457, limit=500)
|
|
312
|
+
print(agg_trades)
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### Candlestick Data (Klines)
|
|
316
|
+
|
|
317
|
+
Get kline/candlestick bars for a symbol:
|
|
318
|
+
|
|
319
|
+
```python
|
|
320
|
+
# Get recent klines (default limit: 500)
|
|
321
|
+
klines = client.klines('BTCUSDT', '1h')
|
|
322
|
+
print(klines)
|
|
323
|
+
|
|
324
|
+
# Get klines with time range
|
|
325
|
+
klines = client.klines(
|
|
326
|
+
'BTCUSDT',
|
|
327
|
+
'1d',
|
|
328
|
+
startTime=1609459200000,
|
|
329
|
+
endTime=1609545600000,
|
|
330
|
+
limit=100
|
|
331
|
+
)
|
|
332
|
+
print(klines)
|
|
333
|
+
|
|
334
|
+
# Available intervals: 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
|
|
335
|
+
|
|
336
|
+
# Process klines
|
|
337
|
+
for kline in klines:
|
|
338
|
+
open_time, open_price, high, low, close, volume, close_time, quote_volume, trades, taker_buy_base, taker_buy_quote, ignore = kline
|
|
339
|
+
print(f"Time: {open_time}, Open: {open_price}, High: {high}, Low: {low}, Close: {close}, Volume: {volume}")
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### Klines to Pandas DataFrame
|
|
343
|
+
|
|
344
|
+
Convert klines to pandas DataFrame for analysis:
|
|
345
|
+
|
|
346
|
+
```python
|
|
347
|
+
import pandas as pd
|
|
348
|
+
from binance.spot import Spot
|
|
349
|
+
|
|
350
|
+
client = Spot()
|
|
351
|
+
|
|
352
|
+
klines = client.klines('BTCUSDT', '1h', limit=100)
|
|
353
|
+
|
|
354
|
+
# Convert to DataFrame
|
|
355
|
+
df = pd.DataFrame(klines, columns=[
|
|
356
|
+
'open_time', 'open', 'high', 'low', 'close', 'volume',
|
|
357
|
+
'close_time', 'quote_volume', 'trades', 'taker_buy_base',
|
|
358
|
+
'taker_buy_quote', 'ignore'
|
|
359
|
+
])
|
|
360
|
+
|
|
361
|
+
# Convert timestamps to datetime
|
|
362
|
+
df['open_time'] = pd.to_datetime(df['open_time'], unit='ms')
|
|
363
|
+
df['close_time'] = pd.to_datetime(df['close_time'], unit='ms')
|
|
364
|
+
|
|
365
|
+
# Convert price columns to float
|
|
366
|
+
price_cols = ['open', 'high', 'low', 'close', 'volume']
|
|
367
|
+
df[price_cols] = df[price_cols].astype(float)
|
|
368
|
+
|
|
369
|
+
print(df.head())
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
### Current Average Price
|
|
373
|
+
|
|
374
|
+
Get current average price for a symbol:
|
|
375
|
+
|
|
376
|
+
```python
|
|
377
|
+
avg_price = client.avg_price('BTCUSDT')
|
|
378
|
+
print(avg_price)
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### 24hr Ticker Price Change Statistics
|
|
382
|
+
|
|
383
|
+
Get 24-hour rolling window price change statistics:
|
|
384
|
+
|
|
385
|
+
```python
|
|
386
|
+
# Get ticker for single symbol
|
|
387
|
+
ticker = client.ticker_24hr('BTCUSDT')
|
|
388
|
+
print(ticker)
|
|
389
|
+
|
|
390
|
+
# Get ticker for multiple symbols
|
|
391
|
+
ticker = client.ticker_24hr(symbols=['BTCUSDT', 'ETHUSDT'])
|
|
392
|
+
print(ticker)
|
|
393
|
+
|
|
394
|
+
# Get ticker for all symbols (warning: large response)
|
|
395
|
+
ticker = client.ticker_24hr()
|
|
396
|
+
print(ticker)
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
### Symbol Price Ticker
|
|
400
|
+
|
|
401
|
+
Get latest price for a symbol:
|
|
402
|
+
|
|
403
|
+
```python
|
|
404
|
+
# Get price for single symbol
|
|
405
|
+
price = client.ticker_price('BTCUSDT')
|
|
406
|
+
print(price)
|
|
407
|
+
|
|
408
|
+
# Get price for multiple symbols
|
|
409
|
+
prices = client.ticker_price(symbols=['BTCUSDT', 'ETHUSDT'])
|
|
410
|
+
print(prices)
|
|
411
|
+
|
|
412
|
+
# Get price for all symbols
|
|
413
|
+
prices = client.ticker_price()
|
|
414
|
+
print(prices)
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
### Symbol Order Book Ticker
|
|
418
|
+
|
|
419
|
+
Get best price/quantity on the order book:
|
|
420
|
+
|
|
421
|
+
```python
|
|
422
|
+
# Get book ticker for single symbol
|
|
423
|
+
book_ticker = client.book_ticker('BTCUSDT')
|
|
424
|
+
print(book_ticker)
|
|
425
|
+
|
|
426
|
+
# Get book ticker for multiple symbols
|
|
427
|
+
book_ticker = client.book_ticker(symbols=['BTCUSDT', 'ETHUSDT'])
|
|
428
|
+
print(book_ticker)
|
|
429
|
+
|
|
430
|
+
# Get book ticker for all symbols
|
|
431
|
+
book_ticker = client.book_ticker()
|
|
432
|
+
print(book_ticker)
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
## Trading Endpoints
|
|
436
|
+
|
|
437
|
+
Trading endpoints require authentication and allow you to place, cancel, and query orders.
|
|
438
|
+
|
|
439
|
+
### New Order
|
|
440
|
+
|
|
441
|
+
Place a new order on the exchange:
|
|
442
|
+
|
|
443
|
+
```python
|
|
444
|
+
from binance.spot import Spot
|
|
445
|
+
|
|
446
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
447
|
+
|
|
448
|
+
# Market buy order
|
|
449
|
+
order = client.new_order(
|
|
450
|
+
symbol='BTCUSDT',
|
|
451
|
+
side='BUY',
|
|
452
|
+
type='MARKET',
|
|
453
|
+
quantity=0.001
|
|
454
|
+
)
|
|
455
|
+
print(order)
|
|
456
|
+
|
|
457
|
+
# Market sell order with quote quantity
|
|
458
|
+
order = client.new_order(
|
|
459
|
+
symbol='BTCUSDT',
|
|
460
|
+
side='SELL',
|
|
461
|
+
type='MARKET',
|
|
462
|
+
quoteOrderQty=100
|
|
463
|
+
)
|
|
464
|
+
print(order)
|
|
465
|
+
|
|
466
|
+
# Limit buy order
|
|
467
|
+
order = client.new_order(
|
|
468
|
+
symbol='BTCUSDT',
|
|
469
|
+
side='BUY',
|
|
470
|
+
type='LIMIT',
|
|
471
|
+
timeInForce='GTC',
|
|
472
|
+
quantity=0.001,
|
|
473
|
+
price=50000
|
|
474
|
+
)
|
|
475
|
+
print(order)
|
|
476
|
+
|
|
477
|
+
# Limit sell order
|
|
478
|
+
order = client.new_order(
|
|
479
|
+
symbol='BTCUSDT',
|
|
480
|
+
side='SELL',
|
|
481
|
+
type='LIMIT',
|
|
482
|
+
timeInForce='GTC',
|
|
483
|
+
quantity=0.001,
|
|
484
|
+
price=60000
|
|
485
|
+
)
|
|
486
|
+
print(order)
|
|
487
|
+
|
|
488
|
+
# Stop-loss order
|
|
489
|
+
order = client.new_order(
|
|
490
|
+
symbol='BTCUSDT',
|
|
491
|
+
side='SELL',
|
|
492
|
+
type='STOP_LOSS_LIMIT',
|
|
493
|
+
timeInForce='GTC',
|
|
494
|
+
quantity=0.001,
|
|
495
|
+
price=48000,
|
|
496
|
+
stopPrice=49000
|
|
497
|
+
)
|
|
498
|
+
print(order)
|
|
499
|
+
|
|
500
|
+
# Take-profit order
|
|
501
|
+
order = client.new_order(
|
|
502
|
+
symbol='BTCUSDT',
|
|
503
|
+
side='SELL',
|
|
504
|
+
type='TAKE_PROFIT_LIMIT',
|
|
505
|
+
timeInForce='GTC',
|
|
506
|
+
quantity=0.001,
|
|
507
|
+
price=62000,
|
|
508
|
+
stopPrice=61000
|
|
509
|
+
)
|
|
510
|
+
print(order)
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
**Order Types:**
|
|
514
|
+
- `MARKET` - Market order
|
|
515
|
+
- `LIMIT` - Limit order
|
|
516
|
+
- `STOP_LOSS` - Stop-loss order
|
|
517
|
+
- `STOP_LOSS_LIMIT` - Stop-loss limit order
|
|
518
|
+
- `TAKE_PROFIT` - Take-profit order
|
|
519
|
+
- `TAKE_PROFIT_LIMIT` - Take-profit limit order
|
|
520
|
+
- `LIMIT_MAKER` - Limit maker order
|
|
521
|
+
|
|
522
|
+
**Time in Force:**
|
|
523
|
+
- `GTC` - Good Till Cancel
|
|
524
|
+
- `IOC` - Immediate or Cancel
|
|
525
|
+
- `FOK` - Fill or Kill
|
|
526
|
+
|
|
527
|
+
### Test New Order
|
|
528
|
+
|
|
529
|
+
Test order placement without actually placing the order:
|
|
530
|
+
|
|
531
|
+
```python
|
|
532
|
+
# Test a limit order
|
|
533
|
+
test_order = client.new_order_test(
|
|
534
|
+
symbol='BTCUSDT',
|
|
535
|
+
side='BUY',
|
|
536
|
+
type='LIMIT',
|
|
537
|
+
timeInForce='GTC',
|
|
538
|
+
quantity=0.001,
|
|
539
|
+
price=50000
|
|
540
|
+
)
|
|
541
|
+
print(test_order)
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
### Query Order
|
|
545
|
+
|
|
546
|
+
Check an order's status:
|
|
547
|
+
|
|
548
|
+
```python
|
|
549
|
+
# Query by orderId
|
|
550
|
+
order = client.get_order('BTCUSDT', orderId=28)
|
|
551
|
+
print(order)
|
|
552
|
+
|
|
553
|
+
# Query by origClientOrderId
|
|
554
|
+
order = client.get_order('BTCUSDT', origClientOrderId='myOrder1')
|
|
555
|
+
print(order)
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
### Cancel Order
|
|
559
|
+
|
|
560
|
+
Cancel an active order:
|
|
561
|
+
|
|
562
|
+
```python
|
|
563
|
+
# Cancel by orderId
|
|
564
|
+
cancel_result = client.cancel_order('BTCUSDT', orderId=28)
|
|
565
|
+
print(cancel_result)
|
|
566
|
+
|
|
567
|
+
# Cancel by origClientOrderId
|
|
568
|
+
cancel_result = client.cancel_order('BTCUSDT', origClientOrderId='myOrder1')
|
|
569
|
+
print(cancel_result)
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Cancel All Open Orders
|
|
573
|
+
|
|
574
|
+
Cancel all active orders on a symbol:
|
|
575
|
+
|
|
576
|
+
```python
|
|
577
|
+
cancel_results = client.cancel_open_orders('BTCUSDT')
|
|
578
|
+
print(cancel_results)
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Cancel and Replace Order
|
|
582
|
+
|
|
583
|
+
Cancel an existing order and place a new order on the same symbol:
|
|
584
|
+
|
|
585
|
+
```python
|
|
586
|
+
# Cancel and replace by orderId
|
|
587
|
+
result = client.cancel_replace(
|
|
588
|
+
symbol='BTCUSDT',
|
|
589
|
+
side='BUY',
|
|
590
|
+
type='LIMIT',
|
|
591
|
+
cancelReplaceMode='STOP_ON_FAILURE',
|
|
592
|
+
timeInForce='GTC',
|
|
593
|
+
cancelOrderId=28,
|
|
594
|
+
quantity=0.002,
|
|
595
|
+
price=51000
|
|
596
|
+
)
|
|
597
|
+
print(result)
|
|
598
|
+
```
|
|
599
|
+
|
|
600
|
+
### Current Open Orders
|
|
601
|
+
|
|
602
|
+
Get all open orders on a symbol:
|
|
603
|
+
|
|
604
|
+
```python
|
|
605
|
+
# Get open orders for specific symbol
|
|
606
|
+
open_orders = client.get_open_orders('BTCUSDT')
|
|
607
|
+
print(open_orders)
|
|
608
|
+
|
|
609
|
+
# Get all open orders
|
|
610
|
+
open_orders = client.get_open_orders()
|
|
611
|
+
print(open_orders)
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### All Orders
|
|
615
|
+
|
|
616
|
+
Get all account orders (active, canceled, or filled):
|
|
617
|
+
|
|
618
|
+
```python
|
|
619
|
+
# Get all orders for a symbol
|
|
620
|
+
all_orders = client.get_orders('BTCUSDT')
|
|
621
|
+
print(all_orders)
|
|
622
|
+
|
|
623
|
+
# Get orders with time range
|
|
624
|
+
all_orders = client.get_orders(
|
|
625
|
+
'BTCUSDT',
|
|
626
|
+
startTime=1609459200000,
|
|
627
|
+
endTime=1609545600000,
|
|
628
|
+
limit=500
|
|
629
|
+
)
|
|
630
|
+
print(all_orders)
|
|
631
|
+
|
|
632
|
+
# Get orders from specific orderId
|
|
633
|
+
all_orders = client.get_orders('BTCUSDT', orderId=28, limit=500)
|
|
634
|
+
print(all_orders)
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
### OCO Orders (One-Cancels-the-Other)
|
|
638
|
+
|
|
639
|
+
Place a pair of orders where if one is executed, the other is canceled:
|
|
640
|
+
|
|
641
|
+
```python
|
|
642
|
+
# Place OCO order
|
|
643
|
+
oco_order = client.new_oco_order(
|
|
644
|
+
symbol='BTCUSDT',
|
|
645
|
+
side='SELL',
|
|
646
|
+
quantity=0.001,
|
|
647
|
+
price=62000,
|
|
648
|
+
stopPrice=48000,
|
|
649
|
+
stopLimitPrice=47500,
|
|
650
|
+
stopLimitTimeInForce='GTC'
|
|
651
|
+
)
|
|
652
|
+
print(oco_order)
|
|
653
|
+
|
|
654
|
+
# Cancel OCO order
|
|
655
|
+
cancel_result = client.cancel_oco_order('BTCUSDT', orderListId=0)
|
|
656
|
+
print(cancel_result)
|
|
657
|
+
|
|
658
|
+
# Query OCO order
|
|
659
|
+
oco_order = client.get_oco_order(orderListId=0)
|
|
660
|
+
print(oco_order)
|
|
661
|
+
|
|
662
|
+
# Get all OCO orders
|
|
663
|
+
oco_orders = client.get_oco_orders()
|
|
664
|
+
print(oco_orders)
|
|
665
|
+
|
|
666
|
+
# Get open OCO orders
|
|
667
|
+
open_oco_orders = client.get_open_oco_orders()
|
|
668
|
+
print(open_oco_orders)
|
|
669
|
+
```
|
|
670
|
+
|
|
671
|
+
## Account Endpoints
|
|
672
|
+
|
|
673
|
+
Account endpoints provide access to account information and require authentication.
|
|
674
|
+
|
|
675
|
+
### Account Information
|
|
676
|
+
|
|
677
|
+
Get current account information:
|
|
678
|
+
|
|
679
|
+
```python
|
|
680
|
+
from binance.spot import Spot
|
|
681
|
+
|
|
682
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
683
|
+
|
|
684
|
+
account = client.account()
|
|
685
|
+
print(f"Account Type: {account['accountType']}")
|
|
686
|
+
print(f"Can Trade: {account['canTrade']}")
|
|
687
|
+
print(f"Can Withdraw: {account['canWithdraw']}")
|
|
688
|
+
print(f"Can Deposit: {account['canDeposit']}")
|
|
689
|
+
|
|
690
|
+
# Get non-zero balances
|
|
691
|
+
balances = [b for b in account['balances'] if float(b['free']) > 0 or float(b['locked']) > 0]
|
|
692
|
+
print(f"Non-zero Balances: {balances}")
|
|
693
|
+
```
|
|
694
|
+
|
|
695
|
+
### Account Trade List
|
|
696
|
+
|
|
697
|
+
Get trades for a specific symbol:
|
|
698
|
+
|
|
699
|
+
```python
|
|
700
|
+
# Get recent trades
|
|
701
|
+
trades = client.my_trades('BTCUSDT')
|
|
702
|
+
print(trades)
|
|
703
|
+
|
|
704
|
+
# Get trades with time range
|
|
705
|
+
trades = client.my_trades(
|
|
706
|
+
'BTCUSDT',
|
|
707
|
+
startTime=1609459200000,
|
|
708
|
+
endTime=1609545600000,
|
|
709
|
+
limit=500
|
|
710
|
+
)
|
|
711
|
+
print(trades)
|
|
712
|
+
|
|
713
|
+
# Get trades from specific ID
|
|
714
|
+
trades = client.my_trades('BTCUSDT', fromId=28457, limit=500)
|
|
715
|
+
print(trades)
|
|
716
|
+
|
|
717
|
+
# Calculate total trading volume
|
|
718
|
+
total_volume = sum(float(trade['qty']) for trade in trades)
|
|
719
|
+
print(f"Total Volume: {total_volume}")
|
|
720
|
+
```
|
|
721
|
+
|
|
722
|
+
### Current Order Count Usage
|
|
723
|
+
|
|
724
|
+
Get current order count usage for rate limits:
|
|
725
|
+
|
|
726
|
+
```python
|
|
727
|
+
rate_limit = client.rate_limit_order()
|
|
728
|
+
print(rate_limit)
|
|
729
|
+
```
|
|
730
|
+
|
|
731
|
+
### Query Prevented Matches
|
|
732
|
+
|
|
733
|
+
Get prevented matches from Self-Trade Prevention:
|
|
734
|
+
|
|
735
|
+
```python
|
|
736
|
+
prevented_matches = client.prevented_matches('BTCUSDT')
|
|
737
|
+
print(prevented_matches)
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
## WebSocket Streams
|
|
741
|
+
|
|
742
|
+
WebSocket streams provide real-time market data with low latency.
|
|
743
|
+
|
|
744
|
+
### WebSocket Stream Client
|
|
745
|
+
|
|
746
|
+
Initialize a WebSocket stream client:
|
|
747
|
+
|
|
748
|
+
```python
|
|
749
|
+
from binance.websocket.spot.websocket_stream import SpotWebsocketStreamClient
|
|
750
|
+
|
|
751
|
+
def message_handler(_, message):
|
|
752
|
+
print(f"Received message: {message}")
|
|
753
|
+
|
|
754
|
+
# Create WebSocket stream client
|
|
755
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
756
|
+
|
|
757
|
+
# Start the client
|
|
758
|
+
ws_client.start()
|
|
759
|
+
|
|
760
|
+
# Subscribe to streams (examples below)
|
|
761
|
+
```
|
|
762
|
+
|
|
763
|
+
### Aggregate Trade Streams
|
|
764
|
+
|
|
765
|
+
Subscribe to aggregate trade updates:
|
|
766
|
+
|
|
767
|
+
```python
|
|
768
|
+
from binance.websocket.spot.websocket_stream import SpotWebsocketStreamClient
|
|
769
|
+
|
|
770
|
+
def message_handler(_, message):
|
|
771
|
+
print(f"Aggregate Trade: {message}")
|
|
772
|
+
|
|
773
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
774
|
+
|
|
775
|
+
# Subscribe to BTCUSDT aggregate trades
|
|
776
|
+
ws_client.agg_trade(symbol='btcusdt')
|
|
777
|
+
|
|
778
|
+
# Keep the connection alive
|
|
779
|
+
import time
|
|
780
|
+
time.sleep(60)
|
|
781
|
+
|
|
782
|
+
# Stop the client
|
|
783
|
+
ws_client.stop()
|
|
784
|
+
```
|
|
785
|
+
|
|
786
|
+
### Trade Streams
|
|
787
|
+
|
|
788
|
+
Subscribe to raw trade updates:
|
|
789
|
+
|
|
790
|
+
```python
|
|
791
|
+
def message_handler(_, message):
|
|
792
|
+
print(f"Trade: {message}")
|
|
793
|
+
|
|
794
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
795
|
+
|
|
796
|
+
# Subscribe to BTCUSDT trades
|
|
797
|
+
ws_client.trade(symbol='btcusdt')
|
|
798
|
+
|
|
799
|
+
import time
|
|
800
|
+
time.sleep(60)
|
|
801
|
+
|
|
802
|
+
ws_client.stop()
|
|
803
|
+
```
|
|
804
|
+
|
|
805
|
+
### Kline/Candlestick Streams
|
|
806
|
+
|
|
807
|
+
Subscribe to candlestick updates:
|
|
808
|
+
|
|
809
|
+
```python
|
|
810
|
+
def message_handler(_, message):
|
|
811
|
+
print(f"Kline: {message}")
|
|
812
|
+
|
|
813
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
814
|
+
|
|
815
|
+
# Subscribe to BTCUSDT 1-minute klines
|
|
816
|
+
ws_client.kline(symbol='btcusdt', interval='1m')
|
|
817
|
+
|
|
818
|
+
# Available intervals: 1s, 1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M
|
|
819
|
+
|
|
820
|
+
import time
|
|
821
|
+
time.sleep(60)
|
|
822
|
+
|
|
823
|
+
ws_client.stop()
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
### Mini Ticker Streams
|
|
827
|
+
|
|
828
|
+
Subscribe to 24hr mini ticker updates:
|
|
829
|
+
|
|
830
|
+
```python
|
|
831
|
+
def message_handler(_, message):
|
|
832
|
+
print(f"Mini Ticker: {message}")
|
|
833
|
+
|
|
834
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
835
|
+
|
|
836
|
+
# Subscribe to BTCUSDT mini ticker
|
|
837
|
+
ws_client.mini_ticker(symbol='btcusdt')
|
|
838
|
+
|
|
839
|
+
# Subscribe to all symbols mini ticker
|
|
840
|
+
ws_client.mini_ticker()
|
|
841
|
+
|
|
842
|
+
import time
|
|
843
|
+
time.sleep(60)
|
|
844
|
+
|
|
845
|
+
ws_client.stop()
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
### Ticker Streams
|
|
849
|
+
|
|
850
|
+
Subscribe to 24hr ticker updates:
|
|
851
|
+
|
|
852
|
+
```python
|
|
853
|
+
def message_handler(_, message):
|
|
854
|
+
print(f"Ticker: {message}")
|
|
855
|
+
|
|
856
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
857
|
+
|
|
858
|
+
# Subscribe to BTCUSDT ticker
|
|
859
|
+
ws_client.ticker(symbol='btcusdt')
|
|
860
|
+
|
|
861
|
+
# Subscribe to all symbols ticker
|
|
862
|
+
ws_client.ticker()
|
|
863
|
+
|
|
864
|
+
import time
|
|
865
|
+
time.sleep(60)
|
|
866
|
+
|
|
867
|
+
ws_client.stop()
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
### Individual Symbol Book Ticker Streams
|
|
871
|
+
|
|
872
|
+
Subscribe to best bid/ask updates:
|
|
873
|
+
|
|
874
|
+
```python
|
|
875
|
+
def message_handler(_, message):
|
|
876
|
+
print(f"Book Ticker: {message}")
|
|
877
|
+
|
|
878
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
879
|
+
|
|
880
|
+
# Subscribe to BTCUSDT book ticker
|
|
881
|
+
ws_client.book_ticker(symbol='btcusdt')
|
|
882
|
+
|
|
883
|
+
import time
|
|
884
|
+
time.sleep(60)
|
|
885
|
+
|
|
886
|
+
ws_client.stop()
|
|
887
|
+
```
|
|
888
|
+
|
|
889
|
+
### Partial Book Depth Streams
|
|
890
|
+
|
|
891
|
+
Subscribe to top bids and asks:
|
|
892
|
+
|
|
893
|
+
```python
|
|
894
|
+
def message_handler(_, message):
|
|
895
|
+
print(f"Partial Depth: {message}")
|
|
896
|
+
|
|
897
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
898
|
+
|
|
899
|
+
# Subscribe to BTCUSDT top 5 levels @ 1000ms
|
|
900
|
+
ws_client.partial_depth(symbol='btcusdt', level=5, speed=1000)
|
|
901
|
+
|
|
902
|
+
# Available levels: 5, 10, 20
|
|
903
|
+
# Available speeds: 1000ms, 100ms
|
|
904
|
+
|
|
905
|
+
import time
|
|
906
|
+
time.sleep(60)
|
|
907
|
+
|
|
908
|
+
ws_client.stop()
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### Diff Depth Stream
|
|
912
|
+
|
|
913
|
+
Subscribe to order book price and quantity depth updates:
|
|
914
|
+
|
|
915
|
+
```python
|
|
916
|
+
def message_handler(_, message):
|
|
917
|
+
print(f"Diff Depth: {message}")
|
|
918
|
+
|
|
919
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
920
|
+
|
|
921
|
+
# Subscribe to BTCUSDT depth updates @ 1000ms
|
|
922
|
+
ws_client.diff_depth(symbol='btcusdt', speed=1000)
|
|
923
|
+
|
|
924
|
+
# Available speeds: 1000ms, 100ms
|
|
925
|
+
|
|
926
|
+
import time
|
|
927
|
+
time.sleep(60)
|
|
928
|
+
|
|
929
|
+
ws_client.stop()
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
### Multiple Streams
|
|
933
|
+
|
|
934
|
+
Subscribe to multiple streams with a single connection:
|
|
935
|
+
|
|
936
|
+
```python
|
|
937
|
+
def message_handler(_, message):
|
|
938
|
+
print(f"Message: {message}")
|
|
939
|
+
|
|
940
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
941
|
+
|
|
942
|
+
# Subscribe to multiple streams
|
|
943
|
+
ws_client.agg_trade(symbol='btcusdt')
|
|
944
|
+
ws_client.trade(symbol='ethusdt')
|
|
945
|
+
ws_client.kline(symbol='bnbusdt', interval='1m')
|
|
946
|
+
ws_client.ticker(symbol='adausdt')
|
|
947
|
+
|
|
948
|
+
import time
|
|
949
|
+
time.sleep(60)
|
|
950
|
+
|
|
951
|
+
ws_client.stop()
|
|
952
|
+
```
|
|
953
|
+
|
|
954
|
+
## WebSocket API
|
|
955
|
+
|
|
956
|
+
WebSocket API allows bidirectional communication for placing orders, querying data, and more.
|
|
957
|
+
|
|
958
|
+
### WebSocket API Client
|
|
959
|
+
|
|
960
|
+
Initialize a WebSocket API client:
|
|
961
|
+
|
|
962
|
+
```python
|
|
963
|
+
from binance.websocket.spot.websocket_api import SpotWebsocketAPIClient
|
|
964
|
+
|
|
965
|
+
def message_handler(_, message):
|
|
966
|
+
print(f"Message: {message}")
|
|
967
|
+
|
|
968
|
+
# Create WebSocket API client
|
|
969
|
+
ws_client = SpotWebsocketAPIClient(
|
|
970
|
+
api_key=api_key,
|
|
971
|
+
api_secret=api_secret,
|
|
972
|
+
on_message=message_handler
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
# The client automatically connects
|
|
976
|
+
```
|
|
977
|
+
|
|
978
|
+
### Ping/Pong
|
|
979
|
+
|
|
980
|
+
Test connectivity:
|
|
981
|
+
|
|
982
|
+
```python
|
|
983
|
+
from binance.websocket.spot.websocket_api import SpotWebsocketAPIClient
|
|
984
|
+
|
|
985
|
+
def message_handler(_, message):
|
|
986
|
+
print(f"Response: {message}")
|
|
987
|
+
|
|
988
|
+
ws_client = SpotWebsocketAPIClient(on_message=message_handler)
|
|
989
|
+
|
|
990
|
+
# Send ping
|
|
991
|
+
ws_client.ping()
|
|
992
|
+
|
|
993
|
+
import time
|
|
994
|
+
time.sleep(2)
|
|
995
|
+
|
|
996
|
+
ws_client.stop()
|
|
997
|
+
```
|
|
998
|
+
|
|
999
|
+
### Server Time
|
|
1000
|
+
|
|
1001
|
+
Get server time:
|
|
1002
|
+
|
|
1003
|
+
```python
|
|
1004
|
+
def message_handler(_, message):
|
|
1005
|
+
print(f"Server Time: {message}")
|
|
1006
|
+
|
|
1007
|
+
ws_client = SpotWebsocketAPIClient(on_message=message_handler)
|
|
1008
|
+
|
|
1009
|
+
# Get server time
|
|
1010
|
+
ws_client.time()
|
|
1011
|
+
|
|
1012
|
+
import time
|
|
1013
|
+
time.sleep(2)
|
|
1014
|
+
|
|
1015
|
+
ws_client.stop()
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
### Order Book via WebSocket API
|
|
1019
|
+
|
|
1020
|
+
Get order book through WebSocket:
|
|
1021
|
+
|
|
1022
|
+
```python
|
|
1023
|
+
def message_handler(_, message):
|
|
1024
|
+
print(f"Order Book: {message}")
|
|
1025
|
+
|
|
1026
|
+
ws_client = SpotWebsocketAPIClient(on_message=message_handler)
|
|
1027
|
+
|
|
1028
|
+
# Get order book
|
|
1029
|
+
ws_client.depth(symbol='BTCUSDT', limit=10)
|
|
1030
|
+
|
|
1031
|
+
import time
|
|
1032
|
+
time.sleep(2)
|
|
1033
|
+
|
|
1034
|
+
ws_client.stop()
|
|
1035
|
+
```
|
|
1036
|
+
|
|
1037
|
+
### Place Order via WebSocket API
|
|
1038
|
+
|
|
1039
|
+
Place orders through WebSocket:
|
|
1040
|
+
|
|
1041
|
+
```python
|
|
1042
|
+
def message_handler(_, message):
|
|
1043
|
+
print(f"Order Response: {message}")
|
|
1044
|
+
|
|
1045
|
+
ws_client = SpotWebsocketAPIClient(
|
|
1046
|
+
api_key=api_key,
|
|
1047
|
+
api_secret=api_secret,
|
|
1048
|
+
on_message=message_handler
|
|
1049
|
+
)
|
|
1050
|
+
|
|
1051
|
+
# Place market buy order
|
|
1052
|
+
ws_client.new_order(
|
|
1053
|
+
symbol='BTCUSDT',
|
|
1054
|
+
side='BUY',
|
|
1055
|
+
type='MARKET',
|
|
1056
|
+
quantity=0.001
|
|
1057
|
+
)
|
|
1058
|
+
|
|
1059
|
+
import time
|
|
1060
|
+
time.sleep(2)
|
|
1061
|
+
|
|
1062
|
+
ws_client.stop()
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
### Account Information via WebSocket API
|
|
1066
|
+
|
|
1067
|
+
Get account information through WebSocket:
|
|
1068
|
+
|
|
1069
|
+
```python
|
|
1070
|
+
def message_handler(_, message):
|
|
1071
|
+
print(f"Account Info: {message}")
|
|
1072
|
+
|
|
1073
|
+
ws_client = SpotWebsocketAPIClient(
|
|
1074
|
+
api_key=api_key,
|
|
1075
|
+
api_secret=api_secret,
|
|
1076
|
+
on_message=message_handler
|
|
1077
|
+
)
|
|
1078
|
+
|
|
1079
|
+
# Get account information
|
|
1080
|
+
ws_client.account_status()
|
|
1081
|
+
|
|
1082
|
+
import time
|
|
1083
|
+
time.sleep(2)
|
|
1084
|
+
|
|
1085
|
+
ws_client.stop()
|
|
1086
|
+
```
|
|
1087
|
+
|
|
1088
|
+
## User Data Streams
|
|
1089
|
+
|
|
1090
|
+
User Data Streams provide real-time updates about account and order changes.
|
|
1091
|
+
|
|
1092
|
+
### Start User Data Stream
|
|
1093
|
+
|
|
1094
|
+
Create a listenKey for user data stream:
|
|
1095
|
+
|
|
1096
|
+
```python
|
|
1097
|
+
from binance.spot import Spot
|
|
1098
|
+
|
|
1099
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
1100
|
+
|
|
1101
|
+
# Create listen key
|
|
1102
|
+
response = client.user_data_stream()
|
|
1103
|
+
listen_key = response['listenKey']
|
|
1104
|
+
print(f"Listen Key: {listen_key}")
|
|
1105
|
+
|
|
1106
|
+
# Use this listenKey with WebSocket
|
|
1107
|
+
```
|
|
1108
|
+
|
|
1109
|
+
### Keep-Alive User Data Stream
|
|
1110
|
+
|
|
1111
|
+
Extend the validity of a listenKey:
|
|
1112
|
+
|
|
1113
|
+
```python
|
|
1114
|
+
# Keep alive (extend validity by 60 minutes)
|
|
1115
|
+
client.renew_user_data_stream(listenKey=listen_key)
|
|
1116
|
+
print("Stream kept alive")
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
### Close User Data Stream
|
|
1120
|
+
|
|
1121
|
+
Close a user data stream:
|
|
1122
|
+
|
|
1123
|
+
```python
|
|
1124
|
+
# Close stream
|
|
1125
|
+
client.close_user_data_stream(listenKey=listen_key)
|
|
1126
|
+
print("Stream closed")
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
### Subscribe to User Data Stream
|
|
1130
|
+
|
|
1131
|
+
Connect to user data stream via WebSocket:
|
|
1132
|
+
|
|
1133
|
+
```python
|
|
1134
|
+
from binance.spot import Spot
|
|
1135
|
+
from binance.websocket.spot.websocket_stream import SpotWebsocketStreamClient
|
|
1136
|
+
|
|
1137
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
1138
|
+
|
|
1139
|
+
# Create listen key
|
|
1140
|
+
response = client.user_data_stream()
|
|
1141
|
+
listen_key = response['listenKey']
|
|
1142
|
+
|
|
1143
|
+
def message_handler(_, message):
|
|
1144
|
+
import json
|
|
1145
|
+
event = json.loads(message)
|
|
1146
|
+
|
|
1147
|
+
if event['e'] == 'executionReport':
|
|
1148
|
+
print(f"Order Update: {event}")
|
|
1149
|
+
elif event['e'] == 'outboundAccountPosition':
|
|
1150
|
+
print(f"Balance Update: {event}")
|
|
1151
|
+
elif event['e'] == 'balanceUpdate':
|
|
1152
|
+
print(f"Balance Update: {event}")
|
|
1153
|
+
|
|
1154
|
+
# Connect to user data stream
|
|
1155
|
+
ws_client = SpotWebsocketStreamClient(on_message=message_handler)
|
|
1156
|
+
ws_client.user_data(listen_key=listen_key)
|
|
1157
|
+
|
|
1158
|
+
# Keep stream alive
|
|
1159
|
+
import time
|
|
1160
|
+
import threading
|
|
1161
|
+
|
|
1162
|
+
def keep_alive():
|
|
1163
|
+
while True:
|
|
1164
|
+
time.sleep(30 * 60) # 30 minutes
|
|
1165
|
+
try:
|
|
1166
|
+
client.renew_user_data_stream(listenKey=listen_key)
|
|
1167
|
+
print("Stream kept alive")
|
|
1168
|
+
except Exception as e:
|
|
1169
|
+
print(f"Keep alive failed: {e}")
|
|
1170
|
+
|
|
1171
|
+
# Start keep-alive thread
|
|
1172
|
+
keep_alive_thread = threading.Thread(target=keep_alive, daemon=True)
|
|
1173
|
+
keep_alive_thread.start()
|
|
1174
|
+
|
|
1175
|
+
# Keep running
|
|
1176
|
+
try:
|
|
1177
|
+
while True:
|
|
1178
|
+
time.sleep(1)
|
|
1179
|
+
except KeyboardInterrupt:
|
|
1180
|
+
ws_client.stop()
|
|
1181
|
+
client.close_user_data_stream(listenKey=listen_key)
|
|
1182
|
+
```
|
|
1183
|
+
|
|
1184
|
+
## Error Handling
|
|
1185
|
+
|
|
1186
|
+
Proper error handling for API requests:
|
|
1187
|
+
|
|
1188
|
+
```python
|
|
1189
|
+
from binance.spot import Spot
|
|
1190
|
+
from binance.error import ClientError, ServerError
|
|
1191
|
+
|
|
1192
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
1193
|
+
|
|
1194
|
+
try:
|
|
1195
|
+
account = client.account()
|
|
1196
|
+
print(f"Success: {account}")
|
|
1197
|
+
except ClientError as error:
|
|
1198
|
+
# Handle client errors (4xx status codes)
|
|
1199
|
+
print(f"Client Error - Status: {error.status_code}, Code: {error.error_code}, Message: {error.error_message}")
|
|
1200
|
+
except ServerError as error:
|
|
1201
|
+
# Handle server errors (5xx status codes)
|
|
1202
|
+
print(f"Server Error - Status: {error.status_code}, Message: {error.error_message}")
|
|
1203
|
+
except Exception as error:
|
|
1204
|
+
# Handle other errors
|
|
1205
|
+
print(f"Error: {error}")
|
|
1206
|
+
```
|
|
1207
|
+
|
|
1208
|
+
### Common Error Codes
|
|
1209
|
+
|
|
1210
|
+
| Code | Message | Description |
|
|
1211
|
+
|-------|----------------------------------|------------------------------------------|
|
|
1212
|
+
| -1000 | UNKNOWN | An unknown error occurred |
|
|
1213
|
+
| -1001 | DISCONNECTED | Internal error; unable to process |
|
|
1214
|
+
| -1002 | UNAUTHORIZED | Invalid API key or signature |
|
|
1215
|
+
| -1003 | TOO_MANY_REQUESTS | Too many requests; rate limit exceeded |
|
|
1216
|
+
| -1007 | TIMEOUT | Request timeout |
|
|
1217
|
+
| -1021 | TIMESTAMP_OUTSIDE_RECV_WINDOW | Timestamp outside recvWindow |
|
|
1218
|
+
| -1022 | INVALID_SIGNATURE | Invalid signature |
|
|
1219
|
+
| -1100 | ILLEGAL_CHARS | Illegal characters in parameter |
|
|
1220
|
+
| -1101 | TOO_MANY_PARAMETERS | Too many parameters |
|
|
1221
|
+
| -1102 | MANDATORY_PARAM_EMPTY_OR_MALFORMED | Mandatory parameter missing/malformed |
|
|
1222
|
+
| -1103 | UNKNOWN_PARAM | Unknown parameter |
|
|
1223
|
+
| -1104 | UNREAD_PARAMETERS | Not all parameters were read |
|
|
1224
|
+
| -1111 | BAD_PRECISION | Precision over maximum defined |
|
|
1225
|
+
| -1112 | NO_DEPTH | No orders on book |
|
|
1226
|
+
| -1114 | TIF_NOT_REQUIRED | Time in force not required |
|
|
1227
|
+
| -1115 | INVALID_TIF | Invalid time in force |
|
|
1228
|
+
| -1116 | INVALID_ORDER_TYPE | Invalid order type |
|
|
1229
|
+
| -1117 | INVALID_SIDE | Invalid side |
|
|
1230
|
+
| -1118 | EMPTY_NEW_CL_ORD_ID | New client order ID empty |
|
|
1231
|
+
| -1119 | EMPTY_ORG_CL_ORD_ID | Original client order ID empty |
|
|
1232
|
+
| -1120 | BAD_INTERVAL | Invalid interval |
|
|
1233
|
+
| -1121 | BAD_SYMBOL | Invalid symbol |
|
|
1234
|
+
| -1125 | INVALID_LISTEN_KEY | Invalid listen key |
|
|
1235
|
+
| -1127 | MORE_THAN_XX_HOURS | Lookup interval too large |
|
|
1236
|
+
| -1128 | OPTIONAL_PARAMS_BAD_COMBO | Invalid parameter combination |
|
|
1237
|
+
| -1130 | INVALID_PARAMETER | Invalid parameter |
|
|
1238
|
+
| -2010 | NEW_ORDER_REJECTED | Order rejected |
|
|
1239
|
+
| -2011 | CANCEL_REJECTED | Cancel rejected |
|
|
1240
|
+
| -2013 | NO_SUCH_ORDER | Order does not exist |
|
|
1241
|
+
| -2014 | BAD_API_KEY_FMT | API key format invalid |
|
|
1242
|
+
| -2015 | REJECTED_MBX_KEY | API key rejected |
|
|
1243
|
+
|
|
1244
|
+
## Rate Limits
|
|
1245
|
+
|
|
1246
|
+
Binance implements rate limits to prevent API abuse.
|
|
1247
|
+
|
|
1248
|
+
### Rate Limit Types
|
|
1249
|
+
|
|
1250
|
+
1. **REQUEST_WEIGHT** - Based on the weight of requests
|
|
1251
|
+
2. **ORDERS** - Based on the number of orders
|
|
1252
|
+
3. **RAW_REQUESTS** - Based on the number of requests
|
|
1253
|
+
|
|
1254
|
+
### Rate Limit Headers
|
|
1255
|
+
|
|
1256
|
+
Enable rate limit headers in client configuration:
|
|
1257
|
+
|
|
1258
|
+
```python
|
|
1259
|
+
from binance.spot import Spot
|
|
1260
|
+
|
|
1261
|
+
client = Spot(
|
|
1262
|
+
api_key=api_key,
|
|
1263
|
+
api_secret=api_secret,
|
|
1264
|
+
show_limit_usage=True,
|
|
1265
|
+
show_header=True
|
|
1266
|
+
)
|
|
1267
|
+
|
|
1268
|
+
response = client.account()
|
|
1269
|
+
|
|
1270
|
+
# Access headers
|
|
1271
|
+
print(f"Used Weight: {response.get('x-mbx-used-weight-1m')}")
|
|
1272
|
+
print(f"Order Count: {response.get('x-mbx-order-count-10s')}")
|
|
1273
|
+
```
|
|
1274
|
+
|
|
1275
|
+
### Best Practices for Rate Limits
|
|
1276
|
+
|
|
1277
|
+
- Use WebSocket streams for real-time data instead of polling REST API
|
|
1278
|
+
- Batch requests when possible
|
|
1279
|
+
- Monitor rate limit headers
|
|
1280
|
+
- Implement exponential backoff for retries
|
|
1281
|
+
- Use `recvWindow` parameter appropriately
|
|
1282
|
+
|
|
1283
|
+
## Advanced Configuration
|
|
1284
|
+
|
|
1285
|
+
### Timestamp Synchronization
|
|
1286
|
+
|
|
1287
|
+
Configure timing window for requests:
|
|
1288
|
+
|
|
1289
|
+
```python
|
|
1290
|
+
from binance.spot import Spot
|
|
1291
|
+
|
|
1292
|
+
client = Spot(
|
|
1293
|
+
api_key=api_key,
|
|
1294
|
+
api_secret=api_secret
|
|
1295
|
+
)
|
|
1296
|
+
|
|
1297
|
+
# Manually set recvWindow for specific request
|
|
1298
|
+
account = client.account(recvWindow=10000) # 10 seconds
|
|
1299
|
+
```
|
|
1300
|
+
|
|
1301
|
+
### Custom Request Parameters
|
|
1302
|
+
|
|
1303
|
+
Pass additional parameters to requests:
|
|
1304
|
+
|
|
1305
|
+
```python
|
|
1306
|
+
# Pass custom client order ID
|
|
1307
|
+
order = client.new_order(
|
|
1308
|
+
symbol='BTCUSDT',
|
|
1309
|
+
side='BUY',
|
|
1310
|
+
type='LIMIT',
|
|
1311
|
+
timeInForce='GTC',
|
|
1312
|
+
quantity=0.001,
|
|
1313
|
+
price=50000,
|
|
1314
|
+
newClientOrderId='my_custom_order_id_123'
|
|
1315
|
+
)
|
|
1316
|
+
```
|
|
1317
|
+
|
|
1318
|
+
### Base URL Selection
|
|
1319
|
+
|
|
1320
|
+
Choose optimal base URL for your region:
|
|
1321
|
+
|
|
1322
|
+
```python
|
|
1323
|
+
# Default (most stable)
|
|
1324
|
+
client1 = Spot(
|
|
1325
|
+
api_key=api_key,
|
|
1326
|
+
api_secret=api_secret,
|
|
1327
|
+
base_url='https://api.binance.com'
|
|
1328
|
+
)
|
|
1329
|
+
|
|
1330
|
+
# GCP (better for some regions)
|
|
1331
|
+
client2 = Spot(
|
|
1332
|
+
api_key=api_key,
|
|
1333
|
+
api_secret=api_secret,
|
|
1334
|
+
base_url='https://api-gcp.binance.com'
|
|
1335
|
+
)
|
|
1336
|
+
|
|
1337
|
+
# Numbered endpoints (better performance, less stability)
|
|
1338
|
+
client3 = Spot(
|
|
1339
|
+
api_key=api_key,
|
|
1340
|
+
api_secret=api_secret,
|
|
1341
|
+
base_url='https://api1.binance.com'
|
|
1342
|
+
)
|
|
1343
|
+
|
|
1344
|
+
# Market data only
|
|
1345
|
+
client4 = Spot(base_url='https://data-api.binance.vision')
|
|
1346
|
+
```
|
|
1347
|
+
|
|
1348
|
+
### Complete Trading Bot Example
|
|
1349
|
+
|
|
1350
|
+
Full example of a simple trading bot:
|
|
1351
|
+
|
|
1352
|
+
```python
|
|
1353
|
+
import os
|
|
1354
|
+
import time
|
|
1355
|
+
import logging
|
|
1356
|
+
from binance.spot import Spot
|
|
1357
|
+
from binance.error import ClientError, ServerError
|
|
1358
|
+
from binance.lib.utils import config_logging
|
|
1359
|
+
|
|
1360
|
+
# Configure logging
|
|
1361
|
+
config_logging(logging, logging.INFO)
|
|
1362
|
+
|
|
1363
|
+
# Initialize client
|
|
1364
|
+
api_key = os.getenv('BINANCE_API_KEY')
|
|
1365
|
+
api_secret = os.getenv('BINANCE_API_SECRET')
|
|
1366
|
+
|
|
1367
|
+
client = Spot(api_key=api_key, api_secret=api_secret)
|
|
1368
|
+
|
|
1369
|
+
def get_account_balance(asset='USDT'):
|
|
1370
|
+
"""Get balance for specific asset"""
|
|
1371
|
+
try:
|
|
1372
|
+
account = client.account()
|
|
1373
|
+
for balance in account['balances']:
|
|
1374
|
+
if balance['asset'] == asset:
|
|
1375
|
+
return float(balance['free'])
|
|
1376
|
+
return 0.0
|
|
1377
|
+
except (ClientError, ServerError) as error:
|
|
1378
|
+
logging.error(f"Error getting balance: {error}")
|
|
1379
|
+
return 0.0
|
|
1380
|
+
|
|
1381
|
+
def get_current_price(symbol='BTCUSDT'):
|
|
1382
|
+
"""Get current price for symbol"""
|
|
1383
|
+
try:
|
|
1384
|
+
ticker = client.ticker_price(symbol=symbol)
|
|
1385
|
+
return float(ticker['price'])
|
|
1386
|
+
except (ClientError, ServerError) as error:
|
|
1387
|
+
logging.error(f"Error getting price: {error}")
|
|
1388
|
+
return 0.0
|
|
1389
|
+
|
|
1390
|
+
def place_market_order(symbol, side, quantity):
|
|
1391
|
+
"""Place market order"""
|
|
1392
|
+
try:
|
|
1393
|
+
order = client.new_order(
|
|
1394
|
+
symbol=symbol,
|
|
1395
|
+
side=side,
|
|
1396
|
+
type='MARKET',
|
|
1397
|
+
quantity=quantity
|
|
1398
|
+
)
|
|
1399
|
+
logging.info(f"Order placed: {order}")
|
|
1400
|
+
return order
|
|
1401
|
+
except ClientError as error:
|
|
1402
|
+
logging.error(f"Order failed: {error.error_message}")
|
|
1403
|
+
return None
|
|
1404
|
+
|
|
1405
|
+
def place_limit_order(symbol, side, quantity, price):
|
|
1406
|
+
"""Place limit order"""
|
|
1407
|
+
try:
|
|
1408
|
+
order = client.new_order(
|
|
1409
|
+
symbol=symbol,
|
|
1410
|
+
side=side,
|
|
1411
|
+
type='LIMIT',
|
|
1412
|
+
timeInForce='GTC',
|
|
1413
|
+
quantity=quantity,
|
|
1414
|
+
price=price
|
|
1415
|
+
)
|
|
1416
|
+
logging.info(f"Limit order placed: {order}")
|
|
1417
|
+
return order
|
|
1418
|
+
except ClientError as error:
|
|
1419
|
+
logging.error(f"Order failed: {error.error_message}")
|
|
1420
|
+
return None
|
|
1421
|
+
|
|
1422
|
+
def main():
|
|
1423
|
+
"""Main trading logic"""
|
|
1424
|
+
symbol = 'BTCUSDT'
|
|
1425
|
+
|
|
1426
|
+
# Get account balance
|
|
1427
|
+
usdt_balance = get_account_balance('USDT')
|
|
1428
|
+
logging.info(f"USDT Balance: {usdt_balance}")
|
|
1429
|
+
|
|
1430
|
+
# Get current price
|
|
1431
|
+
current_price = get_current_price(symbol)
|
|
1432
|
+
logging.info(f"Current BTC Price: {current_price}")
|
|
1433
|
+
|
|
1434
|
+
# Example: Place limit buy order
|
|
1435
|
+
if usdt_balance > 10:
|
|
1436
|
+
buy_price = current_price * 0.99 # 1% below current price
|
|
1437
|
+
quantity = 0.001
|
|
1438
|
+
place_limit_order(symbol, 'BUY', quantity, buy_price)
|
|
1439
|
+
|
|
1440
|
+
if __name__ == '__main__':
|
|
1441
|
+
main()
|
|
1442
|
+
```
|
|
1443
|
+
|
|
1444
|
+
## Useful Links
|
|
1445
|
+
|
|
1446
|
+
- Official Documentation: https://developers.binance.com/docs/binance-spot-api-docs
|
|
1447
|
+
- REST API Documentation: https://developers.binance.com/docs/binance-spot-api-docs/rest-api
|
|
1448
|
+
- WebSocket Streams: https://developers.binance.com/docs/binance-spot-api-docs/web-socket-streams
|
|
1449
|
+
- WebSocket API: https://developers.binance.com/docs/binance-spot-api-docs/websocket-api
|
|
1450
|
+
- GitHub Repository: https://github.com/binance/binance-connector-python
|
|
1451
|
+
- PyPI Package: https://pypi.org/project/binance-connector/
|
|
1452
|
+
- API Testnet: https://testnet.binance.vision
|
|
1453
|
+
- Get API Key: https://www.binance.com/en/my/settings/api-management
|
|
1454
|
+
- API Documentation (Old): https://binance-docs.github.io/apidocs/spot/en/
|