dccd 3.3.0__tar.gz → 3.3.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {dccd-3.3.0 → dccd-3.3.1}/CHANGELOG.md +9 -0
  2. {dccd-3.3.0 → dccd-3.3.1}/PKG-INFO +1 -1
  3. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/kraken.py +10 -4
  4. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_sources.py +4 -0
  5. {dccd-3.3.0 → dccd-3.3.1}/dccd.egg-info/PKG-INFO +1 -1
  6. {dccd-3.3.0 → dccd-3.3.1}/pyproject.toml +1 -1
  7. {dccd-3.3.0 → dccd-3.3.1}/CLAUDE.md +0 -0
  8. {dccd-3.3.0 → dccd-3.3.1}/CONTRIBUTING.md +0 -0
  9. {dccd-3.3.0 → dccd-3.3.1}/LICENSE.txt +0 -0
  10. {dccd-3.3.0 → dccd-3.3.1}/MANIFEST.in +0 -0
  11. {dccd-3.3.0 → dccd-3.3.1}/README.md +0 -0
  12. {dccd-3.3.0 → dccd-3.3.1}/dccd/__init__.py +0 -0
  13. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/__init__.py +0 -0
  14. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/config.py +0 -0
  15. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/events.py +0 -0
  16. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/jobs.py +0 -0
  17. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/monitor.py +0 -0
  18. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/operations.py +0 -0
  19. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/registry.py +0 -0
  20. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/scheduler.py +0 -0
  21. {dccd-3.3.0 → dccd-3.3.1}/dccd/application/service_factory.py +0 -0
  22. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/__init__.py +0 -0
  23. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/capability.py +0 -0
  24. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/dataset.py +0 -0
  25. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/errors.py +0 -0
  26. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/records.py +0 -0
  27. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/symbol.py +0 -0
  28. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/timeutils.py +0 -0
  29. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/transforms.py +0 -0
  30. {dccd-3.3.0 → dccd-3.3.1}/dccd/domain/types.py +0 -0
  31. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/__init__.py +0 -0
  32. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/api/__init__.py +0 -0
  33. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/api/app.py +0 -0
  34. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/cli/__init__.py +0 -0
  35. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/cli/main.py +0 -0
  36. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/__init__.py +0 -0
  37. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/static/favicon.svg +0 -0
  38. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/static/logo.svg +0 -0
  39. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/base.html +0 -0
  40. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/config.html +0 -0
  41. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/dashboard.html +0 -0
  42. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/data.html +0 -0
  43. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/historical.html +0 -0
  44. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/live.html +0 -0
  45. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/login.html +0 -0
  46. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/logs.html +0 -0
  47. {dccd-3.3.0 → dccd-3.3.1}/dccd/interfaces/ui/templates/storage.html +0 -0
  48. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/__init__.py +0 -0
  49. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/base.py +0 -0
  50. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/binance.py +0 -0
  51. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/bitfinex.py +0 -0
  52. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/bitmex.py +0 -0
  53. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/bybit.py +0 -0
  54. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/coinbase.py +0 -0
  55. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/okx.py +0 -0
  56. {dccd-3.3.0 → dccd-3.3.1}/dccd/sources/registry.py +0 -0
  57. {dccd-3.3.0 → dccd-3.3.1}/dccd/storage/__init__.py +0 -0
  58. {dccd-3.3.0 → dccd-3.3.1}/dccd/storage/coverage_sqlite.py +0 -0
  59. {dccd-3.3.0 → dccd-3.3.1}/dccd/storage/parquet.py +0 -0
  60. {dccd-3.3.0 → dccd-3.3.1}/dccd/storage/purge.py +0 -0
  61. {dccd-3.3.0 → dccd-3.3.1}/dccd/storage/remote.py +0 -0
  62. {dccd-3.3.0 → dccd-3.3.1}/dccd/storage/runs_sqlite.py +0 -0
  63. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/__init__.py +0 -0
  64. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/__init__.py +0 -0
  65. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_api.py +0 -0
  66. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_application.py +0 -0
  67. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_backfill_lookback.py +0 -0
  68. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_client.py +0 -0
  69. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_coverage.py +0 -0
  70. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_domain.py +0 -0
  71. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_domain_extended.py +0 -0
  72. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_network.py +0 -0
  73. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_purge.py +0 -0
  74. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_remote_sync.py +0 -0
  75. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_restart.py +0 -0
  76. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_restore.py +0 -0
  77. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_storage.py +0 -0
  78. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_storage_extended.py +0 -0
  79. {dccd-3.3.0 → dccd-3.3.1}/dccd/tests/v3/test_transport.py +0 -0
  80. {dccd-3.3.0 → dccd-3.3.1}/dccd/transport/__init__.py +0 -0
  81. {dccd-3.3.0 → dccd-3.3.1}/dccd/transport/http.py +0 -0
  82. {dccd-3.3.0 → dccd-3.3.1}/dccd/transport/paginate.py +0 -0
  83. {dccd-3.3.0 → dccd-3.3.1}/dccd/transport/ratelimit.py +0 -0
  84. {dccd-3.3.0 → dccd-3.3.1}/dccd/transport/ws.py +0 -0
  85. {dccd-3.3.0 → dccd-3.3.1}/dccd.egg-info/SOURCES.txt +0 -0
  86. {dccd-3.3.0 → dccd-3.3.1}/dccd.egg-info/dependency_links.txt +0 -0
  87. {dccd-3.3.0 → dccd-3.3.1}/dccd.egg-info/entry_points.txt +0 -0
  88. {dccd-3.3.0 → dccd-3.3.1}/dccd.egg-info/requires.txt +0 -0
  89. {dccd-3.3.0 → dccd-3.3.1}/dccd.egg-info/top_level.txt +0 -0
  90. {dccd-3.3.0 → dccd-3.3.1}/setup.cfg +0 -0
@@ -16,6 +16,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
16
16
 
17
17
  ### Removed
18
18
 
19
+ ## [3.3.1] - 2026-06-10
20
+
21
+ ### Fixed
22
+
23
+ - Kraken crypto/crypto OHLC pairs (e.g. `ETH/BTC`): `_kraken_pair` only mapped the
24
+ *base* `BTC→XBT`, producing `XETHXBTC` which Kraken rejects with "Unknown asset
25
+ pair"; it now maps the *quote* too (`XETHXXBT`). Verified against the live Kraken
26
+ API (721 bars). (#113)
27
+
19
28
  ## [3.3.0] - 2026-06-10
20
29
 
21
30
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dccd
3
- Version: 3.3.0
3
+ Version: 3.3.1
4
4
  Summary: Download Crypto Currency Data — hexagonal architecture, async-first.
5
5
  Author-email: Arthur Bernard <arthur.bernard.92@gmail.com>
6
6
  License: MIT
@@ -45,13 +45,19 @@ def _kraken_pair(symbol: Symbol) -> str:
45
45
  >>> from dccd.domain.symbol import Symbol
46
46
  >>> _kraken_pair(Symbol(base='BTC', quote='USD'))
47
47
  'XXBTZUSD'
48
+ >>> _kraken_pair(Symbol(base='ETH', quote='BTC'))
49
+ 'XETHXXBT'
48
50
  """
51
+ # Kraken names BTC as XBT — for the quote too, not just the base, so a
52
+ # crypto/crypto pair like ETH/BTC must become XETHXXBT (not XETHXBTC,
53
+ # which Kraken rejects with "Unknown asset pair").
49
54
  base = "XBT" if symbol.base == "BTC" else symbol.base
55
+ quote = "XBT" if symbol.quote == "BTC" else symbol.quote
50
56
  if base in ("BCH", "DASH"):
51
- return f"{base}{symbol.quote}"
52
- if symbol.quote in ("EUR", "USD", "CAD", "JPY", "GBP"):
53
- return f"X{base}Z{symbol.quote}"
54
- return f"X{base}X{symbol.quote}"
57
+ return f"{base}{quote}"
58
+ if quote in ("EUR", "USD", "CAD", "JPY", "GBP"):
59
+ return f"X{base}Z{quote}"
60
+ return f"X{base}X{quote}"
55
61
 
56
62
 
57
63
  def _ws_pair(symbol: Symbol) -> str:
@@ -115,6 +115,10 @@ class TestKrakenCapabilities:
115
115
  def test_render_symbol(self):
116
116
  assert self.src.render_symbol(BTC_USD) == "XXBTZUSD"
117
117
 
118
+ def test_render_symbol_crypto_quote_btc(self):
119
+ # ETH/BTC: BTC→XBT for the *quote* too, else Kraken rejects "XETHXBTC".
120
+ assert self.src.render_symbol(Symbol(base="ETH", quote="BTC")) == "XETHXXBT"
121
+
118
122
  def test_ohlc_cap_history_recent(self):
119
123
  cap = self.src.capability_for(DataType.OHLC, "rest", "historical")
120
124
  assert cap is not None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dccd
3
- Version: 3.3.0
3
+ Version: 3.3.1
4
4
  Summary: Download Crypto Currency Data — hexagonal architecture, async-first.
5
5
  Author-email: Arthur Bernard <arthur.bernard.92@gmail.com>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dccd"
7
- version = "3.3.0"
7
+ version = "3.3.1"
8
8
  description = "Download Crypto Currency Data — hexagonal architecture, async-first."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes