Files
Auto-Trader/pyproject.toml
T
Haozhe Wu e1dbea8ad3 release: 0.1.16 — a number that can show where it came from
Rolls up 492 commits / 116 merged pull requests since 0.1.15, from 16
contributors.

The final-answer grounding gate stopped guessing what a number is from
the words around it: the model declares each figure's role (observed,
derived, proposed, cited or count), the gate checks the declaration
against the session's tool evidence, and a figure that fails is cut from
the answer instead of the whole answer being refused. A backtest's own
output now grounds the report written about it, run cards cite a metric
only where the saved CSV agrees, and the generated broker matrix states
each profile's permissions as declarations. Research runs keep what they
fetched: compaction follows the model's real context window instead of a
fixed 40K estimate. The missing-data sweep reached 59 more alphas.
Argentina (BYMA), weekly and monthly bars, Bahasa Indonesia, Gildata,
OpenCode, Email and WebSocket channels and four broker connectors (KIS,
Upbit, Toss Securities, Scalable Capital) land alongside.

Verified before release: the reporter's risk-parity prompt, which had
stopped with no_progress after 93 seconds on DeepSeek V4 Pro, completed
on 4a40a7f6's parent in 8m13s with both backtests run, 13 steps saved and
the report released with its core figures grounded.

Version declarations bumped in pyproject.toml, agent/SKILL.md,
Dockerfile, frontend/package.json, both package-lock.json entries, all
nine locales and the Layout test mock. CHANGELOG cites 116/116 merged
pull requests and credits 16/16 authors. README News carries the release
in seven languages, three entries visible.
2026-09-29 16:13:16 +08:00

315 lines
9.2 KiB
TOML

[project]
name = "vibe-trading-ai"
version = "0.1.16"
description = "Natural-language finance research AI agent with backtesting"
requires-python = ">=3.11"
license = "MIT"
readme = "README.md"
authors = [
{name = "HKUDS", email = "hkuds@connect.hku.hk"},
]
keywords = ["finance", "trading", "backtesting", "agent", "swarm", "quantitative"]
classifiers = [
"Development Status :: 4 - Beta",
"Intended Audience :: Financial and Insurance Industry",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Topic :: Office/Business :: Financial :: Investment",
]
dependencies = [
"rich>=13.0.0",
"pyyaml>=6.0.0",
"langchain>=1.3.9,<2",
"langchain-core>=1.0.0,<2",
"langchain-openai>=1.0.0,<2",
"langgraph>=1.2.5,<1.3",
"langgraph-checkpoint>=2.1.0,<5",
"python-dotenv>=1.0.0",
"httpx>=0.28.0",
"h2>=4.4.1",
"defusedxml>=0.7.1",
"oauth-cli-kit>=0.1.3",
"pandas>=2.0.0,<3.0.0",
"openpyxl>=3.1.0",
"python-docx>=1.1.0",
"python-pptx>=0.6.23",
"pypdfium2>=4.0.0",
"Pillow>=12.2.0",
"numpy>=1.24.0",
"scipy>=1.10.0",
"bottleneck>=1.3.7",
"duckdb>=1.2.0",
"scikit-learn>=1.3.0",
"joblib>=1.3.0",
"tushare>=1.2.89",
"requests>=2.31.0",
"yfinance>=0.2.30",
"akshare>=1.12.0",
"ccxt>=4.5.71",
"aiohttp>=3.14.3",
"cryptography>=50.0.0",
"fastapi>=0.104.0",
"uvicorn[standard]>=0.24.0",
"websockets>=12.0",
"pydantic>=2.0.0",
"python-multipart>=0.0.18",
"sse-starlette>=1.6.0",
# 4.0.0 changed MCPError's constructor (message is now separate) and the
# session snapshot shape; tests construct it the 2.x way. Cap until the
# adaptation lands.
"fastmcp>=2.14.0,<4.0.0",
# mcp 1.30.0 enforces RFC 8414 section 3.3 strictly: the `issuer` in an
# authorization server's metadata must equal the issuer used to build the
# well-known URL. IBKR's official MCP server advertises the authorization
# server https://api.ibkr.com/oauth2 while its metadata (verified live on
# 2026-09-08 at both well-known paths) says `"issuer": "https://api.ibkr.com"`,
# so discovery raises OAuthFlowError and the IBKR OAuth connection cannot be
# established at all. The cap is on the real broker path, not on the test
# that caught it — pulled in transitively through fastmcp.
"mcp<1.30",
"ddgs>=6.0.0",
"jinja2>=3.1.0",
"matplotlib>=3.7.0",
"weasyprint>=60.0",
"prompt_toolkit>=3.0.0",
]
[project.urls]
Homepage = "https://vibetrading.wiki/"
Documentation = "https://vibetrading.wiki/docs/"
Repository = "https://github.com/HKUDS/Vibe-Trading"
Issues = "https://github.com/HKUDS/Vibe-Trading/issues"
[project.scripts]
vibe-trading = "cli:main"
vibe-trading-mcp = "mcp_server:main"
[tool.setuptools]
package-dir = {"" = "agent"}
py-modules = ["api_server", "mcp_server"]
[tool.setuptools.packages.find]
where = ["agent"]
include = ["src*", "backtest*", "cli*", "evals*"]
[tool.setuptools.package-data]
"src" = [
"skills/**/*.md",
"skills/**/*.yaml",
"skills/**/*.json",
"skills/**/*.py",
"providers/*.json",
"scheduled_research/playbooks/*.md",
"swarm/presets/*.yaml",
"shadow_account/templates/*.j2",
"shadow_account/templates/*.html",
"shadow_account/templates/*.css",
]
"evals.harness" = ["README.md", "cases/**/*.json"]
"backtest" = ["*.py"]
"src.factors" = ["zoo/**/*.yaml", "zoo/**/*.md", "zoo/**/NOTICE"]
[project.optional-dependencies]
ibkr = [
"ib_async>=2.0",
]
longbridge = [
"longbridge>=0.2.5",
]
mt5 = [
# Official Windows-only bridge to a locally running MetaTrader 5 terminal
# (broker connector + mt5 data loader). Lazy-imported; on other platforms
# the marker makes this a no-op and everything degrades gracefully.
"MetaTrader5>=5.0.45; sys_platform == 'win32'",
]
zerodha = [
# Zerodha Kite Connect (India NSE/BSE) broker connector + india_broker
# loader backend. Lazy-imported with a named error; zerodha_available()
# stays False (loader falls through to Shoonya/Dhan) until installed.
"kiteconnect>=4.0.0",
]
upbit = [
# Upbit (Korea, KRW crypto) broker connector JWT signing. Lazy-imported
# with a named error naming this extra; upbit_jwt_available() stays False
# until installed.
"PyJWT>=2.8.0",
]
deepseek = [
"langchain-deepseek>=1.0.0,<2",
]
copilot = [
# Official GitHub Copilot SDK (provider="copilot"). Optional: every import
# of it in copilot_auth.py is already lazy and raises an actionable install
# hint when absent, so the base install stays lean — and the Windows desktop
# build's embedded runtime does not have to carry it.
"github-copilot-sdk>=1.0.8,<2",
]
anthropic = [
# Native Anthropic Messages API adapter (provider="anthropic"). Optional:
# _build_anthropic lazy-imports it and raises an actionable install hint
# when absent, so the base install stays lean for users who don't use it.
"langchain-anthropic>=1.3.0,<2",
]
openbb = [
# OpenBB Workspace custom-agent bridge (src/openbb_bridge): protocol models
# + SSE helpers. api_server.py registers /agents.json and /v1/query only
# when this import succeeds, so a base install stays unaffected.
"openbb-ai>=2.0.0,<3",
]
krx = [
# Free, no-auth Korea (KRX: KOSPI/KOSDAQ) EOD OHLCV. Without this extra
# the kr_equity chain falls back to yahoo/yfinance (.KS/.KQ suffixes).
"pykrx>=1.0.45",
]
stats = [
# Econometrics behind src/quantlib/timeseries: stationarity (ADF),
# cointegration, Granger causality, Ljung-Box, VIF and GARCH. Those
# functions lazy-import and raise an actionable ImportError naming this
# extra, so the base install stays lean and nothing silently degrades.
"statsmodels>=0.14",
"arch>=6.0",
]
ashare = [
# Free, no-auth A-share source over BaoStock's TCP protocol; bypasses the
# HTTP CDN IP blocks that affect eastmoney-backed sources. The Tencent
# A-share loader needs no extra dependency (stdlib HTTP only).
"baostock>=0.8.8",
]
harmonic = [
"pyharmonics>=1.5.0",
]
smc = [
# Smart Money Concepts (ICT) signal engine — used by exactly one skill
# example, src/skills/smc/example_signal_engine.py, whose SKILL.md already
# tells the reader to install it. It is an extra rather than a base
# dependency because it drags in numba -> llvmlite, and llvmlite ships no
# macOS x86_64 wheel from 0.46 on: as a base dependency it turned every
# Intel-Mac install into a source build that needs cmake (discussion #1035).
"smartmoneyconcepts>=0.0.27",
]
keyring = [
# OS credential vault (Keychain / Credential Manager / Secret Service) for
# user-installed local read-only connector plugins. CredentialStore imports
# it lazily and raises an actionable hint naming this extra, so a base
# install stays lean for users who configure no local connector.
"keyring>=25.0.0",
]
dingtalk = [
"dingtalk-stream>=0.24.0",
]
discord = [
"discord.py>=2.4.0",
]
feishu = [
"lark-oapi>=1.4.0",
"qrcode>=7.4.2",
]
matrix = [
"aiohttp>=3.14.3",
"matrix-nio[e2e]>=0.25.0",
"mistune>=3.0.0",
"nh3>=0.2.18",
]
mochat = [
"msgpack>=1.0.0",
"python-socketio[asyncio_client]>=5.11.0",
]
msteams = [
"cryptography>=50.0.0",
"PyJWT[crypto]>=2.8.0",
]
napcat = [
"aiohttp>=3.14.3",
"websockets>=12.0",
]
qq = [
"aiohttp>=3.14.3",
"qq-botpy>=1.2.0",
]
slack = [
"slack-sdk>=3.33.0",
"slackify-markdown>=0.2.4,<1",
]
telegram = [
"python-telegram-bot>=21.0",
]
wecom = [
"wecom-aibot-sdk>=1.0.0",
]
weixin = [
"qrcode>=7.4.2",
]
whatsapp = [
"neonize>=0.3.18.post0",
]
channels = [
"aiohttp>=3.14.3",
"cryptography>=50.0.0",
"dingtalk-stream>=0.24.0",
"discord.py>=2.4.0",
"lark-oapi>=1.4.0",
"matrix-nio[e2e]>=0.25.0",
"mistune>=3.0.0",
"msgpack>=1.0.0",
"neonize>=0.3.18.post0",
"nh3>=0.2.18",
"PyJWT[crypto]>=2.8.0",
"python-socketio[asyncio_client]>=5.11.0",
"python-telegram-bot>=21.0",
"qrcode>=7.4.2",
"qq-botpy>=1.2.0",
"slack-sdk>=3.33.0",
"slackify-markdown>=0.2.4,<1",
"websockets>=12.0",
"wecom-aibot-sdk>=1.0.0",
]
dev = [
"black>=24.0,<27",
"pytest>=7.0",
"pytest-cov>=4.0",
"pytest-socket>=0.7.0",
"ruff>=0.9,<1",
]
[tool.pytest.ini_options]
testpaths = ["agent/tests"]
pythonpath = ["agent"]
markers = [
"unit: Unit tests (fast, no network)",
"integration: Integration tests (may need network)",
]
[tool.ruff]
target-version = "py311"
line-length = 120
src = ["agent"]
[tool.coverage.run]
source = ["agent"]
omit = [
"agent/tests/*",
"agent/tests/**/*",
"agent/**/__init__.py",
]
[tool.coverage.report]
show_missing = true
skip_empty = true
fail_under = 0
exclude_also = [
"if __name__ == .__main__.",
"raise NotImplementedError",
"\\.\\.\\.",
]
[tool.ruff.lint]
select = ["E", "F", "W"]
ignore = ["E501"]
[tool.ruff.lint.per-file-ignores]
# Alpha zoo files import the full src.factors.base surface verbatim
# to match research-paper formulas. F401 (unused-import) is noise here;
# F841 (unused-local-variable) stays active to catch real formula bugs.
"agent/src/factors/zoo/**/*.py" = ["F401"]