← The Directory
Skill

Vibe Trading

"Vibe-Trading: Your Personal Trading Agent"

View source

English | 中文 | 日本語 | 한국어 | العربية | Español | Bahasa Indonesia

Vibe-Trading Logo

Vibe-Trading: Your Personal Trading Agent

One Command to Empower Your Agent with Comprehensive Trading Capabilities

HKUDS%2FVibe-Trading | Trendshift

Python FastAPI React PyPI License
Feishu WeChat Discord

Website  ·  Docs  ·  News  ·  Features  ·  Shadow Account  ·  Demo  ·  Quick Start  ·  Examples  ·  API / MCP  ·  Roadmap  ·  Contributing

pip install vibe-trading-ai


📰 News

⚠️ Security warning: The X account VibeTrading_HKU, Virtuals project 101845, and token contract 0x640BDBF77b6447E8b7DB7894cED84BD1c40571f4 are not official Vibe-Trading assets. We have never launched or endorsed any token or memecoin. Do not buy, connect a wallet, or sign anything. Details.

  • 2026-10-25 🛠️ Session, market-data and calculation fixes (unreleased): Deleting a session also removes its search entries, and chat titles update correctly when the first message includes attachments or Swarm instructions (#1970, #1969). Fix prematurely truncated CCXT history, Nobitex daily dates and Tiingo class-share symbols (#1999, #1989, #2010). Preserve small trade/chart prices, correct GTJA factor formulas and VWAP units, and reject ambiguous boolean flags before changing state (fix). These fixes are on main for the next release.

  • 2026-10-24 🛠️ MCP, backtest and search fixes (unreleased): MCP loads the runtime .env, while shell tools still require explicit opt-in at startup (#1974). Report assumed futures leverage (#1972), preserve fractional-day spans in annualization (#1971), and try enabled Sogou/Bing fallbacks when ddgs returns no results (fix).

  • 2026-10-23 🛠️ Model, portfolio and futures fixes (unreleased): Direct MiniMax connections default to M3.1 Flash and retain reasoning across tool calls (#1936). Longbridge exposes cash by currency and financing limits across Agent, CLI, API and Web (#1940). Correct global futures routing, contract multipliers and micro-contract fees, with explicit warnings when pricing defaults are used (#1965). Also fix portfolio error redaction, audit rotation, IC statistics, numeric parsing and Weixin attachment collisions. Details in CHANGELOG.

  • 2026-10-22 🚀 v0.1.18 released (Release notes, pip install -U vibe-trading-ai): a leaner agent runtime — tool schemas load on demand, oversized results stay readable in the run directory, Swarm keeps new observations, and usage accounting covers compaction and interrupted calls; automatic chat titles remain. On the 0.1.17 verification backtest it used 7 model calls instead of 12 and about a fifth of the input tokens. It also ships the post-0.1.17 security, grounding, paper-account and packaging fixes. Fixed on main today (next release): a retried provider error no longer halts live model decisions for the rest of the day, and a research goal's final answer is delivered even when it crosses the goal's token budget (CHANGELOG).

Earlier news
  • 2026-10-21 🚀 v0.1.17 released (Release notes, pip install -U vibe-trading-ai): 638 commits and 228 merged pull requests since 0.1.16, plus 41 pull requests whose work landed through maintainer commits, from 33 contributors. The headline is daily paper trading: a paper_trade_step tool for the agent and MCP, plus saved paper accounts through vibe-trading paper, the REST API and a Web page, match orders or a strategy against completed daily bars without ever reaching a broker; saved accounts move forward only (#1939). Most of the rest is correctness, and much of it has one shape: a value that cannot be computed now says so instead of turning into a plausible number. A profit factor with no losing trade, an undefined correlation and an unbounded ratio come back as null, and a factor with too few IC observations is skipped with the reason; a missing price no longer bridges a return; a misspelled or engine-irrelevant backtest setting is reported in the run card. New: Brazil (B3), 478 Alpha Zoo factors (from 462), Slack and Discord in the guided channel setup, Email reports as HTML or a password-protectable PDF, token usage in Run Detail, chat and swarm, a claude-cli provider, and Persian and Turkish for 11 UI languages. Fixed today: the fund-flow fallback names its actual source and keeps total flow apart from main-order flow, and the Telegram setup steps are clarified. Shipped the same evening in v0.1.18: mcp>=1.30 closes CVE-2026-59951 for --transport http; custom model endpoints are re-checked on every connection and work behind fake-IP proxies; grounding reads run_dir/… refs and −$ amounts; Beijing 920xxx codes resolve to .BJ in correlation (CHANGELOG). Thanks @rudycelekli, @Shizoqua, @he-yufeng, @shadowinlife, @zeus229, @alexwan02, @Jackzigen, @cgycorey, @MetaAviator, @lorenzozanee, @Mikesad, @remote-controlled-man, @Romzhou, @sambazhu, @wavebyrd, @BHhhh-123, @Bortlesboat, @bygordon130-hub, @davidalmeida90, @DrDLyuan, @Emad211, @Frank-zhu2000, @goatyyc, @hunters1011-ctrl, @incorpore, @mdb1230, @mminkus, @passionbull, @rwxyx518-prog, @ThreeTima, @tomaszkubiak-courses and @xaritoku!

  • 2026-10-20 🛠️ Backtest diagnostics and research correctness: Warn about unrecognized backtest config keys, show undefined correlations as unknown instead of zero, and reuse the saved annualisation factor when revalidating runs (#1935, #1933, #1915). Also improve factor sample checks, tool input validation, journal market classification, numeric formatting and WeCom streaming. All 14 fixes and remaining limits are in CHANGELOG.

  • 2026-10-19 🛠️ Nine financial correctness fixes: Correct recency weights in factor decay, A-share board limits and Beijing symbol routing, SEC Q4 flow derivation, and event-study estimation windows. Preserve Futu holdings identity and tiny MACD/Bollinger values; reject negative specific variances and apply pair-specific fees to Yahoo forex symbols (#1912, #1920, #1930). See CHANGELOG for all nine fixes and limits.

  • 2026-10-18 🛠️ Scheduling and research reliability: Live scheduling adopts the shared scheduler kernel (#1899), and figure checks preserve currency identity (#1905). Add factor neutralization and PCA (#1817); fix incomplete Swarm event tails and lost Matrix final replies. Details in CHANGELOG.

  • 2026-10-17 🛠️ Token usage and research reliability: View LLM usage in Run Detail, chat and swarm (#1890). Shared scheduling now powers research and optional background jobs (#1893); live scheduling is unchanged. Fix journal date/time pairing, evidence paths, factor ties, memory roots, numeric error handling and channel progress. See CHANGELOG.

  • 2026-10-16 🛠️ Credential safety and financial correctness: Scrub more channel/provider secrets (#1880), refresh cached local bars after source edits (#1879), and allocate reversal fees once (#1891). Correct European journal amounts, strict JSON, zero/negative comparisons, holding periods, weight floors, plateau detection and report paths. See CHANGELOG.

  • 2026-10-15 🛠️ Model spending controls and research reliability: Live runners use independent decision sessions with configurable cadence and persistent daily usage budgets (#1854). Lightweight backtest previews preserve complete trade history (#1853, #1865). Fix percentage evidence arithmetic, copied-run history deduplication, swing-signal timing, crypto routing and credential redaction. See CHANGELOG for scope and limits.

  • 2026-10-14 🛠️ Backtest, search and document fixes: Risk ratios and equity exports now include first-bar PnL (#1844). Session search returns distinct sessions with preserved titles and contextual snippets (#1827, #1834). Improve PDF/Office extraction, reject unresolved evidence references, and strengthen financial-input validation and credential redaction.

  • 2026-10-13 🧩 Portfolio imports, strategy adaptation and research tools: Read-only extraETF holdings imports support dated EUR valuation and allocation proposals; adapted strategies get their own backtest evidence (#1170, #1149). Add tested custom model endpoints, a shared manual Pixel Office task board, Persian/Turkish UI, mStock read-only queries and Gildata research data. Fix settlement-currency accounting, Futu market selection and cost basis, per-symbol HK board lots, saved validation settings and run progress. Complete declared grounding checks and the agent-loop split. mStock remains excluded from portfolio aggregation; Robinhood options execution remains unavailable. See CHANGELOG for scope and limits.

  • 2026-10-12 🧮 Research and backtest updates: Correct opening fills, liquidation-time attribution, drawdown duration, valuation tolerances and SEC filing timing in factor IC (#1780–#1794). Add 13 fundamental/valuation factors, Brazil data and backtests, opt-in ZimaOS templates, and Feishu run progress. See CHANGELOG for scope and data limitations.

  • 2026-10-11 🛠️ Five priority fixes: Derived figures require evidence for every data operand; unsupported live options stay blocked. Offline benchmarks retain their selected source, trade artifacts distinguish break-even exits, and Codex tools preserve optional arguments (#1622, #1779, #1781, #1785).

  • 2026-10-10 🛠️ Slack/Discord setup and reproducible research: Localized channel forms verify bot credentials without saving changes (#1764, #1777). Portfolio research can reuse an immutable snapshot, and Web exports its sanitized JSON (#1769). Indicators report their date boundary and exact input fingerprint; corrupted session records recover without rewriting files. Memory recall, credential redaction and trade-journal detection are corrected. See CHANGELOG.

  • 2026-10-09 🛠️ Channel updates and backtest correctness: Channel settings preserve embedded URL credentials and authenticated WeChat endpoints during in-place updates, with save/reset feedback in all nine languages (#1737, #1742, #1744). Cross-market option volatility uses only timestamps known at each bar; drawdown includes starting capital. Crypto/precious-metal routing, HK duplicate detection, cache recovery, scientific-notation amounts and missing-equity validation are corrected. mootdx leaves the default A-share chain. See CHANGELOG for all thirteen PRs.

  • 2026-10-08 🔐 Protected PDF reports and clearer broker reads: Scheduled Email PDFs support optional AES-256 password protection across Web, CLI playbooks and agent confirmations; the password stays in private channel configuration (#1709). KIS queries all three venue buckets, refreshes an explicitly expired token once, and reports incomplete reads as errors (#1726). Derived formulas keep their arithmetic after descriptive labels while evidence checks remain enforced (#1728).

  • 2026-10-07 🛠️ Research continuity and reliable risk metrics: Volatile workspace state now travels outside the system prompt, preserving its stable prefix (#1708). Cross-market dates align correctly, missing prices no longer bridge return observations, and options Sortino uses full-sample downside deviation (#1710, #1717, #1727). Loader fixtures share one OHLCV contract; credit valuation, style exposures, walk-forward folds and audit diagnostics are corrected.

  • 2026-10-06 🛠️ Live controls and report corrections: Stopping a live runner cancels its current analysis and waits for scheduler cleanup, including startup cancellation and API shutdown; status timestamps use the correct units (#1704). Emergency cancel/flatten scans skip malformed records without abandoning the remaining book (#1703); broker schedules are stored separately and writes handle concurrency and partial writes. US equity half-days respect the early closing bell (#1706). Report corrections preserve figures that passed validation, and bounded feedback no longer implies that unlisted figures passed (#1702).

  • 2026-10-05 🛠️ Research prompts and calculation fixes: Chat accepts longer research prompts and gives a localized recovery message when input is too large (#1701). Backtests use full-sample Sortino downside deviation; grouped validation purges overlapping labels, covariance weights remain finite, shadow RSI uses Wilder seeds, and memory removal accepts filename stems. Invalid call aliases now receive exact source references for correction (#1638); numeric validation stays unchanged.

  • 2026-10-04 🛠️ Scheduled reports and research workflows: Edit scheduled runs and choose a configured destination; Email reports support HTML or PDF attachments (#1649, #1680). Backtests expose structured summaries and paged artifact reads (#1646, #1647). Fixes cover memory-search snippets, export-path guidance, macro truncation, monthly risk, turnover on reversals and cash reentry, IV accuracy, VaR gaps, VCS updates and Robinhood option-order blocking.

  • 2026-10-03 🛠️ Research, reports and data reliability: CJK session search, channel setup, broker exposure pricing and file writes now handle cases that blocked everyday use. PDF delivery embeds CJK fonts, Swarm validates preset inputs and separates task artifacts, and replayed tool results survive context compaction (#1683, #1455, #1635). Backtests keep one adjustment basis, local caches distinguish sources, single-asset caps and weekly/monthly risk use the declared settings, audits retain loss signs, grounding checks the current engine output and exact list references, and Stooq retries after a denial cooldown (#1684, #1650, #1685, #1640).

  • 2026-10-02 🛠️ Backtests and report checks: strategy-file writes retain model provenance without crashing (#1673), and Monte Carlo drawdown and Sharpe include starting capital (#1664). Report audits preserve accounting negatives and units (#1663); grounding artifacts record fired declared checks (#1661); public loader-health reports include sanitized failure reasons (#1643). Indonesian tool documentation matches the registry (#1671).

  • 2026-10-01 ✅ Data correctness and reproducible backtests: A-share adjustment conversion now refuses ambiguous one-bar edge cases (#1551); Southbound Eastmoney amounts are scaled from million HKD and rejected responses no longer look empty (#1486); Northbound fallback data distinguishes post-2024-08-19 turnover from net flow (#1484); Binance-only unpriced positions are marked incomplete without penalising other brokers (#1505); and backtest run cards record model provenance and warn when the training cutoff is unknown or outside the test window (#1618, closes #1613).

  • 2026-09-30 🛠️ Feishu in the Web UI, a momentum factor that read today's price, and a profit factor for runs that never lost: Feishu joins the guided channel setup, with a standalone connection test and a hot reload that closes the old WebSocket (#1572). academic_carhart_mom subtracted the 1-month return from the 12-month one, so it moved with today's close; it is now the return from 12 months ago to 1 month ago (#1578). A run with no losing trade reports its profit factor as undefined instead of 0.0, which ranked it last (#1602). Stooq's anti-bot page now stops every later request in the process, not just the log line (#1637); MCP tool results reach the agent once instead of up to four times (#1634); and the first piece of loop.py moves into its own module (#1636).

  • 2026-09-29 🚀 v0.1.16 released (Release notes, pip install -U vibe-trading-ai): 492 commits and 116 merged pull requests since 0.1.15, from 16 contributors. The theme of this cycle is a number that can show where it came from. The grounding gate no longer guesses 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 it against the session's tool evidence, and a figure that fails is cut instead of the whole answer being refused. A backtest's own output — Sortino, turnover, weights and Monte Carlo p-values, not only Sharpe — now grounds the report written about it, and run cards cite a metric only where the saved CSV agrees. Long research runs keep what they fetched: compaction follows each model's real context window instead of a fixed 40K estimate. The missing-data sweep reached 59 more alphas. Fixed in this release, from a user's report: failed runs keep their steps and the stop message names the call that produced nothing; read_file says where it may read instead of letting the model guess paths until the no-progress stop; on Codex, mid-run instructions no longer replace the system prompt, reasoning carries between turns and the default model is gpt-6-sol; and get_market_data asks for AAPL.US rather than returning empty data for a bare US ticker. New: Argentina (BYMA), weekly and monthly bars, Bahasa Indonesia, Gildata, OpenCode, Email and WebSocket channels, IM channel setup in the Web UI, and KIS, Upbit, Toss Securities and Scalable Capital connectors, 18 brokers in all. Thanks @Shizoqua, @zeus229, @cgycorey, @shadowinlife, @lorenzozanee, @he-yufeng, @chiww, @as950118, @woshi77777stars, @Yoruxyv, @sambazhu, @0xouzm, @tingkk, @tonydo, @alanwilhelm and @modelpath-dev!

  • 2026-09-28 🛠️ Source health and connector transparency: scheduled public-source canaries report outages and data drift with bounded, credential-free probes (#1627); BaoStock socket requests now have deadlines and serialize concurrent sessions (#1615). Copilot credential lookups refresh after a short cache TTL (#1619). A generated broker matrix preserves each profile’s paper/live permissions and labels declared capabilities separately from runtime verification (#1629). Grounding and MT5 follow-up: explicit evidence symbols and exact field references are preserved; localized grouped figures retain the existing numeric tolerance (#1584, #1586, #1588). Text-only correction attempts are bounded (#1600). MT5 search uses the selected terminal and refuses ambiguous broker aliases; backtest sandboxes receive only validated attachment settings (#1597, #1598).

  • 2026-09-27 🛠️ Verifiable run cards and safer research: Run cards now show hashed backtest execution records and verified metric-to-CSV references in JSON, Markdown and Run Detail (#1612). GTJA high/low recency factors use the correct day count and consistent tie handling (#1604); India short covers check the buy-side circuit band (#1608). Token usage remains readable without exempting arbitrary credential strings (#1606), malformed MCP schemas retain their object properties (#1607), and immediate-order goal checks preserve research questions (#1605). Setup documentation now correctly identifies OpenRouter as the shipped default (#1609).

  • 2026-09-26 🛠️ More reliable indicators and trading limits: Technical indicators retain their observation date and can reuse results lost during conversation compaction (#1590, #1601). All five Qlib158 WVMA windows now use absolute returns in the numerator (#1594); Benford checks preserve the correct leading digit at numeric boundaries (#1591). An explicitly zero exposure limit stays zero (#1593), and Dhan paper orders reject fractional or invalid quantities without rounding away input precision (#1595). Invalid optional numeric environment variables fall back to defaults while explicit configuration constraints remain enforced (#1592). Runtime triggers keep the correct field defaults and subclass factory behavior (#1599).

  • 2026-09-25 🛠️ More reliable research sessions and channel diagnostics: A text column in a backtest CSV no longer discards the numeric metrics (#1579), and conversation compaction now counts reasoning content in its retained-message budget (#1582). Failed channel loads now log the actual exception (#1580); the Telegram guide clarifies that CLI and Web controls share the same API runtime (#1583). Robinhood portfolio reads reject malformed buying-power objects while keeping omitted or null values unknown (#1526). Leaving a chat also cancels pending history-scroll timers. Thanks @Shizoqua and @lorenzozanee!

  • 2026-09-24 💱 A dollar line priced as pesos, Email and WebSocket in the Web UI, and a CI break from an SDK update: BYMA and the TSX list US-dollar lines beside their home-currency ones (GGALD.BA, DLR-U.TO), and an Argentine or Canadian backtest priced them in its single peso or Canadian-dollar pool. The loaders now admit a line only in its market's currency, as LSE lines already were, and every other declared quote currency travels with the data, so an answer names the right one (#1576). Hong Kong's RMB and USD counters (80700.HK, 9834.HK), which HKEX numbers in their own code ranges, are refused in a Hong Kong backtest for the same reason and quoted in their own currency. Stock profiles carry the listing's own venue and currency beside the issuer's fundamentals (#1577), grounding and symbol search know every market the data layer routes (#1575), and technical_indicators reports volume with the unit its source declares — board lots or shares, 100× apart (#1571). Email and WebSocket join the guided channel setup, with mail-server certificates now verified and settings writes closed to cross-site pages, and a plain IMAP login is upgraded with STARTTLS before the password goes out (#1544). Fixed: an explicit provider header lost to an ambient twin under openai 3.19.2, which had turned every PR's CI red (#1568); a backtest from a microsecond-resolution source was dated 1970 (#1560); a research goal that is plainly an order is refused again (#1562); a strict-bench OOS split could leave one side empty (#1559); HRP label alignment, cross-validation label order and non-finite quant inputs (#1555, #1556, #1557, #1558); the shadow-account overtrading window (#1563); and asset growth was read day over day (#1564). Thanks @Shizoqua, @zeus229 and @shadowinlife!

  • 2026-09-23 🇦🇷 Argentine listings, a short book sized upside down, and the last half of the tail-risk gate: .BA symbols — BYMA equities and CEDEARs — route to Yahoo as their own ARS market, and the Web UI groups and labels them like any other; an Argentine backtest still fails closed until BYMA execution rules are modelled (#1543). The mean-variance and turnover-aware optimizers scored every position as if it were held long, so the strongest shorts got the least capital. Both now size on position returns, where a long and a short of two correlated names hedge each other instead of reading as correlated — on a +0.92 correlated pair the old objective put the whole book on the long, the new one splits it 0.51 / -0.49 (#1548). And a tail-risk figure now has to name its own field once a session holds more than one measure or confidence level, so an ES 95% can no longer quote the VaR 95% value under a call id (#1425). Fixed: Monte-Carlo validation annualises at the venue's bars per year instead of a hardcoded 252, so its Sharpe agrees with the rest of the same report (#1546); a futures order on a negative-price bar is no longer rejected outright (#1547); a factor's IC ratio is left unset for a negative baseline instead of reading real decay as healthy improvement (#1549); and two memories sharing a title under different types keep their own index rows and link targets (#1545). Thanks @zeus229, @Shizoqua and @he-yufeng!

  • 2026-09-22 📅 Weekly and monthly bars, and a compaction replay that could lose evidence: get_market_data and backtests take 1W and 1M (rejected since 09-20 so 1M would not fetch minute bars). Every source still serves daily bars and the period bar is built from them, dated on the last trading day of its week or month, so a 21-month review is one call of 21 bars (#1479). A price index is stamped unadjusted instead of by what its source does to a stock (#1541). A read-only tool result that context compaction removed is restored from the run's own memory instead of fetched again, capped per run, and a write empties that memory so a regenerated file is read afresh (#1488). A tail-risk figure declared with a field ref is checked against that field, so a VaR 99% quoting the 95% value is caught (#1444). QVeris refuses stock and ETF bars, whose adjustment its search-ranked pick cannot state, and quotes priced per result (#1494). Thanks @sambazhu, @zeus229, @he-yufeng, @jw232 and @cgycorey!

  • 2026-09-22 💸 A backtest that died when funding pushed cash below zero, and three more tools that read a rejected query as no data: a crypto funding debit can leave free cash below zero, and the next position the strategy wanted then found no size that fit, not even zero, so the run aborted with "planned order … exceeds available capital" (or "insufficient capital for position rebalance"). That open is now skipped and reported once as insufficient_capital, the bar's reductions still run, and a close whose loss exceeds its margin still aborts the bar as before (#1542). Block trades, margin trading and financial statements now tell Eastmoney rejecting a stale query apart from a genuinely empty answer, through the same check shareholder count, dragon-tiger and lockup expiry use. Answers in Spanish, German and other decimal-comma locales now ground 17,93 % or 1.410,00 CNY against the tool results, while two unspaced numbers like 1400,1777 stay two numbers, and a figure has to match its evidence to the precision it is written at (#1517). Thanks @turtle696966969696 for a trace reconciled to the cent, and @zeus229!

  • 2026-09-21 🔌 IM channels configured from the Web UI, and 24 alphas that emitted a value computed from a missing bar: Settings now edits each IM channel with masked secrets, a connection test on the unsaved form, and a per-channel hot apply with no restart; DingTalk and QQ get guided setups (#1520, #1529), and every adapter logs through stdlib again, so diagnostics that a {} placeholder used to swallow reach the log (#1533). In the Alpha Zoo, a comparison whose operand is NaN because its window holds a missing bar reads False and emits a constant; the #1463 sweep, which nudged the bar by a tick, could not see it. A gap-versus-gap-free check found 24 more alphas, which now mask on their inputs' reach while a correlation undefined on complete data keeps its old verdict (#1523, #1534, #1463). Data: a lockup's free_shares is the unlocking quantity, not the float it was read from (#1513); dragon-tiger seats are ranked within each listing reason (#1512); shareholder-count history returns real periods (#1518); Tencent, Eastmoney and AKShare A-share prices are labelled dividend-additive (#1497); Gildata joins the A-share chain as a token-gated source (#1474); portfolios value any ISO-4217 currency and fail one source, not the snapshot, on a missing rate (#1510); connector account shows Binance, Futu and Trading 212 balances (#1539). New: Bahasa Indonesia UI and README (#1482). Removed: the Requesty provider — point openrouter at its base URL instead. Thanks @shadowinlife, @he-yufeng, @Shizoqua, @lorenzozanee, @cgycorey, @zeus229, @sambazhu, @Yoruxyv and @jastincheis!

  • 2026-09-20 🛠️ Clearer data requests and everyday fixes: monthly 1M requests are now explicitly rejected instead of silently fetching one-minute bars (#1487); weekly/monthly support remains tracked in #1479. Welcome quick actions highlight the selected chip (#1500), DingTalk sanitizes downloaded filenames (#1506), Signal preserves text around mentions after emoji (#1478), and credit-spread tables merge equivalent 5 / 5.0 tenor columns (#1507).

  • 2026-09-19 🛠️ Data errors that looked like missing disclosures or the wrong provider: A-share shareholder counts work again after an upstream column rename; rejected queries now report the provider's error instead of claiming the stock has no disclosure (#1490). Market-data provenance now names the loader that actually served each symbol, with the matching fallback flag and adjustment label, even when the requested SDK is unavailable (#1491). QVeris no longer overwrites indicators with an end date (#1496); adjustment selection, adjusted-response parsing and billing remain tracked in #1494. Thanks @cgycorey and @lorenzozanee!

  • 2026-09-18 ✂️ A redacted answer that lost its row numbers, and one starved order counted as twenty-six: when the grounding gate released an answer with its unverified figures cut, a ranked table came back with (omitted※) where 1, 2, 3, the 12m in its headers and "3 names" in the prose had been. Every integer in a table cell counted as a measurement, and each cut figure's digits were then swept off the rest of the page. A column that numbers its rows is now structure, a plain integer beside words in a cell is read as it would be in a sentence, and the sweep never keys on a single digit; invented returns and multiples are still cut (#1471). In hold mode, the search that scales a basket down to the available cash booked a zero_size rejection on every step, so one contract the cash could not hold read as 26 lot-rounding failures; it is now one insufficient_capital (#1470). Fixed: a local: code in a backtest is served from your own dataset or refused, never filled from a network source (#1467); the event-study CAR standard error now includes the covariance between daily forecasts that share estimated parameters — with a 30-day estimation window the standardised CAR's variance on null events was 1.41–1.46 and is now 1.07–1.08 (#1466); a real historical_var / parametric_var result grounds the VaR it returned (#1464); and twenty alphas no longer fill a missing bar with a constant, while recursive smoothers skip the gap and continue under a rule that is now written down and tested (#1463). Later the same day: a plain LANGCHAIN_PROVIDER=openai setup with gpt-5.6-terra failed on its first tool call, because Chat Completions refuses function tools for the gpt-5.6 models unless the reasoning effort is none. The adapter now retries such a request once on /v1/responses, where the reasoning is kept, and remembers that route for the model (#1473). New: OpenCode Go / Zen as a built-in opencode provider that sends the x-opencode-session id the relay requires, in the compaction thread too (#1416, closes #1415). Merged: an entry memory GC archived is no longer handed to compression as well (#1450); the Patell z uses each normal-return model's own degrees of freedom (#1449); the microstructure estimators reject NaN and infinite inputs instead of returning a zero spread (#1451); a source that must never fall back to the network keeps that promise per symbol too (#1441); and a backtest checks the declared interval against the served bar spacing before annualising, so a daily file declared 1H is no longer annualised at the hourly rate and a weekly file annualises at 52 (#1432). Thanks @5gaLbt and @turtle696966969696 for the reports, and @tonydo, @Shizoqua and @chiww for the fixes!

  • 2026-09-17 🔐 A Robinhood login that reaches several accounts, and a live gate that refused every real order while its tests passed: Robinhood can now be a read-only portfolio source that reads exactly one account, picked from Robinhood's own list with nothing preselected (#1428), and live trading binds each mandate to one account the same way (#1442). The runner and the pre-trade gate had been calling Robinhood with no account and reading its replies one level too shallow, so every reconciliation aborted and every order was refused, while the tests stayed green because their fixtures used a reply shape Robinhood never sends. Positions show unpriced until the quote reply is mapped. Fixed: a swarm worker saves its message log on every exit path that writes a summary (#1439); qlib158's up- and down-day counts no longer count a missing close as a flat day (#1459); a strategy's decay check no longer reads an infinite Sharpe as healthy (#1447); and a custom alpha-zoo root no longer replaces a bundled alpha of the same name process-wide (#1468). Thanks @balu1866 for the reply shapes, and @cgycorey and @0xouzm!

  • 2026-09-16 🧪 Four numerical slips that each returned a plausible number: "low" sat in the sentiment lexicon as both a bullish and a bearish word, cancelling itself out (#1448); head-and-shoulders detection divided by a signed shoulder average, so lopsided shoulders on a negative-valued series passed the symmetry check (#1456); the options engine annualised over one bar fewer than the shared metrics, exaggerating short runs (#1458); and copula pseudo-observations ranked a missing value as the largest and gave ties arbitrary distinct ranks (#1453). Thanks @Shizoqua.

  • 2026-09-15 🧮 A grounding gate that decided what a number was from the words around it: the check every market answer passes before release used to infer whether a figure was a price, a target or a metric from a catalogue of phrasings — 65 regular expressions that grew a fix commit per wording and could give a sentence and its translation different verdicts. The model now declares what each figure is in a figures block the reader never sees (observed, derived, proposed, cited, count); the gate reads only a number's shape and checks every declaration against the session's tool results. A rejected answer gets one correction that names each failing figure with the nearest observed prints, and if it still fails it is released with only those figures cut ((略※) / (omitted※)) instead of being replaced wholesale by a canned refusal, which remains only for an identity problem or a run that observed no price. While it waits, the chat shows "Checking the figures in this answer" in all eight languages. Before release it went through three rounds of adversarial review and real model runs, which added decimal commas, year-shaped prices, untagged code fences, integer prices of instruments quoted in the thousands, prices declared as counts and unchecked numbers reaching the stream. Metadata counts and metric-name tokens no longer ground a metric, and a sentence with several metrics is no longer rejected (#1418, #1420, #1421, #1426, #1433). Thanks @zeus229, @he-yufeng and @5gaLbt!

  • 2026-09-14 🇰🇷 A-shares backtested as perpetual futures, and a swarm argument the model could set but never change: every branchless data source that serves A-shares — local, tencent, eastmoney, baostock, mootdx, sina — routed a pure A-share basket to the crypto engine, which applies none of the A-share rules (stamp tax, T+1, price limits, 100-share lots) and does charge an 8-hourly perpetual funding fee against the position. The run succeeded and its metrics were internally consistent, which is what made it dangerous; a pure A-share basket now reaches ChinaAEngine from every source (#1431). Separately, the swarm worker overwrote every tool call's run_dir with the agent workspace, so for the tools that declare it — backtest above all — the model could pass any directory and read none of it, while the error named no path. A declared run_dir is now honoured inside the workspace and refused outside it with the boundary named, and the backtest tool says which directory it checked (#1430, #1429). New: four connectors land together and the count reaches 18 — KIS (한국투자증권; a genuine 모의투자 paper sandbox on its own host, plus read-only live), Upbit (KRW crypto; paper + read-only live, capped because the exchange exposes no paper/live discriminator), Toss Securities (read-only live; the closed-order history is paged to completion and refused rather than truncated past the cap; read paths validated against a real account) and Scalable Capital's Agentic MCP as a fully read-only profile with an explicit tool allowlist and no order capability (#1407, #1408, #1409, #1417). Fixed: the shared SDK diagnostics told every broker's user to check Longbridge; they now name the affected broker's SDK or gateway in all eight languages (#1436). Thanks @chiww, @cgycorey, @as950118, @dudco and @tingkk!

  • 2026-09-13 🗂️ A broker reply in the wrong shape that counted as an empty account, and run-card diagnostics that never reached the card: the portfolio layer read positions with an empty list as the default, so a reply that never carried a positions list — an MCP response with no mapping yet, or IBKR's official MCP answering without structured positions — became a source holding nothing, and the snapshot was stored as complete. That is exactly the quietly smaller portfolio the aggregation exists to rule out, so a read without a positions list is now refused: the source shows as an error and the snapshot is marked incomplete, while a genuinely empty account ("positions": []) still reads as empty. It surfaced while reviewing a new MCP connector whose holdings are not mapped yet. Separately, the run card kept only scalar metrics, so every dict- or list-shaped diagnostic the engine writes for card readers was dropped — a reader could see how many plans were rejected, but not for which symbol or why. Those metrics now travel in a structured_metrics block, capped at 4 KiB of UTF-8 JSON per metric with anything larger named under _omitted, and render in the Run Card tab in all eight languages (#1424). Thanks @cgycorey!

  • 2026-09-12 📥 A dividend row that looks like a holding, and a number format where one misplaced separator is a thousandfold error: extraETF's CSV exports can now be read into the portfolio layer's position shape — read-only, standard library only, and failing closed on anything it cannot read without guessing (#1406, toward #1170). The Investments export becomes positions and the Transaktionen export becomes typed movements, so a Dividende row, which carries a quantity and a price of its own, is never read as a position, and a transactions file cannot pose as an empty portfolio. Numbers follow the export's German grammar exactly: 1.386,608 is 1386.608, a US-ordered 1,234.56 is refused rather than read a thousandfold off, and a value the eight-decimal wire format cannot hold is refused rather than rounded — 0,000000004 shares would otherwise have become zero. An unknown header (the error names both known column sets), an unknown transaction label, a movement with no instrument, and one instrument listed twice under a single portfolio ID are all refused, while the same ISIN under two portfolio IDs — the export's normal multi-portfolio case — stays two positions. The export carries no snapshot date, so the file's modification time is reported as source_mtime and no position claims an observation time. Nothing calls the reader yet; wiring it into the portfolio container is next. Thanks @cgycorey and @KaiLuettmann!

  • 2026-09-11 📉 Eight years of Tencent history that came back as the last two, and an evidence gate that turned away every backtest the agent ran itself: Tencent's fqkline endpoint serves the last 500 bars of a window, not the first — a CSI 300 request for 2018-01-01..2026-06-30 returns 2024-06-06..2026-06-30 — while the loader paginated forward, stepped past the window after one page and returned a tail-only series with exit code 0 and no warning. It now walks backward from the end date, re-requests an empty page once before believing it, treats an error-shaped reply as a failure, and bumps the loader cache version so series cached by the old walk are never served again (#1411, closes #1410). refresh_strategy_evidence rejected every run produced by the backtest tool, because only the agent runtime wrote the state.json its ingestion gate reads; the tool now records success, failure and timeout itself, and the gate stays fail-closed for runs nobody vouches for (#1413, closes #1412). Concurrent cold-start data requests could come back _unresolved for symbols that were perfectly available: the loader registry marked itself initialised before its imports ran, so simultaneous first callers saw it empty — seven of eight in the reporter's run (#1405, closes #1403). A swarm worker's skills: list, documented as its allowlist, is now enforced by load_skill instead of only by the prompt (#1414), and the correlation skill's Engle-Granger example, which crashed on an unnamed series, now calls the tested quantlib functions instead of its own OLS fit (#1404). One more was ours: thirteen broker config files that hold API keys — alpaca.json, zerodha.json and the rest — were missing from .gitignore though its comment claimed them, so anyone whose VIBE_TRADING_HOME is the checkout was one git add -A away from committing credentials; a test now derives the list from the code. So was a paper cancel that answered for orders it never placed: the Zerodha, Dhan and Shoonya paper connectors simulate orders locally but read the real account, and acknowledged a cancel for any order id — a live one included, which would have kept working; they now accept only the ids their simulator issued. Thanks @shadowinlife, @alanwilhelm and @Shizoqua!

  • 2026-09-10 🧾 A remediation message that named a variable nothing reads, and an adapted strategy that wore its parent's sign-off: when stooq answers with its anti-bot challenge page, the loader tells the operator how to route around it — and both halves of that advice were unreachable as printed. VIBE_TRADING_MARKET_DATA_ORDER_* is read nowhere: the registry builds MARKET_DATA_ORDER_<MARKET> and the config layer passes it to a bare os.getenv, so exporting the name as printed was a silent no-op and stooq stayed at position 2 of the US-equity chain. The other half, "drop stooq from it", is rejected outright — an override must be a permutation of the default chain, so a source can be reordered but not removed. The message now names the variable the registry actually reads and states the constraint, pinned to the registry rather than to a literal so it cannot drift again (#1402). Separately, the first half of description-driven strategy adaptation landed: an adapted strategy is a new artifact pointing at its parent through derived_from, the description may change universe, name and position sizing while the signal is copied verbatim, and the child starts with empty evidence so its numbers come from its own backtest instead of inheriting the parent's (#1391, refs #1149). Two gaps were closed on the way in, both one field over from the rule that PR was written to enforce. dataclasses.replace copies every field the call does not name, s