bitvavo-api-upgraded 1.17.2__py3-none-any.whl โ†’ 2.2.0__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.
@@ -0,0 +1,806 @@
1
+ Metadata-Version: 2.3
2
+ Name: bitvavo-api-upgraded
3
+ Version: 2.2.0
4
+ Summary: A unit-tested fork of the Bitvavo API
5
+ Author: Bitvavo BV (original code), NostraDavid
6
+ Author-email: NostraDavid <55331731+NostraDavid@users.noreply.github.com>
7
+ License: ISC License
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Environment :: Console
10
+ Classifier: Framework :: Pytest
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Intended Audience :: Financial and Insurance Industry
13
+ Classifier: License :: OSI Approved :: ISC License (ISCL)
14
+ Classifier: Operating System :: MacOS :: MacOS X
15
+ Classifier: Operating System :: Microsoft :: Windows
16
+ Classifier: Operating System :: POSIX
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Programming Language :: Python
23
+ Classifier: Typing :: Typed
24
+ Requires-Dist: pydantic-settings==2.*,>=2.6
25
+ Requires-Dist: requests==2.*,>=2.26
26
+ Requires-Dist: structlog>=21.5,==25.*
27
+ Requires-Dist: websocket-client==1.*,>=1.2
28
+ Requires-Dist: cudf-cu12>=24.0.0 ; extra == 'cudf'
29
+ Requires-Dist: narwhals>=2.0.0 ; extra == 'cudf'
30
+ Requires-Dist: narwhals[dask]>=2.0.0 ; extra == 'dask'
31
+ Requires-Dist: narwhals[duckdb]>=2.0.0 ; extra == 'duckdb'
32
+ Requires-Dist: narwhals[ibis]>=2.0.0 ; extra == 'ibis'
33
+ Requires-Dist: narwhals[modin]>=2.0.0 ; extra == 'modin'
34
+ Requires-Dist: narwhals[pandas]>=2.0.0 ; extra == 'pandas'
35
+ Requires-Dist: narwhals[polars]>=2.0.0 ; extra == 'polars'
36
+ Requires-Dist: narwhals[pyarrow]>=2.0.0 ; extra == 'pyarrow'
37
+ Requires-Dist: narwhals[pyspark]>=2.0.0 ; extra == 'pyspark'
38
+ Requires-Dist: narwhals[pyspark-connect]>=2.0.0 ; extra == 'pyspark-connect'
39
+ Requires-Dist: narwhals[sqlframe]>=2.0.0 ; extra == 'sqlframe'
40
+ Maintainer: NostraDavid
41
+ Maintainer-email: NostraDavid <55331731+NostraDavid@users.noreply.github.com>
42
+ Requires-Python: >=3.9
43
+ Project-URL: changelog, https://github.com/Thaumatorium/bitvavo-api-upgraded/blob/master/CHANGELOG.md
44
+ Project-URL: homepage, https://github.com/Thaumatorium/bitvavo-api-upgraded
45
+ Project-URL: repository, https://github.com/Thaumatorium/bitvavo-api-upgraded
46
+ Provides-Extra: cudf
47
+ Provides-Extra: dask
48
+ Provides-Extra: duckdb
49
+ Provides-Extra: ibis
50
+ Provides-Extra: modin
51
+ Provides-Extra: pandas
52
+ Provides-Extra: polars
53
+ Provides-Extra: pyarrow
54
+ Provides-Extra: pyspark
55
+ Provides-Extra: pyspark-connect
56
+ Provides-Extra: sqlframe
57
+ Description-Content-Type: text/markdown
58
+
59
+ # Bitvavo API (upgraded)
60
+
61
+ A **typed, tested, and enhanced** Python wrapper for the Bitvavo cryptocurrency exchange API. This is an "upgraded" fork of the official Bitvavo SDK with comprehensive type hints, unit tests, and improved developer experience.
62
+
63
+ ## Quick Start
64
+
65
+ ```bash
66
+ pip install bitvavo_api_upgraded
67
+ ```
68
+
69
+ ### Optional Dataframe Support
70
+
71
+ This package supports multiple dataframe libraries via [Narwhals](https://narwhals-dev.github.io/narwhals/), providing a unified interface across:
72
+
73
+ - **pandas** - The most popular Python data analysis library
74
+ - **polars** - Fast, memory-efficient DataFrames in Rust
75
+ - **cuDF** - GPU-accelerated DataFrames (NVIDIA RAPIDS)
76
+ - **modin** - Distributed pandas on Ray/Dask
77
+ - **PyArrow** - In-memory columnar data format
78
+ - **Dask** - Parallel computing with task scheduling
79
+ - **DuckDB** - In-process analytical database
80
+ - **Ibis** - Portable analytics across backends
81
+ - **PySpark** - Distributed data processing
82
+ - **PySpark Connect** - Client for remote Spark clusters
83
+ - **SQLFrame** - SQL-like operations on DataFrames
84
+
85
+ Install with your preferred dataframe library:
86
+
87
+ ```bash
88
+ # Basic installation (dict output only)
89
+ pip install bitvavo_api_upgraded
90
+
91
+ # With pandas support
92
+ pip install bitvavo_api_upgraded[pandas]
93
+
94
+ # With polars support
95
+ pip install bitvavo_api_upgraded[polars]
96
+
97
+ # With multiple libraries
98
+ pip install bitvavo_api_upgraded[pandas,polars,pyarrow]
99
+
100
+ # With GPU acceleration (cuDF)
101
+ pip install bitvavo_api_upgraded[cudf]
102
+
103
+ # With distributed computing (Dask)
104
+ pip install bitvavo_api_upgraded[dask]
105
+
106
+ # Note: polars-gpu support will be available in a future release
107
+ ```
108
+
109
+ Scroll down for detailed usage examples and configuration instructions.
110
+
111
+ ## What Makes This "Upgraded"?
112
+
113
+ This wrapper improves upon the official Bitvavo SDK with:
114
+
115
+ - ๐ŸŽฏ **Complete type annotations** for all functions and classes
116
+ - ๐Ÿงช **Comprehensive test suite** (found and fixed multiple bugs in the original)
117
+ - ๐Ÿ“‹ **Detailed changelog** tracking all changes and improvements
118
+ - ๐Ÿ”„ **Up-to-date API compliance** including MiCA regulatory requirements
119
+ - ๐Ÿ“š **Enhanced documentation** with examples and clear usage patterns
120
+ - ๐Ÿ **Modern Python support** (3.9+, dropped EOL versions)
121
+ - ๐Ÿ”‘ **Multi-key & keyless support** for enhanced rate limiting and public access
122
+ - โšก **Better error handling** and rate limiting
123
+ - ๐Ÿ”ง **Developer-friendly tooling** (ruff, mypy, pre-commit hooks)
124
+ - ๐Ÿ“Š **Unified dataframe support** via Narwhals (pandas, polars, cuDF, modin, PyArrow, Dask, DuckDB, Ibis, PySpark, SQLFrame)
125
+
126
+ ## Features
127
+
128
+ ### Full API Coverage
129
+
130
+ - โœ… All REST endpoints (public and private)
131
+ - โœ… **Multiple API key support** with automatic load balancing
132
+ - โœ… **Keyless access** for public endpoints without authentication
133
+ - โœ… **Comprehensive dataframe support** via Narwhals (pandas, polars, cuDF, modin, PyArrow, Dask, DuckDB, Ibis, PySpark, and more)
134
+ - โœ… WebSocket support with reconnection logic
135
+ - โœ… Rate limiting with automatic throttling
136
+ - โœ… MiCA compliance reporting endpoints
137
+
138
+ ### Developer Experience
139
+
140
+ - โœ… Type hints for better IDE support
141
+ - โœ… Comprehensive error handling
142
+ - โœ… Detailed logging with `structlog`
143
+ - โœ… Configuration via `.env` files
144
+ - โœ… Extensive test coverage
145
+
146
+ ### Production Ready
147
+
148
+ - โœ… Automatic rate limit management
149
+ - โœ… Multi-key failover support
150
+ - โœ… Connection retry logic
151
+ - โœ… Proper error responses
152
+ - โœ… Memory efficient WebSocket handling
153
+
154
+ ## Configuration
155
+
156
+ Create a `.env` file in your project root:
157
+
158
+ ```env
159
+ # Single API key (traditional)
160
+ BITVAVO_APIKEY=your-api-key-here
161
+ BITVAVO_APISECRET=your-api-secret-here
162
+
163
+ # Multiple API keys (for rate limiting)
164
+ # BITVAVO_APIKEYS='[{"key": "key1", "secret": "secret1"}, {"key": "key2", "secret": "secret2"}]'
165
+
166
+ # Keyless access (public endpoints only)
167
+ BITVAVO_PREFER_KEYLESS=true
168
+
169
+ # Enhanced settings
170
+ BITVAVO_API_UPGRADED_DEFAULT_RATE_LIMIT=750
171
+ BITVAVO_API_UPGRADED_PREFER_KEYLESS=false
172
+ ```
173
+
174
+ Then use the settings:
175
+
176
+ ```python
177
+ from bitvavo_api_upgraded import Bitvavo, BitvavoSettings
178
+
179
+ # Option 1: Manual configuration
180
+ bitvavo = Bitvavo({
181
+ 'APIKEY': 'your-key',
182
+ 'APISECRET': 'your-secret'
183
+ })
184
+
185
+ # Option 2: Auto-load from .env
186
+ settings = BitvavoSettings()
187
+ bitvavo = Bitvavo(settings.model_dump())
188
+
189
+ # Option 3: Multiple API keys
190
+ bitvavo = Bitvavo({
191
+ 'APIKEYS': [
192
+ {'key': 'key1', 'secret': 'secret1'},
193
+ {'key': 'key2', 'secret': 'secret2'}
194
+ ]
195
+ })
196
+
197
+ # Option 4: Keyless (public endpoints only)
198
+ bitvavo = Bitvavo({'PREFER_KEYLESS': True})
199
+ ```
200
+
201
+ ## WebSocket Usage
202
+
203
+ ```python
204
+ from bitvavo_api_upgraded import Bitvavo
205
+
206
+ def handle_ticker(data):
207
+ print(f"Ticker update: {data}")
208
+
209
+ def handle_error(error):
210
+ print(f"Error: {error}")
211
+
212
+ # Initialize WebSocket
213
+ bitvavo = Bitvavo({'APIKEY': 'key', 'APISECRET': 'secret'})
214
+ ws = bitvavo.newWebsocket()
215
+ ws.setErrorCallback(handle_error)
216
+
217
+ # Subscribe to ticker updates
218
+ ws.subscriptionTicker("BTC-EUR", handle_ticker)
219
+
220
+ # Keep connection alive
221
+ try:
222
+ while True:
223
+ time.sleep(1)
224
+ except KeyboardInterrupt:
225
+ ws.closeSocket()
226
+ ```
227
+
228
+ ## Multi-Key & Keyless Examples
229
+
230
+ ### Multiple API Keys for Rate Limiting
231
+
232
+ ```python
233
+ from bitvavo_api_upgraded import Bitvavo
234
+
235
+ # Configure multiple API keys
236
+ bitvavo = Bitvavo({
237
+ 'APIKEYS': [
238
+ {'key': 'key1', 'secret': 'secret1'},
239
+ {'key': 'key2', 'secret': 'secret2'},
240
+ {'key': 'key3', 'secret': 'secret3'}
241
+ ]
242
+ })
243
+
244
+ # API automatically balances load across keys
245
+ balance = bitvavo.balance({}) # Uses least-used key
246
+ orders = bitvavo.getOrders('BTC-EUR', {}) # May use different key
247
+ trades = bitvavo.getTrades('BTC-EUR', {}) # Automatic failover if rate limit reached
248
+ ```
249
+
250
+ ### Keyless Access (Public Endpoints)
251
+
252
+ ```python
253
+ from bitvavo_api_upgraded import Bitvavo
254
+
255
+ # No API keys needed for public data
256
+ bitvavo = Bitvavo({'PREFER_KEYLESS': True})
257
+
258
+ # These work without authentication and don't count against your rate limits
259
+ markets = bitvavo.markets({})
260
+ ticker = bitvavo.ticker24h({'market': 'BTC-EUR'})
261
+ trades = bitvavo.publicTrades('BTC-EUR', {})
262
+ book = bitvavo.book('BTC-EUR', {})
263
+ candles = bitvavo.candles('BTC-EUR', '1h', {})
264
+
265
+ # Private endpoints will still require authentication
266
+ # account = bitvavo.account() # This would fail without API keys
267
+ ```
268
+
269
+ ### Hybrid Configuration
270
+
271
+ ```python
272
+ # Combine keyless preference with API keys for optimal performance
273
+ bitvavo = Bitvavo({
274
+ 'APIKEYS': [
275
+ {'key': 'key1', 'secret': 'secret1'},
276
+ {'key': 'key2', 'secret': 'secret2'}
277
+ ],
278
+ 'PREFER_KEYLESS': True # Use keyless for public endpoints, API keys for private
279
+ })
280
+
281
+ # Public calls use keyless (no rate limit impact)
282
+ markets = bitvavo.markets({})
283
+
284
+ # Private calls use API keys with load balancing
285
+ balance = bitvavo.balance({})
286
+ ```
287
+
288
+ ## API Examples
289
+
290
+ ### Public Endpoints (No Authentication)
291
+
292
+ ```python
293
+ # Get server time
294
+ time_resp = bitvavo.time()
295
+
296
+ # Get all markets
297
+ markets = bitvavo.markets({})
298
+
299
+ # Get specific market
300
+ btc_market = bitvavo.markets({'market': 'BTC-EUR'})
301
+
302
+ # Get order book
303
+ book = bitvavo.book('BTC-EUR', {})
304
+
305
+ # Get recent trades
306
+ trades = bitvavo.publicTrades('BTC-EUR', {})
307
+
308
+ # Get 24h ticker
309
+ ticker = bitvavo.ticker24h({'market': 'BTC-EUR'})
310
+ ```
311
+
312
+ ### Private Endpoints (Authentication Required)
313
+
314
+ ```python
315
+ # Get account info
316
+ account = bitvavo.account()
317
+
318
+ # Get balance
319
+ balance = bitvavo.balance({})
320
+
321
+ # Place order (requires operatorId for MiCA compliance)
322
+ order = bitvavo.placeOrder(
323
+ market="BTC-EUR",
324
+ side="buy",
325
+ orderType="limit",
326
+ body={"amount": "0.01", "price": "45000"},
327
+ operatorId=12345
328
+ )
329
+
330
+ # Get order history
331
+ orders = bitvavo.getOrders('BTC-EUR', {})
332
+
333
+ # Cancel order
334
+ cancel_result = bitvavo.cancelOrder(
335
+ market="BTC-EUR",
336
+ orderId="order-id-here",
337
+ operatorId=12345
338
+ )
339
+ ```
340
+
341
+ ### MiCA Compliance Features
342
+
343
+ ```python
344
+ # Generate trade report
345
+ trade_report = bitvavo.reportTrades(
346
+ market="BTC-EUR",
347
+ options={
348
+ "startDate": "2025-01-01T00:00:00.000Z",
349
+ "endDate": "2025-01-31T23:59:59.999Z"
350
+ }
351
+ )
352
+
353
+ # Generate order book report
354
+ book_report = bitvavo.reportBook(
355
+ market="BTC-EUR",
356
+ options={
357
+ "startDate": "2025-01-01T00:00:00.000Z",
358
+ "endDate": "2025-01-31T23:59:59.999Z"
359
+ }
360
+ )
361
+
362
+ # Get account history
363
+ history = bitvavo.accountHistory(options={})
364
+ ```
365
+
366
+ ### Dataframe Usage
367
+
368
+ The library supports multiple dataframe formats for tabular data like market data, asset information, and candlestick data:
369
+
370
+ ```python
371
+ from bitvavo_api_upgraded import Bitvavo
372
+
373
+ bitvavo = Bitvavo({'APIKEY': 'key', 'APISECRET': 'secret'})
374
+
375
+ # Get markets as different dataframe types
376
+ markets_dict = bitvavo.markets({}, output_format='dict') # Default dict format
377
+ markets_pandas = bitvavo.markets({}, output_format='pandas') # Pandas DataFrame
378
+ markets_polars = bitvavo.markets({}, output_format='polars') # Polars DataFrame
379
+ markets_pyarrow = bitvavo.markets({}, output_format='pyarrow') # PyArrow Table
380
+
381
+ # Get assets information as dataframes
382
+ assets_cudf = bitvavo.assets(
383
+ {},
384
+ output_format='cudf' # GPU-accelerated with cuDF
385
+ )
386
+
387
+ # Get candlestick data with distributed processing
388
+ candles_dask = bitvavo.candles(
389
+ 'BTC-EUR',
390
+ '1h',
391
+ {'limit': 100},
392
+ output_format='dask' # Distributed with Dask
393
+ )
394
+
395
+ # Get public trades with analytical databases
396
+ trades_duckdb = bitvavo.publicTrades(
397
+ 'BTC-EUR',
398
+ {'limit': 1000},
399
+ output_format='duckdb' # DuckDB relation
400
+ )
401
+
402
+ # Account balance with PySpark for big data processing
403
+ balance_spark = bitvavo.balance(
404
+ {},
405
+ output_format='pyspark' # PySpark DataFrame
406
+ )
407
+ ```
408
+
409
+ ### Working with Different Libraries
410
+
411
+ ```python
412
+ # Pandas example - most common
413
+ import pandas as pd
414
+ df = bitvavo.markets({}, output_format='pandas')
415
+ print(df.describe())
416
+ df.to_csv('markets.csv')
417
+
418
+ # Polars example - faster for large datasets
419
+ import polars as pl
420
+ df = bitvavo.candles('BTC-EUR', '1h', {'limit': 1000}, output_format='polars')
421
+ result = df.filter(pl.col('close') > 50000).select(['timestamp', 'close'])
422
+
423
+ # DuckDB example - analytical queries
424
+ import duckdb
425
+ rel = bitvavo.publicTrades('BTC-EUR', {'limit': 10000}, output_format='duckdb')
426
+ high_volume_trades = duckdb.query("SELECT * FROM rel WHERE amount > 1.0")
427
+
428
+ # PyArrow example - columnar data
429
+ import pyarrow as pa
430
+ table = bitvavo.assets({}, output_format='pyarrow')
431
+ df = table.to_pandas() # Convert to pandas when needed
432
+ ```
433
+
434
+ ## Error Handling
435
+
436
+ ```python
437
+ from bitvavo_api_upgraded import Bitvavo
438
+
439
+ bitvavo = Bitvavo({'APIKEY': 'key', 'APISECRET': 'secret'})
440
+
441
+ response = bitvavo.placeOrder(
442
+ market="BTC-EUR",
443
+ side="buy",
444
+ orderType="limit",
445
+ body={"amount": "0.01", "price": "45000"},
446
+ operatorId=12345
447
+ )
448
+
449
+ # Check for errors
450
+ if isinstance(response, dict) and 'errorCode' in response:
451
+ print(f"Error {response['errorCode']}: {response['error']}")
452
+ else:
453
+ print(f"Order placed successfully: {response['orderId']}")
454
+ ```
455
+
456
+ ## Rate Limiting
457
+
458
+ ```python
459
+ # Check remaining rate limit
460
+ remaining = bitvavo.getRemainingLimit()
461
+ print(f"Remaining API calls: {remaining}")
462
+
463
+ # The library automatically handles rate limiting
464
+ # But you can check limits before making calls
465
+ if remaining > 10:
466
+ # Safe to make API calls
467
+ response = bitvavo.balance({})
468
+
469
+ # With multiple API keys, rate limits are distributed
470
+ bitvavo_multi = Bitvavo({
471
+ 'APIKEYS': [
472
+ {'key': 'key1', 'secret': 'secret1'},
473
+ {'key': 'key2', 'secret': 'secret2'}
474
+ ]
475
+ })
476
+
477
+ # Each key gets its own rate limit pool
478
+ # Automatic failover when one key hits limits
479
+ for i in range(2000): # Would exceed single key limit
480
+ markets = bitvavo_multi.markets({}) # Automatically switches keys
481
+
482
+ # Keyless calls don't count against authenticated rate limits
483
+ bitvavo_keyless = Bitvavo({'PREFER_KEYLESS': True})
484
+ markets = bitvavo_keyless.markets({}) # Uses public rate limit pool
485
+ ```
486
+
487
+ ## Development & Contributing
488
+
489
+ ````shell
490
+ echo "install development requirements"
491
+ uv sync
492
+ echo "run tox, a program that creates separate environments for different python versions, for testing purposes (among other things)"
493
+ uv run tox
494
+ ## Development & Contributing
495
+
496
+ ### Setup Development Environment
497
+
498
+ ```shell
499
+ # Install uv (modern Python package manager)
500
+ curl -LsSf https://astral.sh/uv/install.sh | sh
501
+
502
+ # Clone and setup
503
+ git clone https://github.com/Thaumatorium/bitvavo-api-upgraded.git
504
+ cd bitvavo-api-upgraded
505
+
506
+ # Install dependencies
507
+ uv sync
508
+
509
+ # Run tests across Python versions
510
+ uv run tox
511
+
512
+ # Run tests for current Python version
513
+ uv run pytest
514
+
515
+ # Type checking
516
+ uv run mypy src/
517
+
518
+ # Linting and formatting
519
+ uv run ruff check
520
+ uv run ruff format
521
+ ````
522
+
523
+ ### Project Structure
524
+
525
+ ```text
526
+ src/bitvavo_api_upgraded/ # Source code
527
+ โ”œโ”€โ”€ __init__.py # Main exports
528
+ โ”œโ”€โ”€ bitvavo.py # Core API class
529
+ โ”œโ”€โ”€ settings.py # Pydantic settings
530
+ โ”œโ”€โ”€ helper_funcs.py # Utility functions
531
+ โ””โ”€โ”€ type_aliases.py # Type definitions
532
+
533
+ tests/ # Comprehensive test suite
534
+ docs/ # Documentation
535
+ ```
536
+
537
+ ### Semantic Versioning
538
+
539
+ This project follows [semantic versioning](https://semver.org/):
540
+
541
+ 1. **MAJOR** version for incompatible API changes
542
+ 2. **MINOR** version for backwards-compatible functionality additions
543
+ 3. **PATCH** version for backwards-compatible bug fixes
544
+
545
+ ## Type Annotations
546
+
547
+ This package includes a `py.typed` file to enable type checking. Reference: [Don't forget py.typed for your typed Python package](https://blog.whtsky.me/tech/2021/dont-forget-py.typed-for-your-typed-python-package/)
548
+
549
+ ## Migration from Official SDK
550
+
551
+ ### Key Differences
552
+
553
+ - Import: `from bitvavo_api_upgraded import Bitvavo` (instead of `from python_bitvavo_api.bitvavo import Bitvavo`)
554
+ - **Breaking Change**: Trading operations require `operatorId` parameter
555
+ - **New**: Multiple API key support for better rate limiting
556
+ - **New**: Keyless access for public endpoints
557
+ - **New**: Comprehensive dataframe support
558
+ - Enhanced error handling and type safety
559
+ - Better configuration management with `.env` support
560
+
561
+ ### Migration Steps
562
+
563
+ 1. Update import statements
564
+ 2. Add `operatorId` to trading method calls
565
+ 3. Optional: Migrate to `.env` configuration
566
+ 4. Optional: Configure multiple API keys for better rate limits
567
+ 5. Optional: Enable keyless mode for public endpoint efficiency
568
+ 6. Enjoy improved type hints and error handling!
569
+
570
+ ### Enhanced Features (Optional)
571
+
572
+ ```python
573
+ # Traditional single key (works as before)
574
+ bitvavo = Bitvavo({'APIKEY': 'key', 'APISECRET': 'secret'})
575
+
576
+ # New: Multiple keys for rate limiting
577
+ bitvavo = Bitvavo({
578
+ 'APIKEYS': [
579
+ {'key': 'key1', 'secret': 'secret1'},
580
+ {'key': 'key2', 'secret': 'secret2'}
581
+ ]
582
+ })
583
+
584
+ # New: Keyless for public endpoints
585
+ bitvavo = Bitvavo({'PREFER_KEYLESS': True})
586
+
587
+ # New: Dataframe support
588
+ markets_df = bitvavo.markets({}, output_format='pandas')
589
+ ```
590
+
591
+ ---
592
+
593
+ ## Original Bitvavo SDK Documentation
594
+
595
+ The following is preserved from the original Bitvavo SDK for reference.
596
+
597
+ Crypto starts with Bitvavo. You use Bitvavo SDK for Python to buy, sell, and
598
+ store over 200 digital assets on Bitvavo from inside your app.
599
+
600
+ To trade and execute your advanced trading strategies, Bitvavo SDK for Python is
601
+ a wrapper that enables you to easily call every endpoint in [Bitvavo
602
+ API](https://docs.bitvavo.com/).
603
+
604
+ - [Prerequisites](#prerequisites) - what you need to start developing with
605
+ Bitvavo SDK for Python
606
+ - [Get started](#get-started) - rapidly create an app and start trading with
607
+ Bitvavo
608
+ - [About the SDK](#about-the-sdk) - general information about Bitvavo SDK for
609
+ Python
610
+ - [API reference](https://docs.bitvavo.com/) - information on the specifics of
611
+ every parameter
612
+
613
+ This page shows you how to use Bitvavo SDK for Python with WebSockets. For REST,
614
+ see the [REST readme](docs/rest.md).
615
+
616
+ ## Prerequisites
617
+
618
+ To start programming with Bitvavo SDK for Python you need:
619
+
620
+ - [Python3](https://www.python.org/downloads/) installed on your development
621
+ environment
622
+
623
+ If you are working on macOS, ensure that you have installed SSH certificates:
624
+
625
+ ```terminal
626
+ open /Applications/Python\ 3.12/Install\ Certificates.command
627
+ open /Applications/Python\ 3.12/Update\ Shell\ Profile.command
628
+ ```
629
+
630
+ - A Python app. Use your favorite IDE, or run from the command line
631
+ - An [API key and
632
+ secret](https://support.bitvavo.com/hc/en-us/articles/4405059841809)
633
+ associated with your Bitvavo account
634
+
635
+ You control the actions your app can do using the rights you assign to the API
636
+ key. Possible rights are:
637
+
638
+ - **View**: retrieve information about your balance, account, deposit and
639
+ withdrawals
640
+ - **Trade**: place, update, view and cancel orders
641
+ - **Withdraw**: withdraw funds
642
+
643
+ Best practice is to not grant this privilege, withdrawals using the API do
644
+ not require 2FA and e-mail confirmation.
645
+
646
+ ## Get started
647
+
648
+ Want to quickly make a trading app? Here you go:
649
+
650
+ 1. **Install Bitvavo SDK for Python**
651
+
652
+ In your Python app, add [Bitvavo SDK for
653
+ Python](https://github.com/bitvavo/python-bitvavo-api) from
654
+ [pypi.org](https://pypi.org/project/python-bitvavo-api/):
655
+
656
+ ```shell
657
+ python -m pip install python_bitvavo_api
658
+ ```
659
+
660
+ If you installed from `test.pypi.com`, update the requests library: `pip
661
+ install --upgrade requests`.
662
+
663
+ 1. **Create a simple Bitvavo implementation**
664
+
665
+ Add the following code to a new file in your app:
666
+
667
+ ```python
668
+ from python_bitvavo_api.bitvavo import Bitvavo
669
+ import json
670
+ import time
671
+
672
+ # Use this class to connect to Bitvavo and make your first calls.
673
+ # Add trading strategies to implement your business logic.
674
+ class BitvavoImplementation:
675
+ api_key = "<Replace with your your API key from Bitvavo Dashboard>"
676
+ api_secret = "<Replace with your API secret from Bitvavo Dashboard>"
677
+ bitvavo_engine = None
678
+ bitvavo_socket = None
679
+
680
+ # Connect securely to Bitvavo, create the WebSocket and error callbacks.
681
+ def __init__(self):
682
+ self.bitvavo_engine = Bitvavo({
683
+ 'APIKEY': self.api_key,
684
+ 'APISECRET': self.api_secret
685
+ })
686
+ self.bitvavo_socket = self.bitvavo_engine.newWebsocket()
687
+ self.bitvavo_socket.setErrorCallback(self.error_callback)
688
+
689
+ # Handle errors.
690
+ def error_callback(self, error):
691
+ print("Add your error message.")
692
+ #print("Errors:", json.dumps(error, indent=2))
693
+
694
+ # Retrieve the data you need from Bitvavo in order to implement your
695
+ # trading logic. Use multiple workflows to return data to your
696
+ # callbacks.
697
+ def a_trading_strategy(self):
698
+ self.bitvavo_socket.ticker24h({}, self.a_trading_strategy_callback)
699
+
700
+ # In your app you analyse data returned by the trading strategy, then make
701
+ # calls to Bitvavo to respond to market conditions.
702
+ def a_trading_strategy_callback(self, response):
703
+ # Iterate through the markets
704
+ for market in response:
705
+
706
+ match market["market"]:
707
+ case "ZRX-EUR":
708
+ print("Eureka, the latest bid for ZRX-EUR is: ", market["bid"] )
709
+ # Implement calculations for your trading logic.
710
+ # If they are positive, place an order: For example:
711
+ # self.bitvavo_socket.placeOrder("ZRX-EUR",
712
+ # 'buy',
713
+ # 'limit',
714
+ # { 'amount': '1', 'price': '00001' },
715
+ # self.order_placed_callback)
716
+ case "a different market":
717
+ print("do something else")
718
+ case _:
719
+ print("Not this one: ", market["market"])
720
+
721
+
722
+
723
+ def order_placed_callback(self, response):
724
+ # The order return parameters explain the quote and the fees for this trade.
725
+ print("Order placed:", json.dumps(response, indent=2))
726
+ # Add your business logic.
727
+
728
+
729
+ # Sockets are fast, but asynchronous. Keep the socket open while you are
730
+ # trading.
731
+ def wait_and_close(self):
732
+ # Bitvavo uses a weight based rate limiting system. Your app is limited to 1000 weight points per IP or
733
+ # API key per minute. The rate weighting for each endpoint is supplied in Bitvavo API documentation.
734
+ # This call returns the amount of points left. If you make more requests than permitted by the weight limit,
735
+ # your IP or API key is banned.
736
+ limit = self.bitvavo_engine.getRemainingLimit()
737
+ try:
738
+ while (limit > 0):
739
+ time.sleep(0.5)
740
+ limit = self.bitvavo_engine.getRemainingLimit()
741
+ except KeyboardInterrupt:
742
+ self.bitvavo_socket.closeSocket()
743
+
744
+
745
+ # Shall I re-explain main? Naaaaaaaaaa.
746
+ if __name__ == '__main__':
747
+ bvavo = BitvavoImplementation()
748
+ bvavo.a_trading_strategy()
749
+ bvavo.wait_and_close()
750
+ ```
751
+
752
+ 1. **Add security information**
753
+
754
+ You must supply your security information to trade on Bitvavo and see your
755
+ account information using the authenticate methods. Replace the values of
756
+ `api_key` and `api_secret` with your credentials from [Bitvavo
757
+ Dashboard](https://account.bitvavo.com/user/api).
758
+
759
+ You can retrieve public information such as available markets, assets and
760
+ current market without supplying your key and secret. However,
761
+ unauthenticated calls have lower rate limits based on your IP address, and
762
+ your account is blocked for longer if you exceed your limit.
763
+
764
+ 1. **Run your app**
765
+
766
+ - Command line warriors: `python3 <filename>`.
767
+ - IDE heroes: press the big green button.
768
+
769
+ Your app connects to Bitvavo and returns a list the latest trade price for each
770
+ market. You use this data to implement your trading logic.
771
+
772
+ ## About the SDK
773
+
774
+ This section explains global concepts about Bitvavo SDK for Python.
775
+
776
+ ### Rate limit
777
+
778
+ Bitvavo uses a weight based rate limiting system. Your app is limited to 1000
779
+ weight points per IP or API key per minute. When you make a call to Bitvavo API,
780
+ your remaining weight points are returned in the header of each REST request.
781
+
782
+ Websocket methods do not return your returning weight points, you track your
783
+ remaining weight points with a call to:
784
+
785
+ ```python
786
+ limit = bitvavo.getRemainingLimit()
787
+ ```
788
+
789
+ If you make more requests than permitted by the weight limit, your IP or API key
790
+ is banned.
791
+
792
+ The rate weighting for each endpoint is supplied in the [Bitvavo API
793
+ documentation](https://docs.bitvavo.com/).
794
+
795
+ ### Requests
796
+
797
+ For all methods, required parameters are passed as separate values, optional
798
+ parameters are passed as a dictionary. Return parameters are in dictionary
799
+ format: `response['<key>'] = '<value>'`. However, as a limit order requires more
800
+ information than a market order, some optional parameters are required when you
801
+ place an order.
802
+
803
+ ### Security
804
+
805
+ You must set your API key and secret for authenticated endpoints, public
806
+ endpoints do not require authentication.