Vibe-Trading — measuring a 33,000-star head-on competitor side by side with weltiq

One strategy, run on both HKUDS/Vibe-Trading and a weltiq paper account, with the same items measured on each. Why its external connectors are read-only, and wh

Part 17. Vibe-Trading — putting a head-on competitor alongside weltiq and giving both the same job

Done when: you have run one identical rule on both HKUDS/Vibe-Trading and weltiq and put the bar count, fill count, round-trip count, realized P&L and total fees side by side.

What it does Tell it in plain language and it writes the strategy code itself, runs the backtest on its own engine, and produces a dashboard with a tear sheet and charts. It carries 18 broker connectors, 90 skills and 16 messenger integrations
Who it fits Anyone whose idea is still a sentence and who needs help turning it into a rule · anyone who wants data from several markets in one place with no keys · anyone who already has a broker account
Who it doesn't fit Anyone who wants to place an order before creating a broker account (all 13 order-capable paper profiles require an account) · anyone for whom LLM cost is a concern (one backtest is dozens of calls)
What you end up with A measured side-by-side of the same rule on both, a reproducibility check of both backtests, and the weltiq ledger loaded read-only into the other side's portfolio
What you need · cost Code free (MIT) · Model required — the one comparison run here was 27 calls · 1.51M tokens · under $1 · no broker account (which is why the other side's orders could not be placed)
Time · difficulty 5.2s clone + 49.8s install. 17 minutes 49 seconds for the one comparison run. Difficulty medium
Relationship to weltiq It does exactly the same job head-on. So section 5 is not "how to connect" but why an honest "use them together" exercise does not come out, and section 6 is a chooser by use case
Test environment · date macOS 26.6.2 · arm64 · CPython 3.14.7 · PyPI vibe-trading-ai 0.1.15 · 2026-09-22 01:45–03:25 KST
Disclosure weltiq pays me to write this series. Everything said about the tool comes from runs I did myself

The human sentences are the commands I actually typed, rewritten as conversation. The output is measured and the numbers are untouched. I created no broker account and no exchange account — order execution on the HKUDS/Vibe-Trading side all requires a broker account, so I could not do it, and I say so. The only place an order actually went out is weltiq paper. This article recommends no strategy and does not say which tool is better overall — only which side is ahead on which axis. The raw logs are in the verification record.


1. What this is

HKUDS/Vibe-Trading is a natural-language financial research and backtesting agent out of the Data Intelligence Lab at the University of Hong Kong (HKUDS). Write "backtest this rule" and it writes the strategy code itself, runs it on its own engine, and produces a dashboard with a tear sheet and charts.

Item Value How it was checked
URL github.com/HKUDS/Vibe-Trading
License MIT GitHub API
Stars ★33,780 · 5,511 forks (observed 2026-09-22) GitHub API
Last push 2026-09-21T12:54:29Z (yesterday) GitHub API
Created 2026-04-01 · 28 open issues · not archived GitHub API
Version PyPI vibe-trading-ai 0.1.15 vibe-trading --version
Python declares 3.11+, classifiers stop at 3.13. Installed and ran on 3.14.7 this article's environment
Skills · connectors 90 skills · 18 broker connectors, 55 profiles --skills · BUILTIN_PROFILES

The README alone is 317,515 bytes, translated into seven languages including Korean.

The overlapping sentence is this — "paper and live are separated structurally, not by a config value." weltiq says it and so does the other side. That makes a head-on comparison honest. I took the 55 connector profiles apart and counted.

built-in profiles: 55   connectors: 18
alpaca, binance, dhan, etoro, futu, ibkr, kis, longbridge, mt5, okx,
robinhood, scalable, shoonya, tiger, toss, trading212, upbit, zerodha
order-capable profiles: 21     paper: 28   live: 27     paper AND order-capable: 13

Thirteen paper profiles can actually place orders — Alpaca Paper, Binance Paper, OKX Paper, KIS Paper, Upbit Paper, Tiger Paper. Korean brokers (KIS, Toss) and Upbit are already on the list. But all thirteen need that broker's account and API key.

$ vibe-trading connector use alpaca-paper-trade && vibe-trading connector check
  Connector alpaca · Environment paper · Transport broker_sdk · alpaca-py missing
Alpaca connector not configured: missing api_key, secret_key.

Since this article created no accounts, not one of the other side's order paths was run. That is the biggest hole in this comparison, and section 6 records exactly where the blanks are.


2. Installing

Warning — this tool costs money. One backtest is dozens of LLM calls. The single comparison run in this article used deepseek/deepseek-v4-pro for 27 calls · 1,464,686 input tokens (1,307,013 of them cache hits) · 45,717 output tokens · 1,510,403 total. Those are the tool's own figures from llm_usage.json. In money it stayed under $1, and the reason I do not pin the dollar figure to the last digit is at the end of section 7. Local models through Ollama cost nothing, but the README itself notes that small models are unreliable at tool calling.

One PyPI line (pip install vibe-trading-ai) works, but I cloned the repository because I needed to read the code.

git clone --depth 1 https://github.com/HKUDS/Vibe-Trading.git && cd Vibe-Trading
python3 -m venv .venv314 && ./.venv314/bin/pip install -e .

The clone took 5.2 seconds (118MB) and the install 49.8 seconds (with a warm pip cache). It pulls 178 packages — langchain, langgraph, ccxt, akshare, tushare, yfinance, scikit-learn, weasyprint and matplotlib are all in there.

Installation finished

From clone to version output. Two lines to look at — vibe-trading 0.1.15 means the install is done, and Python 3.14.7 means it installed on a version this project does not list in its official classifiers.

The LLM key goes in agent/.env — LANGCHAIN_PROVIDER=openrouter, OPENROUTER_API_KEY=sk-or-..., LANGCHAIN_MODEL_NAME=deepseek/deepseek-v4-pro.

Where it gets stuck

Symptom Cause Fix
Worried pip install -e . will break on 3.14 3.14 is not in the classifiers It just worked here. All 178 had wheels
Not sure where the executable is There are three commands vibe-trading (TUI) · vibe-trading serve (web) · vibe-trading-mcp (MCP)
Not sure where the config files pile up Default is ~/.vibe-trading Move it with VIBE_TRADING_HOME
The backtest refuses with "run_dir outside allowed roots" The run directory is whitelisted Add it to VIBE_TRADING_ALLOWED_RUN_ROOTS. A safeguard, not a bug

3. The first result — and how to bring up the dashboard

One CLI line is the smallest example.

./.venv314/bin/vibe-trading run -p "Backtest a BTC-USDT 20/50 moving-average strategy and summarize return and drawdown"

This is what it looks like when it works. A preflight table comes up first (LLM connection, OKX, yfinance, akshare and ccxt each OK or N/A, with a line like 6/7 services ready), and then the tool calls stream past one line at a time: load_skill(...) → write_file code/signal_engine.py → backtest ....

The defining screen is the dashboard rather than the terminal. From a repository checkout you have to build the frontend first (install 2.5s + build 5.7s).

cd frontend && npm install && npm run build && cd ..     # Node 22+
./.venv314/bin/vibe-trading serve --port 9101            # this is the line that brings up the dashboard

You go to http://localhost:9101; the default port is 8899. Opened on the same machine there is no login and no key. To view it from another device you put an API_AUTH_KEY in agent/.env and enter the same key once in Settings; without that, sensitive endpoints return 403. Every screen is visible, but LLM charges start the moment you run the agent.

The first screen

Right after vibe-trading serve --port 9101. Look at the left sidebar — Agent, Runtime, Scheduled, Reports, Portfolio, Alpha Zoo, Options Lab, Correlation Matrix. On first open there is only Agent; the useful screens appear after you run something. So the first thing to press is the input box in the middle.

There are two roads to a useful screen. Put one prompt into Agent (this costs money) and that run gets a whole set of dashboard, chart, tear sheet, Trades and Run Card tabs. Open Alpha Zoo and you get a list of 462 pre-built alphas without calling an LLM once.

Alpha Zoo

A screen that opens with no LLM call. Look at the size of the list — registered alphas can also be benchmarked from the CLI with vibe-trading alpha bench --zoo ... --universe btc-usdt, and that path skips the agent so it carries no charge.


4. The best way to use it — the same job on both sides

Nail down the conditions first. Change them afterwards and this article becomes an advertisement.

Fixed Value
Strategy 20/60 simple moving-average golden cross entry → 3% stop, 6% take profit
Instrument · timeframe BTC/USDT spot · 1-hour bars
Period 2026-06-24 02:00 to 2026-09-21 16:00 (KST)
Size · fee 0.01 BTC fixed, one position at a time · 0.1% taker, both sides
Measured bars · fills · round trips · realized P&L · total fees · does it give the raw fills · is it the same run twice

I chose this strategy because both sides have it. weltiq's stock template TPL-005 (golden-cross trend) is exactly this rule and is on the free tier. The other side got the same rule as one plain-language paragraph (verbatim in the verification record).

The other side's result — back after 17 minutes 49 seconds.

Status: SUCCESS   Elapsed: 17m 49s   Run ID: 20260922_015121_68_3A0E89
Reason: final answer released with unverified figures redacted after 3 rejected drafts
Metrics: return=0.0010, sharpe=2.8231, max_dd=-0.0007, trades=4.0000

From one plain-language paragraph it wrote the strategy code (signal_engine.py) itself, ran it on its own engine, and found 4 round trips. It took dozens of tool calls, 17 minutes 49 seconds and $0.987102, and it re-ran the backtest three times along the way while adjusting the configuration. And although I asked for five numbers, most of the cells came back (omitted) — why is below.

The Vibe-Trading research dashboard

The other side, given the same job. Look at the metric strip at the top — TRADES 4, WIN RATE +75.00%, and at the far right AVG HOLD DAYS 300.5. A three-month backtest cannot have an average hold of 300 days. The card below states the data source as okx and the engine as DAILY engine — I asked for 1-hour bars and the engine label says daily.

The fill list

The Trades tab of the same run. Three columns to look at — QTY at 0.009995–0.010001 (the requested 0.01 went in correctly), REASON at the far right showing signal ×7 and end_of_backtest ×1 (the last one was not a stop or a target but a forced close because the period ended), and at the top 8 trades Buy 4 · Sell 4 Total P&L +121.29. The weltiq screen has no equivalent of that REASON column.**

The candle chart with entries and exits marked

The Chart tab. Look at the eight pins on the candles — green B for buys, red S for sells. Which bar it went in and out on is visible at a glance. weltiq has no such screen — to see the same information you read the fill table and pull up the candles separately. The metric strip at the top is the same run as the previous screenshot, so the numbers match.

The artifacts land on disk as they are — trades.csv, fills.jsonl, equity.csv, positions.csv, metrics.csv, risk_xray.json, ohlcv_BTC-USDT.csv, code/signal_engine.py, config.json, run_card.md. And run_card.md carries config_hash, strategy_hash and the sha256 of all twelve artifacts. This is something the other side does very well.

The weltiq result — the same rule over binance-spot BTCUSDT 1-hour bars, 2160 hours.

{ "run_id": "bt_31eb97f8e955c4a7", "n_bars": 2151, "n_fills": 9,
  "pnl": "114.13547620000", "fees": "6.16770728", "n_trades": 4,
  "execution_assumptions": ["bar_close_modeled_spread"], "data_mode": "idealized" }

2,151 bars, 9 fills, 4 round trips, realized P&L 114.13547620 USDT, fees 6.16770728 USDT. Running it twice gave identical numbers, with only the run_id differing. The time, price, fee and liquidity flag of all nine fills stay in the ledger, and the ninth is a buy that has not closed, which is why there are 4 round trips.

Side by side

Measured Vibe-Trading weltiq
Candle source OKX (chosen automatically) Binance (the venue requested)
Bars in the artifacts, but redacted from the answer 2151
Round trips 4 4
Fills 8 (last one force-closed) 9 (last buy left open)
Size (0.01 requested) 0.009993 – 0.010001 (after adjusting the capital figure three times) 0.01 (as declared)
Exit reason recorded signal ×3, end_of_backtest ×1 No
End-of-period handling force close leaves the position open
Realized P&L +121.2863 USDT +114.1355 USDT
Total fees 2.0298 USDT (effective 0.05% in · 0.02% out) 6.16770728 USDT (effective 0.1000% on all)
Did the requested fee apply No (0.1% both sides was requested) Yes
Run it twice engine identical · agent not guaranteed identical
Artifacts 12 CSV/JSONL files + sha256 REST response + ledger SQL
Time · cost 17 min 49 s · 27 LLM calls · 1.51M tokens one curl · 0 LLM calls

The round-trip count is 4 on both. Different exchange candles and different engines, and the same rule found the same number of trades — which means both sides' signal computation is at least looking at the same thing over this window.

Do not read the P&L numbers (121.29 vs 114.14) as better or worse. They are not on the same basis — the candle source differs (OKX vs Binance), the other side force-closed at the end of the period and realized +42.36 from the last leg while weltiq finished with it open, and fees are 2.03 there against 6.17 here. The fee gap alone is 4.14, more than half of the 7.15 P&L gap. This is not a performance comparison; it is an instrument comparison.

And building that table turned up a hole on weltiq's side. Buy orders carry "signal": "golden_cross", but sell orders carry no reason at all. So whether the 06-30 sell was a stop or a target cannot be read from the record; you have to divide the prices yourself (60594 → 58406 is −3.6%, which looks like a stop — but that is inference, not record). The other side hands you this through the reason column in trades.csv and a by_exit_reason aggregate. The other side is ahead on this axis.

Is it the same run twice — a draw

Feeding the other side's engine the same config.json and the same signal_engine.py twice produced identical sha256 for trades.csv, equity.csv, metrics.csv and fills.jsonl. Its backtest engine is deterministic.

The agent loop is another matter. The same prompt carries no guarantee that the LLM writes the same signal_engine.py, and within this single run it re-ran three times while changing the configuration. "The engine is deterministic" and "asking the tool gives the same answer" are different statements. weltiq's structure fixes the strategy document first and has the engine read it, so the execution path has no such layer — there is a place where natural language is formalized into a document, but what comes out is a declarative document rather than arbitrary Python. The other side generates code, so the range of expressible rules is far wider, and in exchange a human has to check that code on every run.

Four places where they diverged

One. It took three backtests to land "0.01 BTC fixed." The other side's engine sizes positions by weight, not quantity, so there is no field for "0.01 BTC fixed" and the LLM translated it as weight = POSITION_BTC * close.iloc[i] / INITIAL_CASH. For that code to behave as intended, initial_cash in config.json has to equal INITIAL_CASH in the code — and the agent hunted for that value three times: 1,000 → 10,000,000 (size came out around 1.0 BTC, 100x the target) → 100,000 (size 0.009993–0.010001). The 100x came out on the second attempt, and the agent caught it itself and fixed it on the third.

Correction. Writing this, I nearly misread the second run's intermediate artifacts as the final ones and wrote "the size went out 100x and nobody caught it." I found it while re-taking the screenshots and seeing 0.01 on screen. The one who was wrong was me, not the tool. I leave this paragraph in rather than deleting it.

The real thing to read is here — to put "fixed quantity" into a weight-based engine you have to route around it through the capital figure, and landing that figure cost 3 backtests, 27 LLM calls and 17 minutes 49 seconds. On weltiq it is one line, "sizing": {"qty": "0.01"}, and it lands first time. In exchange weltiq cannot do weight-based sizing at all. Neither is better; they are different axes.

Two. The fee I specified did not apply. I nailed 0.1% taker on both sides, and dividing the actual fees by the notional split them apart.

Vibe-Trading (artifacts/fills.jsonl · all 8)
  open   notional=644.7138  fee=0.3224  ->  0.0500%
  close  notional=624.6759  fee=0.1249  ->  0.0200%
  ...                                        (identical across all 8)   total 2.0298 USDT
weltiq (all 9 ledger rows)
  notional=605.9442  fee=0.60594419  ->  0.1000%
  notional=816.4807  fee=0.81648074  ->  0.1000%                        total 6.16770728 USDT

0.05% on entry and 0.02% on exit. All eight rows carry those two values with no exception, so it is a rule rather than a slip — but that rule differs from the commission: 0.001 I put in config.json. Why it comes out that way was not determined in this article — the crypto default rate may override it, or the commission may be split across the two sides. The point to take is this. If you specify a fee and a different one is applied, that backtest's P&L is not the answer to the question you asked.

The weltiq fill history screen

weltiq's fill history. Look at the Fee column — 0.858 on 0.01 @ 85,795.15, 0.086 on 0.001 @ 85,860.28. Exactly 0.1% throughout. And the same screen shows a weltiq bug — Turnover in the summary is empty and Effective rate reads NaN %. This account has USD and USDT fills mixed together so they cannot be summed, and instead of an error it puts NaN straight on screen. Printed as it is, not hidden.*

Three. The evidence guard erased the answer — and this is an axis where the other side is ahead. All five requested numbers (bars, fills, round trips, realized P&L, total fees) came back (omitted), with this at the bottom.

54 figure(s) that could not be matched to this session's tool data were omitted. Observed OHLC range: BTC-USDT: 80857.6–86351.4 USDT (source: okx; currency conversion: none).

This tool erases from its answer any number it cannot match against this session's tool output. It rejected three of its own drafts and only released an answer after redacting the 54 figures it still could not match. Against the problem of an LLM inventing plausible numbers, weltiq has no such layer at all. It also produces false positives — the bar count and fill count are sitting perfectly well inside artifacts/ and were redacted anyway, and the "~0.01 BTC" case above shows that it checks numbers but not sentences. The precise assessment: a good layer, not yet a fine-meshed one.

Four. avg_holding_days: 300.5. A three-month backtest reporting an average hold of 300 days. The holding_bars in trades.csv are 151, 407, 635 and 9, averaging exactly 300.5 — it averaged the bar count and labelled it "days." It looks like the same root as putting in 1-hour bars and getting an engine label of daily. The holding_days column itself is correctly 6, 16 and 26, so only the summary-metric step went wrong.

The columns only weltiq ran — orders, unattended execution, recovery

The other side could not run these three. All 13 order-capable profiles require a broker account and this article created none. That is not a blank but "it would work with an account and I did not make one."

On the weltiq side the limit approval blocks you first — {"code":"envelope_required","detail":"no order-limit approval permits this symbol"}. And that limit cannot be created with an API key; only a browser session (a person) can. After creating it, the round trip came back filled in 53ms on the buy and 54ms on the sell. An autonomous agent cannot widen its own limits — that is where "the human draws the boundary" exists as code.

The loop was only half closed. Analysis → order → fill confirmation is exactly as below, but the step of reading the record, revising the rule and reordering was not done. This part's subject is comparison, so I kept to one container, and at the time of writing changing the rule meant bringing up a new one.

Since then (2026-09-23): a maintenance path exists. You swap only the strategy on a stopped container — the container, the simulated capital and the P&L so far all carry over (stop → replace → restart). Redoing this experiment today, the loop could be closed inside one container.

I brought up one unattended container. To make an entry signal likely I cut the moving averages to 2/3, and set the stop conditions to −0.5 USDT daily P&L and a 1-hour run limit. The stop condition is a required field, not an option — leave it out and nothing comes up. And what it is doing stays in the record as a state machine.

02:12:13 started → 02:12:19 warmup → 02:13:09 entry_blocked (reason=short_not_supported)
→ 02:14:10 no_signal → 02:20:00 order_pending → 02:21:00 holding

At 02:20:00 a golden_cross signal filled 0.01 BTC at 85795.14865650, with a fee of 0.85795149 USDT deducted from the ledger. At the same moment a stop-loss sell is placed alongside as a stop_market — the boundary stands before anyone is watching.

The weltiq container detail

weltiq at the same moment. Three places — the status line reading Holding — watching exit conditions, the ORDERS row sell (close) / stop_market / acked (the stop placed at the moment of entry), and Auto-stop −0.5 · 9/22, 03:12 AM at the far right. All three keep running with the agent switched off.

Of the two conditions set, the run limit arrived first: stopping at 03:12:41, stopped at 03:13:27. autostop {"reason":"expired","daily_pnl":"1.7125384300","position_kept":false} — it closed the position as it stopped, and the fills filled out into a round trip (02:20:00 buy 0.01 @ 85795.14865650 fee 0.85795149 / 03:13:00 sell 0.01 @ 85966.40249950 fee 0.85966402).

And here I found a problem on weltiq's side. The daily_pnl of 1.7125384300 in the log is (85966.40249950 − 85795.14865650) × 0.01 — the figure before fees. The fees actually deducted from the ledger come to 1.71761551 across the two rows, so with fees included this round trip is −0.00507708, very slightly negative. The code is pnl = sign * (px - pos.entry_px) * qty * mult, with no fees in it. So stop_max_loss judges on the price difference rather than the loss after fees.

That defect, though, is not why this run failed to hit the loss condition. The net P&L including fees, −0.00507708, is nowhere near the −0.5 threshold I set. Even with fees properly deducted, this round trip was never in a position to fire. The defect shows up in the case where a fee-driven loss reaches the threshold, and the more frequently a strategy trades the sooner it gets there. The time condition's firing was actually observed; the loss condition's firing is unverified.

Disconnect and reconnect was only partly done. Restarting the engine process is prohibited in this environment, so instead I restarted a stopped container. The API explicitly returns what carries over — previous_stop_reasons: ["expired"], previous_cumulative_pnl: "1.7125384300", cumulative_pnl: "reset_to_zero", daily_pnl: "kept_if_same_trading_day", positions_carried: []. It writes out in the resume response, as strings, what is kept and what is reset — no guessing needed. Recovery across an engine process restart is unverified in this article. Once the checks were done this container was stopped and deleted.


5. Read-only connectors — why "use them together" does not work

I think this section is the most practically useful thing here for a reader.

HKUDS/Vibe-Trading lets users build and plug in their own connector (a connector.json plus an adapter.py). So I built a weltiq connector, added one orders.write line to capabilities, and validated it.

A write manifest rejected

Look at the two red lines. Declare a write capability and it is rejected with read capabilities only; drop the readonly flag to false alone and it is rejected with must be read-only. Only reverting to read-only passes.

It is in the code too — agent/src/trading/local_plugins.py requires _REQUIRED_CAPABILITIES = {"account.read", "positions.read"} and rejects anything outside _ALLOWED_CAPABILITIES with local connector plugins may declare read capabilities only. The README's line holds exactly — "A manifest declaring any write capability is rejected."

This is not a bad decision. Refusing to give order authority to somebody else's code is the defensively correct choice. But the consequence is that the door for weltiq to enter that execution layer is locked.

Does MCP work — yes, but you pass through a gate. You can pull an external MCP server's tools into its own registry, but broker-ish servers are treated differently. The classification is a three-rung ladder — (1) readOnlyHint, (2) a maintainer-curated tool-name map (the map wins, and a false readOnlyHint cannot demote a WRITE), (3) neither, in which case it is UNKNOWN and treated exactly like WRITE (fail-closed) — and WRITE/UNKNOWN tools are wrapped in an order gate (mandate → expiry → kill switch → account binding → order-intent parsing → position and balance lookup → limit check).

In short: plugging in the weltiq MCP server is not blocked. But order tools have to pass the other side's gate, and then the boundary is drawn by them rather than by weltiq. Stop conditions, limits and kill switches end up in two places. That is duplication rather than integration, which is why this part does not give instructions for using them together. (This section's scope of verification is reading the code — I did not actually plug it in and call an order tool.)

Reading, on the other hand, I did connect for real. I wrote roughly 70 lines of adapter that reads weltiq's /v1/account/summary and installed it.

$ vibe-trading connector validate ./plug/weltiq-paper   → Valid read-only connector
$ vibe-trading connector account     currency USDT · balance 548038.3639757 · equity 669503.4621897
$ vibe-trading connector positions   BTCUSDT  1.4132  USDT
$ vibe-trading connector orders
profile 'weltiq-paper-live-readonly' does not support get_open_orders through the generic trading tool yet

Reading works, and the order path is not even registered. Putting it on the portfolio screen hit one more wall — "error": "portfolio currency is not a valid ISO-4217 code: USDT". The other side's portfolio valuation core accepts only ISO-4217 currencies (USD, HKD, CNY), and USDT is a token ticker, so it is refused. And it excludes the failed source rather than quietly folding it into the total, and marks the snapshot INCOMPLETE — correct behaviour, and at the same time a real limit on loading a crypto paper ledger as-is. Making the adapter report USD attached it immediately.

The weltiq paper ledger loaded into the Vibe-Trading portfolio

Look at the legend under the doughnut in the middle — BTCUSDT, AAPL and NVDA all came up from one weltiq paper account. The badge at top left reads Local read-only · Multi-account. Reading connects like this, and there is no way to place an order from this screen. The Valuation coverage 15.5% on the right comes from my adapter not filling in all the cash and positions, not from anything on their side.

I also left BTCUSDT showing as stock in the Type column. A self-built connector is Experimental grade by default and the other side puts a warning on screen saying per-broker verification is needed — meaning it does not hide it.


6. After using it — which side is ahead on which axis

Axes where weltiq loses

Axis Evidence
Distribution and install One line, pip install vibe-trading-ai. ★33,780 · 5,511 forks. weltiq has no public distribution
Range of expressible rules It writes signal_engine.py itself from one paragraph. weltiq is a declarative document, so a rule outside its blocks cannot be written
Screens Dashboard, charts, tear sheet, attribution, correlation matrix, 462 alphas. weltiq has no screen that pins entries and exits onto candles
Breadth of data OKX, yfinance, akshare, mootdx and 100+ through CCXT, with no keys. weltiq uses only the candles it collects
Numeric evidence guard It erases from its answer numbers it cannot match against tool output. weltiq has no such layer at all
Reproducibility manifest config_hash, strategy_hash and sha256 for twelve artifacts. weltiq has no artifact hashes
Exit reason recorded A reason column and a by_exit_reason aggregate. weltiq sell orders have no reason field at all
Korean broker profiles KIS, Toss and Upbit profiles are already on the list
Two weltiq defects daily_pnl does not deduct fees · the fill summary prints Effective rate: NaN % straight to screen · /v1/fees/compare does not work across mixed currencies

Axes where weltiq is ahead

Axis Evidence
Orders with no account All 13 of their paper order profiles require a broker account. weltiq fills in 53ms with one key
The stop condition is mandatory Without it no container comes up. Reaching the deadline closing the position too was actually observed
A record of unattended residency warmup → entry_blocked → no_signal → order_pending → holding, timestamped to the second
Only a human widens a limit An API key cannot create an order limit. Only a browser session
The specified fee is the applied fee Put in 0.1% and all nine rows are 0.1000%. The other side applied 0.05% in / 0.02% out on the same setting
Directness of size declaration One line, "qty": "0.01". The other side is weight-based and needed three capital adjustments
Fees equal the ledger fills_fee and ledger_fee come back matched: true

Draws — engine reproducibility (same input, same output on both; the other side matches down to artifact sha256) · the round-trip count from the same rule (4 on both) · refusing order authority to external extensions (they reject the manifest, weltiq will not widen a limit without a session — different methods, same direction).

Axes I honestly could not measure


7. So which one — by your situation

I will not rank them. Instead, split it by what you are trying to do.

If this is your situation This side
Your idea is still a sentence and you need help turning it into a rule HKUDS/Vibe-Trading
You want data from several markets (A-shares, HK, US, crypto) in one place with no keys HKUDS/Vibe-Trading
You need presentable research output with charts, a tear sheet and attribution HKUDS/Vibe-Trading
You already have a broker account and API key and want to run in that account's paper environment HKUDS/Vibe-Trading
You want to actually place an order before creating a broker account weltiq
The position and the stop condition have to keep running after you close the laptop weltiq
You want to delegate to an agent but draw a limit the agent cannot cross weltiq
You need to reconcile every fill's fee against the ledger weltiq

There is exactly one way to use both. Build the rule over there, have a human read it and carry it into a weltiq strategy document, run it in a weltiq container, and feed the weltiq paper ledger back into their portfolio through a read-only connector. Section 5 did it for real and it works. But it does not connect automatically — a human steps in once in the middle.

Correction notice — I could not pin the cost to the last digit. This is why section 2 gives no dollar figure. The OpenRouter key I used is shared with other experiments, so the account-wide usage increase over this work window ($1.584998) includes runs that were not mine. So I only wrote the token counts — those come from the tool's own llm_usage.json for my run alone, so they are certain. The account increase measured right after the run was $0.987102, which is the upper bound for this single run.


8. Coming next

Part 18 is LangAlpha.

This part looked at the place where a human carries a tool's decision into a rule. Part 18 is about a tool that fills that place in advance — LangAlpha takes one instrument and writes the entry condition, target, invalidation price, time exit and size on a single sheet. "Why buy" arrives next to "where do I admit I was wrong." We will see whether that invalidation price carries straight over into an order condition, and what is left after it does.

Getting ready for weltiq — 3 lines 1. Sign up: {{CTA_URL}} 2. My page → Connections, issue an API key 3. claude mcp add weltiq --header "Authorization: Bearer <key>" https://weltiq.ai/mcp

That is where to look when you want to place the same rule as a real order before creating a broker account.


Every command, output and number in this article came from actual runs on 2026-09-22. No broker account was created, and the only place an order went out is weltiq paper. None of it is a trading opinion, and it does not say which tool is better overall. The trial and error, raw logs and the items not run are in the verification record.