Files
Danglewood 869cfed125 [Release] openbb-v5.0.0 (#7741)
* merge branch develop with main

* bump desktop version

* fix the merge

* sync Cargo.lock to desktop 2.0.0

* fix cli conftest.py

---------

Co-authored-by: deeleeramone <>
2026-09-29 10:58:44 -07:00

144 lines
4.5 KiB
Python

"""Deribit through the REST API, against the live exchange."""
import pytest
from .cases import CHARTS, FEEDS, MODELS, TABLES, case_id, namespace
pytestmark = pytest.mark.integration
def _get(api: dict, path: str, params: dict):
"""Call one route and return its decoded body.
Raises
------
AssertionError
If the route does not answer 200.
"""
import requests
written = {
key: str(value).lower() if isinstance(value, bool) else value
for key, value in params.items()
}
response = requests.get(
f"{api['base']}{path}", params=written, headers=api["headers"], timeout=120
)
assert response.status_code == 200, f"{path} {params}: {response.text}"
return response.json()
class TestModels:
"""Every model-backed route returns rows."""
@pytest.mark.parametrize("case", MODELS, ids=case_id)
def test_returns_rows(self, api, case):
"""The route answers with an OBBject body holding at least one row."""
router, name, params = case
body = _get(
api,
f"/{namespace(router, name)}/{router}/{name}",
{"provider": "deribit", **params},
)
assert body["provider"] == "deribit"
assert body["results"]
def test_an_unoffered_depth_is_refused(self, api):
"""A book depth Deribit does not return is refused before the exchange."""
import requests
response = requests.get(
f"{api['base']}/deribit/market/order_book",
params={"provider": "deribit", "symbol": "BTC-PERPETUAL", "depth": "7"},
headers=api["headers"],
timeout=60,
)
assert response.status_code in (400, 422)
assert "not 7" in response.text
class TestFeeds:
"""Every choice feed and scalar route answers."""
@pytest.mark.parametrize("case", FEEDS, ids=case_id)
def test_answers(self, api, case):
"""The route returns something to offer."""
router, name, params = case
body = _get(api, f"/deribit/{router}/{name}", params)
assert body is not None
assert body not in ([], {})
class TestAnalysisTables:
"""The options analysis routes return ranked or priced rows."""
@pytest.mark.parametrize(
"case", TABLES, ids=lambda case: case_id(("options", *case))
)
def test_returns_rows(self, api, case):
"""The route answers with rows."""
name, params = case
body = _get(api, f"/deribit/options/{name}", params)
assert body["results"]
def test_the_optimizer_codes_every_row(self, api):
"""Each ranked position names the Deribit combo it is."""
body = _get(
api, "/deribit/options/optimizer", {"symbol": "BTC", "target_price": 100000}
)
assert all(row["code"] for row in body["results"])
class TestCharts:
"""Every chart route draws, and hands back its rows on request."""
@pytest.mark.parametrize(
"case", CHARTS, ids=lambda case: case_id(("options", *case))
)
def test_draws_a_figure(self, api, case):
"""The route answers with a Plotly figure and its display config."""
name, params = case
figure = _get(api, f"/deribit/options/{name}", params)
assert figure["data"]
assert figure["layout"]["title"]["text"]
assert figure["config"]["responsive"] is True
@pytest.mark.parametrize(
"name", sorted({name for name, _params in CHARTS}), ids=str
)
def test_raw_returns_rows(self, api, name):
"""With raw set, the route answers with the rows behind the chart."""
rows = _get(api, f"/deribit/options/{name}", {"symbol": "BTC", "raw": True})
assert isinstance(rows, list)
assert rows
def test_the_payoff_draws_a_ranked_position(self, api):
"""The legs the optimizer prints draw back as that position."""
view = {"symbol": "BTC", "target_price": 100000}
row = _get(api, "/deribit/options/optimizer", view)["results"][-1]
figure = _get(api, "/deribit/options/payoff", {**view, "legs": row["legs"]})
assert row["strategy"] in figure["layout"]["title"]["text"]
def test_an_unlisted_underlying_is_a_404(self, api):
"""An underlying Deribit lists no options on answers 404."""
import requests
response = requests.get(
f"{api['base']}/deribit/options/smile",
params={"symbol": "NOPE"},
headers=api["headers"],
timeout=60,
)
assert response.status_code == 404