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.
- cryptovol-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +42 -0
- cryptovol-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +22 -0
- cryptovol-0.1.0/.github/pull_request_template.md +10 -0
- cryptovol-0.1.0/.github/workflows/ci.yml +37 -0
- cryptovol-0.1.0/.github/workflows/docs.yml +24 -0
- cryptovol-0.1.0/.github/workflows/publish.yml +39 -0
- cryptovol-0.1.0/.gitignore +42 -0
- cryptovol-0.1.0/CHANGELOG.md +16 -0
- cryptovol-0.1.0/CONTRIBUTING.md +44 -0
- cryptovol-0.1.0/LICENSE +21 -0
- cryptovol-0.1.0/PKG-INFO +281 -0
- cryptovol-0.1.0/README.md +238 -0
- cryptovol-0.1.0/cryptovol/__init__.py +60 -0
- cryptovol-0.1.0/cryptovol/client.py +443 -0
- cryptovol-0.1.0/cryptovol/exceptions.py +64 -0
- cryptovol-0.1.0/cryptovol/models.py +194 -0
- cryptovol-0.1.0/cryptovol/py.typed +0 -0
- cryptovol-0.1.0/docs/errors.md +80 -0
- cryptovol-0.1.0/docs/index.md +65 -0
- cryptovol-0.1.0/docs/quickstart.md +134 -0
- cryptovol-0.1.0/docs/recipes.md +121 -0
- cryptovol-0.1.0/docs/reference.md +33 -0
- cryptovol-0.1.0/examples/01_quickstart.py +11 -0
- cryptovol-0.1.0/examples/02_smile.py +34 -0
- cryptovol-0.1.0/examples/03_risk_reversal.py +24 -0
- cryptovol-0.1.0/examples/04_greeks.py +30 -0
- cryptovol-0.1.0/examples/05_handle_plan_errors.py +31 -0
- cryptovol-0.1.0/mkdocs.yml +74 -0
- cryptovol-0.1.0/pyproject.toml +86 -0
- cryptovol-0.1.0/tests/__init__.py +0 -0
- cryptovol-0.1.0/tests/conftest.py +19 -0
- cryptovol-0.1.0/tests/test_client.py +248 -0
|
@@ -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,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__`.
|
cryptovol-0.1.0/LICENSE
ADDED
|
@@ -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.
|
cryptovol-0.1.0/PKG-INFO
ADDED
|
@@ -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
|
+
[](https://pypi.org/project/cryptovol/)
|
|
47
|
+
[](https://pypi.org/project/cryptovol/)
|
|
48
|
+
[](https://github.com/FlyCapital/cryptovol-python/actions/workflows/ci.yml)
|
|
49
|
+
[](https://opensource.org/licenses/MIT)
|
|
50
|
+
[](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).
|