[project] name = "fxhnt" version = "0.1.0" description = "Agentic strategy-research & multi-strategy execution platform — discover, backtest, OOS-validate at scale" requires-python = ">=3.11" dependencies = [ "numpy>=1.26", "pydantic>=2.6", "pydantic-settings>=2.2", "sqlalchemy>=2.0", "duckdb>=1.0", "typer>=0.12", "scikit-learn>=1.4", # Pin protobuf < 6: protobuf 6's runtime-version validator rejects grpcio-health-checking 1.82's stubs # (VersionError), which crashes the dagster webserver + daemon on code-location load. Keep the 5.x line # that dagster 1.12 / grpcio were built against. (Transitive dep; pinned directly to hold it back.) "protobuf<6", ] [project.optional-dependencies] dev = ["pytest>=8.0", "pytest-xdist>=3.6", "hypothesis>=6.100", "ruff>=0.5", "mypy>=1.10"] crypto = ["ccxt>=4.4"] ibkr = ["ib-async>=2.0"] agent = ["langgraph>=0.2", "langchain-core>=0.3", "langchain-ollama>=0.2"] data = ["databento>=0.50"] web = ["fastapi>=0.110", "uvicorn[standard]>=0.29", "jinja2>=3.1", "httpx>=0.27"] pg = ["psycopg[binary]>=3.1"] factory = ["scipy>=1.11"] orchestration = ["dagster>=1.12,<1.13", "dagster-webserver>=1.12,<1.13", "dagster-postgres>=0.28,<0.29", "dagster-k8s>=0.28,<0.29"] # Surfer PoC paper-track (vendored crypto XS-momentum + VRP). torch is a faithful-port requirement # (signal_sweep.sharpe_t/validate + surfer_poc.backtest use it) — CPU wheel only (no GPU in the cockpit pod). poc = ["torch>=2.2"] [tool.uv.sources] torch = { index = "pytorch-cpu" } [[tool.uv.index]] name = "pytorch-cpu" url = "https://download.pytorch.org/whl/cpu" explicit = true [project.scripts] fxhnt = "fxhnt.cli:app" [build-system] requires = ["setuptools>=68"] build-backend = "setuptools.build_meta" [tool.setuptools.packages.find] where = ["src"] # Ship the cockpit web assets (Jinja2 templates + logo/htmx static) inside the wheel — without this, # `pip install .` omits non-Python files and `fxhnt serve` crashes on a missing static/ dir in the image. [tool.setuptools.package-data] "fxhnt.adapters.web" = ["templates/*.html", "static/*"] [tool.ruff] line-length = 120 target-version = "py311" [tool.ruff.lint] select = ["E", "F", "I", "UP", "B", "SIM"] [tool.mypy] python_version = "3.11" strict = true ignore_missing_imports = true # Vendored third-party code (faithful verbatim copies, only import/path edits) is intentionally untyped — # annotating it would diverge from upstream. Exclude it from strict checking; callers treat it as Any. exclude = '^src/fxhnt/vendor/' [[tool.mypy.overrides]] module = "fxhnt.vendor.*" ignore_errors = true follow_imports = "skip" [tool.pytest.ini_options] pythonpath = ["src"] testpaths = ["tests"] # Parallel by default: the suite is sqlite-per-test / tmp_path isolated, so it fans out cleanly across # cores (~7min serial -> ~1min on 16 cores). Override with `-n0` to force serial for debugging. addopts = "-n auto" markers = [ "slow: heavy real-compute/DB tests (4-sleeve walk-forwards, gauntlet DSR, forward-engine recompute). Skip the fast inner loop with `-m 'not slow'`.", ]