OpenAlice — the orchestrator that hands your own agent market tools and a trading account
OpenAlice brings no model of its own; it brings the agent you already use. I counted its 76 tools by hand, watched an order stop dead in front of a human approv
Part 16. OpenAlice — the orchestrator that hands your own agent market tools and a trading accountDone when: you have stood OpenAlice up with no broker account, watched an order your agent placed stop dead in front of a human approval, and carried that decision into a weltiq strategy container far enough to get a round-trip fill.
| What it does | Brings no model of its own. It brings the agent you already use (Claude Code, Codex and the like) and hands it market data, a research workspace and a trading account as 76 tools |
| Who it fits | Anyone already running an agent, and especially anyone who wants a record of "what the agent proposed" |
| Who it doesn't fit | Anyone validating a strategy sensitive to fill costs or liquidity on this tool's simulator · anyone who wants unattended repetition with nobody at the desk |
| What you end up with | A local workspace with 76 tools attached, one order stopped in front of an approval, and the round-trip fill record the resulting rule produced on weltiq |
| What you need · cost | Code free (AGPL-3.0) · Model your agent's LLM calls · Market data free, 0 keys · 0 broker accounts |
| Time · difficulty | 33.6 seconds to clone and install, five minutes to a screen. Difficulty medium — two environment variables and one build line |
| Relationship to weltiq | Decisions and reasoning come in, execution goes out. The rule the agent produced was carried into weltiq, run resident, and the record fed back — one full turn around the loop (section 5) |
| Test environment · date | macOS 26.6.2 · arm64 · Node 26.8.1 · pnpm 11.7.0 · OpenAlice 0.94.1-beta · 2026-09-22 01:44–02:16 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. Every order is simulated — OpenAlice's own simulator on one side, weltiq paper on the other. Not one broker account was connected, and none of this is a trading opinion. The raw logs are in the verification record.
1. What this is
First, which repository this is. Several repositories carry the name (a 2021 C++ game, a personal-assistant project and others), so I checked by GitHub search and settled on TraderAlice/OpenAlice. It introduces itself as "Your one-person Wall Street — bring your AI agents, market tools, research and trading accounts into one local workspace." The structure matters throughout, so here it is in three pieces.
| Piece | What it is |
|---|---|
| Alice | The body. It manages market data, news, fundamentals, the research workspace and the schedule, and exposes all of it as an MCP server |
| UTA (Unified Trading Account) | The broker abstraction layer. CCXT, Alpaca, IBKR, LeverUp and Longbridge attach as separate Broker Packs; the only built-in is a Mock simulator |
| Trading as Git | Orders are handled like git — add (stage) → commit (reasoning as the message) → push (execute). And push requires human approval by default |
What sits in the deciding seat is not this repository's code but your agent, using the tools this repository handed it. OpenAlice itself gathers the tools, keeps the record, and stands the order in front of a human before it goes out.
| Item | Value | How it was checked |
|---|---|---|
| URL | github.com/TraderAlice/OpenAlice |
|
| License | AGPL-3.0 | GitHub API |
| Stars | ★7,125 · 1,133 forks (observed 2026-09-22) | GitHub API |
| Last push | 2026-09-20 | GitHub API |
| Created | 2026-02-18 · 77 open issues · not archived | GitHub API |
| Version | 0.94.1-beta · TypeScript |
package.json |
| Size | 11 workspace packages + 2 services, 2,129 .ts files |
ls · find |
| Tool count | 76 | counted directly in section 3 |
AGPL-3.0 is worth flagging. Using it on your own laptop is fine, but modify it and offer it to others as a service and the source-disclosure obligation follows. Here is the warning the README wrote for itself — it is also why this article stays on paper.
Trading execution is beta. Start with simulator, paper, demo, or testnet accounts. OpenAlice is experimental software; it provides no guarantees of correctness, reliability, profitability, or loss prevention.
2. Installing
Three prerequisites — Node.js 22.19 or newer (I was on 26.8.1), pnpm 11.7.0 (npx pnpm@11.7.0 works fine), and no money. The desktop app release is the official route, but I stood it up from source to see inside.
git clone --depth 1 https://github.com/TraderAlice/OpenAlice.git
cd OpenAlice
npx --yes pnpm@11.7.0 install
Measured: clone 5.081 seconds (84MB repository), install 28.472 seconds (1.2GB afterwards · 1,055 entries in node_modules/.pnpm) — 33.6 seconds to clone and install. But run pnpm dev at this point and the web UI does not come up ([vite] Failed to resolve entry for package "@traderalice/connector-protocol"). The internal workspace packages have not been built yet; one more line fixes it (measured 4.543 seconds). And two defaults have to change before the trading side opens — the place I was stuck longest.
# (1) build the workspace packages (once)
npx --yes pnpm@11.7.0 -F @traderalice/connector-protocol -F @traderalice/uta-protocol \
-F @traderalice/opentypebb -F @traderalice/ibkr -F @traderalice/guardian-runtime build
# (2) trading mode pro (leave it out and it comes up lite and UTA never starts)
# + set enabled to true in data/config/mcp.json (default false)
OPENALICE_HOME=~/.openalice OPENALICE_TRADING_MODE=pro \
OPENALICE_WEB_PORT=9050 OPENALICE_MCP_PORT=9051 OPENALICE_UTA_PORT=9052 \
OPENALICE_UI_PORT=9054 npx --yes pnpm@11.7.0 dev
This is what it looks like when it works. (I pinned the ports because other things were running on that machine; leave them out and it finds free ones.)
[guardian] mode → pro (env, env-locked) [guardian] UTA → http://127.0.0.1:9052
[guardian] Alice → http://localhost:9050 [guardian] MCP → http://127.0.0.1:9051/mcp
[guardian] UI → http://localhost:9054
[alice] tool-center: 76 tools registered
Guardian is the parent, and Alice, UTA and the agent sessions come up underneath it as separate processes. If one dies, Guardian brings it back.
OpenAlice on first boot
The first screen when you open http://localhost:9054. If Market and Trading are in the left sidebar, OPENALICE_TRADING_MODE=pro took — in lite mode the Trading item is simply absent. The "Initialize Ask Alice" in the middle creates the conversational workspace once, and this article never pressed it.
Where it gets stuck
| Symptom | Cause | Fix |
|---|---|---|
| The web UI is a vite error screen | Workspace packages not built | The -F … build line above. Once is enough |
| No Trading in the sidebar | OPENALICE_TRADING_MODE unset → lite |
Set it to pro and restart |
/mcp returns 404 |
enabled: false in data/config/mcp.json |
Set it to true and restart |
| The ports change every time | It searches for free ports by default | Pin OPENALICE_*_PORT, or use data/config/ports.json |
| 404 in the browser | There are four addresses — UI 9054, API 9050, trading 9052, MCP 9051 | The UI → line in the boot log is the answer |
| No brokers listed | Live broker SDKs are separate Broker Packs, not in the core | This article uses only the built-in mock-simulator |
3. The first result
The dashboard is the body, and there is no login — it binds to local loopback and there are no accounts at all (the admin token printed once on first boot is for remote access). Prices, charts, fundamentals and news are all visible with no key. The only keys needed are your agent's model credentials and a live broker key, and this article uses neither.
The first screen is empty, and there are two ways to something useful. In Market, type a ticker and the chart, fundamentals and news come straight up. In Trading, create one account and Portfolio and Trading as Git come alive — you can create one with the built-in mock-simulator even with no broker account.
Trading → All Accounts, one simulator account
The screen after pressing Trading and creating one account. The "Total Equity (USD) $10,000.00" in the middle is the simulator account just created, and "No open positions." below it is normal. Look at the red 1 badge next to "Trading as Git" in the second panel on the left — it means one commit is waiting for approval, and section 4 comes back to this screen. The Snapshots toggle at bottom right is the account snapshot interval (15 minutes by default).
The smallest example is counting how many tools attached. What this tool is worth comes down to "what does my agent get to use."
What you say
Connect to the OpenAlice MCP and show me the tool list.
What comes back (names only, out of the 76, grouped and shortened)
server: open-alice 1.0.0 tools: 76
trading(25) listUTAs getAccount getPortfolio getOrders getOrderBook getQuote
placeOrder modifyOrder closePosition cancelOrder
tradingLog tradingShow tradingStatus tradingCommit tradingPush tradingReject tradingSync
market(14) marketSearchForResearch searchBars getMarketBars marketSnapshot calculateQuant
marketGetBoard sectorRotation cryptoFuturesInstruments setMarketVendor
equity(8) equityGetProfile equityGetFinancials equityGetRatios equityGetEarningsCalendar
equityGetInsiderTrading equityGetShortInterest equityGetEstimates equityDiscover
ETF·news(8) etfSearch etfGetInfo etfGetHoldings etfGetSectors globRss grepRss windowRss readRss
macro(20) economyFredSearch economyFredSeries economyBlsSeries economyFomcDocuments …
Only 7 of the 76 change state — placeOrder, modifyOrder, closePosition, cancelOrder, tradingCommit, tradingPush, tradingReject. The other 69 read, and that ratio is the character of this tool.
Now create an account. No broker account required.
{"id":"mock-simulator-efe8abb4","presetId":"mock-simulator","presetConfig":{"cash":10000}}
listUTAs → capabilities {"supportedSecTypes":["STK","CRYPTO"],
"supportedOrderTypes":["MKT","LMT","STP","STP LMT"]}
health {"status":"healthy","reach":"readable","tier":"trading"}
getAccount → {"netLiquidation":"10000","totalCashValue":"10000","realizedPnL":"0"}
This is what it looks like when it works. health.status of healthy and cash of 10,000 and you are ready.
curl -s http://127.0.0.1:9050/api/trading/config/broker-presets | python3 -m json.tool
curl -s -X POST http://127.0.0.1:9050/api/trading/config/uta \
-H 'Content-Type: application/json' \
-d '{"presetId":"mock-simulator","label":"weltiq-blog-sim","presetConfig":{"cash":10000}}'
On the MCP side, talk Streamable HTTP to `127.0.0.1:9051/mcp` with `initialize` → `tools/list` → `tools/call`.
Rather than launching Claude Code inside OpenAlice, the runs in this article attached an OpenRouter model (
openai/gpt-5.6-luna) to that same MCP surface. The tools the agent sees and the responses it gets are the same, but it is not identical conditions, and I say so.
4. The best way to use it — stage the order and let a human approve it
If I had to pick one best use, it is Trading as Git. When the agent calls placeOrder, no order goes out — it is only staged, like git's add. The tool description says exactly that ("Stage an order (will execute on tradingPush)").
What you say
Buy 10 AAPL at market, and write why in the commit message.
What comes back (four calls collected into one block)
placeOrder → {"staged": true, "index": 0,
"operation": {"action":"placeOrder","symbol":"AAPL",
"order":{"action":"BUY","orderType":"MKT","totalQuantity":"10"}}}
tradingCommit → {"prepared": true, "hash": "bcc0e8ab",
"message": "weltiq blog A16: stage 10 AAPL to observe the approval gate"}
tradingPush → {"message": "Push requires manual approval (AI trading is disabled).
Tell the user to review and approve the pending operations
in the Web UI (Trading as Git page, or the account detail page)."}
It stops here. Not one order has gone out yet.
Trading as Git — a commit waiting for approval
The screen right after the agent called tradingPush. "1 commit waiting for approval" at top left, the 1 Needs / 0 Staged / 2 Pushed counter, and on the right the Needs approval badge with the Approve & Push and Reject buttons are the heart of this tool. The "Operation diff" in the middle is the one order that would go out on approval (BUY AAPL · MKT → qty 10), and the red box below is the warning — "Approval pushes these operations to the broker account. Check account, side, quantity, and order type before confirming." The agent can get this far and no further; those two buttons belong to a human.**
In the code it is one switch, and the default is off (allowAiTrading: z.boolean().default(false)). Turning it on requires a human double-confirm under Settings → Agent Permissions. I never turned it on in this article.
Now approve it from the human's seat.
POST …/wallet/push (with no body)
→ 409 {"error": "expectedPendingHash is required", "code": "PENDING_HASH_REQUIRED"}
POST …/wallet/push {"expectedPendingHash": "bcc0e8ab"}
→ 200 {"hash": "bcc0e8ab", "submitted": [{"status": "filled", "orderId": "mock-ord-1"}]}
"Approve whatever is pending" does not work. You have to send the hash of the commit you actually read — the guarantee that what you read and what you approved are the same thing is nailed into the protocol. The fill result is worth writing down too.
quote just before the fill bid 99.99 | ask 100.01 | last 100
fill 10 AAPL @ 100.00 status filled
account cash 10000 → 9000 netLiquidation 10000 (unchanged)
commissionAndFees 1.7976931348623157e+308 ← IBKR's "unset" sentinel
The built-in simulator has no fees and no spread. It was a buy and it filled at last 100.00 rather than the ask of 100.01, and netLiquidation did not drop by a cent. That is not a criticism but a calibration point — the preset description says "For UI/AI repro testing only."
I tried a reject as well. tradingReject returns {"hash":"b39f9859","message":"[rejected] BTCUSDT 1m long-only: …"}. The rejected decision is not deleted — it stays in the log with a [rejected] prefix.
Trading as Git — a rejected commit in detail
The Trading → Trading as Git screen. b39f9859 in the list on the left is the commit the agent pushed, and the body on the right is the reasoning the agent wrote itself (numbers like SMA20 85846.32, SMA50 85829.37 and RSI14 56.41 are in there verbatim). Look at BUY BTCUSDT user rejected in the "Operation diff" in the middle — the fact that a human rejected it stays in the diff too. 0 Needs / 0 Staged / 2 Pushed at top left is the current staging state.
Disconnect and reconnect — the decision record lives, the position dies
I killed every process and brought it back, with 10 AAPL held in the simulator.
before restart positions [{"symbol":"AAPL","quantity":"10","avgCost":"100"}] · cash 9000
after restart positions [] · cash 10000
wallet/log 1 commit (bcc0e8ab) ← unchanged on both sides
The commit log survives because git wrote it to disk; the simulator's positions and cash live in process memory and return to their initial values. This is not a bug but a property the preset description states up front — "everything is wiped on dev server restart." Still, if your plan was to check a multi-day strategy on the simulator, stop here. Attach a real broker and the state lives on the broker's side, but this article used no broker, so recovery with a live broker attached is unverified.
Trading → Overview right after a restart
The same screen right after the restart. At the top, Total Equity $10,000.00 · Cash $10,000.00 · "No open positions." — the 10 AAPL are gone and cash is back to its initial value. And yet Recent Trades below still holds both commits (b39f9859 and bcc0e8ab, reasoning sentences included). The position dies and the decision record lives, both in one screenshot.
The trap — it invents symbols that do not exist
The agent actually walked into this during the second decision, so it gets its own note. Call for candles on the simulator account through calculateQuant and any string at all returns candles.
bars("mock-simulator-…|BTCUSD", "1m", count=500)
→ {"value": [149.9, 148.95, 147.45]} ← these are not bitcoin prices
dataRange from 2025-05-10 … to 2026-09-21, bars 500, interval "1m"
← "500 one-minute candles" spanning 16 months
bars("mock-simulator-…|ZZZNOTREAL", "1m", count=10)
→ {"value": [100.9]} isLatestActual true barCapability "realtime"
← a symbol that does not exist, and no error
marketSnapshot("BTC") → barId yfinance|BTC close 38.02 ← the US-listed ticker 'BTC'
marketSnapshot("BTC-USD") → barId yfinance|BTC-USD ← this one is bitcoin
The point is that you can pick up the wrong ruler. Synthetic numbers come back with no error and no warning, so check the barId with your own eyes when doing research.
The other side deserves saying too. The real market-data tools are the most honest in this series. Ask for 90 BTC-USD candles and a paragraph comes back underneath saying it does not know its own delay ("actual delay is unknown"); Korean tickers need 005930.KS, and when the 21 September row had an empty close it said it dropped that row and nailed down isLatestActual: false and staleTradingDays: 1.
The BTCUSD chart on OpenAlice's Market screen
Searching BTC-USD and opening Bitcoin USD. Look at "366 bars · 2025-09-21 — 2026-09-21" at top right and the delayed badge next to the symbol — which window from which source is stated on top of the chart. And look also at AAPL / mock-simulator sitting at the top of the search results on the left. The simulator account is registered as a market-data vendor, so AAPL muscles into a "BTC-USD" search.*
5. Moving it to weltiq
OpenAlice's output is not one order but "rule plus reasoning." The reasoning is in the commit message and the numbers are in the staged operation.
The order a person carries it in
(1) write the rule document POST /v1/strategy-rules
(2) write the thesis yourself POST /v1/ai/thesis
(3) set the stop conditions POST /v1/containers (stop_max_loss and stop_after_hours required)
(4) it runs unattended. The container keeps to the rule with both the human and OpenAlice off
Steps (2) and (3) cannot be skipped — leave them out and you get {"code":"thesis_required"} with three questions, or {"loc":["body","stop_max_loss"],"msg":"Field required"}.
The route for carrying one staged order into a weltiq one-off order was blocked — POST /v1/orders/oneoff returns 422 envelope_required, and POST /v1/envelopes, which creates that approval, returns 403 session_required (no API keys). A human approval stands in front of weltiq's one-off orders too. So I took the route that carries the rule instead. Both products have the same shape of door — OpenAlice in front of tradingPush, weltiq in front of orders/oneoff.
The best combination — approve once, measure on weltiq
| Who | Does what |
|---|---|
| OpenAlice | Gathers the data, lets the agent decide, and nails the reasoning into a commit message |
| The human | Reads that commit and approves or rejects it. Only the approved ones become weltiq documents |
| weltiq | Runs it resident somewhere with costs and fills, and produces a record |
| OpenAlice again | Takes that raw record and decides again |
Rather than turning allowAiTrading on for automatic execution, use the commit as the place a human reads. The reason is exactly what section 4 measured — the built-in simulator has zero fees and zero spread, so it is not an instrument for measuring cost.
I did carry it over for real. The mission was one sentence — "Trade bitcoin and make me a profit. Set the entry and exit rules as numbers, and explain why you chose them." — and all the human supplied was that sentence plus facts about the destination grammar (block names and arguments, and "long only, no leverage"). I did not choose the instrument, the direction or the numbers.
"20/50 SMA crossover는 1분봉의 매우 짧은 잡음을 일부 줄이면서 단기 상승 추세를 추종하도록 선택했다. 1.5% trailing stop은 정상적인 1분봉 변동에는 어느 정도 여유를 주면서도 추세 반전 시 손실을 제한하기 위한 설정이다. 0.01 BTC는 당시 가격 기준 약 859달러의 명목금액으로, 10,000달러 paper 계정에서 과도한 노출을 피하기 위해 정했다." — the agent's own output, in Korean (2026-09-22 02:06 KST). In English: "I chose the 20/50 SMA crossover to follow a short-term uptrend while filtering out some of the very short noise in one-minute candles. The 1.5% trailing stop leaves room for normal one-minute movement while limiting the loss when the trend reverses. 0.01 BTC is about $859 notional at that price, chosen to avoid excessive exposure in a $10,000 paper account."
| What the agent produced | The weltiq document | Carried? |
|---|---|---|
sma_cross(fast 20, slow 50) |
crossover(sma(close,20), sma(close,50)) |
as is |
trailing_stop(1.5) |
managed_exit(trailing_pct "1.5") |
as is |
fixed_qty 0.01 |
fixed_qty qty "0.01" |
as is |
| — | managed_exit(stop_pct …) |
it was blank |
The fourth row is this part's honesty moment. The weltiq grammar requires a protective stop percentage separately from the trailing stop, and the agent did not supply that field. Rather than approximating it I asked back, and the answer was {"stop_pct":"1.0","why":"A 1.0% hard stop limits adverse loss while leaving the 1.5% trailing stop room to follow normal short-term volatility."}.
The weltiq strategy list — the two carried documents
weltiq's "My strategies" screen. Look at the two rows — the numbers the agent produced have become weltiq rule sentences. The first is sma(close, 20)/sma(close, 50) with a 1.5% trail; the second is sma(close, 30)/sma(close, 80) with a 2.0% trail. The 1/100 on the right is how many runs this document has had. The account identifier is masked.
The same document somewhere with costs
I replayed the hardened document over 30 days of weltiq candles — binance-spot BTCUSDT one-minute, 43,188 candles, 75 fills across 37 round trips, realized P&L −16.40950921 and fees 58.61362146 (zero rejections). The fees are 3.6 times the total loss. Changing the rate changed nothing — recomputing the same fills under a different exchange's rules gave delta 0E-8, because binance-spot and bybit-spot are both a flat 0.1%. In this strategy the axis that moves cost is round-trip count, not the rate.
One full turn around the loop
I drew the boundary (BTC spot, capital 10,000, stop at 200 cumulative loss, auto-terminate after 2 hours), brought up a container, and then actually went after the stop conditions.
PATCH …/limits {"stop_max_loss":"20"}
→ 200 {"changed":{"max_loss":{"from":"200","to":"20","direction":"tighten"}}}
PATCH …/limits {"stop_max_loss":"500"}
→ 403 {"code":"session_required",
"detail":"widening a limit is only possible from a logged-in session (tightening also works via API key or MCP)"}
Tightening works and widening does not. This is the counterpart to the allowAiTrading gate — over there, "a human before execution"; over here, "a human to widen a limit." I also actually made it fire by pulling the time limit forward (autostop {"reason":"expired","cumulative_pnl":"-0.08602147500"} → stopped).
That container produced one genuine round trip. The rule opened it and the termination condition closed it.
BUY 0.005 BTCUSDT @ 85980.07714750 fee 0.42990039 taker (expected 85971.48) 02:04:00
SELL 0.005 BTCUSDT @ 85962.87285250 fee 0.42981436 taker (expected 85971.47) 02:06:00
realized_pnl -0.08602147500 · fees 0.85971475
equity 10000 → 9999.05426378 (-0.0095%)
Both fills came out 8.597 USDT away from the expected price. Up on the buy, down on the sell, exactly the same distance — half the modelled spread each way, 1.0bp. Put it next to section 4's "ignore the quote and fill at last" and you can see the difference between the two instruments' scales.
weltiq fill history
weltiq's "History" screen. The two lines in the middle — 02:04:00 buy 0.005 @ 85,980.08 / 02:06:00 sell 0.005 @ 85,962.87 — are the round trip from this article. Note the fee column (0.430), the taker marking, and the Binance spot · weltiq paper source attached to every row. Rows carrying the backtest badge above are replay fills and are distinguished. The account identifier is masked, and "Effective rate NaN %" is genuinely what the screen showed — untouched.
I handed the raw 30-day replay result and the raw container export back to the agent unprocessed and asked it to decide again.
"이전 20/50 SMA 교차 전략은 30일 리플레이에서 37회 거래를 발생시켰고 총 손익 -16.4095, 수수료 58.6136으로 과도한 매매와 수수료 부담을 보였습니다. 30/80으로 늦춰 같은 추세추종 구조를 유지하면서 1분봉 잡음을 줄이도록 했습니다. trailing stop은 1.5%에서 2.0%로 넓혀 작은 되돌림에 의한 조기 청산을 완화했습니다. 손실 전략을 수정하는 테스트 단계이므로 수량은 0.01 BTC에서 0.005 BTC로 절반 축소했습니다." — the agent's own output, in Korean (2026-09-22 02:10 KST). In English: "The previous 20/50 SMA crossover produced 37 trades over the 30-day replay, with a total P&L of −16.4095 and fees of 58.6136, showing excessive trading and a fee burden. I slowed it to 30/80 to keep the same trend-following structure while cutting one-minute noise. I widened the trailing stop from 1.5% to 2.0% to soften early exits on small pullbacks. Since this is a test stage revising a losing strategy, I halved the size from 0.01 BTC to 0.005 BTC."
With the revised numbers (20/50 → 30/80, trail 1.5% → 2.0%, protective stop 1.0% → 3.0%, size 0.01 → 0.005 BTC) I rebuilt the document and brought up a new container. The round trip above happened in that container. The loop closed. Then I replayed the same 30 days again and put the two documents side by side.
| 1st (20/50, trail 1.5%, 0.01) | 2nd (30/80, trail 2.0%, 0.005) | |
|---|---|---|
| Candles | 43,188 | 43,188 |
| Fills | 75 | 39 |
| Round trips | 37 | 19 |
| Realized P&L (gross) | −16.40950921 | −3.98620772 |
| Fees | 58.61362146 | 15.22453619 |
| Net | −75.02313067 | −19.21074391 |
Both are negative. This is not a story about making money. What changed is the size of the cost, and that the agent cut it itself after looking at weltiq's record. Read the numbers precisely though: round trips halved (37→19) and size halved too (0.01→0.005), so the 74% drop in fees is two effects multiplied — fees per round trip went 1.584 → 0.801, exactly the size ratio. And this one 30-day window proves nothing. What was confirmed is "the feedback went round," not "the revised one is better."
One wall. During the second decision the agent tried to stage a new order and hit Error: A commit is awaiting approval. Push or reject it before staging more operations. One commit that nobody approved or rejected stops everything after it. That is design rather than a bug, but if you plan to run unattended you need to know it.
What this combination does not give you: there is no way to feed the result back into OpenAlice automatically, and the Trading-as-Git log and the weltiq journal do not know about each other. The live stretch is also still closed (live_orders: false) — "the same document passes through backtest and paper as the same body" is the fact, and what comes after it is planned.
6. After using it
What was good
- Orders stop in front of a human.
allowAiTradingdefaults to off, and a push returns a sentence telling you to get human approval. Very few tools ship this gate on by default - Approval is locked by hash. Without
expectedPendingHashyou get a 409. And rejected decisions are not deleted either; they just get a[rejected]prefix - Reasoning as the commit message is a good idea. The decision and the reason for it are nailed down together with a timestamp — there is no better output shape for running feedback
- It writes down what it does not know. It does not know the delay, this candle is not the latest, this row was dropped for empty OHLC. And you can go all the way through without a broker account
What fell short
- The built-in simulator invents symbols that do not exist.
ZZZNOTREALreturns candles withisLatestActual: trueattached. A research tool quietly handing over synthetic numbers is dangerous - That simulator has no fees, no spread and no liquidity constraint. Worse, the account registers as a market-data vendor via
asVendorand bleeds into research, and a restart wipes every position - Two defaults are quietly off (
OPENALICE_TRADING_MODEandmcp.enabled), and the web UI does not come up withpnpm devstraight after install. None of the three lines is in the README - One pending approval blocks the next decision. And it is AGPL-3.0, so read the license first if you plan to offer it as a service
Cost
| Item | Value |
|---|---|
| Code · market data | Free (AGPL-3.0 · 0 API keys · 0 broker accounts) |
| Model | Your agent's LLM calls |
| Time | clone 5.1s · install 28.5s · package build 4.5s |
Who it fits — anyone already using Claude Code or Codex who wants to hand that agent market data and a trading account in one place. Who it does not fit — anyone validating a strategy sensitive to fill cost and liquidity on this tool's simulator, and anyone who wants unattended repetition with nobody at the desk.
7. Coming next
Part 17 is HKUDS/Vibe-Trading (★33.7k). It is the largest thing in this series and it overlaps weltiq the most. OpenAlice left the execution layer open so you could swap brokers in; Vibe-Trading implemented all of it itself — 18 broker connectors and paper orders — and restricts external plugin connectors to read-only. So the next part is not "how do you attach it" but "what is the same and where do they diverge." The columns weltiq loses get written down as they are.
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/mcpThat is where to measure the fees, spread and recovery OpenAlice's simulator does not, using the same decision.
Every command, output and number in this article came from actual runs on 2026-09-22. No real money moved; everything is simulated. None of it is a trading opinion. The trial and error, raw logs and the items not run are in the verification record.