Methodology
FUND demo-90d · PAPER  ·  2026-05-30 04:24 UTC
How the fund tradespolicy values shown reflect the live RiskPolicy

Ronnie_Fund is a single-account, long-only systematic strategy that runs once per trading day. It evaluates a fixed equity universe through a multi-agent LLM pipeline, applies a deterministic risk layer, and submits market orders against either a paper ledger or a mirrored Charles Schwab brokerage account. This page documents the rules. They are sourced from RiskPolicy and the daily-cycle scheduler at request time, not hardcoded into the page.

1 · Daily cycle

A single launchd job (com.tradingagents.daily-cycle) fires at 12:30 PM ET on weekdays. The cycle is idempotent for a given trading day: a second invocation without --force exits cleanly. Same-day re-runs are explicitly opted into.

The cycle, end to end:

universe.txt
   → agent graph (per ticker, sequential)
   → bundle written to reports/<TKR>_<TS>/
   → signal_extractor parses 5_portfolio/decision.md
   → Allocator emits OrderProposal candidates
   → stop-loss generator emits exit proposals
   → RiskEngine accepts / resizes / rejects each proposal
   → MirrorRouter routes to PaperBroker (always) and SchwabBroker (if live)
   → ledger updated · NAV marked · macOS notification

Per-ticker errors do not poison the cycle. A failing graph run for one symbol is recorded as cycle_ticker_error in the audit log and the cycle continues with the next ticker.

2 · Universe

The active universe lives at data/universes/active.txt — one ticker per line, # introduces a comment. Edits take effect on the next cycle; no restart required. The current list reflects the Aschenbrenner thesis (compute, power, electrical infrastructure, hyperscalers, defense, BTC sleeve) — the strategic backbone is documented separately in docs/strategy/aschenbrenner-thesis.md.

3 · From signal to proposal

For each ticker the agent graph produces a structured decision bundle. The 5_portfolio/decision.md file is parsed for a rating of Buy, Hold, or Sell, plus a horizon and rationale. Holds emit no proposal. Buys and sells are handed to the Allocator.

The Allocator maps each signal to a target weight as a fraction of NAV. The mapping is presently coarse — a single default target per direction, bounded above by the per-name cap — and is the layer most likely to evolve as conviction-tier signal output stabilizes. Per-position sizing is always re-checked by the RiskEngine before any order leaves the pipeline.

4 · Risk gates

Every proposal is evaluated by the RiskEngine, which can accept, resize, or reject it. Each decision is written to the audit log as a risk_decision row before any order leaves the engine.

4.1 Per-name concentration

CAP 12% OF NAV

No single ticker may exceed 12% of NAV after the proposal would fill. Proposals that breach are resized to the cap; if the resize falls below the minimum lot, the proposal is rejected.

4.2 Theme caps

AI_INFRA ≤ 60%

DEFENSE ≤ 5%

Aggregate exposure to a theme is bounded above by its cap, measured as a fraction of total NAV (not the equity sleeve net of BTC). With a 30% BTC sleeve target, the practical ceiling on AI-infra names is 60% of total NAV, which corresponds to roughly 86% of the actively-traded equity sleeve at full BTC deployment. The defense cap of 5% caps a deliberately small sleeve. Themes outside the cap dictionary are uncapped via this mechanism; the per-name 12% cap still applies.

4.3 BTC sleeve

TARGET 30% ± 5% · MSTR ≤ 6%

BTC exposure is held at a target weight of 30% of NAV inside a ±5% band via the IBIT spot ETF and an actively-traded MSTR position. MSTR is independently capped at 6% of NAV given its embedded leverage to BTC. Proposals that would push the sleeve above the band's upper edge are resized; below the lower edge, a buy is favored.

4.4 Stop-loss (per position)

TRIGGER AT -8.0%

Every cycle, before evaluating new buy/sell signals, the stop-loss generator inspects each open position. If the unrealized return on a position is at or below -8.0% from the position's average cost basis, an exit proposal is emitted. Stops do not trail and are not measured against a high-water mark — a position that appreciates materially and then reverses will not trigger the stop unless the decline breaches the original cost basis.

4.5 Drawdown circuit breaker

HALT NEW BUYS BELOW -15% YTD

If the fund's calendar-year-to-date NAV is at or below -15% versus its January 1 opening NAV, the engine rejects all new buy proposals for the remainder of the calendar year. Exit proposals (sells, stops) continue to be processed normally. The breaker resets on January 1 regardless of inception date — a fund that goes live in Q4 has only a partial first-year window before its first reset, after which the next-year baseline is the January 1 NAV that follows.

4.6 Uninvested cash reserve

CASH ≥ $0

The cash floor specifies a minimum idle balance the engine will protect. A buy proposal whose cost would consume that reserve is rejected outright, not resized down. The current floor of $0 means buys are bounded only by the actual cash balance; raising the floor is the standard mechanism for reserving liquidity for redemptions, planned contributions, or risk-event cash. When buys hit this gate, the smart-rebalance funder (§5) can free cash by trimming a low-conviction position so the next cycle can re-attempt the buy.

4.7 Earnings blackout

BUY rejected when next-earnings is within 5 calendar days

The fund's typical horizon (3–6 months) doesn't justify paying the IV ramp into a binary print. New BUY proposals on a ticker reporting within the blackout window are rejected at the gate. SELLs are unaffected — the operator must always be able to exit before a print if the thesis breaks. Set the field to 0 on the policy to disable. Earnings dates are refreshed each cycle from the market-data adapter and cached in earnings_calendar.

4.8 Wash-sale lookback

BUY rejected within 30-day window after a loss-realizing sell of the same ticker

IRS §1091 disallows a loss when a substantially-identical security is bought within 30 calendar days of the sale; the disallowed amount is added to the replacement lot's basis. The gate prevents the foot-gun pre-trade by querying tax_lot_consumptions for recent loss-sells on the proposal's ticker. Active windows surface on the Tax page and on each affected position drilldown. Coverage limits: ticker-exact match only (no "substantially identical" fuzzy matching), single-fund only, and no post-trade basis adjustment if a wash slips through. Smart-rebalance funding sells are exempt from this gate by design — they're already operator-visible.

4.9 Cross-asset hedge floor

Aggregate value of TLT, GLD ≥ 0% of NAV

An opt-in defensive sleeve to dampen concentration risk. When the aggregate market value of hedge_tickers falls below hedge_floor_pct × NAV, the cycle emits a buy proposal on the first hedge ticker sized to close the gap. The buy goes through the same RiskEngine, so per-name caps still apply. The system never auto-sells hedges — the operator owns the unwind decision (insurance isn't auto-trimmed when it's working). Disabled by default (0%).

5 · Smart-rebalance funder

When a BUY hits cash_floor, emit ≤ 2 funding sells of 25% of a low-conviction position

Cycle 3 (2026-05-08) ended 47 signals → 28 buy proposals → 0 fills, all 28 rejected for cash_floor (fund 99.6% deployed). Without a mechanism to free cash, every high-conviction buy dies on contact with the gate. The funder closes that loop deterministically.

  • Trigger: any buy rejected with reason containing "cash floor".
  • Selection: open positions sorted by unrealized return (most-negative first — cut losers); tiebreak by smaller notional. Skips BTC sleeve tickers (owned by §4.3), tickers already being sold or bought this cycle, and operator-pinned tickers.
  • Sizing: floor(quantity × funding_sell_pct_of_position), with a 1-share floor.
  • Outcome: generated sells fill same-cycle if accepted; the buys they fund get a fresh chance the next cycle with freed cash. Two-cycle latency is acceptable for a daily fund and avoids paired-batch broker semantics.

Off via smart_rebalance_enabled = false. Operator-pinned tickers are excluded entirely — see the Pin button on each position drilldown.

6 · Order construction & fills

Accepted proposals become orders rows with order_type = market and time_in_force = day. The cycle fires at 12:30 PM ET; market data for sizing checks, paper fills, and end-of-cycle NAV marks is fetched from the market-data adapter at cycle time, not from prior close or next open. Two execution paths exist:

  • PaperBroker — always runs. Uses a realistic fill model: last quote bid/ask, spread-half slippage in basis points scaled by notional, and a flat commission. Fills are written immediately as the cycle does not wait for asynchronous broker state.
  • SchwabBroker — only runs when live_trading_enabled is set in system_state. Submits via the Schwab Trader API and writes a synthetic fill keyed to the venue order id; the actual settled fill is reconciled separately (deferred to Phase 7d).

The MirrorRouter always sends to paper and conditionally forwards to Schwab.

7 · NAV mark and lifecycle

At the end of each cycle the fund's NAV is recomputed from cash plus mark-to-market position value (last quote × quantity, falling back to cost basis when the market data adapter cannot quote). One NavSnapshot row is written per trading day; the value flows into every chart and statistic on the rest of the terminal.

8 · Return calculation conventions

Return statistics are computed from NAV snapshots starting at the date of the first fill — not from the date the fund record was created. The intent is to avoid annualizing across a ramp-up period when most capital was uninvested, which would produce arithmetic noise rather than a meaningful figure; it is not a presentation choice to flatter returns.

  • Total Return is the realized change in NAV from inception to the most recent snapshot.
  • CAGR and Calmar are reported only when post-inception history exceeds 30 days. Below that threshold, annualization is statistical noise and both fields render as n/a.
  • Sharpe and Sortino are computed on daily NAV returns, annualized at √252, with a risk-free rate of zero. This convention overstates both ratios relative to any calculation that uses the contemporaneous T-bill rate; figures here are not directly comparable to published fund metrics.
  • Performance numbers presented on this site are not prepared in accordance with GIPS or any other recognized performance-reporting standard.

9 · Tax-lot accounting

Every BUY fill writes a row to tax_lots capturing acquisition date, price, and quantity. Every SELL fill consumes lots in FIFO order (oldest acquisition first), writing one tax_lot_consumptions row per (sell × lot) pair with computed realized P&L, holding period, and ST/LT classification (holding > 365 days = long-term).

FIFO is the U.S. federal default convention and matches how Schwab reports on Form 1099-B when no specific lot is identified at sale. Year-end Form 8949 export is available via:

tradingagents tax export --fund-id N --year YYYY

Output lands in reports/tax/<fund>/form-8949-YYYY.csv. The Tax page (/terminal/tax) shows realized YTD/all-time KPIs, year-by-year breakdown, and the wash-sale window roster.

Glossary

NAV
Net Asset Value. Cash balance plus the mark-to-market value of all open positions at the most recent quote.
Inception
The date of the first fill executed by the fund. All return statistics are anchored here, not at fund creation.
Total Return
(NAVt / NAVinception) − 1, expressed as a percent.
CAGR
Compound annual growth rate. (1 + Total Return)(365.25 / span_days) − 1. Suppressed when span_days < 30.
Volatility (ann.)
Standard deviation of daily NAV returns × √252.
Sharpe
(mean daily return × 252) ÷ annualized volatility. Risk-free rate assumed to be zero.
Sortino
Same as Sharpe but the denominator uses only downside deviation (semi-deviation of negative returns).
Max Drawdown
Largest peak-to-trough decline in NAV over the post-inception window, expressed as a negative percent.
Calmar
CAGR ÷ |Max Drawdown|. Suppressed when CAGR is unavailable.
Signal
The structured output of the multi-agent graph for a given ticker on a given date — at minimum a Buy / Hold / Sell rating and rationale. Holds emit no proposal.
Conviction
The strength of a signal expressed as a target weight in NAV. Currently coarse (one default per direction); intended to evolve into a tiered mapping as agent output stabilizes.
Sleeve
A bounded sub-portfolio defined by purpose — e.g., the BTC sleeve (IBIT + MSTR, target 30% of NAV) or the equity sleeve (everything other than BTC).
Theme
Coarse classification of a ticker (AI Infra, BTC Sleeve, Defense, Other). Used for cap enforcement only — does not affect signal generation. Mapping lives in tradingagents/portfolio/themes.py.
Per-name cap
Maximum fraction of NAV any single position may occupy. (12% default).
Drawdown breaker
YTD drawdown threshold below which new buy orders are rejected. (-15% default; resets Jan 1.)
Stop-loss
Position-level return threshold at which an exit proposal is emitted. (-8.0% default.)
Mirror router
Routing layer that always sends orders to the paper ledger and optionally forwards to Schwab when live trading is enabled.
Slippage (bps)
Modeled execution cost above mid-quote, measured in basis points (1 bp = 0.01%). Scales with notional in the paper fill model.
Audit log
Append-only event log capturing every cycle event, risk decision, order, and fill.
Tax lot
One row in tax_lots for each BUY fill capturing acquisition date, price, and quantity. SELL fills consume lots in FIFO order; the resulting consumptions carry realized P&L and ST/LT classification.
FIFO
First-In-First-Out — the U.S. federal default tax-lot consumption order. Schwab and other retail brokerages apply FIFO when no specific lot is identified at sale.
Form 8949
The IRS form for reporting capital gains and losses from securities sales. The CLI export (tradingagents tax export) produces one row per consumption with the columns the form requires.
Wash sale
An IRS §1091 disallowance triggered when a substantially-identical security is bought within 30 days of a loss-realizing sell. The risk gate prevents wash sales pre-trade by rejecting BUYs on tickers in the lookback window. Active windows surface on the Tax page and on the affected position drilldown.
Smart-rebalance funder
The cycle helper that emits funding sells of low-conviction positions when buys are rejected for cash floor. Picks the worst-performing non-BTC, non-pinned position to trim. Off via smart_rebalance_enabled = false.
Hedge sleeve
A bounded sub-portfolio of negatively-correlated holdings (e.g., TLT for rate moves, GLD for tail risk). The hedge floor policy ensures aggregate market value of hedge_tickers stays ≥ hedge_floor_pct × NAV. Defaults to disabled.
Risk Watch
Proactive alerts surfaced on the morning memo: stop-near-trigger, concentration approaching cap, drawdown approaching breaker, stale signal (no agent report in 14+ days).
Ronnie_Fund is a single personal brokerage account operated by its owner for personal investment purposes only. This site is a private operational dashboard and is not intended for distribution to any third party. Nothing on this site constitutes investment advice, a recommendation, an offer to sell, or a solicitation of an offer to buy any security. Past performance is not indicative of future results. All investments involve risk, including possible loss of principal. Performance statistics presented here are calculated using the methodology described on this page and are not prepared in accordance with GIPS or any other recognized performance-reporting standard. Return calculations use a risk-free rate of zero; figures are not directly comparable to published fund metrics. Trading signals are generated in part by large language model (LLM) outputs, which may be incorrect or systematically biased; the operator assumes all responsibility for trade decisions. The fund holds concentrated positions in volatile instruments including cryptocurrency-linked securities. The universe, risk policy, and operational parameters are subject to change without notice.