dexterm

docs › Autotrade (paper)

Autotrade (paper)

Strategies you write or copy from presets, validated in one file, and backtests on your own recorded history with a held-out check. Paper only, self-directed, not financial advice.

What it is (paper, self-directed)#

Autotrade (paper) is a strategy file plus an engine that replays it. You write the rules: which coins count as candidates, how a position is sized, how it is exited, and how much loss is allowed. The engine applies exactly those rules, and every size is clamped by them. It runs on paper by default: there is no key, wallet or signer anywhere in a strategy, and a paper run never signs or sends anything. A strategy that says "mode": "live" validates with a warning and runs only with dexterm autotrade run --live, through the live signer and its caps (experimental, can lose all the funds in the trading wallet).

It is self-directed: your strategies, on your machine, with your own recorded history. Nobody runs a strategy for you, and a preset is an example, not a recommendation.

What ships today, covered below:

  • Strategies and presets: presets, your own strategy files, validation and the change journal, on the command line or on the [Q screen](#on-the-q-screen).
  • Backtests and their limits: replays on recorded history, the held-out check, and what the data cannot tell you.
  • The runner and candidate sessions: dexterm autotrade run --paper, your own Claude working each candidate the screener finds, every size clamped by your strategy.
  • Exits and wakes: the exits that run on their own, the judgement calls your agent is woken for, and what it can and cannot do with them.
  • Change a strategy by chat: the analyst proposes, you see the diff and apply it with a key (a less-safe change needs a second key).
  • Running it all day: how long a run lasts, which Claude account it uses, the day caps and the usage guard.
  • Stopping it: a soft stop, a flatten and the panic switch, the heartbeat, and checking the record of a run.
  • What it costs: the Claude usage of a session, measured.
  • What it will not do: live money, copy-trading automation, managing anyone else's money.

On your phone: your own Telegram bot sends the entries, exits, PnL cards and halts, takes /pause and /kill, and can make every entry wait for your tap (entry.decide: "agent+approve").

Still to come, documented here when it lands: a background service that keeps the runner going without a terminal, and the runner filling through the paper desk with the exit monitor as its own process.

Strategies and presets#

A strategy is one JSON file (dexterm-strategy/1) with six parts:

  • Entry: the screener filter grammar, verbatim (for example liq >= 30K vol1h > 15K !flag:mint !flag:freeze), an age window, safety gates (no mint or freeze authority, top-10 share, dev share, a market-cap source split, a "young and already vertical" reject, and what to do when the holder source is down) and triggers (every screen match, or a 5-minute momentum push).
  • Exits: one or more exit profiles: a take-profit ladder, a trailing stop, a time stop, an optional hard stop, thesis breaks (a liquidity drop, a market-cap source split, dead volume), a maximum hold time and, for the moonbag profile, a cost-recovery sell and a trail on the free bag that is left.
  • Sizing: a fixed amount, a percent of the book, risk-sized against the stop, or scaled by the agent's confidence inside your bounds, with optional scale-in tranches. Every size is capped by a maximum percent and a maximum dollar amount.
  • Risk: a per-trade loss cap, a daily loss halt, drawdown size-down and halt levels, the most positions open at once, total exposure, entries per day, a loss-streak cooldown and per-coin re-entry rules.
  • Agent and execution: the session limits for the runner and the fill model's fee, slippage, network fee, price-impact cap and the liquidity below which a bag cannot be sold.

The file is closed: an unknown key is refused with its path, so a strategy cannot carry a signer, wallet or key section. Validation also checks the rules a schema cannot (a take-profit ladder that climbs, sell fractions that add up to at most the whole position, sizing parameters that match the sizing mode, drawdown levels in order) and prints every problem with its path. Every strategy gets a content hash, so a backtest line always names the exact rules it ran.

Presets#

Six read-only presets ship with dexterm, each on paper (five with a $1,000 paper book, yolo with $200):

presetthe idea
scalpyoung pairs (under 6 h) on a 5-minute push, small take-profits, a hard stop and a short time exit
swingpairs from 1 hour to a week old on every screen match, wider take-profits and trail, a review after 90 minutes
runnerolder pairs with deeper liquidity, sized by confidence, a wide trail and a long hold
moonbagvery young pairs (under 2 h) on an early push, with the holder-safety gates: take the cost back at about 2x, then hold a free bag with a loose trail
sample-dip-laddera shareable example of a custom strategy: risk-sized, buys half and adds half on a dip
yoloHIGH RISK: one young pair at a time after the holder-safety gates and a live LARP check, the cost back at about 2x, then a free bag; paper only. See Full-port yolo strategy

About moonbag: most early entries lose. Young pairs rug often, and a rug cannot be sold: once liquidity is pulled, the bag is stuck and counts as zero. The preset therefore uses small tickets and no hard stop, and the point is the rare coin that runs. Read its backtest's tail numbers, never only the total.

Your strategies#

Your strategies live in ~/.dexterm/strategies/<id>.json (or $DEXTERM_HOME/strategies), one file each. Every change is validated first (an invalid file is never written) and appended to ~/.dexterm/strategies/.journal.jsonl with who made it, the change, and the content hash before and after. Removing a strategy moves it to .removed/, never deletes it.

dexterm autotrade list                          # your strategies and the presets: version, hash, mode, last backtest
dexterm autotrade new my-swing --from swing     # copy a preset to edit
dexterm autotrade validate my-swing             # every problem, with its path
dexterm autotrade import ./shared.json          # store a strategy file (always as paper)
dexterm autotrade journal my-swing              # the change history
dexterm autotrade remove my-swing

A file of yours with a preset's id is used instead of that preset. Importing always sets the mode to paper, whatever the file says.

On the Q screen#

the dexterm autotrade editor on sample data: a strategy form in sections with the screen filter being typed, a caret under the column of an unknown field, the validation panel naming the problem and an exit-profile sketch
the strategy editor on sample data: a typo in the screen filter is caught at its column while you type

Press Q on any screen for AUTOTRADE, paper only. tab moves between its views:

  • Strategies: the presets and your own files with mode, version, content hash and the last backtest (net, drawdown, trades). n copies the selected preset under a new id, d duplicates any strategy, ⏎ or e opens it in the editor, x writes it to a shareable file in ~/.dexterm/exports, and i imports a file (always as paper). o opens the card of a change the analyst proposed in chat (how that works).
  • Editor: one form in six sections (entry, exits, risk, sizing, agent, execution). ⏎ changes the selected field (a true/false field flips in place). Every change re-validates the whole strategy and every problem shows next to its field with its path; the screen filter is checked by the screener's own parser while you type, and the column of a mistake is marked. Each exit profile gets a one-line sketch of its stop, take-profits, trails and limits. s saves only a valid strategy, as a new version with the change in the journal; u undoes your last unsaved change, or, with nothing unsaved, the last saved one (as a new version). The presets open read-only: copy one first.
  • Compare: c on two strategies in the list shows them side by side with the fields that differ first, and b backtests both on the same window of recorded history.
  • Backtest: b backtests the selected strategy on the last 14 days of your recorded history and shows the report: trades, win rate with its interval, net, drawdown, the tail numbers, an equity line, results by exit rule, profile and trigger, the size clamps that fired, the refused entries and the limits box. w runs a sweep around the default exit profile's own settings with the held-out check described below; its verdict is printed as is. Both run in the background, so the app stays live.
  • Runner: a running paper runner's heartbeat, any halt, its candidates, sessions, positions and the last lines of its run file; a runner whose heartbeat is more than 30 seconds old shows as stale. ! stops it, p pauses and resumes new entries, and f then y flattens it (see Stopping it).

Nothing on this screen can switch a strategy to live, arm a mandate or touch a wallet or a key: the mode is not an editable field, an import is always paper, and a strategy that says live is refused for backtests.

Backtests and their limits#

dexterm autotrade backtest my-swing               # over your recorder history (read-only)
dexterm autotrade backtest moonbag --every-candidate --recall 5,10
dexterm autotrade sweep scalp                    # tune on older coins, check on the newest ones
dexterm backtest --subject strategy --strategy swing

A backtest replays the strategy over the history the recorder saved on your machine, with the same entry rules, clamp and exit logic a run would use, and mechanical entries (no agent). It never touches the network or a model. The report gives the trades, wins and losses with a 95% interval on the win rate, the net, the drawdown on marked equity, how many bags could not be sold, and which exit rule, profile and trigger each result came from. Below 20 trades it says to read the counts, not the rates.

For strategies that live on a rare tail, like moonbag, it also prints:

  • the tail: trades that ended at -80% or worse or could not be sold, how many took their cost back, the net without the single best trade, the result per dollar staked with a bootstrap 95% interval, and the exit-multiple median, 90th percentile and maximum;
  • --every-candidate: every candidate entered at a fixed $20 with the book's caps lifted, so each entry is an independent sample and the result does not depend on which coins arrived first;
  • --recall 5,10: of the coins that later ran 5x or 10x, how many the entry rules passed, which rule refused the others, and how each entered one was closed.

The held-out check. sweep tries a grid of parameters (for example the trail width or the first take-profit). It splits the coins by when they were first seen: the newest 30% are held out, and no coin is in both halves. It tunes on the older coins only, then checks the held-out coins exactly twice, with the unchanged strategy and with the tuned one. It only reports a gain when both halves have at least 20 trades and the tuned strategy makes money on the held-out coins. A tuned strategy that only loses less is reported as exactly that.

Finer history for the coins that matter. The recorder's snapshots are written on moves of about 5% at the screen's refresh pace, which hides the path a stop or a take-profit lives on. Run the headless recorder with dexterm record run --focus-ticks and it also samples the coins you hold on paper or have open every 5 seconds, and your watchlist and autotrade candidates every 10 seconds, with 1-minute candles built from those samples. A backtest reads those samples in time order next to the snapshots, so for those coins a stop fills at the next 5- or 10-second sample instead of the next snapshot. The slower fields (24-hour volume, holders, top-10 share, authorities) come from the coin's latest earlier snapshot, never a later one. Samples are kept 14 days and candles 90 days. With --retention-mb N the recorder removes the oldest history to stay under N MB instead of pausing; what is kept and for how long is in recorded history.

On the history recorded so far, every preset lost money when entered mechanically. The engine is a way to test your own rules honestly, not a source of profitable ones, and a backtest is not a forecast.

The limits are printed with every report:

  • Coarse prices. Most of the history is recorder snapshots (written on moves of about 5% or every 30 minutes while a coin was listed), not trades, so stops and take-profits fill at the next recorded price. Coins sampled with --focus-ticks are finer (5 to 10 seconds), but a move between two samples is still invisible, and their candles' highs and lows are of the samples, not of every trade.
  • Modelled fills. Price impact on the recorded pool, plus fee, slippage and network fee; not real quotes.
  • Survivorship. Only coins the app recorded are in the history; coins nobody saw are absent.
  • Rugs. A bag below the exit-liquidity floor cannot be sold and counts as zero, and a rug between two snapshots fills at whatever the next snapshot says.
  • Early entries look later than they are. A young pair enters the history only once a feed lists it, and pairs that rugged before any feed saw them are missing, so the measured rug rate is a floor.
  • Missing signals. Narrative, followed-wallet, social and dev-sell signals are not in the history, so those triggers and exits never fire in a backtest.
  • No agent. A backtest has no agent latency and no agent judgement; agent backtests cost Claude usage and stay small.

The runner and candidate sessions#

dexterm autotrade run my-swing --paper                                  # live data, your own Claude login
dexterm autotrade run my-swing --paper --replay tape.json               # a recorded tape, paced
dexterm autotrade run my-swing --paper --stub --replay tape.json        # a scripted agent: no Claude usage

dexterm autotrade run works one strategy on paper, headless, and only one runner runs per machine. It screens the same live data as the app with the app's free sources and request limits: the screener's coins every 10 seconds, and the coins it is working (candidates and positions) every 5 seconds, 30 coins per DexScreener call, under a daily call ceiling. --replay FILE paces a tape saved with dexterm autotrade extract instead; --max-minutes N stops after N minutes; Ctrl+C stops it cleanly.

It talks in market cap. The run's lines (BUY ABC [swing]: $25.00 at $69.7K mcap), the candidate's DOSSIER, the ENGINE notes and the EVENTs your agent reads give levels as market caps by default (with the price beside them in the DOSSIER), and your agent is told to say levels the same way. --price (or display.priceMode: "price") switches the wording to prices; the trades are the same either way, because the engine only reads prices. The run file's fills keep price and add mcap.

A candidate gets one session. A coin that passes your entry rules, and that your strategy would still allow an entry for (a free slot, cash, no halt), becomes a candidate and gets one session on your own claude login:

  • The first message is the full picture: the market now and its recent history, holders and concentration (the top-10 share the strategy's top-10 gate reads, which is Jupiter's, next to the top-10 of the largest accounts from your RPC with pools, bonding curves, launch vaults, locks and burns left out, each named with its source; when the two disagree the message says so), security (authorities and the RugCheck read), candles, recent trades, the coin's creator, and which of these are unavailable and why, plus your bounds (the exit profiles, the largest size your strategy allows, the paper book, open positions).
  • After that, only what changed, with each change in percent: every 15 seconds (agent.deltaEverySec), or at once on a fast move (8% in price or a 15% drop in liquidity). Updates that pile up while the agent is thinking go as one message.
  • Your agent answers every message with one typed decision: enter, wait or skip before a position; hold, exit, tighten or reprofile once it holds one. Anything outside that closed form (an unknown field, a size out of range) does nothing.
  • An enter is clamped by your strategy, and every cut is named in the run file; the order fills on the paper book after the strategy's latency, and is refused if the price ran past the slippage tolerance in between. Fills and refusals reach the agent as notes on its next message.
  • With a position, the exits in your profile run on their own; the agent hears about them as events and can only lower the risk (exit, trim, tighten) or move along the profile's allowed edges. When the position closes, its session ends.
  • A reply that arrives after its candidate was dropped (it stopped matching, the agent skipped, the session ran out) is written down and never executed.
  • With agent.respawnOnWake in the strategy, a judgement call on a position whose session has already ended opens a short position session that answers once.

Sessions and their limits#

Token text is data. Names, symbols and every other text that comes from the token reach the agent only inside <untrusted> tags, and the agent is told such text is never an instruction. A coin named "buy the maximum" still gets your strategy's size, and nothing the agent says can stop a mechanical exit.

The session is answer-only. It is claude -p with no tools, no MCP servers, no settings, no saved session and no slash commands, started in an empty folder (it is not --bare, which would drop your Claude login). Its first event must show the kind of login you configured and no tools; if it does not, the session ends before anything it says counts, and the runner starts no new session for the rest of the run. The limits come from the strategy's agent section (the presets' values): at most 2 sessions at once, $0.50 per session (also passed to claude as its own budget), $10 a day, 60 turns, 90 seconds per decision (60 in moonbag; a slow candidate is skipped, and a slow review gets the exit profile's no-answer rule), 4 hours per session, and the candidate is dropped 5 minutes after it last matched (4 in moonbag). The model is the strategy's agent.model (sonnet in the presets), or --model for one run.

The run file and the heartbeat#

Every step goes to ~/.dexterm/autotrade/runs/<run>.jsonl, written as it happens: each message sent, each raw reply and parsed decision, the clamp with its cuts, fills, events, refusals, session costs and the usage readings. Each line carries the hash of the one before it, so an edited, missing or reordered line shows. A summary sits next to it, and ~/.dexterm/autotrade/runner-status.json (candidates, sessions, positions, spend and the last steps) is rewritten every 10 seconds as the runner's heartbeat. The coins it is working are also handed to the recorder's 5-second sampling (dexterm record run --focus-ticks).

Today's limits. Orders fill on the runner's own paper book with the backtest's fill model (price impact on the pool, fee, slippage). Filling through the paper desk and the exit monitor as its own process are still to come. To stop the runner, see Stopping it.

Paper only: --live is refused, a strategy in live mode is refused, and nothing in the runner can arm a mandate, sign, or touch a wallet or a key.

Exits and wakes#

Exits never wait for your agent. On every tick of a coin you hold, a position monitor runs your exit profile's mechanical rules at once, in this order, and a full exit ends that tick:

  1. Rug or liquidity pull: the pool is under the strategy's execution.minExitLiquidityUsd. A bag that cannot be sold is marked stuck and tried again on every tick.
  2. Thesis breaks: liquidity down by the profile's percent from its recent high, a market-cap source split (the two sources count supplies more than 5× apart; a price move alone never counts, even when one source's figure is minutes old), or dead volume. (The dev-sell exit needs on-chain sell events, which are not recorded yet, so it does not fire.)
  3. Maximum hold (maxHoldMinutes): the position's own dead-man.
  4. Hard stop, when the profile has one.
  5. Cost recovery (moonbag): once, at the profile's gain (+100% in moonbag), sell the slice whose proceeds pay back what the position cost, at most maxSellFrac of the bag (60% in moonbag). What is left is a free bag.
  6. The take-profit ladder: several steps can fill on one jump.
  7. The bag trail (moonbag): only after the cost came back, measured from the peak since entry (55% in moonbag).
  8. The trailing stop.
  9. The time stop, when its action is exit.
  10. Scale-in tranches (sizing.ladder), each re-capped by your strategy.

Wakes. Only after those rules ran does the position's session hear anything, and everything from one tick goes out as one message:

EVENT tp_filled: TP1 filled at +62.0%; 67% of the original size left
position p1: profile swing, cost $20.00, +62.0% on the mid price, TP filled 1, 67% of the size left, liq $100K
Reply with one of: hold, exit, tighten, reprofile.
eventwhenyour agent may answerno answer, or no session
tp_filleda take-profit step filled (when the profile asks for it)hold, exit, tighten, reprofilehold
cost_recoveredthe cost-recovery sell filled (moonbag)hold, exit, tightenhold
time_review / time_tightenthe profile's clock ran out below its targethold, exit, tightenthe profile's wake.noAnswer (swing: exit, runner: hold)
drawdownthe position fell to the profile's wake.drawdownPcthold, exit, tightenhold
thesis_warningliquidity fell part of the way to a thesis exithold, exit, tightenhold
mechanical_exitafter any mechanical exit (for information)hold—
stucka sell could not executeholdtried again every tick

What an answer can do. Your agent can only lower the risk:

  • exit sells everything, and exit with a fraction trims.
  • tighten arms the trailing stop now; on a free bag it halves the bag trail (never below 10%), and nothing can loosen it again.
  • reprofile moves only along the profile's reprofileTo edges, and a move to a profile that allows a bigger size needs the first take-profit filled.
  • It can never add size: an enter or a size on a held coin is refused and written down.
  • It can never stop or delay a mechanical exit: the next tick's rules run whether a reply is pending or not. A reply that lands after its position closed, or after agent.decideWithinSec, is written down and never executed.

On the paper desk. When the monitor runs as its own process, its orders go through the same paper desk that agents use, so every fence there applies around your strategy's own clamp:

  • A paper-only mandate you armed yourself with a keypress (dexterm mandate draft --paper). Its caps apply at the agent tier (a quarter of the per-trade cap), and an entry is refused without one.
  • Each entry registers an exit plan with the desk, and each monitor sell is journaled as agent.paper.exit.<rule> (for example agent.paper.exit.cost-recovery or agent.paper.exit.bag-trail). Every fill carries a short note naming the run, the position, the profile and the exit rule.
  • A cost-recovery slice is sized on at most three Jupiter quotes (one for the largest allowed slice, one to confirm the estimate, at most one correction); without a quote it waits for the next tick instead of guessing.
  • A close-only control state lets exits run while every new buy is refused, also after the mandate has expired. dexterm wallet panic stops everything, exits included.

Restarts and the dead-man. The monitor rebuilds its positions from the paper journal and the run files. An exit that was journaled but had not filled when it stopped is never sent again; the next tick decides afresh. Paper positions it did not open are left alone. It writes ~/.dexterm/autotrade/monitor-status.json every 10 seconds, and entries are refused when that is more than 30 seconds old. It keeps exiting while the runner is down, but it adds no scale-in tranche then.

Today's limits. The monitor and the desk changes are in the app, but dexterm autotrade run does not use them yet. Until it does, these same rules run in the same order on the engine's own paper book, the one backtests use.

Paper only: the monitor refuses a strategy in live mode, and nothing in it can arm a mandate, sign, or touch a wallet or a key.

Change a strategy by chat#

Ask the analyst (a) to change one of your strategies in plain words, for example "make my swing exit faster" or "fewer entries a day on my copy of moonbag". The analyst can read your strategies and backtest them, but it can only propose a change: nothing it says changes a file.

A proposal is a small set of field changes (at most 20) with a one-line reason. Before you see it, dexterm applies it to a copy, validates the result like any strategy, and compares every risk number with the current version:

  • TIGHTER: at least one risk number got safer and none got less safe.
  • NEUTRAL: nothing that moves risk changed (a name, a description, a take-profit step).
  • LOOSER: at least one risk number got less safe: a bigger size or exposure, a higher loss limit, a stop or a trail removed or widened, a safety gate removed, a screen clause dropped, more or costlier agent sessions, or a cheaper fill model.

The proposal shows up as a card on the Q screen under PROPOSALS FROM CHAT. o opens the newest one (the selected strategy's first) with every changed field, old and new, who proposed it and why:

  • y applies a tighter or neutral proposal as a new version of the strategy. The change journal records the proposal's id, who proposed it, the change and the content hash before and after.
  • A LOOSER proposal needs two keys: the first y opens the "less safe" popup that lists every field getting looser, and only a second y applies it. Any other key cancels.
  • n dismisses the proposal; esc closes the card and keeps it for later.

Applying checks the proposal again from scratch: if the strategy changed since it was made, it is refused (dismiss it and ask again), and the tighter or looser verdict is worked out again rather than taken from the card.

What the analyst can never change. The mode (so it can never switch a strategy to live), the book, the daily session budget and the exit-liquidity floor are yours only: a proposal that touches them, directly or by replacing the section around them, is refused before it reaches you. It cannot apply a proposal or skip the second key either. A shipped preset is read-only, so the analyst proposes a copy under a new id instead, always on paper.

A backtest next to it. The analyst can backtest a proposal next to the current version on the same window of your recorded history (up to 14 days). That backtest is read-only (nothing is saved), runs one at a time and is rate-limited, and it carries the limits above: read the number of trades before the totals.

An agent you connect over MCP (dexterm mcp) gets the same seven tools under the same rules: strategy_list, strategy_get, strategy_validate, strategy_propose_edit, strategy_propose_new, strategy_backtest and autotrade_status. An AI scan session cannot propose at all.

Paper only. Not financial advice.

Running it all day#

dexterm autotrade run is a headless process: start it in a terminal (or a terminal multiplexer such as tmux) and it works until you stop it, --max-minutes runs out, or you press Ctrl+C. A two-hour run is measured under What it costs. Screening uses no model at all, so a runner that is only watching costs no Claude usage; usage starts when a coin matches.

  • One runner per machine. A second run is refused while one is working. A lock left by a runner that crashed is taken over once its process is gone.
  • Each run has its own paper book. It starts from the strategy's bankroll, and a new run starts a fresh one. A run that ends with positions still open says how many on its last line and in its run file; nothing carries them into the next run.
  • Leave the terminal open. The runner stops when its terminal session ends, and the computer's sleep pauses it. A background service that starts it with your login and keeps it going is still to come.

Which account, day caps and the usage guard#

These come from ~/.dexterm/autotrade/runner.json (dexterm-runner/1), which stays on your machine and is never part of a strategy or a shared file. Without it the runner uses your default claude login and these defaults:

{ "schema": "dexterm-runner/1",
  "account": { "kind": "native" },
  "caps": { "candidateSessionsPerDay": 48, "positionSessionsPerDay": 48, "modelUsdPerDay": 20, "turnsPerDay": 2000 },
  "allowanceGuard": { "fiveHourMax": 0.6, "sevenDayMax": 0.8, "onLimit": "pause-until-reset" } }
  • account.kind is native (your default login), oauth-token (a long-lived Claude login token from a helper command or a keychain item, handed to claude on a file descriptor; it is never on a command line, in a file or in the run file), config-dir (a separate Claude config folder with its own login) or api-key (a pay-as-you-go key from a helper or the keychain, in the session's environment only). The file names where to fetch a secret, never the secret.
  • The stricter of runner.json and the strategy applies.
  • A day is a real day by the clock (it starts at 00:00 UTC), also in a --replay: a fast replay of many recorded days still spends at most one day's caps per real day.
  • The usage guard reads the usage your Claude sessions report: above 60% of the five-hour or 80% of the seven-day allowance no new session starts, and after a usage limit the runner waits for the reset.

Several strategies at once#

dexterm autotrade run --all --paper runs every strategy you list in ~/.dexterm/autotrade/autotrade.json at the same time, on the same live data. Use it to forward-test several ideas side by side: a scalp and a moonbag, or one preset next to your copy of it with a single change.

  • One data feed for all of them. The screener fetches once and every strategy screens the same coins with its own entry rules, so three strategies do not cost three times the data requests. A coin's dossier is fetched once (at most every 30 seconds), whichever strategy asks for it.
  • Each strategy has its own book. It gets its own bankroll, run id and run file (~/.dexterm/autotrade/runs/<run>.jsonl, hash-chained), loss limits and breaker, candidate sessions and model spend budget. A breaker or a stop on one strategy never stops another. Or let several strategies trade from one paper account, the way several bots would share one wallet.
  • Shared limits for all of them. Model sessions open at once, model spend per day, sessions per day, turns per day, the usage guard of your Claude account and one check of how busy your computer is all count across every strategy. When one of them is reached, every strategy waits.

It is still one runner on your machine: a second run (one strategy or --all) is refused while it works.

The autotrade.json file#

{
  "schema": "dexterm-autotrade/1",
  "strategies": [
    { "id": "moon-a", "preset": "moonbag", "bankroll": { "usd": 500 } },
    { "id": "fast", "preset": "my-scalp", "bankroll": { "sol": 1 }, "caps": { "modelUsdPerDay": 2, "maxSessions": 1 } },
    { "id": "dip", "file": "/Users/you/strategies/dip.json", "bankroll": { "usd": 200 }, "enabled": false }
  ],
  "global": { "maxConcurrentSessions": 3, "modelUsdPerDay": 15 }
}
  • **id** names the strategy in this run: in its run file, on the Q screen and in every alert. Each id is used once.
  • **preset is a shipped preset or one of your own strategies; file** is an absolute path to a strategy file. Give exactly one.
  • **bankroll** is in USD, or in SOL (converted at the SOL price when the run starts; a replay takes "solUsd" or --sol-usd). Without it the strategy's own bankroll applies.
  • **caps** can only tighten a strategy: maxSessions, modelUsdPerDay, candidateSessionsPerDay, positionSessionsPerDay and turnsPerDay. The stricter of the strategy, these caps, runner.json and global always applies.
  • **enabled: false** keeps a strategy in the list without starting it. dexterm autotrade start <id> starts it later in the running run.
  • **global** holds the shared limits. The defaults are 3 sessions open at once, $20 of model spend a day, 96 candidate and 96 position sessions a day, and 4,000 turns a day. The day caps in runner.json still apply on top.

Up to 8 strategies (a strategy on several paper accounts counts once per account). Every strategy must check out before anything starts: a typo, an unknown preset or a strategy that is not on paper stops the whole run with each problem named. --config FILE reads another file. The file is yours: no tool, chat or agent can add a strategy to it or change a bankroll or a cap.

Paper accounts#

A paper account is one simulated wallet that several strategies trade from together. List the accounts in autotrade.json and point a strategy at one with account instead of giving it a bankroll:

{
  "schema": "dexterm-autotrade/1",
  "accounts": [
    { "id": "main", "bankroll": { "usd": 1000 } },
    { "id": "yolo", "bankroll": { "sol": 1 } }
  ],
  "strategies": [
    { "id": "moon", "preset": "moonbag", "account": "main" },
    { "id": "scalp", "preset": "scalp", "account": ["main", "yolo"] },
    { "id": "solo", "preset": "my-scalp", "bankroll": { "usd": 200 } }
  ]
}
  • Many strategies, one wallet. moon and scalp both trade from main's cash: a buy by one leaves less for the other, a sale pays back into the same account, and every size is a share of the whole account (cash plus what is held). An order is checked against the cash again at the fill, so two strategies can never spend the same dollars.
  • One strategy, many wallets. A list of accounts runs the same strategy once per account, here as scalp-main and scalp-yolo. Each one is its own strategy in the run: its own run file, positions, loss limits, sessions and spend budget, and dexterm autotrade stop --strategy scalp-yolo stops only that one.
  • What stays per strategy: its positions, its share of the money at risk (maxExposurePct counts its own positions against the account), its loss streak and cooldowns, its per-coin rules, its entries per day and its model budget. Its drawdown limit reads the account: when the account falls far enough, each strategy on it stops entering at its own limit.
  • Mixing is fine. Strategies with their own bankroll run next to strategies on accounts. A strategy on an account takes no bankroll of its own, and an account it names must be in accounts; anything else stops the run before it starts, with the problem named.

Accounts live for the run: each starts at its bankroll when the run starts (a SOL balance at the SOL price, or "solUsd" / --sol-usd in a replay), and a strategy you start again later joins the same account. Up to 8 accounts. Paper only: an account is simulated cash and never backs a live strategy.

Comparing them#

dexterm autotrade status --all (and the Q screen's runner view while a parallel run works) shows one row per strategy:

ColumnWhat it counts
ACCOUNTthe paper account it trades from (shown when any strategy uses one)
P/L, P/L %the strategy's paper book against its own bankroll; on a paper account, its own trades against the account's balance
WIN, CLOSEDthe share of closed trades that made money, next to how many closed
OPENpositions it holds now
RUGS, RUG EXPexits caused by a rug or a liquidity pull, and the share of the money it put in that went into those coins
MISSEDcoins it saw as candidates, did not enter, that later traded at 2x or more of the price it saw
SPEND, $/ENTRYits model spend, and that spend per entry

Below the table: one row per paper account (start, equity, cash, P/L, open positions and the strategies on it), the strategies together with each account counted once, and the shared limits in use today. --json gives the same numbers for a script. Read the closed-trade counts before the percentages: a few hours of paper trading is not evidence that one strategy is better.

One strategy, or all of them#

  • All of them: dexterm autotrade stop, dexterm autotrade flatten, dexterm autotrade pause and resume, the Q screen's !, f and p, dexterm wallet panic, and Ctrl+C.
  • One of them: dexterm autotrade stop --strategy ID (no new entries, its sessions close, its exits run until it holds nothing; final for that run), flatten --strategy ID, pause --strategy ID and resume --strategy ID, and dexterm autotrade start ID for a listed strategy that is not running. The other strategies keep going.

An agent you connect over MCP can read the list and the comparison, accounts included (autotrade_parallel_list, autotrade_parallel_compare), and can start, stop or pause one strategy that you listed (autotrade_parallel_start, autotrade_parallel_stop). It cannot add a strategy or an account, move a strategy to another account, change a size or a cap, or start anything that is not on paper.

Paper only: --live and "mode": "live" are refused. dexterm holds no key; live trading happens in a Telegram trading bot of your choice (see Live trading). Simulated fills, not financial advice.

Stopping it#

Three switches, from soft to hard. You use them; your agent cannot. A session has no tools, and its answer has no stop, resume or flatten in it.

switchwhat stopswhat keeps runningafter it
dexterm autotrade stop, or ! on the Q screennew entries; every session closes; orders not yet filled are droppedthe mechanical exits on what you holdthe runner ends once nothing is held
dexterm autotrade flatten, or f then y on the Q screenthe same, then every paper position sells at its next ticka coin that cannot sell (a pulled pool) is retried every tickthe runner ends once nothing is held
dexterm wallet panicthe runner halts on its next step, as in a stop; every paper desk refuses toothe runner's mechanical exitsnothing starts again until dexterm wallet resume, a keypress on a real terminal

p on the Q screen pauses new entries, and p again resumes them; open positions keep their exits either way.

With several strategies at once, these switches act on every strategy, and --strategy ID on stop, flatten, pause and resume acts on one. An agent you connect over MCP can stop or pause one strategy you listed there, never all of them and never the panic.

How a stop reaches the runner#

  • stop and flatten write a request for the running run to ~/.dexterm/autotrade/control.json. The runner reads it on every step and shows the halt in its heartbeat file, and the command waits up to 10 seconds (--wait SEC) to tell you it did.
  • A stop is final for that run: a flatten can follow it, nothing lifts it. To trade again, start a new run.
  • A request for an older run never touches a new one, and a control file the runner cannot read counts as a stop.
  • flatten asks for y on a real terminal; --yes answers for a script (a flatten only sells).
  • The runner reads the panic file on every step, and dexterm autotrade run will not start while it is on.

The heartbeat#

  • The runner rewrites runner-status.json every 10 seconds. If it cannot (a full disk, a removed folder), it takes no new entries until it can again, because the Q screen and the exit monitor would see it as gone. With no fresh heartbeat the Q screen shows the runner as stale.
  • Each position keeps its own maxHoldMinutes exit, and a session that dies or times out never holds up an exit.

Checking the record of a run#

dexterm autotrade audit lists your runs. dexterm autotrade audit --verify (all runs, --last, or one run id) recomputes each run file's hash chain and checks it against the run's summary, so an edited, missing, reordered or cut-off line is named by its event number. It exits with code 1 when a run does not verify.

What each session shows first#

Before its first answer counts, a session's start event must list no tools and no MCP servers; otherwise the session ends. The run file also records how many plugins, agents and skills your Claude reports for the session: your own plugins and agents can still list as loaded, and with no tools they cannot act.

Paper only. Not financial advice.

What it costs (Claude usage per session)#

A session costs Claude usage on your own account, counted from what claude reports (total_cost_usd; on a subscription that figure is notional, but it is what the runner's caps count). The screening itself uses no model at all: Claude is only called when a coin matches.

**Measured on sonnet** (the presets' model) on 2026-10-21: a two-hour run of the moonbag preset on live data, with the strategy's own session limits and a $2.75 day cap in runner.json:

in that runmeasured
coins that matched and got a session17 in two hours
turns24: 16 skips, 5 waits, 1 entry and 2 answers about the position
a first look at a coin (one turn)$0.006 to $0.010
a coin watched for a few updates, then skipped (2 to 3 turns)$0.012 to $0.018
the one full loop: entry, a cost-recovery event, the close (3 turns)$0.017
the whole run$0.17, well under its cap

Replies took 2.6 to 8.8 seconds (median 5.3), and the first message was about 1.1 KB. The run file of that run verifies with dexterm autotrade audit --verify.

How much a run costs depends mostly on how many coins match your entry rules and how long each one is watched: every update your agent reads is a turn, and a held position adds a turn for each event. Your caps bound it either way: $0.50 per session and $10 a day from the strategy, and the day caps and usage guard in runner.json.

**Measured on haiku** (--model haiku), on one recorded coin replayed at a 1.5-second pace with the swing preset and its session budget cut to $0.05:

sessionwhat happenedturnscost
1full picture → wait, update → skip2$0.0009
2full picture → wait, two updates → skip3$0.0012
3full picture → updates → enter (clamped to $80), two take-profit events → hold, trail exit → acknowledged, session ended7$0.0023

Three sessions, 12 turns, $0.0044 in all; on haiku a full candidate → position → close loop was $0.0023. Replies took 1.3 to 4.9 seconds (median 2.8).

The run file has each session's cost, and runner-status.json today's total.

Paper only. Not financial advice.

What it will not do#

  • Live money. A run never signs and never sends a transaction: --live and a strategy in live mode are refused, and the runner holds no key. Live trading happens in a Telegram trading bot of your choice, outside dexterm (see Live trading).
  • Copy-trading automation. It does not copy anyone's trades.
  • Managing anyone else's money. It runs your strategies on your machine, with your own Claude login and your own paper book. Nobody runs a strategy for you: there are no hosted runners, no pooled accounts, no fee on its trades and no strategy marketplace.
  • Decide outside your rules. Your agent chooses only inside the bounds you wrote. It cannot raise a size, block an exit, lift a stop or apply a strategy change; you apply a change with a key.
  • Promise results. Presets are examples, and every backtest prints the limits of its data.

Paper only. Not financial advice.