quantflow 0.2.8__tar.gz → 0.2.9__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.
- {quantflow-0.2.8 → quantflow-0.2.9}/PKG-INFO +13 -6
- {quantflow-0.2.8 → quantflow-0.2.9}/pyproject.toml +9 -8
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/__init__.py +1 -1
- quantflow-0.2.8/quantflow/cli/__init__.py → quantflow-0.2.9/quantflow/cli/app.py +10 -69
- quantflow-0.2.9/quantflow/cli/commands.py +102 -0
- quantflow-0.2.9/quantflow/cli/script.py +14 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/options/pricer.py +2 -2
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/ou.py +7 -2
- quantflow-0.2.9/quantflow/utils/__init__.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/bins.py +8 -6
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/paths.py +1 -1
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/types.py +5 -4
- {quantflow-0.2.8 → quantflow-0.2.9}/readme.md +6 -1
- {quantflow-0.2.8 → quantflow-0.2.9}/LICENSE +0 -0
- {quantflow-0.2.8/quantflow/data → quantflow-0.2.9/quantflow/cli}/__init__.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/cli/settings.py +0 -0
- {quantflow-0.2.8/quantflow/options → quantflow-0.2.9/quantflow/data}/__init__.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/data/fmp.py +0 -0
- {quantflow-0.2.8/quantflow/sp → quantflow-0.2.9/quantflow/options}/__init__.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/options/bs.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/options/calibration.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/options/inputs.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/options/surface.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/py.typed +0 -0
- {quantflow-0.2.8/quantflow/utils → quantflow-0.2.9/quantflow/sp}/__init__.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/base.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/bns.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/cir.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/copula.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/dsp.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/heston.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/jump_diffusion.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/poisson.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/sp/weiner.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/dates.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/df.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/distributions.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/functions.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/interest_rates.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/marginal.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/numbers.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/plot.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/transforms.py +0 -0
- {quantflow-0.2.8 → quantflow-0.2.9}/quantflow/utils/volatility.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: quantflow
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.9
|
|
4
4
|
Summary: quantitative analysis
|
|
5
5
|
License: BSD-3-Clause
|
|
6
6
|
Author: Luca
|
|
@@ -11,15 +11,17 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.12
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Provides-Extra: cli
|
|
14
15
|
Provides-Extra: data
|
|
15
16
|
Requires-Dist: aio-fluid[http] (>=1.2.1,<2.0.0) ; extra == "data"
|
|
16
|
-
Requires-Dist:
|
|
17
|
-
Requires-Dist:
|
|
18
|
-
Requires-Dist:
|
|
17
|
+
Requires-Dist: asciichartpy (>=1.5.25,<2.0.0) ; extra == "cli"
|
|
18
|
+
Requires-Dist: ccy (==1.6.0)
|
|
19
|
+
Requires-Dist: click (>=8.1.7,<9.0.0) ; extra == "cli"
|
|
19
20
|
Requires-Dist: polars[pandas,pyarrow] (>=1.11.0,<2.0.0)
|
|
20
|
-
Requires-Dist: prompt-toolkit (>=3.0.43,<4.0.0)
|
|
21
|
+
Requires-Dist: prompt-toolkit (>=3.0.43,<4.0.0) ; extra == "cli"
|
|
21
22
|
Requires-Dist: pydantic (>=2.0.2,<3.0.0)
|
|
22
23
|
Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
|
|
24
|
+
Requires-Dist: rich (>=13.9.4,<14.0.0) ; extra == "cli"
|
|
23
25
|
Requires-Dist: scipy (>=1.14.1,<2.0.0)
|
|
24
26
|
Project-URL: Documentation, https://quantmind.github.io/quantflow/
|
|
25
27
|
Project-URL: Homepage, https://github.com/quantmind/quantflow
|
|
@@ -56,6 +58,11 @@ pip install quantflow
|
|
|
56
58
|
|
|
57
59
|
## Command line tools
|
|
58
60
|
|
|
59
|
-
|
|
61
|
+
The command line tools are available when installing with the extra `cli` and `data` dependencies.
|
|
60
62
|
|
|
63
|
+
```bash
|
|
64
|
+
pip install quantflow[cli,data]
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
It is possible to use the command line tool `qf` to download data and run pricing and calibration scripts.
|
|
61
68
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "quantflow"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.9"
|
|
4
4
|
description = "quantitative analysis"
|
|
5
5
|
authors = ["Luca <luca@quantmind.com>"]
|
|
6
6
|
license = "BSD-3-Clause"
|
|
@@ -15,13 +15,14 @@ Documentation = "https://quantmind.github.io/quantflow/"
|
|
|
15
15
|
python = ">=3.11"
|
|
16
16
|
scipy = "^1.14.1"
|
|
17
17
|
pydantic = "^2.0.2"
|
|
18
|
-
ccy = {version="1.6.0"
|
|
19
|
-
asciichart = "^0.1"
|
|
18
|
+
ccy = {version="1.6.0"}
|
|
20
19
|
python-dotenv = "^1.0.1"
|
|
21
|
-
asciichartpy = "^1.5.25"
|
|
22
|
-
prompt-toolkit = "^3.0.43"
|
|
23
20
|
polars = {version = "^1.11.0", extras=["pandas", "pyarrow"]}
|
|
21
|
+
asciichartpy = { version = "^1.5.25", optional = true }
|
|
22
|
+
prompt-toolkit = { version = "^3.0.43", optional = true }
|
|
24
23
|
aio-fluid = {version = "^1.2.1", extras=["http"], optional = true}
|
|
24
|
+
rich = {version = "^13.9.4", optional = true}
|
|
25
|
+
click = {version = "^8.1.7", optional = true}
|
|
25
26
|
|
|
26
27
|
[tool.poetry.group.dev.dependencies]
|
|
27
28
|
black = "^24.1.1"
|
|
@@ -29,11 +30,12 @@ pytest-cov = "^6.0.0"
|
|
|
29
30
|
mypy = "^1.13.0"
|
|
30
31
|
ghp-import = "^2.0.2"
|
|
31
32
|
ruff = "^0.8.1"
|
|
32
|
-
pytest-asyncio = "^0.
|
|
33
|
+
pytest-asyncio = "^0.25.0"
|
|
33
34
|
|
|
34
35
|
|
|
35
36
|
[tool.poetry.extras]
|
|
36
37
|
data = ["aio-fluid"]
|
|
38
|
+
cli = ["asciichartpy", "prompt-toolkit", "rich", "click"]
|
|
37
39
|
|
|
38
40
|
[tool.poetry.group.book]
|
|
39
41
|
optional = true
|
|
@@ -48,7 +50,7 @@ sympy = "^1.12"
|
|
|
48
50
|
ipywidgets = "^8.0.7"
|
|
49
51
|
|
|
50
52
|
[tool.poetry.scripts]
|
|
51
|
-
qf = "quantflow.cli:main"
|
|
53
|
+
qf = "quantflow.cli.script:main"
|
|
52
54
|
|
|
53
55
|
[build-system]
|
|
54
56
|
requires = ["poetry-core>=1.0.0"]
|
|
@@ -68,7 +70,6 @@ profile = "black"
|
|
|
68
70
|
|
|
69
71
|
[tool.ruff]
|
|
70
72
|
lint.select = ["E", "F"]
|
|
71
|
-
extend-exclude = ["fluid_apps/db/migrations"]
|
|
72
73
|
line-length = 88
|
|
73
74
|
|
|
74
75
|
[tool.hatch.version]
|
|
@@ -1,25 +1,15 @@
|
|
|
1
|
-
import asyncio
|
|
2
1
|
import os
|
|
3
2
|
from dataclasses import dataclass, field
|
|
4
3
|
from typing import Any
|
|
5
4
|
|
|
6
5
|
import click
|
|
7
|
-
import dotenv
|
|
8
|
-
import pandas as pd
|
|
9
|
-
from asciichartpy import plot
|
|
10
|
-
from ccy.cli.console import df_to_rich
|
|
11
6
|
from prompt_toolkit import PromptSession
|
|
12
7
|
from prompt_toolkit.history import FileHistory
|
|
13
8
|
from rich.console import Console
|
|
14
9
|
from rich.text import Text
|
|
15
10
|
|
|
16
|
-
from quantflow.data.fmp import FMP
|
|
17
11
|
|
|
18
|
-
from . import settings
|
|
19
|
-
|
|
20
|
-
dotenv.load_dotenv()
|
|
21
|
-
|
|
22
|
-
FREQUENCIES = tuple(FMP().historical_frequencies())
|
|
12
|
+
from . import settings, commands
|
|
23
13
|
|
|
24
14
|
|
|
25
15
|
@click.group()
|
|
@@ -27,60 +17,14 @@ def qf() -> None:
|
|
|
27
17
|
pass
|
|
28
18
|
|
|
29
19
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
data = asyncio.run(get_profile(symbol))[0]
|
|
35
|
-
main.print(data.pop("description"))
|
|
36
|
-
df = pd.DataFrame(data.items(), columns=["Key", "Value"])
|
|
37
|
-
main.print(df_to_rich(df))
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
@qf.command()
|
|
41
|
-
@click.argument("symbol")
|
|
42
|
-
@click.option(
|
|
43
|
-
"-h",
|
|
44
|
-
"--height",
|
|
45
|
-
type=int,
|
|
46
|
-
default=20,
|
|
47
|
-
show_default=True,
|
|
48
|
-
help="Chart height",
|
|
49
|
-
)
|
|
50
|
-
@click.option(
|
|
51
|
-
"-l",
|
|
52
|
-
"--length",
|
|
53
|
-
type=int,
|
|
54
|
-
default=100,
|
|
55
|
-
show_default=True,
|
|
56
|
-
help="Number of data points",
|
|
57
|
-
)
|
|
58
|
-
@click.option(
|
|
59
|
-
"-f",
|
|
60
|
-
"--frequency",
|
|
61
|
-
type=click.Choice(FREQUENCIES),
|
|
62
|
-
default="",
|
|
63
|
-
help="Number of data points",
|
|
64
|
-
)
|
|
65
|
-
def chart(symbol: str, height: int, length: int, frequency: str) -> None:
|
|
66
|
-
"""Symbol chart"""
|
|
67
|
-
df = asyncio.run(get_prices(symbol, frequency))
|
|
68
|
-
data = list(reversed(df["close"].tolist()[:length]))
|
|
69
|
-
print(plot(data, {"height": height}))
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
async def get_prices(symbol: str, frequency: str) -> pd.DataFrame:
|
|
73
|
-
async with FMP() as cli:
|
|
74
|
-
return await cli.prices(symbol, frequency)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
async def get_profile(symbol: str) -> list[dict]:
|
|
78
|
-
async with FMP() as cli:
|
|
79
|
-
return await cli.profile(symbol)
|
|
20
|
+
qf.add_command(commands.exit)
|
|
21
|
+
qf.add_command(commands.profile)
|
|
22
|
+
qf.add_command(commands.search)
|
|
23
|
+
qf.add_command(commands.chart)
|
|
80
24
|
|
|
81
25
|
|
|
82
26
|
@dataclass
|
|
83
|
-
class
|
|
27
|
+
class QfApp:
|
|
84
28
|
console: Console = field(default_factory=Console)
|
|
85
29
|
|
|
86
30
|
def __call__(self) -> None:
|
|
@@ -116,16 +60,13 @@ class App:
|
|
|
116
60
|
if not text:
|
|
117
61
|
return
|
|
118
62
|
elif text == "help":
|
|
119
|
-
return qf.main(["--help"], standalone_mode=False)
|
|
120
|
-
elif text == "exit":
|
|
121
|
-
raise click.Abort()
|
|
63
|
+
return qf.main(["--help"], standalone_mode=False, obj=self)
|
|
122
64
|
|
|
123
65
|
try:
|
|
124
|
-
qf.main(text.split(), standalone_mode=False)
|
|
66
|
+
qf.main(text.split(), standalone_mode=False, obj=self)
|
|
125
67
|
except click.exceptions.MissingParameter as e:
|
|
126
68
|
self.error(e)
|
|
127
69
|
except click.exceptions.NoSuchOption as e:
|
|
128
70
|
self.error(e)
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
main = App()
|
|
71
|
+
except click.exceptions.UsageError as e:
|
|
72
|
+
self.error(e)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import click
|
|
4
|
+
import asyncio
|
|
5
|
+
import pandas as pd
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
|
+
from asciichartpy import plot
|
|
8
|
+
from ccy.cli.console import df_to_rich
|
|
9
|
+
from quantflow.data.fmp import FMP
|
|
10
|
+
|
|
11
|
+
FREQUENCIES = tuple(FMP().historical_frequencies())
|
|
12
|
+
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from quantflow.cli.app import QfApp
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def from_context(ctx: click.Context) -> QfApp:
|
|
18
|
+
return ctx.obj # type: ignore
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@click.command()
|
|
22
|
+
def exit() -> None:
|
|
23
|
+
"""Exit the program"""
|
|
24
|
+
raise click.Abort()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@click.command()
|
|
28
|
+
@click.argument("symbol")
|
|
29
|
+
@click.pass_context
|
|
30
|
+
def profile(ctx: click.Context, symbol: str) -> None:
|
|
31
|
+
"""Company profile"""
|
|
32
|
+
app = from_context(ctx)
|
|
33
|
+
data = asyncio.run(get_profile(symbol))
|
|
34
|
+
if not data:
|
|
35
|
+
raise click.UsageError(f"Company {symbol} not found - try searching")
|
|
36
|
+
else:
|
|
37
|
+
d = data[0]
|
|
38
|
+
app.print(d.pop("description") or "")
|
|
39
|
+
df = pd.DataFrame(d.items(), columns=["Key", "Value"])
|
|
40
|
+
app.print(df_to_rich(df))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
@click.command()
|
|
44
|
+
@click.argument("text")
|
|
45
|
+
@click.pass_context
|
|
46
|
+
def search(ctx: click.Context, text: str) -> None:
|
|
47
|
+
"""Search companies"""
|
|
48
|
+
app = from_context(ctx)
|
|
49
|
+
data = asyncio.run(search_company(text))
|
|
50
|
+
df = pd.DataFrame(data, columns=["symbol", "name", "currency", "stockExchange"])
|
|
51
|
+
app.print(df_to_rich(df))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@click.command()
|
|
55
|
+
@click.argument("symbol")
|
|
56
|
+
@click.option(
|
|
57
|
+
"-h",
|
|
58
|
+
"--height",
|
|
59
|
+
type=int,
|
|
60
|
+
default=20,
|
|
61
|
+
show_default=True,
|
|
62
|
+
help="Chart height",
|
|
63
|
+
)
|
|
64
|
+
@click.option(
|
|
65
|
+
"-l",
|
|
66
|
+
"--length",
|
|
67
|
+
type=int,
|
|
68
|
+
default=100,
|
|
69
|
+
show_default=True,
|
|
70
|
+
help="Number of data points",
|
|
71
|
+
)
|
|
72
|
+
@click.option(
|
|
73
|
+
"-f",
|
|
74
|
+
"--frequency",
|
|
75
|
+
type=click.Choice(FREQUENCIES),
|
|
76
|
+
default="",
|
|
77
|
+
help="Frequency of data - if not provided it is daily",
|
|
78
|
+
)
|
|
79
|
+
def chart(symbol: str, height: int, length: int, frequency: str) -> None:
|
|
80
|
+
"""Symbol chart"""
|
|
81
|
+
df = asyncio.run(get_prices(symbol, frequency))
|
|
82
|
+
if df.empty:
|
|
83
|
+
raise click.UsageError(
|
|
84
|
+
f"No data for {symbol} - are you sure the symbol exists?"
|
|
85
|
+
)
|
|
86
|
+
data = list(reversed(df["close"].tolist()[:length]))
|
|
87
|
+
print(plot(data, {"height": height}))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
async def get_prices(symbol: str, frequency: str) -> pd.DataFrame:
|
|
91
|
+
async with FMP() as cli:
|
|
92
|
+
return await cli.prices(symbol, frequency)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
async def get_profile(symbol: str) -> list[dict]:
|
|
96
|
+
async with FMP() as cli:
|
|
97
|
+
return await cli.profile(symbol)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
async def search_company(text: str) -> list[dict]:
|
|
101
|
+
async with FMP() as cli:
|
|
102
|
+
return await cli.search(text)
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import dotenv
|
|
2
|
+
|
|
3
|
+
dotenv.load_dotenv()
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
from .app import QfApp
|
|
7
|
+
except ImportError:
|
|
8
|
+
raise ImportError(
|
|
9
|
+
"Cannot run qf command line, "
|
|
10
|
+
"quantflow needs to be installed with cli & data extras, "
|
|
11
|
+
"pip install quantflow[cli, data]"
|
|
12
|
+
) from None
|
|
13
|
+
|
|
14
|
+
main = QfApp()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from dataclasses import dataclass, field
|
|
4
|
-
from typing import Any, Generic, NamedTuple, TypeVar
|
|
4
|
+
from typing import Any, Generic, NamedTuple, TypeVar, cast
|
|
5
5
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
import pandas as pd
|
|
@@ -156,7 +156,7 @@ class OptionPricer(Generic[M]):
|
|
|
156
156
|
moneyness_ttm = np.linspace(-max_moneyness_ttm, max_moneyness_ttm, support)
|
|
157
157
|
implied = np.zeros((len(ttm), len(moneyness_ttm)))
|
|
158
158
|
for i, t in enumerate(ttm):
|
|
159
|
-
maturity = self.maturity(t)
|
|
159
|
+
maturity = self.maturity(cast(float, t))
|
|
160
160
|
implied[i, :] = maturity.interp(moneyness_ttm * np.sqrt(t)).implied_vols
|
|
161
161
|
properties: dict = dict(
|
|
162
162
|
xaxis_title="moneyness_ttm",
|
|
@@ -9,7 +9,7 @@ from scipy.stats import gamma, norm
|
|
|
9
9
|
|
|
10
10
|
from ..utils.distributions import Exponential
|
|
11
11
|
from ..utils.paths import Paths
|
|
12
|
-
from ..utils.types import FloatArrayLike, Vector
|
|
12
|
+
from ..utils.types import FloatArrayLike, Vector, Float
|
|
13
13
|
from .base import Im, IntensityProcess
|
|
14
14
|
from .poisson import CompoundPoissonProcess, D
|
|
15
15
|
from .weiner import WeinerProcess
|
|
@@ -139,7 +139,12 @@ class GammaOU(NGOU[Exponential]):
|
|
|
139
139
|
return Paths(t=time_horizon, data=paths)
|
|
140
140
|
|
|
141
141
|
def _advance(
|
|
142
|
-
self,
|
|
142
|
+
self,
|
|
143
|
+
i: int,
|
|
144
|
+
pp: np.ndarray,
|
|
145
|
+
dt: Float,
|
|
146
|
+
arrival: Float = 0,
|
|
147
|
+
jump: Float = 0,
|
|
143
148
|
) -> int:
|
|
144
149
|
x = pp[i - 1]
|
|
145
150
|
kappa = self.kappa
|
|
File without changes
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Sequence, cast, Any
|
|
2
2
|
|
|
3
3
|
import numpy as np
|
|
4
4
|
from pandas import DataFrame
|
|
@@ -13,9 +13,9 @@ def pdf(
|
|
|
13
13
|
symmetric: float | None = None,
|
|
14
14
|
precision: int = 6,
|
|
15
15
|
) -> DataFrame:
|
|
16
|
-
max_value = np.max(data)
|
|
17
|
-
min_value = np.min(data)
|
|
18
|
-
domain = max(abs(data)) if symmetric is not None else max_value - min_value
|
|
16
|
+
max_value = cast(float, np.max(data))
|
|
17
|
+
min_value = cast(float, np.min(data))
|
|
18
|
+
domain: float = max(abs(data)) if symmetric is not None else max_value - min_value # type: ignore
|
|
19
19
|
if num_bins is None:
|
|
20
20
|
if not delta:
|
|
21
21
|
num_bins = 50
|
|
@@ -39,7 +39,9 @@ def pdf(
|
|
|
39
39
|
return DataFrame(dict(pdf=pdf), index=x[1:-1])
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def event_density(
|
|
42
|
+
def event_density(
|
|
43
|
+
df: DataFrame, columns: Sequence[str], num: int = 10
|
|
44
|
+
) -> dict[str, Any]:
|
|
43
45
|
"""Calculate the probability density of the number of events
|
|
44
46
|
in the dataframe columns
|
|
45
47
|
"""
|
|
@@ -48,5 +50,5 @@ def event_density(df: DataFrame, columns: Sequence, num: int = 10) -> Dict:
|
|
|
48
50
|
for col in columns:
|
|
49
51
|
counts, _ = np.histogram(df[col], bins=bins)
|
|
50
52
|
counts = counts / np.sum(counts)
|
|
51
|
-
data[col] = counts[:num]
|
|
53
|
+
data[col] = counts[:num] # type: ignore
|
|
52
54
|
return data
|
|
@@ -51,7 +51,7 @@ class Paths(BaseModel, arbitrary_types_allowed=True):
|
|
|
51
51
|
@property
|
|
52
52
|
def ys(self) -> list[list[float]]:
|
|
53
53
|
"""Paths as list of list (for visualization tools)"""
|
|
54
|
-
return self.data.transpose().tolist()
|
|
54
|
+
return self.data.transpose().tolist() # type: ignore
|
|
55
55
|
|
|
56
56
|
def mean(self) -> FloatArray:
|
|
57
57
|
"""Mean of paths"""
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
from decimal import Decimal
|
|
2
|
-
from typing import Optional, Union
|
|
2
|
+
from typing import Optional, Union, Any
|
|
3
3
|
|
|
4
4
|
import pandas as pd
|
|
5
5
|
import numpy as np
|
|
6
6
|
import numpy.typing as npt
|
|
7
7
|
|
|
8
8
|
Number = Decimal
|
|
9
|
-
|
|
9
|
+
Float = float | np.floating[Any]
|
|
10
|
+
Numbers = Union[int, Float, np.number]
|
|
10
11
|
NumberType = Union[float, int, str, Number]
|
|
11
12
|
Vector = Union[int, float, complex, np.ndarray, pd.Series]
|
|
12
|
-
FloatArray = npt.NDArray[np.
|
|
13
|
-
IntArray = npt.NDArray[np.
|
|
13
|
+
FloatArray = npt.NDArray[np.floating[Any]]
|
|
14
|
+
IntArray = npt.NDArray[np.signedinteger[Any]]
|
|
14
15
|
FloatArrayLike = FloatArray | float
|
|
15
16
|
|
|
16
17
|
|
|
@@ -28,5 +28,10 @@ pip install quantflow
|
|
|
28
28
|
|
|
29
29
|
## Command line tools
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
The command line tools are available when installing with the extra `cli` and `data` dependencies.
|
|
32
32
|
|
|
33
|
+
```bash
|
|
34
|
+
pip install quantflow[cli,data]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
It is possible to use the command line tool `qf` to download data and run pricing and calibration scripts.
|
|
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
|