Bot factory
Create and operate autonomous LLM paper-trading bots — each a persona plus risk config that reasons over live candles and trades a local paper ledger, fully isolated from the pipeline and the live engine.
The bot factory is Forven's autonomous LLM paper-trading surface. A bot is not a graduated strategy — it is an LLM agent you configure with a persona and a set of risk limits, which then runs on a timer: each cycle it looks at recent market data, decides to buy, sell, short, cover, hold, or observe, and books the result as a paper trade in a local ledger. Bots are deliberately separate from the gauntlet pipeline and the live HyperLiquid engine — they are a sandbox for watching how a prompt-driven trader behaves, not a path to real capital.
Forven is a research tool. Bots are always paper-only — there is no live or testnet order path from the bot factory at all. Every bot trade is inserted into a local paper ledger against live market prices; nothing reaches an exchange. This is a highly experimental feature: an LLM making autonomous trade calls is nondeterministic, and any numbers a bot produces are illustrative, not predictive, and never financial advice.
What a bot is
A bot is a configured LLM trader that runs as its own background process. You give it a personality and a rulebook in plain language and a set of hard numeric limits; the model supplies the decisions and Forven enforces the limits. A bot's configuration has two halves.
Persona (what the model reads).
- Soul — the bot's temperament and personality.
- Strategy — the approach it should take.
- Context — seed knowledge you want it to start with.
- Guardrails — behavioral rules. These are best-effort and LLM-interpreted, not a hard guarantee — the numeric limits below are what actually enforce safety.
- Model — the LLM it runs on. Leave it blank to inherit your configured default provider (bots use the same bring-your-own-key routing as the agents).
- Reasoning verbosity —
minimal,standard, orverbose.
Risk and execution (what Forven enforces).
capital_allocation(default100,000) — the bot's starting paper capital.max_position_pct(10) — the largest single position as a share of equity. A hard block.max_concurrent_positions(5) — longs and shorts counted together.max_drawdown_pct(3) — the bot pauses itself if equity falls this far from its peak.stop_loss_pct/take_profit_pct— optional automatic exits.taker_fee_bps,slippage_bps,funding_rate_bps_per_day— the cost model applied to every fill and open position.cooldown_seconds(60) — the delay between decision cycles.session_hours— an optional trading window (supports overnight windows).asset_mode(free_roamorlocked) pluslocked_pairs.max_llm_calls_per_day(200) andmax_consecutive_errors(5) — the spend and error circuit breakers.
There is no "container image," symbol/timeframe bundle, or strategy to wrap. You create a bot from a template or from scratch.
Where it lives in the UI
The factory is three routes:
/bot-factory— the bot list. Each card shows the bot's status, model, watched pairs, capital, and LLM-call usage, with Create, Start, Stop, Edit, Clone, and Delete controls. A Kill All Bots control appears only while a bot is running. A persistent amber "Highly Experimental" banner sits at the top./bot-factory/[id]— the detail and monitor page. A stats header (capital, max position, a live drawdown gauge, LLM calls today, consecutive errors) sits above five tabs: Activity Feed (the decision log), Open Positions, Trade History, Memory, and Config Versions (with a field-by-field version diff)./bot-factory/editor— the create/edit form, opened with?id=,?template=, or?strategy=. It has Core, Trading, and Advanced tabs, and can Save as Template.
Every action is operator-gated. The backend requires an operator key (FORVEN_OPERATOR_KEY) on the /api/bot-factory/* endpoints, so the factory is unavailable to read-only sessions.
How a bot runs
Once started, a bot spawns a detached OS subprocess that loops on its cooldown. Each cycle it:
- Checks its circuit breakers — consecutive errors, the daily LLM-call cap, and the session-hours window.
- Fetches a market snapshot: 1-hour OHLCV candles for its watched pairs, from Binance via CCXT. A bot sees nothing else — no web, no news, no other timeframes.
- Marks its open positions to the live price, accrues funding, and fires any stop-loss / take-profit exits.
- Checks the drawdown gate.
- Recalls its memory, then calls the LLM for a decision.
- Executes the decision as a paper fill (applying fees and slippage), then sleeps until the next cycle.
Bots observe live prices only for the pairs they watch. In free_roam mode a bot watches only BTC/USDT and ETH/USDT — the editor labels this "Default Pairs (BTC/ETH)" precisely because it is not a market-wide scan. Use locked mode with locked_pairs to pin a specific set.
Lifecycle states
A bot is stopped, running, paused, or error. Start spawns the process; Stop kills it. A bot pauses itself — it is not an operator action — when it trips the consecutive-error circuit breaker, hits its daily LLM-call cap, or breaches its max-drawdown limit. It goes to error on process death or a stale heartbeat. The manager auto-recovers running and errored bots when the backend restarts, and a daily-capped bot resumes on its own at UTC midnight when the call budget resets.
Steps: create and run a bot
- Open
/bot-factoryand review the fleet. - Click Create (or Clone on an existing bot) to open the editor. Optionally pick a template to pre-fill the persona and limits.
- On the Core tab, write the soul, strategy, context, and guardrails, and choose a model (or leave it blank for your default provider).
- On the Trading tab, set capital, the risk percentages, optional stop-loss / take-profit, the fee and slippage model, cooldown, verbosity, asset mode, and session hours.
- On the Advanced tab, set the daily LLM-call cap and the consecutive-error breaker.
- Click Create Bot to save the configuration.
- Click Start on the new bot to spawn its process; use Stop to halt it.
What you'll see
The new bot appears with a status dot. Open it to watch the Activity Feed stream decisions (trade, observation, pass, error, paused, with BUY/SELL/SHORT/COVER and long/short badges), the Open Positions tab mark to a live price, and the Trade History and Memory tabs fill in as it runs. Because bots are paper-only, none of this touches an exchange — treat every figure as illustrative.
Long and short
Bots trade both directions. The decision vocabulary is BUY / SELL / SHORT / COVER / HOLD / OBSERVE:
- BUY opens (or adds to) a long; SELL closes the long.
- SHORT opens a short — it profits when price falls; COVER closes the short.
- A bot holds at most one long and one short per ticker, and P&L, stop-loss / take-profit direction, slippage, and funding are all computed direction-aware.
Opens must be priceable from the live snapshot or they are blocked, no single position may exceed max_position_pct of equity (a hard block), and max_concurrent_positions counts longs and shorts together. Aggregate leverage above equity raises a soft warning only — paper leverage is allowed by design.
Accounting is ledger-authoritative
A bot's realized_pnl is derived from its trade ledger, not accumulated in memory:
- On close, gross P&L is computed and both entry and exit fees are subtracted before the bot's realized P&L is credited.
- Funding is booked per cycle — charged to longs, credited to shorts.
- Equity shown to the model is
capital_allocation + realized_pnl, and positions are auto-sized fractionally from that equity — the LLM does not specify a quantity. - A peak-equity watermark is persisted, so pausing and restarting a bot cannot silently reset its max-drawdown gate.
- On startup Forven reconciles each bot's realized P&L from the ledger, so a crash between a close and its equity write self-heals.
Headline win-rate and P&L come from a server-side stat over all of a bot's trades, not a recent slice, and show "—" when there are no closed, decisive trades yet.
Isolation
Isolation is the core of this design, on two axes.
Bots never touch live trading. Every bot trade is tagged source='bot:{id}' and is excluded from the live engine's risk reasoning: it does not appear in the brain's context, the risk audit, strategy analytics, exchange reconciliation, or the global kill-switch flatten. A bot paper position on BTC can never raise a false duplicate against a real HyperLiquid position, and the kill-switch will never force-close it at a live price. Bot safety is entirely self-contained — its own drawdown gate, circuit breaker, daily cap, and stop-loss / take-profit — so the risk page's global controls are neither its safety net nor a threat to it.
Bots are isolated from each other. Each bot runs as a detached subprocess with a minimal, non-inherited environment: it gets only the credential for its own LLM provider — no exchange or Discord secrets — plus its own rotated log file and its own memory collection, which is dropped when the bot is deleted. Stop and kill target the exact process for that bot, never a recycled PID or the parent.
Honesty
The bot factory is deliberate about not overstating what it knows:
- No fabricated marks. An open position with no live price feed shows a "—" and zero unrealized P&L, never the entry price echoed back as a fake-flat mark. The drawdown gauge on the detail page mirrors exactly what the runner enforces.
- No phantom capabilities. Bots do not browse the web, read news, or see multiple timeframes — the templates say so plainly. The former news-reading template is now the honest tape-reading "Catalyst Reaction Trader," whose own description states it does not browse the web.
- Honest labels.
free_roamis labeled "Default Pairs (BTC/ETH)," guardrails are labeled best-effort, and a failed LLM call is not charged against the daily budget.
Endpoints
Every action is an operator-gated HTTP call against the local API (default 127.0.0.1:8003). The whole router sits behind require_operator_access.
| Method | Path | Purpose |
|---|---|---|
GET POST | /api/bot-factory/bots | List the fleet, or create a bot. |
GET PUT DELETE | /api/bot-factory/bots/{id} | Inspect, update, or delete a bot. |
POST | /api/bot-factory/bots/{id}/start · /stop · /clone | Start, stop, or clone a bot. |
POST | /api/bot-factory/kill-all | Stop every running bot (two-step confirm in the UI). |
GET | /api/bot-factory/bots/{id}/trades · /stats · /positions | Trade ledger, aggregate stats, open positions. |
GET | /api/bot-factory/bots/{id}/decisions · /memory | The decision log and the bot's memory. |
GET | /api/bot-factory/bots/{id}/versions · /versions/{v1}/diff/{v2} | Config version history and a version diff. |
GET POST | /api/bot-factory/templates | List or save persona templates. |
GET DELETE | /api/bot-factory/templates/{id} | Read or delete a custom template (built-ins are protected). |
GET | /api/bot-factory/from-strategy/{strategy_id} | Pre-fill a bot from an existing strategy (seeds text only). |
Update hot-reloads certain risk fields into a running bot. Delete stops the subprocess, closes the bot's open paper trades, and drops its memory collection before removing the record. Clone creates a new {name} (copy) bot record immediately rather than only opening the editor.
To list the fleet from PowerShell with an operator key:
$headers = @{ "x-operator-key" = $env:FORVEN_OPERATOR_KEY }
Invoke-RestMethod -Uri "http://127.0.0.1:8003/api/bot-factory/bots" -Headers $headersBuilt-in templates
Four personas ship as a starting point: Momentum Scalper, Mean Reversion Scanner, Catalyst Reaction Trader, and Conservative Swing Trader. Each omits an explicit model (so it inherits your default provider) and is scoped to the 1-hour data a bot actually sees. Save your own with Save as Template in the editor.
Caveats
- Highly experimental. The list page carries this warning for a reason — autonomous LLM trading is nondeterministic and unproven. Watch what a bot does; do not walk away and assume it behaves.
- Always paper. There is no live or testnet order path from a bot. Every fill is simulated in a local ledger against live prices.
- It spends tokens. A running bot calls the LLM every cycle on your own key. The
max_llm_calls_per_daycap is the hard ceiling; see models & providers and cost controls. - A bot sees only 1-hour candles for its watched pairs — no web, no news, no other timeframes.
free_roammeans BTC/ETH only, not the whole market. - Its safety gates are its own. Per-bot drawdown, circuit breaker, daily cap, and stop-loss / take-profit are enforced inside the bot; the global risk-page kill-switch deliberately does not touch bot trades.
Related
- Paper trading — the supported execution mode bots simulate against.
- Models & providers (BYOK) — the LLM routing a bot's model resolves through.
- Cost controls — how LLM spend is bounded.
- The memory bank — how a bot's isolated memory works.
- Risk & safety — the live-engine controls, and why they leave bot trades alone.
Settings
The unified Settings hub at /settings — Data, Lab, Trading, Agents, Models, Notifications, System, Sandbox, and the Danger Zone — plus the setup wizard and unsaved-changes guard.
AI Drop Zone
Sessions (ADZ-####) that scope batch strategy uploads and backtest runs into one queryable namespace, so you can later ask "what did I test?"