bitvavo-api-upgraded 1.15.8__py3-none-any.whl → 1.17.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.
@@ -1,10 +1,12 @@
1
+ from __future__ import annotations
2
+
3
+ import datetime as dt
1
4
  import hashlib
2
5
  import hmac
3
6
  import json
4
7
  import time
5
- import datetime as dt
6
8
  from threading import Thread
7
- from typing import Any, Callable, Dict, List, Union
9
+ from typing import Any, Callable
8
10
 
9
11
  import websocket as ws_lib
10
12
  from requests import delete, get, post, put
@@ -13,22 +15,22 @@ from websocket import WebSocketApp # missing stubs for WebSocketApp
13
15
 
14
16
  from bitvavo_api_upgraded.helper_funcs import configure_loggers, time_ms, time_to_wait
15
17
  from bitvavo_api_upgraded.settings import BITVAVO_API_UPGRADED
16
- from bitvavo_api_upgraded.type_aliases import anydict, errordict, intdict, ms, s_f, strdict
18
+ from bitvavo_api_upgraded.type_aliases import anydict, errordict, intdict, ms, s_f, strdict, strintdict
17
19
 
18
20
  configure_loggers()
19
21
 
20
22
  logger = get_logger(__name__)
21
23
 
22
24
 
23
- def createSignature(timestamp: ms, method: str, url: str, body: anydict, APISECRET: str) -> str:
25
+ def createSignature(timestamp: ms, method: str, url: str, body: anydict | None, api_secret: str) -> str:
24
26
  string = f"{timestamp}{method}/v2{url}"
25
- if len(body.keys()) != 0:
27
+ if body is not None and len(body.keys()) > 0:
26
28
  string += json.dumps(body, separators=(",", ":"))
27
- signature = hmac.new(APISECRET.encode("utf-8"), string.encode("utf-8"), hashlib.sha256).hexdigest()
29
+ signature = hmac.new(api_secret.encode("utf-8"), string.encode("utf-8"), hashlib.sha256).hexdigest()
28
30
  return signature
29
31
 
30
32
 
31
- def createPostfix(options: anydict) -> str:
33
+ def createPostfix(options: anydict | None) -> str:
32
34
  """Generate a URL postfix, based on the `options` dict.
33
35
 
34
36
  ---
@@ -39,11 +41,29 @@ def createPostfix(options: anydict) -> str:
39
41
  Returns:
40
42
  str: [description]
41
43
  """
44
+ options = _default(options, {})
42
45
  params = [f"{key}={options[key]}" for key in options]
43
46
  postfix = "&".join(params) # intersperse
44
47
  return f"?{postfix}" if len(options) > 0 else postfix
45
48
 
46
49
 
50
+ def _default(value: anydict | None, fallback: anydict) -> anydict:
51
+ """
52
+ Note that is close, but not actually equal to:
53
+
54
+ `return value or fallback`
55
+
56
+ I checked this with a temporary hypothesis test.
57
+
58
+ This note is all you will get out of me.
59
+ """
60
+ return value if value is not None else fallback
61
+
62
+
63
+ def _epoch_millis(dt: dt.datetime) -> int:
64
+ return int(dt.timestamp() * 1000)
65
+
66
+
47
67
  def asksCompare(a: float, b: float) -> bool:
48
68
  return a < b
49
69
 
@@ -53,10 +73,10 @@ def bidsCompare(a: float, b: float) -> bool:
53
73
 
54
74
 
55
75
  def sortAndInsert(
56
- asks_or_bids: List[List[str]],
57
- update: List[List[str]],
76
+ asks_or_bids: list[list[str]],
77
+ update: list[list[str]],
58
78
  compareFunc: Callable[[float, float], bool],
59
- ) -> Union[List[List[str]], errordict]:
79
+ ) -> list[list[str]] | errordict:
60
80
  for updateEntry in update:
61
81
  entrySet: bool = False
62
82
  for j in range(len(asks_or_bids)):
@@ -70,16 +90,15 @@ def sortAndInsert(
70
90
  asks_or_bids[j] = updateEntry
71
91
  entrySet = True
72
92
  break
73
- else:
74
- asks_or_bids.pop(j)
75
- entrySet = True
76
- break
93
+ asks_or_bids.pop(j)
94
+ entrySet = True
95
+ break
77
96
  if not entrySet:
78
97
  asks_or_bids.append(updateEntry)
79
98
  return asks_or_bids
80
99
 
81
100
 
82
- def processLocalBook(ws: "Bitvavo.WebSocketAppFacade", message: anydict) -> None:
101
+ def processLocalBook(ws: Bitvavo.WebSocketAppFacade, message: anydict) -> None:
83
102
  market: str = ""
84
103
  if "action" in message:
85
104
  if message["action"] == "getBook":
@@ -88,29 +107,31 @@ def processLocalBook(ws: "Bitvavo.WebSocketAppFacade", message: anydict) -> None
88
107
  ws.localBook[market]["asks"] = message["response"]["asks"]
89
108
  ws.localBook[market]["nonce"] = message["response"]["nonce"]
90
109
  ws.localBook[market]["market"] = market
91
- elif "event" in message:
92
- if message["event"] == "book":
93
- market = message["market"]
110
+ elif "event" in message and message["event"] == "book":
111
+ market = message["market"]
94
112
 
95
- if message["nonce"] != ws.localBook[market]["nonce"] + 1:
96
- # I think I've fixed this, by looking at the other Bitvavo repos (search for 'nonce' or '!=' 😆)
97
- ws.subscriptionBook(market, ws.callbacks[market])
98
- return
99
- ws.localBook[market]["bids"] = sortAndInsert(ws.localBook[market]["bids"], message["bids"], bidsCompare)
100
- ws.localBook[market]["asks"] = sortAndInsert(ws.localBook[market]["asks"], message["asks"], asksCompare)
101
- ws.localBook[market]["nonce"] = message["nonce"]
113
+ if message["nonce"] != ws.localBook[market]["nonce"] + 1:
114
+ # I think I've fixed this, by looking at the other Bitvavo repos (search for 'nonce' or '!=' 😆)
115
+ ws.subscriptionBook(market, ws.callbacks[market])
116
+ return
117
+ ws.localBook[market]["bids"] = sortAndInsert(ws.localBook[market]["bids"], message["bids"], bidsCompare)
118
+ ws.localBook[market]["asks"] = sortAndInsert(ws.localBook[market]["asks"], message["asks"], asksCompare)
119
+ ws.localBook[market]["nonce"] = message["nonce"]
102
120
 
103
121
  if market != "":
104
122
  ws.callbacks["subscriptionBookUser"][market](ws.localBook[market])
105
123
 
106
124
 
107
125
  class ReceiveThread(Thread):
108
- def __init__(self, ws: WebSocketApp, ws_facade: "Bitvavo.WebSocketAppFacade"):
126
+ """This used to be `class rateLimitThread`."""
127
+
128
+ def __init__(self, ws: WebSocketApp, ws_facade: Bitvavo.WebSocketAppFacade) -> None:
109
129
  self.ws = ws
110
130
  self.ws_facade = ws_facade
111
131
  Thread.__init__(self)
112
132
 
113
133
  def run(self) -> None:
134
+ """This used to be `self.waitForReset`."""
114
135
  try:
115
136
  while self.ws_facade.keepAlive:
116
137
  self.ws.run_forever()
@@ -118,9 +139,8 @@ class ReceiveThread(Thread):
118
139
  self.ws_facade.authenticated = False
119
140
  time.sleep(self.ws_facade.reconnectTimer)
120
141
  if self.ws_facade.bitvavo.debugging:
121
- logger.debug(
122
- f"we have just set reconnect to true and have waited for {self.ws_facade.reconnectTimer}",
123
- )
142
+ msg = f"we have just set reconnect to true and have waited for {self.ws_facade.reconnectTimer}"
143
+ logger.debug(msg)
124
144
  self.ws_facade.reconnectTimer = self.ws_facade.reconnectTimer * 2
125
145
  except KeyboardInterrupt:
126
146
  if self.ws_facade.bitvavo.debugging:
@@ -136,17 +156,18 @@ def callback_example(response: Any) -> None:
136
156
 
137
157
  I made this so you can see what kind of function you'll need to stick into the websocket functions.
138
158
  """
139
- if isinstance(response, Dict):
159
+ if isinstance(response, dict):
140
160
  # instead of printing, you could save the object to a file:
141
161
  import json
142
162
  from pathlib import Path
143
163
 
144
164
  HERE = Path.cwd() # root of your project folder
145
165
  filepath = HERE / "your_output.json"
146
- # a = append; figure out yourself to create multiple callback functions, probably one for each type of call that you want to make
166
+ # a = append; figure out yourself to create multiple callback functions, probably one for each type of call that
167
+ # you want to make
147
168
  with filepath.open("a") as file:
148
169
  file.write(json.dumps(response))
149
- elif isinstance(response, List):
170
+ elif isinstance(response, list):
150
171
  # Whether `item` is a list or a dict doesn't matter to print
151
172
  for item in response:
152
173
  print(item)
@@ -187,9 +208,9 @@ def error_callback_example(msg: errordict) -> None:
187
208
  content=f"{msg}",
188
209
  ).execute()
189
210
  ```
190
- """
211
+ """ # noqa: E501
191
212
  # easiest thing is to use the logger, but there's a good chance this message gets silently eaten.
192
- logger.error(msg)
213
+ logger.error("error", msg=msg)
193
214
 
194
215
 
195
216
  class Bitvavo:
@@ -211,7 +232,9 @@ class Bitvavo:
211
232
  ```
212
233
  """
213
234
 
214
- def __init__(self, options: Dict[str, Union[str, int]] = {}):
235
+ def __init__(self, options: dict[str, str | int] | None = None) -> None:
236
+ if options is None:
237
+ options = {}
215
238
  _options = {k.upper(): v for k, v in options.items()}
216
239
  self.base: str = str(_options.get("RESTURL", "https://api.bitvavo.com/v2"))
217
240
  self.wsUrl: str = str(_options.get("WSURL", "wss://ws.bitvavo.com/v2/"))
@@ -220,7 +243,7 @@ class Bitvavo:
220
243
  self.APISECRET = str(_options.get("APISECRET", ""))
221
244
  self.rateLimitRemaining: int = 1000
222
245
  self.rateLimitResetAt: ms = 0
223
- # TODO(NostraDavid) for v2: remove this functionality - logger.debug is a level that can be set
246
+ # TODO(NostraDavid): for v2: remove this functionality - logger.debug is a level that can be set
224
247
  self.debugging = bool(_options.get("DEBUGGING", False))
225
248
 
226
249
  def calcLag(self) -> ms:
@@ -256,7 +279,7 @@ class Bitvavo:
256
279
  """
257
280
  return self.rateLimitRemaining
258
281
 
259
- def updateRateLimit(self, response: Union[anydict, errordict]) -> None:
282
+ def updateRateLimit(self, response: anydict | errordict) -> None:
260
283
  """
261
284
  Update the rate limited
262
285
 
@@ -264,34 +287,33 @@ class Bitvavo:
264
287
 
265
288
  If you're not banned, then use the received headers to update the variables.
266
289
  """
267
- if "errorCode" in response:
268
- if response["errorCode"] == 105:
269
- self.rateLimitRemaining = 0
270
- # rateLimitResetAt is a value that's stripped from a string.
271
- # Kind of a terrible way to pass that information, but eh, whatever, I guess...
272
- # Anyway, here is the string that's being pulled apart:
273
- # "Your IP or API key has been banned for not respecting the rate limit. The ban expires at ${expiryInMs}""
274
- self.rateLimitResetAt = ms(response["error"].split(" at ")[1].split(".")[0])
275
- timeToWait = time_to_wait(self.rateLimitResetAt)
276
- logger.warning(
277
- "banned",
278
- info={
279
- "wait_time_seconds": timeToWait + 1,
280
- "until": (dt.datetime.now() + dt.timedelta(seconds=timeToWait + 1)).isoformat(),
281
- },
282
- )
283
- logger.info("napping-until-ban-lifted")
284
- time.sleep(timeToWait + 1) # plus one second to ENSURE we're able to run again.
285
- if "Bitvavo-Ratelimit-Remaining" in response:
286
- self.rateLimitRemaining = int(response["Bitvavo-Ratelimit-Remaining"])
287
- if "Bitvavo-Ratelimit-ResetAt" in response:
288
- self.rateLimitResetAt = int(response["Bitvavo-Ratelimit-ResetAt"])
290
+ if "errorCode" in response and response["errorCode"] == 105: # noqa: PLR2004
291
+ self.rateLimitRemaining = 0
292
+ # rateLimitResetAt is a value that's stripped from a string.
293
+ # Kind of a terrible way to pass that information, but eh, whatever, I guess...
294
+ # Anyway, here is the string that's being pulled apart:
295
+ # "Your IP or API key has been banned for not respecting the rate limit. The ban expires at ${expiryInMs}""
296
+ self.rateLimitResetAt = ms(response["error"].split(" at ")[1].split(".")[0])
297
+ timeToWait = time_to_wait(self.rateLimitResetAt)
298
+ logger.warning(
299
+ "banned",
300
+ info={
301
+ "wait_time_seconds": timeToWait + 1,
302
+ "until": (dt.datetime.now(tz=dt.timezone.utc) + dt.timedelta(seconds=timeToWait + 1)).isoformat(),
303
+ },
304
+ )
305
+ logger.info("napping-until-ban-lifted")
306
+ time.sleep(timeToWait + 1) # plus one second to ENSURE we're able to run again.
307
+ if "bitvavo-ratelimit-remaining" in response:
308
+ self.rateLimitRemaining = int(response["bitvavo-ratelimit-remaining"])
309
+ if "bitvavo-ratelimit-resetat" in response:
310
+ self.rateLimitResetAt = int(response["bitvavo-ratelimit-resetat"])
289
311
 
290
312
  def publicRequest(
291
313
  self,
292
314
  url: str,
293
315
  rateLimitingWeight: int = 1,
294
- ) -> Union[List[anydict], List[List[str]], intdict, strdict, anydict, errordict]:
316
+ ) -> list[anydict] | list[list[str]] | intdict | strdict | anydict | errordict:
295
317
  """Execute a request to the public part of the API; no API key and/or SECRET necessary.
296
318
  Will return the reponse as one of three types.
297
319
 
@@ -305,9 +327,9 @@ class Bitvavo:
305
327
  Returns:
306
328
  ```python
307
329
  # either of one:
308
- Dict[str, Any]
309
- List[Dict[str, Any]]
310
- List[List[str]]
330
+ dict[str, Any]
331
+ list[dict[str, Any]]
332
+ list[list[str]]
311
333
  ```
312
334
  """
313
335
  if (self.rateLimitRemaining - rateLimitingWeight) <= BITVAVO_API_UPGRADED.RATE_LIMITING_BUFFER:
@@ -323,12 +345,12 @@ class Bitvavo:
323
345
  )
324
346
  if self.APIKEY != "":
325
347
  now = time_ms() + BITVAVO_API_UPGRADED.LAG
326
- sig = createSignature(now, "GET", url.replace(self.base, ""), {}, self.APISECRET)
348
+ sig = createSignature(now, "GET", url.replace(self.base, ""), None, self.APISECRET)
327
349
  headers = {
328
- "Bitvavo-Access-Key": self.APIKEY,
329
- "Bitvavo-Access-Signature": sig,
330
- "Bitvavo-Access-Timestamp": str(now),
331
- "Bitvavo-Access-Window": str(self.ACCESSWINDOW),
350
+ "bitvavo-access-key": self.APIKEY,
351
+ "bitvavo-access-signature": sig,
352
+ "bitvavo-access-timestamp": str(now),
353
+ "bitvavo-access-window": str(self.ACCESSWINDOW),
332
354
  }
333
355
  r = get(url, headers=headers, timeout=(self.ACCESSWINDOW / 1000))
334
356
  else:
@@ -337,16 +359,16 @@ class Bitvavo:
337
359
  self.updateRateLimit(r.json())
338
360
  else:
339
361
  self.updateRateLimit(dict(r.headers))
340
- return r.json() # type:ignore
362
+ return r.json() # type:ignore[no-any-return]
341
363
 
342
364
  def privateRequest(
343
365
  self,
344
366
  endpoint: str,
345
367
  postfix: str,
346
- body: anydict,
368
+ body: anydict | None = None,
347
369
  method: str = "GET",
348
370
  rateLimitingWeight: int = 1,
349
- ) -> Union[List[anydict], List[List[str]], intdict, strdict, anydict, Any, errordict]:
371
+ ) -> list[anydict] | list[list[str]] | intdict | strdict | anydict | Any | errordict:
350
372
  """Execute a request to the private part of the API. API key and SECRET are required.
351
373
  Will return the reponse as one of three types.
352
374
 
@@ -364,22 +386,22 @@ class Bitvavo:
364
386
  Returns:
365
387
  ```python
366
388
  # either of one:
367
- Dict[str, Any]
368
- List[Dict[str, Any]]
369
- List[List[str]]
389
+ dict[str, Any]
390
+ list[dict[str, Any]]
391
+ list[list[str]]
370
392
  ```
371
393
  """
372
394
  if (self.rateLimitRemaining - rateLimitingWeight) <= BITVAVO_API_UPGRADED.RATE_LIMITING_BUFFER:
373
395
  self.sleep_until_can_continue()
374
- # if this method breaks: add `= {}` after `body:Dict``
396
+ # if this method breaks: add `= {}` after `body: dict`
375
397
  now = time_ms() + BITVAVO_API_UPGRADED.LAG
376
398
  sig = createSignature(now, method, (endpoint + postfix), body, self.APISECRET)
377
399
  url = self.base + endpoint + postfix
378
400
  headers = {
379
- "Bitvavo-Access-Key": self.APIKEY,
380
- "Bitvavo-Access-Signature": sig,
381
- "Bitvavo-Access-Timestamp": str(now),
382
- "Bitvavo-Access-Window": str(self.ACCESSWINDOW),
401
+ "bitvavo-access-key": self.APIKEY,
402
+ "bitvavo-access-signature": sig,
403
+ "bitvavo-access-timestamp": str(now),
404
+ "bitvavo-access-window": str(self.ACCESSWINDOW),
383
405
  }
384
406
  if self.debugging:
385
407
  logger.debug(
@@ -405,12 +427,15 @@ class Bitvavo:
405
427
  self.updateRateLimit(dict(r.headers))
406
428
  return r.json()
407
429
 
408
- def sleep_until_can_continue(self):
430
+ def sleep_until_can_continue(self) -> None:
409
431
  napTime = time_to_wait(self.rateLimitResetAt)
410
432
  logger.warning("rate-limit-reached", rateLimitRemaining=self.rateLimitRemaining)
411
- logger.info("napping-until-reset", napTime=napTime,
412
- currentTime=dt.datetime.now().isoformat(),
413
- targetDatetime=dt.datetime.fromtimestamp(self.rateLimitResetAt / 1000.0).isoformat())
433
+ logger.info(
434
+ "napping-until-reset",
435
+ napTime=napTime,
436
+ currentTime=dt.datetime.now(tz=dt.timezone.utc).isoformat(),
437
+ targetDatetime=dt.datetime.fromtimestamp(self.rateLimitResetAt / 1000.0, tz=dt.timezone.utc).isoformat(),
438
+ )
414
439
  time.sleep(napTime + 1) # +1 to add a tiny bit of buffer time
415
440
 
416
441
  def time(self) -> intdict:
@@ -432,9 +457,9 @@ class Bitvavo:
432
457
  {"time": 1539180275424 }
433
458
  ```
434
459
  """
435
- return self.publicRequest(f"{self.base}/time")
460
+ return self.publicRequest(f"{self.base}/time") # type: ignore[return-value]
436
461
 
437
- def markets(self, options: strdict) -> Union[List[anydict], anydict, errordict]:
462
+ def markets(self, options: strdict | None = None) -> list[anydict] | anydict | errordict:
438
463
  """Get all available markets with some meta-information, unless options is given a `market` key.
439
464
  Then you will get a single market, instead of a list of markets.
440
465
 
@@ -484,9 +509,9 @@ class Bitvavo:
484
509
  ```
485
510
  """
486
511
  postfix = createPostfix(options)
487
- return self.publicRequest(f"{self.base}/markets{postfix}")
512
+ return self.publicRequest(f"{self.base}/markets{postfix}") # type: ignore[return-value]
488
513
 
489
- def assets(self, options: strdict) -> Union[List[anydict], anydict]:
514
+ def assets(self, options: strdict | None = None) -> list[anydict] | anydict:
490
515
  """Get all available assets, unless `options` is given a `symbol` key.
491
516
  Then you will get a single asset, instead of a list of assets.
492
517
 
@@ -533,9 +558,9 @@ class Bitvavo:
533
558
  ```
534
559
  """
535
560
  postfix = createPostfix(options)
536
- return self.publicRequest(f"{self.base}/assets{postfix}")
561
+ return self.publicRequest(f"{self.base}/assets{postfix}") # type: ignore[return-value]
537
562
 
538
- def book(self, market: str, options: intdict) -> Union[Dict[str, Union[str, int, List[str]]], errordict]:
563
+ def book(self, market: str, options: intdict | None = None) -> dict[str, str | int | list[str]] | errordict:
539
564
  """Get a book (with two lists: asks and bids, as they're called)
540
565
 
541
566
  ---
@@ -577,9 +602,9 @@ class Bitvavo:
577
602
  ```
578
603
  """
579
604
  postfix = createPostfix(options)
580
- return self.publicRequest(f"{self.base}/{market}/book{postfix}")
605
+ return self.publicRequest(f"{self.base}/{market}/book{postfix}") # type: ignore[return-value]
581
606
 
582
- def publicTrades(self, market: str, options: Dict[str, Union[str, int]]) -> Union[List[anydict], errordict]:
607
+ def publicTrades(self, market: str, options: strintdict | None = None) -> list[anydict] | errordict:
583
608
  """Publically available trades
584
609
 
585
610
  ---
@@ -599,7 +624,8 @@ class Bitvavo:
599
624
  options={
600
625
  "limit": [ 1 .. 1000 ], default 500
601
626
  "start": int timestamp in ms >= 0
602
- "end": int timestamp in ms <= 8_640_000_000_000_000 # (that's somewhere in the year 2243, or near the number 2^52)
627
+ # (that's somewhere in the year 2243, or near the number 2^52)
628
+ "end": int timestamp in ms <= 8_640_000_000_000_000
603
629
  "tradeIdFrom": "" # if you get a list and want everything AFTER a certain id, put that id here
604
630
  "tradeIdTo": "" # if you get a list and want everything BEFORE a certain id, put that id here
605
631
  }
@@ -626,14 +652,17 @@ class Bitvavo:
626
652
  ```
627
653
  """
628
654
  postfix = createPostfix(options)
629
- return self.publicRequest(f"{self.base}/{market}/trades{postfix}", 5)
655
+ return self.publicRequest(f"{self.base}/{market}/trades{postfix}", 5) # type: ignore[return-value]
630
656
 
631
- def candles(
657
+ def candles( # noqa: PLR0913
632
658
  self,
633
659
  market: str,
634
660
  interval: str,
635
- options: Dict[str, Union[str, int]],
636
- ) -> Union[List[List[str]], errordict]:
661
+ options: strintdict | None = None,
662
+ limit: int | None = None,
663
+ start: dt.datetime | None = None,
664
+ end: dt.datetime | None = None,
665
+ ) -> list[list[str]] | errordict:
637
666
  """Get up to 1440 candles for a market, with a specific interval (candle size)
638
667
 
639
668
  Extra reading material: https://en.wikipedia.org/wiki/Candlestick_chart
@@ -679,11 +708,18 @@ class Bitvavo:
679
708
  ]
680
709
  ```
681
710
  """
711
+ options = _default(options, {})
682
712
  options["interval"] = interval
713
+ if limit is not None:
714
+ options["limit"] = limit
715
+ if start is not None:
716
+ options["start"] = _epoch_millis(start)
717
+ if end is not None:
718
+ options["end"] = _epoch_millis(end)
683
719
  postfix = createPostfix(options)
684
- return self.publicRequest(f"{self.base}/{market}/candles{postfix}")
720
+ return self.publicRequest(f"{self.base}/{market}/candles{postfix}") # type: ignore[return-value]
685
721
 
686
- def tickerPrice(self, options: strdict) -> Union[List[strdict], strdict]:
722
+ def tickerPrice(self, options: strdict | None = None) -> list[strdict] | strdict:
687
723
  """Get the current price for each market
688
724
 
689
725
  ---
@@ -729,9 +765,9 @@ class Bitvavo:
729
765
  ```
730
766
  """
731
767
  postfix = createPostfix(options)
732
- return self.publicRequest(f"{self.base}/ticker/price{postfix}")
768
+ return self.publicRequest(f"{self.base}/ticker/price{postfix}") # type: ignore[return-value]
733
769
 
734
- def tickerBook(self, options: strdict) -> Union[List[strdict], strdict]:
770
+ def tickerBook(self, options: strdict | None = None) -> list[strdict] | strdict:
735
771
  """Get current bid/ask, bidsize/asksize per market
736
772
 
737
773
  ---
@@ -770,9 +806,9 @@ class Bitvavo:
770
806
  ```
771
807
  """
772
808
  postfix = createPostfix(options)
773
- return self.publicRequest(f"{self.base}/ticker/book{postfix}")
809
+ return self.publicRequest(f"{self.base}/ticker/book{postfix}") # type: ignore[return-value]
774
810
 
775
- def ticker24h(self, options: strdict) -> Union[List[anydict], anydict, errordict]:
811
+ def ticker24h(self, options: strdict | None = None) -> list[anydict] | anydict | errordict:
776
812
  """Get current bid/ask, bidsize/asksize per market
777
813
 
778
814
  ---
@@ -834,11 +870,12 @@ class Bitvavo:
834
870
  ]
835
871
  ```
836
872
  """
873
+ options = _default(options, {})
837
874
  rateLimitingWeight = 25
838
875
  if "market" in options:
839
876
  rateLimitingWeight = 1
840
877
  postfix = createPostfix(options)
841
- return self.publicRequest(f"{self.base}/ticker/24h{postfix}", rateLimitingWeight)
878
+ return self.publicRequest(f"{self.base}/ticker/24h{postfix}", rateLimitingWeight) # type: ignore[return-value]
842
879
 
843
880
  def placeOrder(self, market: str, side: str, orderType: str, body: anydict) -> anydict:
844
881
  """Place a new order on the exchange
@@ -959,15 +996,14 @@ class Bitvavo:
959
996
  "disableMarketProtection": true
960
997
  }
961
998
  ```
962
- """
999
+ """ # noqa: E501
963
1000
  body["market"] = market
964
1001
  body["side"] = side
965
1002
  body["orderType"] = orderType
966
- return self.privateRequest("/order", "", body, "POST")
1003
+ return self.privateRequest("/order", "", body, "POST") # type: ignore[return-value]
967
1004
 
968
1005
  def updateOrder(self, market: str, orderId: str, body: anydict) -> anydict:
969
- """Update an existing order for a specific market. Make sure that at least one of the optional parameters is set,
970
- otherwise nothing will be updated.
1006
+ """Update an existing order for a specific market. Make sure that at least one of the optional parameters is set, otherwise nothing will be updated.
971
1007
 
972
1008
  ---
973
1009
  Args:
@@ -1044,10 +1080,10 @@ class Bitvavo:
1044
1080
  "disableMarketProtection": true
1045
1081
  }
1046
1082
  ```
1047
- """
1083
+ """ # noqa: E501
1048
1084
  body["market"] = market
1049
1085
  body["orderId"] = orderId
1050
- return self.privateRequest("/order", "", body, "PUT")
1086
+ return self.privateRequest("/order", "", body, "PUT") # type: ignore[return-value]
1051
1087
 
1052
1088
  def cancelOrder(self, market: str, orderId: str) -> strdict:
1053
1089
  """Cancel an existing order for a specific market
@@ -1072,9 +1108,9 @@ class Bitvavo:
1072
1108
  ```
1073
1109
  """
1074
1110
  postfix = createPostfix({"market": market, "orderId": orderId})
1075
- return self.privateRequest("/order", postfix, {}, "DELETE")
1111
+ return self.privateRequest("/order", postfix, {}, "DELETE") # type: ignore[return-value]
1076
1112
 
1077
- def getOrder(self, market: str, orderId: str) -> Union[List[anydict], errordict]:
1113
+ def getOrder(self, market: str, orderId: str) -> list[anydict] | errordict:
1078
1114
  """Get an existing order for a specific market
1079
1115
 
1080
1116
  ---
@@ -1137,9 +1173,9 @@ class Bitvavo:
1137
1173
  ```
1138
1174
  """
1139
1175
  postfix = createPostfix({"market": market, "orderId": orderId})
1140
- return self.privateRequest("/order", postfix, {}, "GET")
1176
+ return self.privateRequest("/order", postfix, {}, "GET") # type: ignore[return-value]
1141
1177
 
1142
- def getOrders(self, market: str, options: anydict) -> Union[List[anydict], errordict]:
1178
+ def getOrders(self, market: str, options: anydict | None = None) -> list[anydict] | errordict:
1143
1179
  """Get multiple existing orders for a specific market
1144
1180
 
1145
1181
  ---
@@ -1209,12 +1245,13 @@ class Bitvavo:
1209
1245
  }
1210
1246
  ]
1211
1247
  ```
1212
- """
1248
+ """ # noqa: E501
1249
+ options = _default(options, {})
1213
1250
  options["market"] = market
1214
1251
  postfix = createPostfix(options)
1215
- return self.privateRequest("/orders", postfix, {}, "GET", 5)
1252
+ return self.privateRequest("/orders", postfix, {}, "GET", 5) # type: ignore[return-value]
1216
1253
 
1217
- def cancelOrders(self, options: anydict) -> Union[List[strdict], errordict]:
1254
+ def cancelOrders(self, options: anydict | None = None) -> list[strdict] | errordict:
1218
1255
  """Cancel all existing orders for a specific market (or account)
1219
1256
 
1220
1257
  ---
@@ -1240,9 +1277,9 @@ class Bitvavo:
1240
1277
  ```
1241
1278
  """
1242
1279
  postfix = createPostfix(options)
1243
- return self.privateRequest("/orders", postfix, {}, "DELETE")
1280
+ return self.privateRequest("/orders", postfix, {}, "DELETE") # type: ignore[return-value]
1244
1281
 
1245
- def ordersOpen(self, options: anydict) -> Union[List[anydict], errordict]:
1282
+ def ordersOpen(self, options: anydict | None = None) -> list[anydict] | errordict:
1246
1283
  """Get all open orders, either for all markets, or a single market
1247
1284
 
1248
1285
  ---
@@ -1307,13 +1344,14 @@ class Bitvavo:
1307
1344
  ]
1308
1345
  ```
1309
1346
  """
1347
+ options = _default(options, {})
1310
1348
  rateLimitingWeight = 25
1311
1349
  if "market" in options:
1312
1350
  rateLimitingWeight = 1
1313
1351
  postfix = createPostfix(options)
1314
- return self.privateRequest("/ordersOpen", postfix, {}, "GET", rateLimitingWeight)
1352
+ return self.privateRequest("/ordersOpen", postfix, {}, "GET", rateLimitingWeight) # type: ignore[return-value]
1315
1353
 
1316
- def trades(self, market: str, options: anydict) -> Union[List[anydict], errordict]:
1354
+ def trades(self, market: str, options: anydict | None = None) -> list[anydict] | errordict:
1317
1355
  """Get all historic trades from this account
1318
1356
 
1319
1357
  ---
@@ -1354,12 +1392,13 @@ class Bitvavo:
1354
1392
  }
1355
1393
  ]
1356
1394
  ```
1357
- """
1395
+ """ # noqa: E501
1396
+ options = _default(options, {})
1358
1397
  options["market"] = market
1359
1398
  postfix = createPostfix(options)
1360
- return self.privateRequest("/trades", postfix, {}, "GET", 5)
1399
+ return self.privateRequest("/trades", postfix, {}, "GET", 5) # type: ignore[return-value]
1361
1400
 
1362
- def account(self) -> Dict[str, strdict]:
1401
+ def account(self) -> dict[str, strdict]:
1363
1402
  """Get all fees for this account
1364
1403
 
1365
1404
  ---
@@ -1380,9 +1419,18 @@ class Bitvavo:
1380
1419
  }
1381
1420
  ```
1382
1421
  """
1383
- return self.privateRequest("/account", "", {}, "GET")
1422
+ return self.privateRequest("/account", "", {}, "GET") # type: ignore[return-value]
1423
+
1424
+ def fees(self, market: str | None = None, quote: str | None = None) -> list[strdict] | errordict:
1425
+ options = {}
1426
+ if market is not None:
1427
+ options["market"] = market
1428
+ if quote is not None:
1429
+ options["quote"] = quote
1430
+ postfix = createPostfix(options)
1431
+ return self.privateRequest("/account/fees", postfix, {}, "GET") # type: ignore[return-value]
1384
1432
 
1385
- def balance(self, options: strdict) -> Union[List[strdict], errordict]:
1433
+ def balance(self, options: strdict | None = None) -> list[strdict] | errordict:
1386
1434
  """Get the balance for this account
1387
1435
 
1388
1436
  ---
@@ -1411,7 +1459,7 @@ class Bitvavo:
1411
1459
  ```
1412
1460
  """
1413
1461
  postfix = createPostfix(options)
1414
- return self.privateRequest("/balance", postfix, {}, "GET", 5)
1462
+ return self.privateRequest("/balance", postfix, {}, "GET", 5) # type: ignore[return-value]
1415
1463
 
1416
1464
  def depositAssets(self, symbol: str) -> strdict:
1417
1465
  """Get the deposit address (with paymentId for some assets) or bank account information to increase your balance
@@ -1446,9 +1494,9 @@ class Bitvavo:
1446
1494
  ```
1447
1495
  """
1448
1496
  postfix = createPostfix({"symbol": symbol})
1449
- return self.privateRequest("/deposit", postfix, {}, "GET")
1497
+ return self.privateRequest("/deposit", postfix, {}, "GET") # type: ignore[return-value]
1450
1498
 
1451
- def depositHistory(self, options: anydict) -> Union[List[anydict], errordict]:
1499
+ def depositHistory(self, options: anydict | None = None) -> list[anydict] | errordict:
1452
1500
  """Get the deposit history of the account
1453
1501
 
1454
1502
  Even when you want something from a single `symbol`, you'll still receive a list with multiple deposits.
@@ -1495,9 +1543,9 @@ class Bitvavo:
1495
1543
  }
1496
1544
  ]
1497
1545
  ```
1498
- """
1546
+ """ # noqa: E501
1499
1547
  postfix = createPostfix(options)
1500
- return self.privateRequest("/depositHistory", postfix, {}, "GET", 5)
1548
+ return self.privateRequest("/depositHistory", postfix, {}, "GET", 5) # type: ignore[return-value]
1501
1549
 
1502
1550
  def withdrawAssets(self, symbol: str, amount: str, address: str, body: anydict) -> anydict:
1503
1551
  """Withdraw a coin/token to an external crypto address or bank account.
@@ -1530,13 +1578,13 @@ class Bitvavo:
1530
1578
  "amount": "1.5"
1531
1579
  }
1532
1580
  ```
1533
- """
1581
+ """ # noqa: E501
1534
1582
  body["symbol"] = symbol
1535
1583
  body["amount"] = amount
1536
1584
  body["address"] = address
1537
- return self.privateRequest("/withdrawal", "", body, "POST")
1585
+ return self.privateRequest("/withdrawal", "", body, "POST") # type: ignore[return-value]
1538
1586
 
1539
- def withdrawalHistory(self, options: anydict) -> Union[List[anydict], anydict]:
1587
+ def withdrawalHistory(self, options: anydict | None = None) -> list[anydict] | errordict:
1540
1588
  """Get the withdrawal history
1541
1589
 
1542
1590
  ---
@@ -1572,11 +1620,11 @@ class Bitvavo:
1572
1620
  }
1573
1621
  }
1574
1622
  ```
1575
- """
1623
+ """ # noqa: E501
1576
1624
  postfix = createPostfix(options)
1577
- return self.privateRequest("/withdrawalHistory", postfix, {}, "GET", 5)
1625
+ return self.privateRequest("/withdrawalHistory", postfix, {}, "GET", 5) # type: ignore[return-value]
1578
1626
 
1579
- def newWebsocket(self) -> "Bitvavo.WebSocketAppFacade":
1627
+ def newWebsocket(self) -> Bitvavo.WebSocketAppFacade:
1580
1628
  return Bitvavo.WebSocketAppFacade(self.APIKEY, self.APISECRET, self.ACCESSWINDOW, self.wsUrl, self)
1581
1629
 
1582
1630
  class WebSocketAppFacade:
@@ -1586,7 +1634,14 @@ class Bitvavo:
1586
1634
  It's a facade for the WebSocketApp class, with its own implementation for the on_* methods
1587
1635
  """
1588
1636
 
1589
- def __init__(self, APIKEY: str, APISECRET: str, ACCESSWINDOW: int, WSURL: str, bitvavo: "Bitvavo"):
1637
+ def __init__(
1638
+ self,
1639
+ APIKEY: str,
1640
+ APISECRET: str,
1641
+ ACCESSWINDOW: int,
1642
+ WSURL: str,
1643
+ bitvavo: Bitvavo,
1644
+ ) -> None:
1590
1645
  self.APIKEY = APIKEY
1591
1646
  self.APISECRET = APISECRET
1592
1647
  self.ACCESSWINDOW = ACCESSWINDOW
@@ -1623,35 +1678,38 @@ class Bitvavo:
1623
1678
  self.keepAlive = False
1624
1679
  self.receiveThread.join()
1625
1680
 
1626
- def waitForSocket(self, ws: WebSocketApp, message: str, private: bool) -> None:
1681
+ def waitForSocket(self, ws: WebSocketApp, message: str, private: bool) -> None: # noqa: ARG002, FBT001
1627
1682
  while True:
1628
1683
  if (not private and self.open) or (private and self.authenticated and self.open):
1629
1684
  return
1630
1685
  time.sleep(0.1)
1631
1686
 
1632
- def doSend(self, ws: WebSocketApp, message: str, private: bool = False) -> None:
1633
- # TODO(NostraDavid) add nap-time to the websocket, or do it here; I don't know yet.
1687
+ def doSend(self, ws: WebSocketApp, message: str, private: bool = False) -> None: # noqa: FBT001, FBT002
1688
+ # TODO(NostraDavid): add nap-time to the websocket, or do it here; I don't know yet.
1634
1689
  if private and self.APIKEY == "":
1635
- logger.error("no-apikey", tip="set the API key to be able to make private API calls")
1690
+ logger.error(
1691
+ "no-apikey",
1692
+ tip="set the API key to be able to make private API calls",
1693
+ )
1636
1694
  return
1637
1695
  self.waitForSocket(ws, message, private)
1638
1696
  ws.send(message)
1639
1697
  if self.bitvavo.debugging:
1640
1698
  logger.debug("message-sent", message=message)
1641
1699
 
1642
- def on_message(self, ws, msg: str) -> None: # noqa: C901 (too-complex)
1700
+ def on_message(self, ws: Any, msg: str) -> None: # noqa: C901, PLR0912, PLR0915, ARG002 (too-complex)
1643
1701
  if self.bitvavo.debugging:
1644
1702
  logger.debug("message-received", message=msg)
1645
1703
  msg_dict: anydict = json.loads(msg)
1646
1704
  callbacks = self.callbacks
1647
1705
 
1648
1706
  if "error" in msg_dict:
1649
- if msg_dict["errorCode"] == 105:
1707
+ if msg_dict["errorCode"] == 105: # noqa: PLR2004
1650
1708
  self.bitvavo.updateRateLimit(msg_dict)
1651
1709
  if "error" in callbacks:
1652
1710
  callbacks["error"](msg_dict)
1653
1711
  else:
1654
- logger.error(msg_dict)
1712
+ logger.error("error", msg_dict=msg_dict)
1655
1713
 
1656
1714
  if "action" in msg_dict:
1657
1715
  if msg_dict["action"] == "getTime":
@@ -1686,6 +1744,8 @@ class Bitvavo:
1686
1744
  callbacks["trades"](msg_dict["response"])
1687
1745
  elif msg_dict["action"] == "privateGetAccount":
1688
1746
  callbacks["account"](msg_dict["response"])
1747
+ elif msg_dict["action"] == "privateGetFees":
1748
+ callbacks["fees"](msg_dict["response"])
1689
1749
  elif msg_dict["action"] == "privateGetBalance":
1690
1750
  callbacks["balance"](msg_dict["response"])
1691
1751
  elif msg_dict["action"] == "privateDepositAssets":
@@ -1702,17 +1762,13 @@ class Bitvavo:
1702
1762
  market = msg_dict["response"]["market"]
1703
1763
  if "book" in callbacks:
1704
1764
  callbacks["book"](msg_dict["response"])
1705
- if self.keepBookCopy:
1706
- if market in callbacks["subscriptionBook"]:
1707
- callbacks["subscriptionBook"][market](self, msg_dict)
1765
+ if self.keepBookCopy and market in callbacks["subscriptionBook"]:
1766
+ callbacks["subscriptionBook"][market](self, msg_dict)
1708
1767
 
1709
1768
  elif "event" in msg_dict:
1710
1769
  if msg_dict["event"] == "authenticate":
1711
1770
  self.authenticated = True
1712
- elif msg_dict["event"] == "fill":
1713
- market = msg_dict["market"]
1714
- callbacks["subscriptionAccount"][market](msg_dict)
1715
- elif msg_dict["event"] == "order":
1771
+ elif msg_dict["event"] == "fill" or msg_dict["event"] == "order":
1716
1772
  market = msg_dict["market"]
1717
1773
  callbacks["subscriptionAccount"][market](msg_dict)
1718
1774
  elif msg_dict["event"] == "ticker":
@@ -1727,29 +1783,27 @@ class Bitvavo:
1727
1783
  callbacks["subscriptionCandles"][market][interval](msg_dict)
1728
1784
  elif msg_dict["event"] == "book":
1729
1785
  market = msg_dict["market"]
1730
- if "subscriptionBookUpdate" in callbacks:
1731
- if market in callbacks["subscriptionBookUpdate"]:
1732
- callbacks["subscriptionBookUpdate"][market](msg_dict)
1733
- if self.keepBookCopy:
1734
- if market in callbacks["subscriptionBook"]:
1735
- callbacks["subscriptionBook"][market](self, msg_dict)
1786
+ if "subscriptionBookUpdate" in callbacks and market in callbacks["subscriptionBookUpdate"]:
1787
+ callbacks["subscriptionBookUpdate"][market](msg_dict)
1788
+ if self.keepBookCopy and market in callbacks["subscriptionBook"]:
1789
+ callbacks["subscriptionBook"][market](self, msg_dict)
1736
1790
  elif msg_dict["event"] == "trade":
1737
1791
  market = msg_dict["market"]
1738
1792
  if "subscriptionTrades" in callbacks:
1739
1793
  callbacks["subscriptionTrades"][market](msg_dict)
1740
1794
 
1741
- def on_error(self, ws, error: Any) -> None:
1795
+ def on_error(self, ws: Any, error: Any) -> None: # noqa: ARG002
1742
1796
  if "error" in self.callbacks:
1743
1797
  self.callbacks["error"](error)
1744
1798
  else:
1745
1799
  logger.error(error)
1746
1800
 
1747
- def on_close(self, ws) -> None:
1801
+ def on_close(self, ws: Any) -> None: # noqa: ARG002
1748
1802
  self.receiveThread.stop()
1749
1803
  if self.bitvavo.debugging:
1750
1804
  logger.debug("websocket-closed")
1751
1805
 
1752
- def checkReconnect(self) -> None: # noqa: C901 (too-complex)
1806
+ def checkReconnect(self) -> None: # noqa: C901, PLR0912 (too-complex)
1753
1807
  if "subscriptionTicker" in self.callbacks:
1754
1808
  for market in self.callbacks["subscriptionTicker"]:
1755
1809
  self.subscriptionTicker(market, self.callbacks["subscriptionTicker"][market])
@@ -1777,7 +1831,7 @@ class Bitvavo:
1777
1831
  for market in self.callbacks["subscriptionBookUser"]:
1778
1832
  self.subscriptionBook(market, self.callbacks["subscriptionBookUser"][market])
1779
1833
 
1780
- def on_open(self, ws) -> None:
1834
+ def on_open(self, ws: Any) -> None: # noqa: ARG002
1781
1835
  now = time_ms() + BITVAVO_API_UPGRADED.LAG
1782
1836
  self.open = True
1783
1837
  self.reconnectTimer = 0.5
@@ -2028,13 +2082,19 @@ class Bitvavo:
2028
2082
  }
2029
2083
  ]
2030
2084
  ```
2031
- """
2085
+ """ # noqa: E501
2032
2086
  self.callbacks["publicTrades"] = callback
2033
2087
  options["market"] = market
2034
2088
  options["action"] = "getTrades"
2035
2089
  self.doSend(self.ws, json.dumps(options))
2036
2090
 
2037
- def candles(self, market: str, interval: str, options: anydict, callback: Callable[[Any], None]) -> None:
2091
+ def candles(
2092
+ self,
2093
+ market: str,
2094
+ interval: str,
2095
+ options: anydict,
2096
+ callback: Callable[[Any], None],
2097
+ ) -> None:
2038
2098
  """Get up to 1440 candles for a market, with a specific interval (candle size)
2039
2099
 
2040
2100
  Extra reading material: https://en.wikipedia.org/wiki/Candlestick_chart
@@ -2175,7 +2235,7 @@ class Bitvavo:
2175
2235
  # and another 215 markets below this point
2176
2236
  ]
2177
2237
  ```
2178
- """
2238
+ """ # noqa: E501
2179
2239
  self.callbacks["tickerBook"] = callback
2180
2240
  options["action"] = "getTickerBook"
2181
2241
  self.doSend(self.ws, json.dumps(options))
@@ -2374,7 +2434,7 @@ class Bitvavo:
2374
2434
  "disableMarketProtection": true
2375
2435
  }
2376
2436
  ```
2377
- """
2437
+ """ # noqa: E501
2378
2438
  self.callbacks["placeOrder"] = callback
2379
2439
  body["market"] = market
2380
2440
  body["side"] = side
@@ -2382,9 +2442,16 @@ class Bitvavo:
2382
2442
  body["action"] = "privateCreateOrder"
2383
2443
  self.doSend(self.ws, json.dumps(body), True)
2384
2444
 
2385
- def updateOrder(self, market: str, orderId: str, body: anydict, callback: Callable[[Any], None]) -> None:
2386
- """Update an existing order for a specific market. Make sure that at least one of the optional parameters is set,
2387
- otherwise nothing will be updated.
2445
+ def updateOrder(
2446
+ self,
2447
+ market: str,
2448
+ orderId: str,
2449
+ body: anydict,
2450
+ callback: Callable[[Any], None],
2451
+ ) -> None:
2452
+ """
2453
+ Update an existing order for a specific market. Make sure that at least one of the optional parameters
2454
+ is set, otherwise nothing will be updated.
2388
2455
 
2389
2456
  ---
2390
2457
  Args:
@@ -2462,7 +2529,7 @@ class Bitvavo:
2462
2529
  "disableMarketProtection": true
2463
2530
  }
2464
2531
  ```
2465
- """
2532
+ """ # noqa: E501
2466
2533
  self.callbacks["updateOrder"] = callback
2467
2534
  body["market"] = market
2468
2535
  body["orderId"] = orderId
@@ -2581,9 +2648,12 @@ class Bitvavo:
2581
2648
  options={
2582
2649
  "limit": [ 1 .. 1000 ], default 500
2583
2650
  "start": int timestamp in ms >= 0
2584
- "end": int timestamp in ms <= 8_640_000_000_000_000 # (that's somewhere in the year 2243, or near the number 2^52)
2585
- "tradeIdFrom": "" # if you get a list and want everything AFTER a certain id, put that id here
2586
- "tradeIdTo": "" # if you get a list and want everything BEFORE a certain id, put that id here
2651
+ # (that's somewhere in the year 2243, or near the number 2^52)
2652
+ "end": int timestamp in ms <= 8_640_000_000_000_000
2653
+ # if you get a list and want everything AFTER a certain id, put that id here
2654
+ "tradeIdFrom": ""
2655
+ # if you get a list and want everything BEFORE a certain id, put that id here
2656
+ "tradeIdTo": ""
2587
2657
  }
2588
2658
  callback=callback_example
2589
2659
  ```
@@ -2758,7 +2828,8 @@ class Bitvavo:
2758
2828
  options={
2759
2829
  "limit": [ 1 .. 1000 ], default 500
2760
2830
  "start": int timestamp in ms >= 0
2761
- "end": int timestamp in ms <= 8_640_000_000_000_000 # (that's somewhere in the year 2243, or near the number 2^52)
2831
+ # (that's somewhere in the year 2243, or near the number 2^52)
2832
+ "end": int timestamp in ms <= 8_640_000_000_000_000
2762
2833
  "tradeIdFrom": "" # if you get a list and want everything AFTER a certain id, put that id here
2763
2834
  "tradeIdTo": "" # if you get a list and want everything BEFORE a certain id, put that id here
2764
2835
  }
@@ -2860,7 +2931,9 @@ class Bitvavo:
2860
2931
  self.doSend(self.ws, json.dumps(options), True)
2861
2932
 
2862
2933
  def depositAssets(self, symbol: str, callback: Callable[[Any], None]) -> None:
2863
- """Get the deposit address (with paymentId for some assets) or bank account information to increase your balance
2934
+ """
2935
+ Get the deposit address (with paymentId for some assets) or bank account information to increase your
2936
+ balance.
2864
2937
 
2865
2938
  ---
2866
2939
  Args:
@@ -2911,7 +2984,8 @@ class Bitvavo:
2911
2984
  "symbol":"EUR"
2912
2985
  "limit": [ 1 .. 1000 ], default 500
2913
2986
  "start": int timestamp in ms >= 0
2914
- "end": int timestamp in ms <= 8_640_000_000_000_000 # (that's somewhere in the year 2243, or near the number 2^52)
2987
+ # (that's somewhere in the year 2243, or near the number 2^52)
2988
+ "end": int timestamp in ms <= 8_640_000_000_000_000
2915
2989
  }
2916
2990
  callback=callback_example
2917
2991
  ```
@@ -2969,9 +3043,15 @@ class Bitvavo:
2969
3043
  amount=10
2970
3044
  address="BitcoinAddress", # Wallet address or IBAN
2971
3045
  options={
2972
- "paymentId": "10002653", # For digital assets only. Should be set when withdrawing straight to another exchange or merchants that require payment id's.
2973
- "internal": false, # For digital assets only. Should be set to true if the withdrawal must be sent to another Bitvavo user internally
2974
- "addWithdrawalFee": false # If set to true, the fee will be added on top of the requested amount, otherwise the fee is part of the requested amount and subtracted from the withdrawal.
3046
+ # For digital assets only. Should be set when withdrawing straight to another exchange or merchants that
3047
+ # require payment id's.
3048
+ "paymentId": "10002653",
3049
+ # For digital assets only. Should be set to true if the withdrawal must be sent to another Bitvavo user
3050
+ # internally
3051
+ "internal": false,
3052
+ # If set to true, the fee will be added on top of the requested amount, otherwise the fee is part of the
3053
+ # requested amount and subtracted from the withdrawal.
3054
+ "addWithdrawalFee": false
2975
3055
  }
2976
3056
  callback=callback_example
2977
3057
  ```
@@ -3009,7 +3089,8 @@ class Bitvavo:
3009
3089
  "symbol":"SHIB"
3010
3090
  "limit": [ 1 .. 1000 ], default 500
3011
3091
  "start": int timestamp in ms >= 0
3012
- "end": int timestamp in ms <= 8_640_000_000_000_000 # (that's somewhere in the year 2243, or near the number 2^52)
3092
+ # (that's somewhere in the year 2243, or near the number 2^52)
3093
+ "end": int timestamp in ms <= 8_640_000_000_000_000
3013
3094
  }
3014
3095
  callback=callback_example
3015
3096
  ```
@@ -3042,8 +3123,11 @@ class Bitvavo:
3042
3123
  self.doSend(self.ws, json.dumps(options), True)
3043
3124
 
3044
3125
  def subscriptionTicker(self, market: str, callback: Callable[[Any], None]) -> None:
3045
- # TODO(NostraDavid) one possible improvement here is to turn `market` into a list of markets, so we can sub to all of them at once. Same goes for other `subscription*()`
3046
- """Subscribe to the ticker channel, which means `callback` gets passed the new best bid or ask whenever they change (server-side).
3126
+ # TODO(NostraDavid): one possible improvement here is to turn `market` into a list of markets, so we can sub
3127
+ # to all of them at once. Same goes for other `subscription*()`
3128
+ """
3129
+ Subscribe to the ticker channel, which means `callback` gets passed the new best bid or ask whenever they
3130
+ change (server-side).
3047
3131
 
3048
3132
 
3049
3133
  ---
@@ -3091,7 +3175,9 @@ class Bitvavo:
3091
3175
  )
3092
3176
 
3093
3177
  def subscriptionTicker24h(self, market: str, callback: Callable[[Any], None]) -> None:
3094
- """Subscribe to the ticker-24-hour channel, which means `callback` gets passed the new object every second, if values have changed.
3178
+ """
3179
+ Subscribe to the ticker-24-hour channel, which means `callback` gets passed the new object every second, if
3180
+ values have changed.
3095
3181
 
3096
3182
  ---
3097
3183
  Args:
@@ -3146,8 +3232,9 @@ class Bitvavo:
3146
3232
  )
3147
3233
 
3148
3234
  def subscriptionAccount(self, market: str, callback: Callable[[Any], None]) -> None:
3149
- """Subscribes to the account channel, which sends an update whenever an event happens which is related to the account.
3150
- These are 'order' events (create, update, cancel) or 'fill' events (a trade occurred).
3235
+ """
3236
+ Subscribes to the account channel, which sends an update whenever an event happens which is related to
3237
+ the account. These are 'order' events (create, update, cancel) or 'fill' events (a trade occurred).
3151
3238
 
3152
3239
  ---
3153
3240
  Args: