Seven agents, one exchange, no human in the loop. You write a policy file once. From then on a deterministic strategy engine trades the twenty most liquid perps on a factor model, the agents supervise, propose and review on a schedule, and every send has to get past a deterministic gate that checks the ticket against your written limits and your live account before a single script is allowed to sign. It runs on Grok Bot, Grok Build, Claude Cowork or Claude Code, on testnet by default, on mainnet when you change one word.
This is an SWC Studio fork of HyperGrok Trading Desk by Andrew Wilkinson and Galleon Labs. The roles, skills and desk vocabulary are theirs; the autonomy and the engine are the fork's additions. See License and credit.
Start
Claude Code
Install the plugin, copy the desk templates, write the policy, and run one cycle by hand before you schedule anything:
/plugin marketplace add swcstudiospace/hypergrok-autonomous-desk
/plugin install hypergrok@hypergrok
claude plugin validate passes on this checkout (29 skills including the 5 commands, 7 agents, 1 hook). Until the v2.4.0 push to GitHub lands, install from a local clone instead: claude plugin marketplace add /workspace/hypergrok then claude plugin install hypergrok@hypergrok; the commands and the guard behave the same either way.
mkdir -p /workspace/trading-desk/{proposals,briefs,research,strategies,data,journal/incidents,watch,autonomy}
cp /workspace/hypergrok/template/autonomy.json /workspace/trading-desk/autonomy.json # then edit account, mode, limits
cp -r /workspace/hypergrok/template/strategies/hg-systematic /workspace/trading-desk/strategies/ # the engine's rules, status: paper
mkdir -p /workspace/trading-desk/.claude && cp /workspace/hypergrok/template/claude/settings.json /workspace/trading-desk/.claude/settings.json
cp /workspace/hypergrok/template/claude/CLAUDE.md /workspace/trading-desk/CLAUDE.md
cd /workspace/trading-desk && claude -p "/hypergrok:desk-cycle /workspace/trading-desk" --permission-mode bypassPermissions --max-turns 40
autonomy.json is the whole of your standing authority: network, account, whether the desk may originate ideas, how often it runs, and the limits every ticket is checked against. Only you edit it. The template ships with mode: testnet and small numbers; read desk-autonomy-policy before you change either.
When one cycle has run cleanly with you watching the transcript, hand it to the scheduler. scripts/autonomy_cycle.py wraps the same claude -p call with a lock, a heartbeat, a log per cycle and a timeout:
python3 /workspace/hypergrok/scripts/autonomy_cycle.py --desk-root /workspace/trading-desk --once # one cycle
python3 /workspace/hypergrok/scripts/autonomy_cycle.py --desk-root /workspace/trading-desk --loop # every cycle_interval_minutes
*/15 * * * * python3 /workspace/hypergrok/scripts/autonomy_cycle.py --desk-root /workspace/trading-desk --once >> /workspace/trading-desk/autonomy/cron.log 2>&1
/hypergrok:desk-status reads the desk back to you at any time; /hypergrok:desk-halt <reason> stops new risk until you resume from your own terminal. desk-claude-code-runtime explains why nothing prompts and what still says no.
When the supervising cycle is running cleanly, start the engine beside it. It runs as its own process (a systemd unit and a Dockerfile are in deploy/) and the cycle switches from proposing trades to checking the engine's:
python3 /workspace/hypergrok/scripts/strategy_engine.py --desk-root /workspace/trading-desk --once --dry-run # print the universe, regime and plan; send nothing
python3 /workspace/hypergrok/scripts/strategy_engine.py --desk-root /workspace/trading-desk --loop --interval 60
The engine runs only strategy folders that carry a signed review. Review the shipped one (or any the Strategist writes) against template/strategy-criteria.json on real history before it trades:
python3 /workspace/hypergrok/scripts/strategy_review.py --desk-root /workspace/trading-desk --strategy hg-systematic
/hypergrok:strategy-review <name> runs the same script and reads the result back to you.
Three more pieces belong to a desk that runs unattended for weeks, all in deploy/supervisor-cron.example and desk-operations: scripts/paper_record.py writes the signed paper record a strategy needs before you may set it live (/hypergrok:paper-record <name> from Claude Code); scripts/strategy_rereview.py reruns every paper and live strategy's review weekly and demotes one that fails; and scripts/desk_dashboard.py renders autonomy/dashboard.html, a read-only page you can glance at. The API wallet key can come from a secrets manager instead of a file (HYPERGROK_KEY_COMMAND); desk_send.py --dry-run tells you which source it would use.
Grok Bot
There is no published Grok Bot template for the fork yet, so the install is the manual path. Open Grok Bot and paste this to any Bot:
Set up the HyperGrok autonomous desk from https://github.com/swcstudiospace/hypergrok-autonomous-desk/blob/v2.4.0/skills/hypergrok-bootstrap/SKILL.md. Follow the bootstrap skill, use https://github.com/swcstudiospace/hypergrok-autonomous-desk/blob/v2.4.0/SETUP.md for the complete runbook, and finish with its evidence receipt.
Bootstrap builds the desk exactly as the original did, read-only: seven Bots, a Trading Floor, twenty-four shared skills, a live zero-key Opening Bell, and a receipt that says no key was requested and no order was sent. Autonomy is switched on afterwards, by you, in this order: provision a testnet API wallet through the secure secret store; write autonomy.json on the desk computer and confirm every value; re-scope Grok Bot's Require Approval rule to everything that reaches /exchange except python3 /workspace/hypergrok/scripts/desk_send.py, plus every fund-moving action; copy template/strategies/hg-systematic into the desk's strategies/ folder; start the engine on the desk computer; then create one Desk Lead routine on cycle_interval_minutes that runs the supervising cycle. Section 4 of desk-autonomous-loop and section 2 of desk-multi-runtime have the exact steps. Run the first cycle with you watching, then let the routine take over.
The desk starts in research mode either way. The first demo uses only Hyperliquid's public /info endpoint: no wallet, account read or order.
Opening Bell
The first thing the desk shows is useful, live output, not a configuration form:
python3 scripts/opening_bell.py --coin ETH
It reports source and UTC time, mid/mark/oracle, 24-hour change and volume, hourly funding, open interest, spread and depth at 5/10/25 bps. Twenty book levels stop a few bps from the mid on a liquid perp, so it re-reads the book at a coarser nSigFigs page until each band is measured, names the page every figure came from, and still marks a band no page reaches as a floor rather than a total. scripts/desk_doctor.py then checks the release, team files, the reviewed skill bytes, desk folders, public connectivity and the autonomy setup. Both are read-only and standard-library Python.
Meet the desk
| Role | What they do for you |
|---|---|
| Desk Lead | Runs the floor and the cycle. Pre-flight, routing, the journal's first line, and the one who halts the desk when something does not reconcile. |
| Market Analyst | Live Hyperliquid data every cycle: price, depth, funding, open interest, candles. Timestamped and sourced. |
| Research Analyst | What is happening and what is scheduled: fundamentals, news, catalysts, onchain and social context. |
| Strategist | Originates trades from your live strategies in strategies/*/RULES.md and, within policy, its own discretionary calls with a stated invalidation. Still writes rules with you and backtests them honestly. |
| Risk Manager | Keeps your written limits, sizes every trade from your live account, writes the machine-readable ticket the gate reads, and can say no. |
| Execution Trader | The one role with the keys. Runs the policy gate on a ticket and, on a PASS, calls the one sending script, once, then reconciles from the exchange record. |
| Trade Reviewer | Keeps the desk journal, writes the cycle summary, and grades every closed trade on process and outcome, separately. |
In Grok Bot six sit together on the Trading Floor group chat and the Trade Reviewer works by DM; in Claude Code they are labelled passes in one session or subagents from agents/. Every trade follows the same path:
idea -> evidence -> risk sign-off -> policy gate -> one send -> reconciliation -> review
A day on the autonomous desk
14:15 UTC, the timer fires. The Desk Lead validates the policy and reads the halt state. The Risk Manager reads clearinghouseState and frontendOpenOrders live: equity 10,200, no positions, nothing resting. The Execution Trader finds nothing in-flight in the send ledger. The analysts scan BTC, ETH and SOL, the three markets the policy allows, with UTC times and sources on every number.
The Strategist finds a trade. The live funding-mean-reversion rules fire on ETH. It opens HG-20260907-01 with origin: strategist:funding-mean-reversion, an entry at 3,000, a stop at 2,900, and the evidence already filled in from the scan. The Risk Manager sizes it from the live book and writes the ticket, in markdown for people and in JSON for the gate:
TICKET HG-20260907-01 | testnet
market ETH-PERP side buy size 0.4827 ETH (~$1,448)
entry limit 3,000 Gtc stop sell 0.4827 @ 2,900 market (sent with the entry)
risk $51.00 = 0.5% of equity $10,200 (clearinghouseState 14:16 UTC) R = 100
sized on a stressed stop: 100 + 3.00 slippage + 2.65 fees = 105.65 per ETH
origin strategist:funding-mean-reversion ticket proposals/HG-20260907-01.ticket.json
The gate reads it. Nobody types "approve". The Execution Trader runs policy_gate.py check, which checks the ticket against autonomy.json, the desk's own ceilings, the halt file, the send ledger and a fresh read of the account, and prints every gate with its numbers:
POLICY GATE | HG-20260907-01 | PASS | 2026-09-07T14:17:02Z
[ok] mode: autonomy mode is testnet
[ok] network: ticket testnet vs policy testnet
[ok] halt: not halted
[ok] ticket-age: 1.0 min since risk PASS (max 30)
[ok] market: ETH in ['BTC', 'ETH', 'SOL']
[ok] risk-arithmetic: size x stressed = 51.00, ticket risk 51.00
[ok] equity-fresh: live equity 10200.00, ticket 10200.00
[ok] risk-per-trade: 0.500% vs max 0.5%
[ok] protection: every open position has a resting stop
[ok] open-risk: 0.500% after (existing 0.00 + 51.00) vs max 2.0%
[ok] daily-loss: day PnL +0.00% vs stop -2.0% (start 10200.00)
[ok] not-sent: HG-20260907-01 not yet sent
[ok] rate-hour: 0 sends in the last hour vs max 4
approval written: proposals/HG-20260907-01.approval.json
The approval is a signed file: an HMAC over the ticket bytes, valid for ten minutes, dead if one byte of the ticket changes, spent by one send.
One send. desk_send.py re-verifies the approval, checks the mid has not drifted past the ticket's slippage bound, writes its intent and client order ids to autonomy/sends.jsonl before anything leaves the machine, and sends entry and stop as one grouped order with a one-minute expiresAfter:
SEND HG-20260907-01 | testnet | entry | grouping normalTpsl
ETH buy 0.4827 @ 3000.0 {"limit": {"tif": "Gtc"}} reduceOnly=False cloid=0x9f3e...
ETH sell 0.4827 @ 2900.0 {"trigger": {"isMarket": true, "triggerPx": 2900.0, "tpsl": "sl"}} reduceOnly=True cloid=0x9f3f...
price check: mid 3000.4 is 1.3 bps from entry 3000.0 (tolerance 10 bps)
response (responded) 2026-09-07T14:17:09Z: {"status": "ok", "response": {"type": "order", "data": {"statuses": [{"resting": {"oid": 77123401}}, {"resting": {"oid": 77123402}}]}}}
execution record: proposals/HG-20260907-01.execution.json
The journal. The Trade Reviewer closes the cycle with one block in journal/2026-09-07.md:
CYCLE 2026-09-07 14:15 UTC | testnet | mode testnet | halt: no
book: equity 10,200.00 | 0 positions | open risk 0.0% | day PnL +0.0%
reconciled: none open
scan: BTC ETH SOL ok (allMids 14:16 UTC)
ideas: strategist:funding-mean-reversion -> HG-20260907-01 (ETH long) | discretionary: none
sized: HG-20260907-01 PASS 0.4827 ETH, risk 51.00
gated: HG-20260907-01 PASS
sent: HG-20260907-01 resting oid 77123401, stop resting 77123402
incidents: none
next: reconcile HG-20260907-01 fills
Something goes wrong. Three cycles later a send times out and the order cannot be found by cloid. The Execution Trader does not resend. It records the unknown result, and the Desk Lead halts the desk:
HALTED 2026-09-07T15:02:41Z by desk: HG-20260907-02 unknown send result, not found by cloid inside expiresAfter
new risk is blocked; reduce-only tickets still pass the policy gate
While halted, every entry ticket fails the halt gate; closes and protective stops still pass, so the desk can always get flat. It keeps reconciling, keeps journaling, and waits. Only you can resume, from your own terminal, and the Claude Code guard denies the agent that command. When you come back, /hypergrok:desk-status tells you what is open, what is protected, and the one thing to look at first.
The engine
The agents are good at evidence, judgement and review and bad at doing the same arithmetic every minute for months. The engine does the arithmetic. scripts/strategy_engine.py and the engine/ package are deterministic, standard-library Python that run as a service beside the desk: every fifteen minutes they rebuild the universe (the top twenty perps by open interest that pass liquidity floors, capped by your policy's allowed_markets, where ["*"] means the whole engine universe); every minute they read the live book, write a protect ticket for any position without a resting stop, and log positions that vanished; every four hours they score the universe on a factor model (vol-normalised momentum, funding carry, short-horizon reversion, halved risk when BTC volatility is extreme) and write the exits and entries the scores call for. Each ticket is the same JSON the Risk Manager would write, with origin: strategist:hg-systematic, and it takes the same path: policy_gate.py check, then one desk_send.py call on a PASS. The engine has no other route to the exchange, and it halts the desk itself on three failed reads, an unknown send result or a position it cannot protect.
Be clear about the clock. This is not what "high frequency" means on an exchange with co-location: risk runs on a one-minute clock and decisions on a four-hour clock, because the backtest showed an hourly decision clock on this fee schedule turning 10,000 USD into 5,400 in seven months, almost all of it fees and stop churn. The desk trades as fast as the evidence says it can afford to.
The evidence is in template/strategies/hg-systematic/BACKTEST.md: scripts/engine_backtest.py runs the same signal and sizing code on real hourly candles and funding from Hyperliquid's public /info endpoint, with fees, slippage and stops filled worse than their trigger. The chosen defaults returned +15.5% over 208 days with a 5.1% maximum drawdown across 128 trades; the same data with equal factor weights returned -32%, and the first configuration tried lost 46%. That sensitivity is the finding. Seven months is one regime, sixty of the trades ended on their stop, and nothing in that file is a forecast. The backtester now also runs on 4-hour bars (--bar-hours 4, back to 2024) and daily bars (back to 2020): on 4h bars over 833 days the same defaults returned +13.47% with a Sharpe of 0.83 and a -7.06% maximum drawdown, +8.36% in-sample and +4.72% out-of-sample. A longer sample is still one sample.
Four things the engine does around the signal, all added in v2.4.0 and all bounded by your policy:
- Real fees.
desk_send.pyrecords your account's actual tier fromuserFeesintoautonomy/fees.json, and the engine sizes and the backtester price from that taker rate instead of the 0.045% default.scripts/execution_stats.pyreads thestepsof every maker-first execution record, measures the fill rate per market, and writes a bounded recommendation formaker_offset_bpsandmaker_wait_sthat the engine applies to the next entry ticket; one small step per run, never past the bounds, and only with five or more samples. - A risk ladder.
limits.risk_ladderinautonomy.jsonis a list of rungs, by default halve at a 3% drawdown from the equity peak and quarter at 6%. When drawdown crosses a rung, the engine's gross exposure and the gate's per-trade risk budget are both multiplied by the rung's scale, and the gate prints it (ladder 0.5 at 3.2% drawdown from peak). The ladder only ever shrinks a number; the backtester applies it identically. - A liquidity check. Before an entry ticket is written, the engine reads resting depth within 10 bps on the entry side from
l2Book. If it is belowlimits.min_depth_multiple(default 20) times the intended notional, the entry is deferred: no ticket, the decision stays open, and the engine retries forentry_retry_minutes(default 30) before moving on. - More than one bet. Two more strategy folders ship as
status: draftintemplate/strategies/:hg-carry(funding carry with a momentum filter, an eight-hour clock and two-day holds) andhg-breakout(a Donchian-style breakout on a four-hour clock with a tighter stop). Two new factors,breakoutandoi_change, are in the engine at weight zero forhg-systematic.scripts/strategy_correlation.pyprints the daily-return correlation between every reviewed strategy from the curve its review stores; a pair above 0.7 is one bet with two names, and the report is what you read before raising any strategy'sshare.
python3 /workspace/hypergrok/scripts/strategy_engine.py --desk-root /workspace/trading-desk --once --dry-run # compute, print, write nothing
python3 /workspace/hypergrok/scripts/strategy_engine.py --desk-root /workspace/trading-desk --once --observe # gate every ticket, send none
python3 /workspace/hypergrok/scripts/strategy_engine.py --desk-root /workspace/trading-desk --loop --interval 60
python3 /workspace/hypergrok/scripts/engine_backtest.py --desk-root /workspace/trading-desk --hours 5000 --top 20 --ablate
python3 /workspace/hypergrok/scripts/engine_backtest.py --desk-root /workspace/trading-desk --hours 5000 --bar-hours 4 # about 833 days on 4h bars
python3 /workspace/hypergrok/scripts/execution_stats.py --desk-root /workspace/trading-desk # fill rates and maker-first recommendations
python3 /workspace/hypergrok/scripts/strategy_correlation.py --desk-root /workspace/trading-desk # correlation between reviewed strategies
The strategy ships as status: paper in strategies/hg-systematic/RULES.md: it trades only while the policy is on testnet, and the engine refuses paper on mainnet. Promotion is two edits by you on two separate days: status: live in RULES.md, then mode: mainnet in autonomy.json. Once a strategy is live, the agents read params.json and the status line; they never write them, and the guard denies the attempt. desk-strategy-engine has the whole of it.
Agents write strategies
Since the strategy-research release the desk is not limited to the one shipped strategy. The Strategist may author its own, and the engine runs every strategy that has passed a written, deterministic gate. The three parts:
The folder contract. A strategy is strategies/<name>/ with RULES.md (frontmatter status: draft | paper | live, share of the policy's position slots, optional allowed_markets; the hypothesis and rules in prose) and params.json (parameters for the same factor engine that runs hg-systematic; every strategy is that engine with different knobs, so reviews compare like with like). The engine gives each runnable strategy its slots by share, narrows each to its own universe subset, attributes every position to the strategy that opened it, and keeps a decision clock per strategy.
The gate. scripts/strategy_review.py backtests the folder on real hourly history with the engine's own code and applies template/strategy-criteria.json: enough trades and days, profit factor, drawdown, fee load, an out-of-sample split, robustness under perturbation (weights tilted, entry threshold shifted, stop multiple scaled), and since v2.4.0 two wider checks: long-history (the same rules on 4-hour bars over about 833 days must return at least 0% with a drawdown no worse than -25%) and wide-universe (the top 40 by open interest on the hourly window must return at least 0%). It writes review.json, signed with the desk's gate key over the exact bytes of RULES.md and params.json, and now stores the backtest's daily curve so scripts/strategy_correlation.py can compare strategies without rerunning them. The engine runs only paper or live strategies with an eligible, signed review younger than fourteen days whose bytes still match; editing either file voids the review. Nobody hand-writes review.json, and a forged one fails the signature.
The ladder. draft is anyone's and the engine ignores it. paper the Strategist may set once a review is eligible, and it trades on testnet only. live is yours alone: the Claude Code guard denies any agent writing status: live or editing a live strategy's files, and review.json and strategy-criteria.json are never agent-written. The Strategist's research loop, weekly budget and anti-overfitting rules are in desk-strategy-research; /hypergrok:strategy-review <name> runs the gate from Claude Code.
Be honest about what a pass means. hg-systematic passed the default criteria: its worst perturbation (factor weights tilted by -0.2) returned -4.85% with an -18.6% drawdown, and 83% of the perturbations were positive. That is a seven-month sample meeting a written bar, and the size of the swing under a small tilt shows how fragile such a record is. A review is a record of what the rules did on one stretch of history, not a forecast, and it never chooses the status.
Running it as a service
An experiment needs a gate. A service that is left alone for weeks needs a few more things, and v2.4.0 adds them.
A paper record before real money. status: live is now refused by the engine unless strategies/<name>/paper-record.json exists, is signed for the strategy's current review, and says ready. scripts/paper_record.py writes it from the engine's realised events on testnet: at least twenty closed trades over seven days, with win rate, average hold, stop rate and drawdown inside the tolerances the paper block of template/strategy-criteria.json sets against the backtest distribution. A paper record that does not resemble the backtest is the most useful thing the desk can tell you before mainnet, because either the market changed or the backtest was wrong, and neither is a reason to go live. Nobody hand-writes the file; the guard and the settings template deny it.
Maker-first execution. An entry ticket with execution.style: maker-first (the shipped params.json sets it) is sent as a post-only order at the mid moved inside by maker_offset_bps, with its stop grouped as before. The sender waits maker_wait_s, cancels what did not fill, protects any partial fill with a standalone stop, and sends the remainder as the bounded IOC it would have been, unless the price has moved past the ticket's tolerance, in which case the remainder is dropped and the record says so. Every step is in the execution record, and the whole sequence is one approval. What it saves is the taker fee and the crossing on the fraction that fills passively: on the shipped strategy's 208-day backtest, assuming half of entries fill as maker, fees drop from 137 to 114 USD on 10,000 and the return moves from +15.5% to +16.4%; at 80% fills, +16.7%. That is one point, because the strategy already trades slowly; it matters far more for anything faster. The fill rate in the backtest is a stated assumption; the paper record measures the real one.
A re-review that can demote. scripts/strategy_review.py now also checks a recent window (the last thirty days must return no worse than -5%), so a strategy whose last month looks nothing like its history fails even when the whole period still passes. scripts/strategy_rereview.py reruns the review for every paper and live strategy on fresh history, weekly from your cron, and on a rejection demotes one rung: live to paper, paper to draft, with an event, an alert and a line the Trade Reviewer picks up. It is the only path that ever moves a status downward on its own. Nothing moves one upward; a pass keeps a strategy where it is.
A page to look at. scripts/desk_dashboard.py renders autonomy/dashboard.html: policy mode, halt, heartbeat age, equity, positions and protection, the universe, an equity line, every strategy with its review, paper record and slots, the last decisions, sends, realised results, alerts and today's journal. One self-contained file, no external requests, refreshes itself every minute, cannot act. --serve puts it on localhost for an SSH tunnel; do not expose it.
A key the desk never sees. engine/secrets.py resolves the API wallet key from the environment, else from HYPERGROK_KEY_COMMAND (a secrets-manager command run without a shell; recipes for 1Password, AWS, GCP, Azure, Vault and Doppler are in desk-operations), else from a file that must be mode 600 and owned by the running user. Only desk_send.py calls it, only at the moment it signs, and it reports which source it used, never the value.
Four runtimes
The desk is files plus scripts. Any runtime that can read the desk root, run Python and start a prompt on a schedule can run it; what differs is where the engine process lives, how the cycle is scheduled, and what stops a wrong write.
| Runtime | Hosts the engine | Runs the supervising cycle | Schedule | Independent guard |
|---|---|---|---|---|
| Grok Bot | yes, on the desk computer | yes, six Bots on the floor | one Desk Lead routine | the re-scoped Require Approval rule |
| Grok Build (CLI) | yes | yes, one session, labelled passes | cron calling grok -p ... --yolo | --deny rules; the sender's own verification |
| Claude Cowork | no; supervises a desk on your linked computer | yes, one session per scheduled task | Cowork scheduled task | the sender's own verification |
| Claude Code (CLI) | yes | yes, labelled passes or subagents | cron calling autonomy_cycle.py --once | hooks/guard.py PreToolUse hook |
The sender's own verification is the floor every runtime stands on: desk_send.py refuses without a valid gate approval whatever asked it to run. desk-multi-runtime has the per-runtime steps, the cron lines and the pre-flight list, and deploy/ has the service unit, Dockerfile and compose file for hosting the engine anywhere with outbound HTTPS.
What the desk knows
Twenty-four skills, in the portable SKILL.md format, shared by every role.
Bootstrap - pinned release install, Opening Bell, team construction, desk doctor and a receipt that distinguishes what happened from what still needs a manual step.
Hyperliquid - setup and API wallets, market data, account state, orders (limit, IOC, take-profit and stop-loss with grouping, client order ids), positions and margin, WebSocket feeds, advanced actions (dead-man's switch, TWAP, spot), and a compact API reference. Copy-pasteable curl for reads; the official Python SDK and @nktkas/hyperliquid for anything that signs.
Desk - how the team works: operating model, the trade lifecycle and ticket, risk limits and sizing arithmetic, the execution protocol, monitoring and routines, post-trade review, incident playbooks, and the strategy lab.
Autonomy - the policy file and the gate that replaces human approval, the unattended cycle and how to schedule it, the Claude Code runtime with its permission template, guard hook and slash commands, the strategy engine and its backtester, the strategy research loop and its gate, the four runtimes and what each one is responsible for, and operations: the key resolver, maker-first execution, the paper-record gate, the weekly re-review, the dashboard and the operator checklist.
Built for real money, nobody watching
- A policy gate, not a person.
scripts/policy_gate.pychecks every ticket against your writtenautonomy.json, the desk's own ceilings, the halt file, the send ledger, the rate caps, the daily loss stop and a live read of your account. It prints every gate with its numbers. A PASS is a signed approval file that dies in ten minutes, dies if the ticket changes, and is spent by one send. A failed read is exit 2, never a pass. - Ceilings you cannot loosen. Your policy may only tighten the autonomy ceilings: 1% per trade, 4% open, 10x, six positions, -5% a day, ten sends an hour. A policy that sets any value looser is invalid as a whole and the gate refuses every ticket until you fix it.
- One sender.
scripts/desk_send.pyis the only thing that signs an/exchangeaction. It refuses without a valid approval, writes its intent to the ledger before the request leaves the machine, sends once withexpiresAfter, and never retries. An unknown result is reconciled by client order id, not resent. - Testnet first.
autonomy.jsonships withmode: testnet. The ticket's network must equal the policy's. Promotion to mainnet is you editing that one word, nothing else. - A kill switch only you release. Any role may halt the desk, and must when a send result is unknown, a position cannot be protected, the loss stop is hit or the account does not reconcile. Reduce-only tickets still pass while halted.
kill_switch.py resumeneeds a human--byand is denied to the agent. - A guard outside the conversation. In Claude Code,
hooks/guard.pyruns before every Bash, Edit and Write call and refuses adesk_send.pycall without a valid approval, any raw/exchangerequest, any fund-moving action, a resume, any write toautonomy.json,risk-limits.md,review.json,paper-record.jsonor the gate key, any write ofstatus: live, and any edit to a live strategy'sRULES.mdorparams.json. Deny wins overbypassPermissions. In Grok Bot the equivalent is the Require Approval rule re-scoped to every exchange path except the reviewed sender. - A trade-only API wallet. The only key the desk ever holds. It can trade; it cannot withdraw. The settings template denies the session reading it, and
desk_send.pyreads it only to sign. - Sized on a stressed stop. A triggered stop is a market order: it slips and pays taker on both legs. The desk sizes on what the stop will actually cost, at your account's real taker rate from
autonomy/fees.json, and the gate recomputes the arithmetic. - A risk ladder that only shrinks.
limits.risk_ladderscales the per-trade budget and the engine's gross exposure down as drawdown from the equity peak crosses each rung (default half at 3%, a quarter at 6%). The gate validates the rungs at load, prints the scale in force on every ticket, and no rung can enlarge anything. - No entry into a thin book. The engine defers an entry when resting depth within 10 bps on its side is below
limits.min_depth_multipletimes the notional, keeps the decision open, and retries forentry_retry_minutesbefore letting it go. - A reviewer who keeps you honest. Every cycle is journaled; every closed trade is graded on process and outcome separately, in a file you can read.
- A strategy gate the agents cannot forge. Any strategy the agents author is backtested on real history by
scripts/strategy_review.pyagainst written criteria and runs only with a signed, fresh review whose bytes match. Only you writestatus: live. - A paper record before live. The engine refuses
status: livewithout a signedpaper-record.jsonfromscripts/paper_record.pysaying the strategy's testnet trades resemble its backtest. The Strategist runs it; only you act on it. - A re-review that demotes.
scripts/strategy_rereview.pyreruns every paper and live strategy's review weekly and demotes one rung on a rejection, with an event and an alert. It is the only thing that moves a status downward on its own, and nothing promotes itself. - A key from a secrets manager.
engine/secrets.pytakes the key from the environment, aHYPERGROK_KEY_COMMAND, or a mode-600 file, refuses anything else, and reports the source rather than the value. The settings template denies the session reading the key file and the service'sengine.env. - Alerts and metrics you can wire in. Set
HYPERGROK_ALERT_WEBHOOK(Slack, Discord or any JSON endpoint) and the desk posts halts, unknown send results, repeated unavailable reads and demotions; every alert is also appended toautonomy/alerts.jsonl. Each engine tick writesautonomy/metrics.prom, a Prometheus text file a node exporter or the supervising cycle can read, andscripts/desk_dashboard.pyturns the same files into a read-only page.
Be clear about what that buys. The gate is arithmetic, not judgement: it guarantees that nothing is sent outside your written limits, on the wrong network, into an unprotected book, past the loss stop, faster than the rate cap, twice for one ticket, or after the ticket went stale. It does not make a bad strategy good, and an agent with shell access and a trading key can do what that key allows; the guard, the ceilings, the trade-only wallet and the testnet-first rule are what bound that. The engine's backtest is one seven-month sample whose result flips sign under a small change of weights, so read it as a record of what was tried, not as a forecast of what comes next. Perpetual futures can liquidate an account. HyperGrok is documentation and scripts, not financial advice.
Also installs in Grok Build and Cursor
The same agents/, skills/ and rules/ load as a plugin: twenty-four skills, and the seven roles as subagents. Grok Build runs the supervising cycle headless with deny rules (see Four runtimes). Cursor has no equivalent of the Claude Code hook or the deny rules, so a desk there is supervised conversationally and the gate still decides.
The same pack installs as a skill from GitHub:
npm exec --package=skills@1.5.23 -- skills add swcstudiospace/hypergrok-autonomous-desk
Listing: skills.sh, populated once the pack has been installed that way.
Inside the repository
SETUP.md what a Grok Bot follows to build the desk, read-only
agents/ seven roles: Bot profile card + full system prompt
skills/ twenty-four skills (bootstrap, hyperliquid-*, desk-*, and the seven autonomy skills)
commands/ /hypergrok:desk-cycle, desk-status, desk-halt, strategy-review, paper-record
hooks/ the Claude Code PreToolUse guard
engine/ the systematic engine: universe, data (candles, funding, open interest, l2 depth), signals (five factors), portfolio, risk (the drawdown ladder), backtest, strategies (the registry), alerts (webhook and metrics), secrets (the key resolver)
deploy/ systemd unit, Dockerfile, compose file, env example, supervisor cron lines
template/ autonomy.json, strategy-criteria.json, the Claude Code settings and CLAUDE.md, the Grok Bot profile and skill hashes
template/strategies/ hg-systematic: RULES.md (status: paper), params.json, BACKTEST.md and the raw trade record; hg-carry and hg-breakout: RULES.md (status: draft), params.json, BACKTEST.md
scripts/ opening_bell, desk_doctor, policy_gate, desk_send, kill_switch, autonomy_cycle, strategy_engine, engine_backtest, strategy_review, paper_record, strategy_rereview, desk_dashboard, execution_stats, strategy_correlation, release checks
docs/ how it works, FAQ, template contract, provenance
assets/ the mascot - use it as your Bots' avatar
| Doc | |
|---|---|
| How the desk works | roles, files, the gate, the strategy gate, trust boundaries, the autonomy boundary |
| FAQ | how it trades without you, how you stop it, the engine and its backtest, agent-written strategies, the risk ladder, thin-book deferrals, fees and correlation, alerts and metrics, the runtimes, mainnet, keys, testnet, customising the team |
| Skills index | every skill and who uses it, including the engine and multi-runtime skills |
| Grok Bot template | public profile, publish contract and clean-install evaluation |
| Provenance | sources, licences and the fork |
| Contributing · Security · Changelog |
License and credit
MIT licensed, with the copyright and permission notice retained when reusing copies or substantial portions.
HyperGrok Autonomous Desk is an SWC Studio fork of HyperGrok Trading Desk by Andrew Wilkinson and Galleon Labs. The seven roles, seventeen original skills and desk vocabulary are theirs; the policy gate, sender, kill switch, Claude Code guard, cycle runner, strategy engine, backtester, strategy gate, paper-record gate, re-review and the seven autonomy skills are the fork's additions.
See reuse and attribution for a ready-to-copy credit line. If this desk helps your work, a star on the original repository is appreciated and entirely optional.