|
5 | 5 | import click |
6 | 6 | import pandas as pd |
7 | 7 | from asciichartpy import plot |
| 8 | +from cache import AsyncTTL |
8 | 9 | from ccy.cli.console import df_to_rich |
9 | 10 |
|
10 | 11 | from quantflow.data.deribit import Deribit |
| 12 | +from quantflow.options.surface import VolSurface |
11 | 13 |
|
12 | 14 | from .base import QuantContext, options, quant_group |
13 | 15 |
|
@@ -36,6 +38,48 @@ def volatility(currency: str, length: int, height: int, chart: bool) -> None: |
36 | 38 | ctx.qf.print(df_to_rich(df)) |
37 | 39 |
|
38 | 40 |
|
| 41 | +@crypto.command() |
| 42 | +@click.argument("currency") |
| 43 | +def term_structure(currency: str) -> None: |
| 44 | + """Provides information about the term structure for given cryptocurrency""" |
| 45 | + ctx = QuantContext.current() |
| 46 | + vs = asyncio.run(get_vol_surface(currency)) |
| 47 | + ts = vs.term_structure().round({"ttm": 4}) |
| 48 | + ts["open_interest"] = ts["open_interest"].map("{:,d}".format) |
| 49 | + ts["volume"] = ts["volume"].map("{:,d}".format) |
| 50 | + ctx.qf.print(df_to_rich(ts)) |
| 51 | + |
| 52 | + |
| 53 | +@crypto.command() |
| 54 | +@click.argument("currency") |
| 55 | +@options.index |
| 56 | +@options.height |
| 57 | +@options.chart |
| 58 | +def implied_vol(currency: str, index: int, height: int, chart: bool) -> None: |
| 59 | + """Display the Volatility Surface for given cryptocurrency |
| 60 | + at a given maturity index |
| 61 | + """ |
| 62 | + ctx = QuantContext.current() |
| 63 | + vs = asyncio.run(get_vol_surface(currency)) |
| 64 | + index_or_none = None if index < 0 else index |
| 65 | + vs.bs(index=index_or_none) |
| 66 | + df = vs.options_df(index=index_or_none) |
| 67 | + df["implied_vol"] = df["implied_vol"] * 100 |
| 68 | + df = df.round({"ttm": 4, "moneyness": 4, "moneyness_ttm": 4, "implied_vol": 5}) |
| 69 | + if chart: |
| 70 | + data = df["implied_vol"].tolist() |
| 71 | + ctx.qf.print(plot(data, {"height": height})) |
| 72 | + else: |
| 73 | + ctx.qf.print(df_to_rich(df)) |
| 74 | + |
| 75 | + |
39 | 76 | async def get_volatility(ctx: QuantContext, currency: str) -> pd.DataFrame: |
40 | 77 | async with Deribit() as client: |
41 | 78 | return await client.get_volatility(params=dict(currency=currency)) |
| 79 | + |
| 80 | + |
| 81 | +@AsyncTTL(time_to_live=10) |
| 82 | +async def get_vol_surface(currency: str) -> VolSurface: |
| 83 | + async with Deribit() as client: |
| 84 | + loader = await client.volatility_surface_loader(currency) |
| 85 | + return loader.surface() |
0 commit comments