QuantVibe
QuantVibe
Language: English | Español
Live Production Terminal: https://quantvibeapp.com

Uses Qlib as the quantitative brain and Vibe-Trading as the execution hands.
QuantVibe is an integration project connecting two independent quantitative finance tools without forking either:
Qlib (Microsoft) trains machine learning models on market data and produces stock rank scores.
Vibe-Trading (HKUDS) is an LLM-powered trading agent that consumes those scores via a read-only MCP server and acts on them (paper trading by default).
The bridge is ~600 lines of clean Python with zero heavy dependencies:
┌──────────── Qlib Side (Dedicated venv) ──────┐ ┌───── Vibe-Trading Side (Dedicated venv) ────┐
│ │ │ │
│ prepare_data OHLCV -> Qlib binary format │ │ LLM Agent (MCP Client) │
│ ↓ │ MCP │ ↓ │
│ train_model LGBModel (or demo fallback) │─────→│ get_latest_signals() │
│ ↓ │ stdio│ ↓ │
│ export_signals top-k + SHA-256 checksum │ │ execute_signals orders plan (paper) │
└──────────────────────────────────────────────┘ │ ↓ │
│ shadow account -> broker │
└──────────────────────────────────────────────┘The two systems never import each other: they communicate exclusively across an immutable signed contract (artifacts/signals.json, tamper-proofed with SHA-256 checksums) and a FastMCP stdio server. Each side runs in its own virtual environment to prevent dependency conflicts.
Features
One-command demo: Runs end-to-end without external services using synthetic trend data and a momentum fallback when pyqlib/yfinance are not installed.
Real mode: Downloads OHLCV data via yfinance -> converts with
qlib.scripts.dump_bin-> computes Alpha158 features -> trains LightGBM ranker -> outputs predictions.Signed signal contract: Schema validation, contiguous rank validation, finite score guarantees, and canonical JSON SHA-256 checksum verification. Any tampering is rejected.
Evaluation gate: Evaluates Spearman correlation (Information Coefficient), ICIR, and top-k hit-rate against forward returns before signals are published. Degraded signals are rejected.
SQLite track record: Every published signal is logged to
artifacts/track_record.dband settled against realized prices.statscommand reports real hit-rate and excess return.FastMCP server (
bridge/mcp_server.py): Exposes three read-only tools:get_latest_signals,list_universe, andsignal_health(freshness check).Guarded execution: By default,
execute_signals.pyonly outputs a dry-run order plan (orders_plan.json). Real broker order submission requires--submitand the explicit environment variableVIBE_ALLOW_ORDERS=1.MetaTrader 5 Native EA Bridge: Zero-copy IPC connection with
QuantVibe_Bridge.mq5for Forex, CFDs, and Prop Firms (FTMO, IC Markets, Darwinex) with sub-millisecond execution.Bloomberg Stream & Macro Intelligence: Real-time RSS streaming financial news with multi-universe monitoring (Mega-Cap Tech, Semiconductors AI, Crypto 24/7, Global Banking, Commodities).
One-Click Execution Desk: Hardware-style order desk with interactive capital sizing slider, automated lot calculation, and explainable AI feature attribution.
Data provenance: Tracks whether each symbol originated from yfinance or the synthetic generator via
manifest.json->signals.json.
Related MCP server: etfedge-mcp
Structure
config/pipeline.json universe, dates, train/valid/test splits, top_k, notional
config/mcp.vibe-trading.example.json MCP server registration config for Vibe-Trading agent
bridge/signal_store.py schema, validation, and SHA-256 checksums (pure Python)
bridge/mcp_server.py FastMCP stdio server (compatible with MCP SDK 1.x / FastMCP)
bridge/track_record.py historical SQLite signal ledger (log / settle / stats)
qlib_side/prepare_data.py yfinance (or synthetic) -> CSV -> Qlib binary format
qlib_side/train_model.py Qlib LGBModel; automatic DemoMomentum fallback
qlib_side/evaluate.py IC / ICIR / hit-rate evaluation + publication gate
qlib_side/export_signals.py predictions.csv -> gate evaluation -> verified signals.json
vibe_side/execute_signals.py signals -> equal-weight plan; double-guarded execution
web/api.py FastAPI REST API, SSE streaming, and static SPA mounting
web/server.py production web runner
web/static/ compiled production frontend assets
web/frontend/ React 19 + TypeScript + Tailwind + Framer Motion
scripts/connectors/QuantVibe_Bridge.mq5 MQL5 native Expert Advisor for MetaTrader 5
scripts/connectors/broker_mt5.py MT5 IPC connector and trade dispatcher
scripts/connectors/broker_alpaca.py Alpaca Markets US Equities connector
scripts/start_web.py one-command web launcher (single port: 8000 or 80)
scripts/run_pipeline.py end-to-end orchestrator across isolated venvs
scripts/setup.ps1 sets up venvs\qlib and venvs\vibe and installs dependencies
Dockerfile Python 3.11 container with pyqlib; runs tests on buildGenerated artifacts:
artifacts/signals.json— signed top-k signals consumed by the MCP agentartifacts/orders_plan.json— equal-weight paper trading order plan (dry_run: true)artifacts/track_record.db— SQLite historical ledger measuring real hit-ratedata/raw/*.csv— OHLCV per symbol with provenance inmanifest.json
Pipeline steps: prepare -> settle -> train -> export -> execute.
The settle step settles historical signals from previous dates using newly available prices.
Web Interface and Terminal (Local, Codespaces & Cloud VPS)
QuantVibe includes a modern fintech terminal web interface built with FastAPI, React 19, TypeScript, and Tailwind CSS. It is designed to run locally, on GitHub Codespaces, or on a cloud VPS using a single unified port (default 8000, or port 80).
Launching the Web Interface
# 1. Install lightweight web dependencies
pip install -r requirements-web.txt
# 2. Launch web server (listens on 0.0.0.0:8000)
python scripts/start_web.pyLocal / Codespaces URL:
http://localhost:8000Interactive Swagger Docs:
http://localhost:8000/docs
Interface Features
Dashboard & Quality Gate: Real-time visual traffic light of model verdict (Spearman IC, ICIR, hit-rate), SHA-256 cryptographic verification status, and interactive Top-$k$ signal table.
Interactive Pipeline Launcher: Mode selector (Demo vs Full Qlib), granular phase triggers, and real-time streaming console output via Server-Sent Events (SSE).
Execution Desk & Guardrails: Visualizer for
orders_plan.json, portfolio exposure breakdown, and a hardware-style safety switch toggling Paper Trading vs real order dispatch (VIBE_ALLOW_ORDERS=1).Track Record & Audit: Historical performance settled in SQLite (
artifacts/track_record.db), hit-rate metrics, and excess return vs universe benchmark.Architecture & MCP Inspector: Status monitor for FastMCP stdio server and indexed knowledge graphs.
MetaTrader 5 Native Bridge: One-click trade dispatcher, broker latency diagnostics, automatic lot recalculation, and EA download installer.
Bloomberg Terminal & Live Market Stream: Live financial news streaming, sentiment analysis, TradingView global quotes tape, and multi-asset universe screeners.
Frontend Development
The frontend source lives in web/frontend/ and compiles to static files in web/static/:
cd web/frontend
pnpm install
pnpm build # builds production assets to web/static/
pnpm dev # Vite dev server on port 5173 with proxy to FastAPI :8000Evaluation Gate and Track Record
Before signals are published, export evaluates the model: Spearman rank correlation (IC) between model scores and realized forward returns per date, ICIR (IC / volatility of IC), and top-k hit-rate. Thresholds are defined in config/pipeline.json -> evaluation.gate. If the model fails validation, signals are blocked (--force bypasses if needed).
To inspect realized performance over time:
python -m bridge.track_record stats # hit-rate, mean return, excess vs universe
python -m bridge.track_record settle # settles pending records with new market pricesFull Setup (Real Data + Real Model)
powershell -ExecutionPolicy Bypass -File scripts/setup.ps1
python scripts/run_pipeline.pyvenv | Packages | Python Version |
|
| 3.10–3.12 required (pyqlib does not build on 3.13+) |
|
| 3.11+ |
Without a compatible interpreter for Qlib, the pipeline falls back to demo mode automatically — output indicates which mode ran.
Docker (Alternative to venvs)
Solves Python version differences: the Docker image runs Python 3.11 with pyqlib preinstalled, running the test suite during build.
docker compose build # builds image and runs tests
docker compose run --rm pipeline # full pipeline with real data/model
docker compose up -d signals-mcp # MCP server over SSE on http://localhost:8000/sseA prebuilt image is also published to GitHub Container Registry with every commit to main:
docker pull ghcr.io/ax3lsk3r3/quantvibe:latest
docker run --rm -v ./data:/app/data -v ./artifacts:/app/artifacts ghcr.io/ax3lsk3r3/quantvibe:latest python scripts/run_pipeline.py --force-demoMount ./data and ./artifacts as volumes so signals, plans, and the track record database persist on your local filesystem.
Running in Production (24/7 Service)
QuantVibe can run as a background service on any Linux, macOS, or Windows host:
git clone https://github.com/Ax3lsk3r3/QuantVibe.git
cd QuantVibe
python3 -m venv venv && source venv/bin/activate
pip install -r requirements-web.txt
python scripts/run_pipeline.py --force-demo
nohup python scripts/start_web.py --port 8000 > web.log 2>&1 &Connecting the Vibe-Trading Agent
Register the MCP server (example in config/mcp.vibe-trading.example.json; verify tool names against your Vibe-Trading installation):
{
"mcpServers": {
"quantvibe-signals": {
"command": "python",
"args": ["-m", "bridge.mcp_server"],
"cwd": "<path-to-this-repo>"
}
}
}Recommended agent workflow:
signal_health— verify signals are fresh (< N hours old).get_latest_signals— inspect rankings and scores; reason about news, risk, and position sizing.Output or execute only the reviewed orders plan.
Live Trading (When Ready)
By design, no order ever reaches a broker implicitly:
# Windows PowerShell
$env:VIBE_ALLOW_ORDERS = "1"
python -m vibe_side.execute_signals --submit --order-cmd-template "<broker CLI> {symbol} {qty}"
# Linux / macOS
export VIBE_ALLOW_ORDERS=1
python -m vibe_side.execute_signals --submit --order-cmd-template "<broker CLI> {symbol} {qty}"If either the --submit flag or the environment variable is missing, execution exits with code 2 and zero orders are placed. Start with Vibe-Trading paper trading accounts before deploying capital.
Signals Payload Format
{
"schema_version": 1,
"generated_at": "2026-08-23T19:33:05+00:00",
"source_model": "LGBModel", // or DemoMomentum
"as_of": "2026-08-21",
"horizon_days": 1,
"universe": ["AAPL", "..."],
"signals": [
{ "instrument": "AAPL", "score": 0.109, "rank": 1 }
],
"metadata": { "data_source": "yfinance", "top_k": 5, "test_window": ["...", "..."] },
"checksum": "sha256 canonical JSON hash" // verified by consumers before loading
}Troubleshooting
pyqlibinstallation fails: You are using Python 3.13 or 3.14. Create the venv using Python 3.10-3.12 (py -3.12).No MCP server runtime found: In the environment executing the MCP server:pip install "mcp>=1.2,<2"orpip install fastmcp.yfinance rate limits: Affected symbols fall back to synthetic data marked in
manifest.json. Deletedata/rawand retry later.
Community
Discussions — architecture and quantitative strategy discussions
Contributing — bug reports and pull requests
Security — vulnerability disclosure policy
Issues — issue templates
Star History
Legal Notice and Disclaimer
This software is provided strictly for educational, experimental, and technical research purposes. None of the modules, code, signals, metrics, or analysis generated by this system constitute financial, investment, legal, or tax advice.
Predictive Modeling Risk: Scores and rankings produced by machine learning models are statistical estimates based on historical data. They do not guarantee future returns or operational certainty.
Overfitting: Backtesting results carry inherent historical fit biases and do not accurately reflect real-world market liquidity, spreads, execution slippage, commissions, or live volatility.
Language Model (LLM) Behavior: Decisions generated by LLM-based agents can exhibit hallucinations, contextual bias, or faulty reasoning regarding market dynamics.
Simulation Only: Users are advised to operate solely within paper trading accounts and zero-risk simulators. Any live capital deployment is the sole and exclusive responsibility of the user.
License
Distributed under the MIT License.
Available Tools
3 toolsget_latest_signalsA
Retrieve the latest quantitative stock selection signals produced by the Qlib ML pipeline.
Use this tool before making any trading or allocation decisions. Signals are ranked
cross-sectionally with higher scores indicating higher predicted relative returns.
Parameters:
top_n: Number of top-ranked instruments to return. Default is 0, which returns
all ranked instruments in the universe. Must be >= 0.
Returns:
A dictionary containing:
- as_of: Effective date of the signals (YYYY-MM-DD).
- generated_at: UTC timestamp when the signals were generated.
- source_model: Name of the model architecture (e.g. LightGBM, Alpha158).
- data_source: Underlying market data feed.
- horizon_days: Prediction horizon in trading days.
- checksum: SHA-256 integrity checksum of the signals payload.
- signals: List of ranked instruments with rank (1..N), symbol, and score.
| Name | Required | Description | Default |
|---|---|---|---|
| top_n | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full disclosure burden and meets it: it explains the ranking semantics ('higher scores indicating higher predicted relative returns'), the top_n=0 default behavior, and enumerates the exact return payload including checksum and timestamps. This goes well beyond a mere 'getter' statement.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well organized into purpose, usage, parameter, and return sections. It is detailed but each sentence adds information; nothing is filler or repetitive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-optional-parameter read tool, the description covers when to use it, what the data represents, how ranking works, and the complete return schema. There is no obvious missing context an agent would need to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description fully compensates by defining top_n's meaning, its default, the 'all instruments' behavior when 0, and the required non-negativity constraint. No parameter ambiguity remains.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb ('Retrieve'), a specific resource ('latest quantitative stock selection signals produced by the Qlib ML pipeline'), and clarifies that scores are cross-sectionally ranked. It does not explicitly differentiate from sibling tools list_universe and signal_health, so it stops just short of a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The phrase 'Use this tool before making any trading or allocation decisions' gives a clear, explicit use case. However, it does not mention when not to use it or contrast it with signal_health/list_universe, so exclusions and alternatives are absent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_universeA
List all stock tickers tracked by the quantitative research and signal generation pipeline.
Use this tool to inspect the active universe of assets covered by QuantVibe before querying
specific signals or checking market coverage.
Returns:
A dictionary containing:
- universe: Sorted list of ticker symbols (e.g. ['AAPL', 'MSFT', 'NVDA']).
- count: Total number of instruments in the universe.
- as_of: Effective date of the asset universe configuration (YYYY-MM-DD).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden; it clarifies this is a read-only listing operation and documents the exact return contract: universe, count, and as_of. It does not disclose edge-case behavior such as empty-universe handling or data freshness beyond the as_of field, but that is minor for a no-argument list tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact, front-loaded with the primary action, and uses a short Returns section that adds concrete structure without bloat. Every sentence contributes to selection or invocation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-argument, simple read tool, the description covers purpose, usage timing, and return semantics. Although an output schema is reportedly present, the description still provides enough detail for an agent to invoke and interpret the result without opening it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so there is nothing for the description to clarify. The baseline of 4 applies, and the description adds no irrelevant parameter noise.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb and resource: 'List all stock tickers tracked by the quantitative research and signal generation pipeline.' It clearly scopes the tool to universe inventory rather than signal generation or health, distinguishing it from get_latest_signals and signal_health.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
States when to use it: 'before querying specific signals or checking market coverage,' which positions it relative to the sibling signal tools. It does not explicitly name the alternative tools or state a when-not-to-use rule, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
signal_healthA
Check the health, integrity, and staleness of the quantitative signals artifact.
Use this tool for system monitoring and sanity checks before consuming signals in automated workflows.
Verifies that the signals file exists, the SHA-256 checksum is valid, and the data is within acceptable age.
Parameters:
max_age_hours: Maximum allowable signal age in hours before considering data stale.
Default is 24.0 hours.
Returns:
A dictionary containing:
- ok: Boolean indicating if the signals file is healthy and fresh.
- age_hours: Current age of the signals in hours since generation.
- max_age_hours: The freshness threshold applied.
- path: Path to the signals file on disk.
- source_model: Model that generated the signals.
- n_signals: Number of valid signals in the payload.
- as_of: Market date of the signals.
| Name | Required | Description | Default |
|---|---|---|---|
| max_age_hours | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It discloses what the tool verifies—file existence, checksum validity, and acceptable age—and describes the returned health details. The read-only nature is implied by 'check' and 'verifies' rather than stated explicitly, so it is strong but not perfect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well organized: lead purpose, usage context, verification details, parameter semantics, and return fields. It is somewhat verbose because it documents return fields even though an output schema exists, but every section adds useful context.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter and no annotations, the description is complete. It covers when to use the tool, what it verifies, the parameter meaning, and the full return payload, so an agent has everything needed to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides only a bare number with no description (0% coverage). The description fully compensates by defining max_age_hours as the maximum allowable signal age before data is considered stale and by noting the default of 24.0 hours.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: checking the health, integrity, and staleness of the signals artifact. It then lists concrete checks (file existence, SHA-256 checksum, age) and positions the tool as a monitoring/sanity-check operation, which distinguishes it from the sibling tools that retrieve signals or list the universe.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly states when to use the tool: for system monitoring and sanity checks before consuming signals in automated workflows. It does not name alternatives or exclusion conditions, but the intended use is clear enough to guide selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v0.1.0- First observed
get_latest_signals - First observed
list_universe - First observed
signal_health
TDQS
Scored across 3 tools
Each tool serves a clearly distinct purpose: retrieving signals, listing the universe, and checking signal health. No overlap or ambiguity between them.
Two tools follow the verb_noun pattern (get_latest_signals, list_universe) while signal_health is a noun-based name. Minor inconsistency but still readable and predictable.
With 3 tools, the server is right at the lower bound of the well-scoped range. Each tool earns its place and covers the core read-only quant signal workflow.
The surface covers latest signals, universe, and health checks. Missing historical signal retrieval or per-symbol queries are minor gaps that can be worked around by filtering the full list.
Maintenance
Related MCP Connectors
Read-only MCP server for The Quiet Protocol's engines, benchmarks, proof, and business data.
7-factor stock scoring MCP server. US/HK/CN, 74 stocks. Free + Premium (USDC/Base). x402 ready.
MCP server giving AI agents one-connection access to China A-share market intelligence: financials,
Research-only MCP server: your AI as a quant research desk. 90 tools, no trades, no brokers.
Related MCP Servers
- -licenseNot gradedqualityNot gradedmaintenanceReal-time financial market data MCP server. Stocks, crypto, technicals, sentiment, FDA calendar. No API keys required.-
- FlicenseNot gradedqualityBmaintenanceRead-only MCP server for Taiwan active ETF research database, providing tools to list ETFs, track buy/sell deltas, view stock history and PnL, and find consensus buys across ETFs.5-

Haruspexofficial
AlicenseNot gradedqualityBmaintenanceMCP server exposing the Haruspex stock-analysis API, headline scores (0-100), score history, batched watchlist scores, stock search, and recent news for US-listed1MIT- AlicenseAqualityCmaintenanceRead-only MCP server for large-scale cross-sectional quant analysis of US stock market data (1.49 billion rows) using ClickHouse.7MIT