Files
Cerbero-Bite/pyproject.toml
T
Adriano db888ce0e8 feat(gui): Phase B — Equity + History pages
Adds the analytics surface of the dashboard:

* gui/data_layer.py — extended with load_closed_positions (windowed
  filter on closed_at) and three pure-function aggregators:
  compute_equity_curve, compute_kpis, compute_monthly_stats. Drawdown
  is measured against the running peak of cumulative realised P&L.
* gui/pages/3_📈_Equity.py — KPI strip, plotly cumulative-PnL line,
  drawdown area below, P&L histogram by close_reason, per-month table
  with win-rate.
* gui/pages/4_📜_History.py — windowed table of closed trades with
  multiselect close-reason and winners/losers radio filters, six-tile
  KPI strip, CSV export button.
* pyproject.toml — relax mypy on plotly + pandas (no shipped stubs).

Validated with synthetic data: 3 trades, 67% win rate, $50 total,
max drawdown $30 — all matching expected math. GUI launches, HTTP 200
on / and /_stcore/health.

353/353 tests still pass; ruff clean; mypy strict src clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 12:11:02 +02:00

149 lines
3.6 KiB
TOML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
[project]
name = "cerbero-bite"
version = "0.0.1"
description = "Rule-based deterministic engine for Cerberus Bite credit spread strategy on ETH options"
readme = "README.md"
requires-python = ">=3.12"
authors = [{ name = "Adriano Dal Pastro", email = "adrianodalpastro@tielogic.com" }]
license = { text = "Proprietary" }
dependencies = [
"pydantic>=2.9",
"pydantic-settings>=2.5",
"click>=8.1",
"rich>=13.9",
"structlog>=24.4",
"apscheduler>=3.10",
"sqlalchemy>=2.0",
"aiosqlite>=0.20",
"pyyaml>=6.0",
"httpx>=0.27",
"tenacity>=9.0",
"python-dateutil>=2.9",
]
[project.optional-dependencies]
gui = [
"streamlit>=1.40",
"plotly>=5.24",
"pandas>=2.2",
"numpy>=2.0",
]
backtest = [
"scipy>=1.14",
"matplotlib>=3.9",
"pandas>=2.2",
"numpy>=2.0",
]
[project.scripts]
cerbero-bite = "cerbero_bite.cli:main"
[dependency-groups]
dev = [
"pytest>=8.3",
"pytest-asyncio>=0.24",
"pytest-cov>=5.0",
"pytest-httpx>=0.33",
"hypothesis>=6.115",
"mypy>=1.13",
"ruff>=0.7",
"pre-commit>=4.0",
"types-PyYAML>=6.0",
"types-python-dateutil>=2.9",
]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/cerbero_bite"]
[tool.ruff]
line-length = 100
target-version = "py312"
src = ["src", "tests"]
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"N", # pep8-naming
"SIM", # flake8-simplify
"RET", # flake8-return
"ARG", # flake8-unused-arguments
"PTH", # flake8-use-pathlib
"ERA", # eradicate
"PL", # pylint
"RUF", # ruff-specific
]
ignore = [
"PLR0913", # too many arguments (we accept config-heavy functions)
"PLR2004", # magic value (we have many domain constants in tests)
"PLR0911", # too many return statements (rule engines have many early returns)
"PLR0912", # too many branches (entry/monitor cycles are inherently long)
"PLR0915", # too many statements (orchestration cycles)
"RUF001", # ambiguous unicode in strings (we use math symbols × ≤ ≥)
"RUF002", # ambiguous unicode in docstrings
"RUF003", # ambiguous unicode in comments
]
[tool.ruff.lint.per-file-ignores]
"tests/**" = ["PLR2004", "ARG", "S101", "ERA001", "B017"]
# Streamlit auto-discovers pages whose file names start with a number and
# may contain icons; the convention conflicts with N999.
"src/cerbero_bite/gui/pages/*" = ["N999"]
[tool.ruff.format]
quote-style = "double"
indent-style = "space"
[tool.mypy]
python_version = "3.12"
strict = true
warn_unreachable = true
warn_redundant_casts = true
warn_unused_ignores = true
disallow_any_generics = true
disallow_untyped_defs = true
no_implicit_reexport = true
files = ["src/cerbero_bite"]
[[tool.mypy.overrides]]
module = ["apscheduler.*", "plotly.*", "pandas.*"]
ignore_missing_imports = true
[tool.pytest.ini_options]
testpaths = ["tests"]
asyncio_mode = "auto"
addopts = [
"-ra",
"--strict-markers",
"--strict-config",
]
markers = [
"slow: marks tests as slow (deselect with '-m \"not slow\"')",
"integration: integration tests with fake MCP",
"golden: golden scenario tests",
]
[tool.coverage.run]
source = ["src/cerbero_bite"]
branch = true
[tool.coverage.report]
exclude_lines = [
"pragma: no cover",
"raise NotImplementedError",
"if TYPE_CHECKING:",
"if __name__ == .__main__.:",
]
show_missing = true
skip_covered = false