cryptovol 0.1.0__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.
@@ -0,0 +1,42 @@
1
+ name: Bug report
2
+ description: Report unexpected SDK behavior
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: what
7
+ attributes:
8
+ label: What happened?
9
+ description: A clear description of the bug.
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: repro
15
+ attributes:
16
+ label: Minimal repro
17
+ description: A short code snippet we can run. **Do not include your API key.**
18
+ render: python
19
+ validations:
20
+ required: true
21
+
22
+ - type: textarea
23
+ id: error
24
+ attributes:
25
+ label: Full traceback / error
26
+ render: shell
27
+
28
+ - type: input
29
+ id: version
30
+ attributes:
31
+ label: cryptovol version
32
+ placeholder: "0.1.0"
33
+ validations:
34
+ required: true
35
+
36
+ - type: input
37
+ id: python
38
+ attributes:
39
+ label: Python version
40
+ placeholder: "3.12.1"
41
+ validations:
42
+ required: true
@@ -0,0 +1,22 @@
1
+ name: Feature request
2
+ description: Suggest a new feature or improvement
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: What problem are you trying to solve?
9
+ validations:
10
+ required: true
11
+
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
16
+ description: How would you like the SDK to behave? Example code snippets are great.
17
+ render: python
18
+
19
+ - type: textarea
20
+ id: alternatives
21
+ attributes:
22
+ label: Alternatives considered
@@ -0,0 +1,10 @@
1
+ # Summary
2
+
3
+ <!-- What does this PR change and why? -->
4
+
5
+ # Checklist
6
+
7
+ - [ ] Tests added or updated
8
+ - [ ] `ruff check cryptovol tests` passes
9
+ - [ ] `pytest` passes
10
+ - [ ] CHANGELOG.md updated under `## [Unreleased]`
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ${{ matrix.os }}
12
+ strategy:
13
+ fail-fast: false
14
+ matrix:
15
+ os: [ubuntu-latest, macos-latest, windows-latest]
16
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+ cache: pip
26
+
27
+ - name: Install
28
+ run: |
29
+ python -m pip install --upgrade pip
30
+ pip install -e ".[dev]"
31
+
32
+ - name: Lint
33
+ if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
34
+ run: ruff check cryptovol tests
35
+
36
+ - name: Test
37
+ run: pytest --cov=cryptovol --cov-report=term-missing
@@ -0,0 +1,24 @@
1
+ name: Deploy docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: write # mkdocs gh-deploy pushes to gh-pages branch
9
+
10
+ jobs:
11
+ deploy:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+ with:
16
+ fetch-depth: 0
17
+ - uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+ cache: pip
21
+ - name: Install
22
+ run: pip install -e ".[docs]"
23
+ - name: Build & deploy
24
+ run: mkdocs gh-deploy --force
@@ -0,0 +1,39 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+ - uses: actions/setup-python@v5
14
+ with:
15
+ python-version: "3.12"
16
+ - name: Install build
17
+ run: python -m pip install --upgrade build
18
+ - name: Build sdist + wheel
19
+ run: python -m build
20
+ - uses: actions/upload-artifact@v4
21
+ with:
22
+ name: dist
23
+ path: dist/
24
+
25
+ publish:
26
+ needs: build
27
+ runs-on: ubuntu-latest
28
+ environment: pypi
29
+ # PyPI Trusted Publishing — configure at https://pypi.org/manage/account/publishing/
30
+ # See https://docs.pypi.org/trusted-publishers/
31
+ permissions:
32
+ id-token: write
33
+ steps:
34
+ - uses: actions/download-artifact@v4
35
+ with:
36
+ name: dist
37
+ path: dist/
38
+ - name: Publish to PyPI
39
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,42 @@
1
+ # Byte-compiled / optimized
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # Distribution / packaging
7
+ .Python
8
+ build/
9
+ dist/
10
+ *.egg-info/
11
+ *.egg
12
+ wheels/
13
+
14
+ # Virtual environments
15
+ .venv/
16
+ venv/
17
+ env/
18
+ ENV/
19
+
20
+ # Test / coverage
21
+ .pytest_cache/
22
+ .coverage
23
+ .coverage.*
24
+ htmlcov/
25
+ .tox/
26
+ .mypy_cache/
27
+ .ruff_cache/
28
+
29
+ # MkDocs
30
+ site/
31
+
32
+ # Editors / OS
33
+ .vscode/
34
+ .idea/
35
+ *.swp
36
+ .DS_Store
37
+ Thumbs.db
38
+
39
+ # Secrets — never commit
40
+ .env
41
+ .envrc
42
+ *.key
@@ -0,0 +1,16 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.0] — 2026-05-16
9
+
10
+ ### Added
11
+ - Initial release.
12
+ - `CryptoVol` synchronous client with `vol_index`, `vol_surface`, `vol_surface_bulk`, `vol_history`.
13
+ - Typed Pydantic v2 response models with `.to_dataframe()` helpers (optional `[pandas]` extra).
14
+ - Exception hierarchy: `AuthenticationError`, `PlanLimitError`, `NotFoundError`, `ValidationError`, `RateLimitError`, `ServerError`, `TimeoutError`.
15
+ - Automatic retries with exponential backoff for 5xx and 429.
16
+ - Examples in `examples/` covering smile reconstruction, vol-index plotting, risk-reversals, and Greeks.
@@ -0,0 +1,44 @@
1
+ # Contributing
2
+
3
+ Thanks for your interest in improving `cryptovol-python`! Bug reports, docs fixes, and feature PRs are all welcome.
4
+
5
+ ## Set up
6
+
7
+ ```bash
8
+ git clone https://github.com/FlyCapital/cryptovol-python.git
9
+ cd cryptovol-python
10
+ python -m venv .venv && source .venv/bin/activate
11
+ pip install -e ".[dev,docs]"
12
+ ```
13
+
14
+ ## Run the test suite
15
+
16
+ ```bash
17
+ pytest # all tests
18
+ pytest --cov # with coverage
19
+ ruff check cryptovol # lint
20
+ ```
21
+
22
+ The default test suite uses `pytest-httpx` and runs entirely offline — no API key required.
23
+
24
+ ## Build the docs locally
25
+
26
+ ```bash
27
+ mkdocs serve
28
+ # open http://127.0.0.1:8000
29
+ ```
30
+
31
+ ## Submitting a PR
32
+
33
+ 1. Open an issue first for non-trivial changes so we can align on scope.
34
+ 2. Add or update tests covering your change.
35
+ 3. Run `ruff check cryptovol` and `pytest` before pushing.
36
+ 4. Update `CHANGELOG.md` under an `## [Unreleased]` heading.
37
+
38
+ ## Reporting bugs
39
+
40
+ Please include:
41
+
42
+ - A minimal repro snippet (omit your API key).
43
+ - The full traceback / error message.
44
+ - `python --version`, `cryptovol.__version__`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 CryptoVol
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,281 @@
1
+ Metadata-Version: 2.4
2
+ Name: cryptovol
3
+ Version: 0.1.0
4
+ Summary: Python SDK for the CryptoVol API — institutional-grade crypto implied volatility data.
5
+ Project-URL: Homepage, https://www.cryptovol.io
6
+ Project-URL: Documentation, https://www.cryptovol.io/docs
7
+ Project-URL: Repository, https://github.com/FlyCapital/cryptovol-python
8
+ Project-URL: Issues, https://github.com/FlyCapital/cryptovol-python/issues
9
+ Project-URL: Get an API key, https://www.cryptovol.io/api
10
+ Author-email: CryptoVol <support@cryptovol.io>
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: bitcoin,crypto,cryptovol,ethereum,implied-volatility,options,quant,sabr,trading,volatility
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Intended Audience :: Financial and Insurance Industry
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: 3.13
25
+ Classifier: Topic :: Office/Business :: Financial :: Investment
26
+ Classifier: Typing :: Typed
27
+ Requires-Python: >=3.9
28
+ Requires-Dist: httpx<1.0,>=0.24
29
+ Requires-Dist: pydantic<3.0,>=2.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: mypy>=1.0; extra == 'dev'
32
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
33
+ Requires-Dist: pytest-httpx>=0.26; extra == 'dev'
34
+ Requires-Dist: pytest>=7.0; extra == 'dev'
35
+ Requires-Dist: ruff>=0.4; extra == 'dev'
36
+ Provides-Extra: docs
37
+ Requires-Dist: mkdocs-material>=9.0; extra == 'docs'
38
+ Requires-Dist: mkdocs>=1.5; extra == 'docs'
39
+ Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
40
+ Provides-Extra: pandas
41
+ Requires-Dist: pandas>=1.5; extra == 'pandas'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # cryptovol-python
45
+
46
+ [![PyPI version](https://img.shields.io/pypi/v/cryptovol.svg)](https://pypi.org/project/cryptovol/)
47
+ [![Python versions](https://img.shields.io/pypi/pyversions/cryptovol.svg)](https://pypi.org/project/cryptovol/)
48
+ [![CI](https://github.com/FlyCapital/cryptovol-python/actions/workflows/ci.yml/badge.svg)](https://github.com/FlyCapital/cryptovol-python/actions/workflows/ci.yml)
49
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
50
+ [![Docs](https://img.shields.io/badge/docs-cryptovol.io-blue)](https://www.cryptovol.io/docs)
51
+
52
+ The official Python SDK for the **[CryptoVol API](https://www.cryptovol.io)** — institutional-grade implied volatility data for crypto options.
53
+
54
+ > SABR-calibrated surfaces · 3 sessions/day (Asia, London, US) · BTC, ETH, SOL, XRP, AVAX, TRX · Constant-maturity history for backtesting
55
+
56
+ ---
57
+
58
+ ## Install
59
+
60
+ ```bash
61
+ pip install cryptovol
62
+ ```
63
+
64
+ Optional pandas integration (for `.to_dataframe()`):
65
+
66
+ ```bash
67
+ pip install "cryptovol[pandas]"
68
+ ```
69
+
70
+ ## Get an API key
71
+
72
+ Sign up at **[cryptovol.io/api](https://www.cryptovol.io/api)** — BASIC, PRO, and ULTRA tiers are available.
73
+
74
+ ## Quick start
75
+
76
+ ```python
77
+ from cryptovol import CryptoVol
78
+
79
+ cv = CryptoVol(api_key="YOUR_RAPIDAPI_KEY")
80
+
81
+ # Daily BTC 30-day implied vol index
82
+ idx = cv.vol_index(ccy="BTC", tenor="30D")
83
+ print(f"Latest BTC 30D IV: {idx.data[-1].vol}%")
84
+
85
+ # ATM vol for a specific expiry, with Greeks
86
+ pt = cv.vol_surface(
87
+ ccy="BTC",
88
+ expiry="2026-12-26",
89
+ strike_type="moneyness",
90
+ strike_value=1.0,
91
+ include_analytics=True,
92
+ )
93
+ print(f"BTC ATM Dec 26: {pt.vol}% delta={pt.analytics.greeks.delta:.3f}")
94
+ ```
95
+
96
+ That's it. The client is typed end-to-end, so your IDE autocompletes every field.
97
+
98
+ ---
99
+
100
+ ## What you can query
101
+
102
+ | Method | Endpoint | What it returns |
103
+ |---|---|---|
104
+ | `cv.vol_index(...)` | `GET /v1/vol-index` | Daily IV index time series (CryptoVIX-style) |
105
+ | `cv.vol_surface(...)` | `GET /v1/vol-surface` | One SABR-interpolated vol point |
106
+ | `cv.vol_surface_bulk(...)` | `POST /v1/vol-surface/bulk` | Many points in one round-trip — efficient |
107
+ | `cv.vol_history(...)` | `GET /v1/vol-history` | Constant-maturity historical IV for backtests |
108
+
109
+ ### Strike conventions
110
+
111
+ `vol_surface` and `vol_surface_bulk` accept three strike types:
112
+
113
+ - **`"moneyness"`** — `strike_value` is the K/S ratio. `1.0` = ATM, `0.9` = 10% OTM put strike.
114
+ - **`"delta"`** — `strike_value` is the BS delta magnitude. `0.25` with `option_type="C"` gives the 25-delta call strike.
115
+ - **`"strike"`** — `strike_value` is the absolute strike (e.g. `100_000`).
116
+
117
+ For `"delta"`, the SDK solves K via SABR-interpolated Newton iteration on the surface — same calibration the API serves.
118
+
119
+ ---
120
+
121
+ ## Common recipes
122
+
123
+ ### Plot the BTC 30-day vol index
124
+
125
+ ```python
126
+ import matplotlib.pyplot as plt
127
+ from cryptovol import CryptoVol
128
+
129
+ cv = CryptoVol(api_key="...")
130
+ df = cv.vol_index(ccy="BTC", tenor="30D",
131
+ start_date="2025-01-01", end_date="2026-05-01").to_dataframe()
132
+
133
+ df["vol"].plot(title="BTC 30D Implied Vol")
134
+ plt.ylabel("IV (%)"); plt.show()
135
+ ```
136
+
137
+ ### Reconstruct a vol smile for one expiry
138
+
139
+ ```python
140
+ expiry = "2026-09-26"
141
+ moneyness_grid = [0.7, 0.8, 0.9, 0.95, 1.0, 1.05, 1.1, 1.2, 1.3]
142
+
143
+ resp = cv.vol_surface_bulk(
144
+ ccy="BTC",
145
+ queries=[
146
+ {"expiry": expiry, "strike_type": "moneyness", "strike_value": m}
147
+ for m in moneyness_grid
148
+ ],
149
+ )
150
+
151
+ for pt in resp.successful:
152
+ print(f"{pt.strike_value:.2f}x K={pt.strike:>10,.0f} vol={pt.vol:.2f}%")
153
+ ```
154
+
155
+ ### Build a 25-delta risk-reversal time series
156
+
157
+ ```python
158
+ import pandas as pd
159
+
160
+ call = cv.vol_history(ccy="BTC", tenor="1M",
161
+ strike_type="delta", strike_value=0.25, option_type="C").to_dataframe()
162
+ put = cv.vol_history(ccy="BTC", tenor="1M",
163
+ strike_type="delta", strike_value=0.25, option_type="P").to_dataframe()
164
+
165
+ rr = call["vol"] - put["vol"]
166
+ rr.plot(title="BTC 1M 25Δ Risk-Reversal")
167
+ ```
168
+
169
+ ### Greeks on a 25-delta call
170
+
171
+ ```python
172
+ pt = cv.vol_surface(
173
+ ccy="BTC", expiry="2026-12-26",
174
+ strike_type="delta", strike_value=0.25, option_type="C",
175
+ include_analytics=True,
176
+ )
177
+ g = pt.analytics.greeks
178
+ print(f"K={pt.strike:.0f} vol={pt.vol:.2f}% Δ={g.delta:.3f} Γ={g.gamma:.6f} V={g.vega:.2f} Θ={g.theta:.2f}")
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Error handling
184
+
185
+ Every API error becomes a typed exception you can catch precisely:
186
+
187
+ ```python
188
+ from cryptovol import CryptoVol, PlanLimitError, ValidationError, RateLimitError
189
+
190
+ cv = CryptoVol(api_key="...")
191
+
192
+ try:
193
+ cv.vol_history(ccy="ETH", tenor="1M",
194
+ strike_type="moneyness", strike_value=1.0)
195
+ except PlanLimitError as e:
196
+ print(f"Plan limit hit — upgrade needed: {e}")
197
+ except ValidationError as e:
198
+ print(f"Bad params: {e}")
199
+ except RateLimitError as e:
200
+ print(f"Slow down: {e}")
201
+ ```
202
+
203
+ Hierarchy:
204
+
205
+ ```
206
+ CryptoVolError # base — catch this to handle anything
207
+ ├── AuthenticationError # 401, or 403 without "plan" in the body
208
+ ├── PlanLimitError # 403 — tier blocks asset/session/history/Greeks
209
+ ├── NotFoundError # 404 — no data for that date/session
210
+ ├── ValidationError # 400 / 422 — malformed params
211
+ ├── RateLimitError # 429 — quota exceeded
212
+ ├── ServerError # 5xx
213
+ └── TimeoutError # request exceeded `timeout`
214
+ ```
215
+
216
+ ---
217
+
218
+ ## Configuration
219
+
220
+ ```python
221
+ from cryptovol import CryptoVol
222
+
223
+ cv = CryptoVol(
224
+ api_key="...",
225
+ timeout=30.0, # per-request timeout (seconds)
226
+ max_retries=3, # retries 5xx and 429 with exponential backoff
227
+ user_agent="my-app/1.2.3",
228
+ )
229
+
230
+ # Or as a context manager — closes the HTTP client on exit
231
+ with CryptoVol(api_key="...") as cv:
232
+ idx = cv.vol_index()
233
+ ```
234
+
235
+ ### Raw JSON
236
+
237
+ Every method accepts `raw=True` if you'd rather skip the typed models and work with plain dicts:
238
+
239
+ ```python
240
+ data = cv.vol_index(ccy="BTC", tenor="30D", raw=True)
241
+ # data is just the parsed JSON
242
+ ```
243
+
244
+ ---
245
+
246
+ ## Plan tiers (at a glance)
247
+
248
+ | | BASIC | PRO | ULTRA |
249
+ |---|---|---|---|
250
+ | Assets | BTC | + ETH, SOL | + XRP, AVAX, TRX |
251
+ | Sessions | US | US | Asia, London, US |
252
+ | History window | 30 days | 1 year | Full archive |
253
+ | `vol_history` endpoint | — | ✓ | ✓ |
254
+ | Greeks / analytics | — | ✓ | ✓ |
255
+ | Quota | 500/month | 70k/day | 100k/day |
256
+
257
+ Hitting a limit raises `PlanLimitError` — the message tells you which tier unlocks it. Full details at **[cryptovol.io/api](https://www.cryptovol.io/api)**.
258
+
259
+ ---
260
+
261
+ ## Development
262
+
263
+ ```bash
264
+ git clone https://github.com/FlyCapital/cryptovol-python.git
265
+ cd cryptovol-python
266
+ pip install -e ".[dev]"
267
+ pytest
268
+ ```
269
+
270
+ ---
271
+
272
+ ## Links
273
+
274
+ - **API docs:** https://www.cryptovol.io/docs
275
+ - **Methodology:** https://www.cryptovol.io/methodology
276
+ - **Research / blog:** https://www.cryptovol.io/blog
277
+ - **Get an API key:** https://www.cryptovol.io/api
278
+
279
+ ## License
280
+
281
+ MIT — see [LICENSE](./LICENSE).