Introduction
RunningAGENCY is a kit for building trading agents. You describe a strategy, by stacking blocks or by writing a function, and publish it. From that timestamp it runs against real prices and accumulates a record of what it decided and why. Other people can put their capital behind an agent, and its builder keeps a share of what it makes for them.
The product is not the agent. It is the record: a run that was written down before anyone knew how it would turn out, and that anybody can recompute. Everything else here exists to make that record trustworthy.
| The builder | Blocks or code. No wallet, no account, no approval. |
| Real prices | Rules run against market data, with execution costs charged. |
| Commission | 7 points of the profit an agent makes for someone else. |
| Open rules | Every agent’s rules are readable on its profile. |
Stage one. Agents deploy no capital: rules, decisions and timestamps are real and execution is modelled. The sixty-day history behind the board is generated demonstration data; the live panel on the front page is a real exchange feed. Chapter 12 sets out that boundary in full, and every chapter here is marked with what it describes.
How AGENCY works
RunningThree layers, and it is worth keeping them apart because they fail differently.
The builder · rules
Where a strategy is expressed. Blocks and code are two surfaces over one rule format; they are not a simple version and a real version. The same object is what the engine runs, which is why a rule shown on an agent’s profile is the rule that ran and not a description of it.
The engine · execution
Where a decision becomes a position. It evaluates the rules, applies the limits afterwards, charges execution costs, and writes the day down. It is deliberately dull and deliberately strict.
The board · assessment
Where records are compared. One rating, one rated round per day, and the same reference for every agent regardless of division. The board ranks; it does not allocate. No capital moves because of a ranking.
Quickstart
RunningFive steps. There is no wallet step in stage one, because there is nothing to connect.
- Open the builder and pick a template. Three starting points, one per division, or a blank sheet. A template is the actual agent from the board, not a simplified copy. You can also fork one from its profile.
- Choose the universe. Which of the thirty-seven instruments the agent may touch at all. Small is better: rules stay comparable when everyone picks from the same pot.
- Stack the rules. Checked top to bottom, first match wins. Reorder them and the preview recalculates. Order is part of the strategy.
- Set the limits. Max trade, cooldown, safe floor, max drawdown. They apply after the rules, always.
- Publish. The agent starts at rating 1200 with status
Unsigned, and its record begins at that timestamp. Nothing from the preview travels with it.
The preview in the builder is a recalculation of the past sixty days. The track record is what happens after you publish. They are drawn differently on purpose. Hatched and labelled Backtest in the builder, plain and labelled Ran, not recalculated on a profile. A record cannot be backdated.
Block reference
RunningFive kinds of block. The tables below are generated from the running engine rather than typed out here, so they cannot describe a version of the builder that no longer exists.
Universe
Which instruments the agent may hold. Anything outside it is dropped from a target allocation, silently and always.
Trigger. What gets watched
Every signal is computed from daily closes, per instrument. A signal that has not got enough history yet reads as unavailable, and a condition on it is false rather than guessed.
Condition. When the trigger counts
A condition can also require the signal to have held for a stretch. Hold
times are given in hours because the live engine ticks every five minutes; a
preview running on daily closes can only check whole days, so it requires
floor(hours / 24) additional days before today. Forty-eight hours means
“today and the two days before”. Anything under 24 hours is not a
constraint on daily data, and the builder says so next to the condition rather
than letting it look like one.
Action. What happens
| Action | Meaning |
|---|---|
Rebalance to | A target allocation in percent. Weights above 100% in total are scaled down; anything left over stays in cash and earns nothing. |
All to safe | The safe instruments of the universe, evenly split. Does nothing if the universe contains none. |
Do nothing | Hold the current weights. Also the default when no rule matches. |
Limit
See chapter 07. Limits are not rules and do not take part in matching. They sit above the whole rule set.
Code API
RunningAny block agent can be ejected to code: once, and not back. The generated function is what runs from then on. It receives a context object and returns a target allocation.
The context
Every call is deterministic and reads only from price history up to the current tick. Nothing in here can see the future, the clock, or the network.
Return value
- An object mapping symbols to weights, for example
{ ETH: 0.6, BUIDL: 0.4 }. - Weights are fractions, not percentages. Negative and zero weights are dropped. There is no shorting in stage one.
- Symbols outside the agent’s universe are ignored.
- A total above 1 is scaled down to 1. A total below 1 leaves the rest in cash.
ctx.hold()means “no change”, which is not the same as returning an empty object. That would mean “sell everything”.
The sandbox
Code runs in a worker with no clock, no randomness and no network. Two layers enforce
it: the source is checked before it runs, and the dangerous names are shadowed inside
the function’s own scope so that they resolve to undefined even if
the check is dodged. Comments and string literals are stripped before the check, so a
word inside a comment does not trip it.
A run is cut off after 3 seconds. That budget is enforced from the outside by terminating the worker. A loop that never ends cannot be interrupted from within, so nothing else would actually work.
Determinism
RunningSame rules plus same prices must give the same result, always, on any machine. This is the constraint everything else is built around, and it is not a preference.
A track record that cannot be recomputed is a claim, not a record. If an agent could roll dice or read a clock, nobody, including us, could ever prove that a published history is the one that actually happened. Recomputability is the entire argument this project rests on, so anything that would break it is refused rather than discouraged.
What this rules out
- Randomness.
Math.randomis unavailable and throws if reached. - The clock.
Dateandperformanceare unavailable. Usectx.day, which counts rated rounds since publication. - The network. No
fetch, no sockets, no imports. An agent sees the prices it is given and nothing else. - Unbounded loops. A loop needs a fixed ceiling. It is also why there is a hard time budget.
- Language model output. Not in the decision path, in any form. A model that is retrained gives different answers to the same question, which is exactly the thing being ruled out.
What happens when an agent breaks the rule
Nothing subtle. The source check rejects it before it runs and returns the reason in
plain words; if it gets past the check, the shadowed name resolves to
undefined and the call fails at runtime, which is reported as a failed
run. A rejected agent does not trade and does not get a rated round. It does
not quietly fall back to holding.
Language models
In the worksChapter 06 says no model output in the decision path. That stays true for every agent running today, and it is worth saying exactly how the coming Claude integration fits around it rather than through it.
Where a model is allowed
- Writing the rules. You describe an agent in a paragraph and Claude proposes blocks, a universe and limits. What runs afterwards is the rule set, which is as deterministic as one you stacked yourself. Nothing changes here.
- Producing a signal. Claude reads the news and publishes a number. Rules read that number the way they read volatility. The model does not choose an allocation, does not size anything, and does not see the portfolio.
Where it is still not allowed
- Inside
decide(). There is noctx.ask()and there will not be one. - Sizing a position, overriding a limit, or reordering rules.
What that costs, precisely
A model call is not reproducible. An agent that reads a news signal therefore cannot be recomputed from scratch. You cannot regenerate the signal by re-running the question. That is a real loss and it is not worth hiding.
What survives is the useful half. Each signal is written down and hashed before any agent reads it, and it goes into the daily hash chain like a price does. So a run replays exactly against the signal that existed at the time, and anyone can still verify that the agent followed its own rules given what it saw. What nobody can do is argue afterwards about what the news said.
Agents using a model signal will carry a marker on the board and on their profile. Two kinds of record with different verification properties must not sit in one column pretending to be the same thing.
Limits
Four limits, applied to whatever the rules or the code produced. They are the reason
decide() returns an allocation rather than placing orders: if an agent
could place orders, it could route around its own bounds, and no amount of care in
the rule set would fix that.
Rules decide, then drawdown stop, then safe floor, then max trade, then cooldown. Each stage can only make the move smaller or later, never larger or sooner.
The drawdown stop in detail
When the portfolio falls below its running high by more than the limit, the system moves everything to the safe instruments, whatever the rules want. The agent gets control back only once the drawdown has recovered to half the limit. A one-sided threshold would let an agent oscillate in and out at the boundary and pay execution costs on every crossing.
The limit is set by whoever puts capital in, not by the agent’s builder. It bounds how far a loss goes; it does not undo one. An agent stopped out at −10% is down 10%.
The engine
The tick
- Mark to market. Positions are revalued at the new prices; the portfolio value and the running high update.
- Decide. Rules are checked top to bottom and the first match wins, or
decide()is called. The result is a target allocation. - Apply limits. In the order given in chapter 07.
- Execute. If the remaining move is larger than half a basis point of the book, it is booked and costs are charged. Otherwise nothing happens.
- Write the day down. Prices used, weights before and after, the rule that fired, the portfolio value, then the day’s hash.
Prices
Design: Pyth Hermes as the primary feed, covering equities and crypto with a confidence band, and CoinGecko as a fallback. Valuation ticks about once a second; rule evaluation is throttled to somewhere between one and five minutes with a cooldown, because an agent that traded every second would be trading noise and the fees would eat any strategy.
Crypto never closes, which removes a whole class of problem: no market hours, no overnight gap, and no stale reference price while a pool keeps moving. An agent trades at the pool price. That is what it would actually get. With an exchange feed used as an outlier check. A pool that goes thin is the hazard that remains, and it is why the DEX spread in the cost model is 45 bp rather than something flattering.
Not yet verified in practice. This preview runs on generated demonstration data. The feed integration is designed, not built.
Execution costs
Charged on every fill from day one. A paper record without execution costs is disproved the moment real money arrives, so the model is deliberately pessimistic.
Total cost for a fill is the sum over each leg of
|Δweight| × (spread + fee + impact × |Δweight|), deducted from the
portfolio value before the new weights take effect. A trade that moves a quarter of
the book therefore pays about three extra basis points of impact on that leg.
Divisions and rating
A division is a declared intent, not a separate ladder. Every agent, whatever its division, is scored against the same reference.
Separate ladders were the original plan, and they are wrong here. Scoring is risk-adjusted excess over the risk-free rate; a Carry ladder would have to use something T-Bill-like as its reference, and then an agent that simply holds T-Bills scores zero excess against a reference that also scores zero. A coin flip it wins half the time, climbing to the reference rating for doing nothing. That is exactly the hole that excess-over-risk-free was introduced to close, reopened one level up.
So the division does two honest things instead: it tells a reader what the agent is trying to do, and it filters the board so like can be compared with like. Two agents with identical ratings can still be doing opposite things. The division is how you tell.
The formula
One rated round per day. Each round compares the agent and its division’s reference on the same measure: return above the risk-free rate, per unit of the risk taken to earn it, over the last thirty trading days. How far ahead one is decides how much of the round it takes, not merely who is ahead.
Each of those three choices replaced one that measured the wrong thing, and each was caught by pointing an agent at the rating rather than at the market:
- Above the risk-free rate, not the raw return. Dividing a raw return by the agent’s own volatility rewards taking no risk without limit: an agent that held nothing but T-Bills and never traded rated 1634 and beat all three published agents. A ladder you win by not playing is not a ladder. The rate is not assumed here. The T-Bills are in the universe, so their daily return is readable. Earn exactly that and the excess is zero.
- A window, not a day. Over a single day, whichever asset swings hardest wins most of them; that measures noise. Held flat through the sixty days, the most volatile memecoin in the universe returned +8.99% with a −43.6% fall and still out-rated an agent that made +12.93% with half the fall. Measured over a window, the falls sit in the denominator and cost something.
- The margin, not just the winner. Scored as win-or-lose, a day of +0.01% against −0.02% counts as much as +5% against −5%, and cash wins roughly half of all rounds simply because the market falls on roughly half of all days.
Dividing by the agent’s own volatility is still the core of it. Without that, the agent taking the most risk wins every round in a rising market, and the rating would measure appetite for risk rather than skill.
COLLECTOR, the carry agent, scores about zero excess and sits near the bottom of the board. That is not a broken agent. It is an accurate reading. Over these sixty days it returned 1.36 % with a 1.35 % worst fall, and the best risk-free instrument in the universe returned almost exactly as much. Earning the risk-free rate is a perfectly sensible thing to do; it is just not evidence of skill, and a rating that measures skill has to say so.
We tried to fix it and the attempt is worth reporting. Four carry rule sets chosen on reasoning. T-Bill base, a modest slice of ETH when volatility is low, out under stress. Scored −1.03, −0.98, −0.01 and +0.11. Carry simply had a thin window.
An exhaustive search over 2,502 variants did find one scoring 2.31, which would have put it top of the board. We did not ship it. Picking the best of 2,502 candidates on the same sixty days they are scored against is overfitting by construction: the number would be real on this window and meaningless on the next. That is the entire reason this site separates a recalculation from a track record. It would be a poor look to break the rule in our own demonstration agents.
K factor and provisional status
Everyone starts at 1200. The first thirty rated rounds use the higher K so a
new agent reaches a sensible neighbourhood quickly; after that the lower K keeps an
established rating from jumping around on single days. This is also what
Provisional means. It is a statement about how much the number
has settled, not about quality.
Capital does not flow to the top automatically. There is no allocator moving money toward whoever is winning. A person books an agent, sets its limits, and can withdraw. A board that moved money by itself would turn the rating into the product, and a rating that allocates capital is a rating worth gaming.
Booking an agent
Stage 2 · designed, not builtNothing described in this chapter exists yet. Stage one deploys no capital, so there is nothing to allocate and the button on every agent profile is switched off.
How it is meant to work
- You set the limits, not the builder. The agent’s published limits are its defaults; an allocator can only make them stricter.
- You sign every trade. In stage two the agent proposes and the wallet holder approves. Nothing is delegated and no contract of ours holds anyone’s funds.
- You can stop at any moment. Withdrawal is not gated on notice periods or lock-ups.
- Capacity is bounded per agent. A strategy that works on a small book does not automatically work on a large one, and pretending otherwise is how allocations go wrong.
Delegated execution. An agent acting without a signature for each trade. Is stage three, and that is the first point at which this project needs its own contracts and an audit. It has neither.
Commissions and fees
Stage 2 · designed, not builtNothing has been booked and no commission has been paid. The design:
| Item | Amount | Note |
|---|---|---|
| To the builder | 7 points | of the profit the agent makes for an allocator |
| To the protocol | 3 points | runs the thing; source of any token buyback |
| On deposits | none | no charge for putting capital in or taking it out |
| On losses | none | there is no profit to share |
| Listing fee | none | publishing an agent is free and needs no token |
High-water mark
Commission is charged on new profit only, measured per allocator against the highest value their position has previously reached. An agent that loses 10% and then gains 10% has earned its builder nothing, because the allocator is not ahead. Without this, a volatile agent would generate fees by oscillating.
Most of what a builder does earns nothing, and that is intentional. Publishing is free, running is free, and being rated is free. Money appears only when someone else’s capital is behind the rules and the rules make some. Paying for activity instead would reward publishing noise.
Real and simulated
RunningIts own chapter rather than a footnote. At this stage the boundary works in our favour: an agent that trades no capital has very little it could be lying about.
On this preview specifically
The prices behind these pages are generated demonstration data, not a live feed, and every chart says so. The three agents on the board are real rule sets whose curves, fills and ratings come from actually running them, but their parameters were chosen on this particular sixty-day window, which makes them a demonstration rather than a track record. That is the same boundary the builder draws around every preview.
Verification
Each rated day is hashed together with the previous day’s hash. Change one day in the middle and every hash after it changes with it, which makes a quiet improvement to the past impossible to hide. For us as much as for anyone.
What goes into a day
The payload is serialised as JSON with keys in that order and hashed with SHA-256. The first day is chained to sixty-four zeros. The result is the day hash published on the agent’s profile.
Recomputing a record yourself
- Take the agent’s rules from its profile. They are the object the engine runs, not a description.
- Take the prices for its universe over the same days.
- Run the tick loop from chapter 08, charging the costs from the same chapter.
- Hash each day as above and chain it to the previous hash.
- Compare against the published hashes. Any difference tells you the exact day it starts.
node verify.js in the project checks both directions: recomputing a
run reproduces all sixty hashes exactly, and nudging one day’s portfolio value
by 0.5% breaks the chain from precisely that day onward and changes every hash below
it.
Network and addresses
Mixed · read the split belowTwo different answers, and running them together is how people end up trusting the wrong thing. The token contract exists. The protocol contracts do not.
| Contract | Status | Audited |
|---|---|---|
| $AGENCY token | deployed on Ethereum | no |
| Vaults, execution, delegation | none written, none deployed | n/a, nothing to audit |
Nothing of ours holds anybody’s trading capital, because in stage one there is no trading capital and in stage two every trade is signed by the wallet holder. Contracts that could hold funds belong to stage three, and that is the point at which an audit becomes necessary rather than decorative.
The chain agents trade on
| Network | Ethereum (mainnet) |
| Chain ID | 1 (0x1) |
| Gas token | ETH |
| Wallets | any EIP-1193 wallet |
| Venue | Uniswap pools |
| Our contracts there | none |
Why Ethereum. Two reasons, and the second one is why this site can show anything moving at all. Everything an agent needs is already issued there. ETH, the DeFi majors, the DEX pairs, and tokenised T-Bills like BUIDL and USDY. And crypto has free, public, round-the-clock price feeds with no API key, while an equity feed is licensed, gated and dark two-thirds of the day. That is what makes a live agent panel possible.
The chain the token lives on
| Network | Ethereum |
| Chain ID | 1 (0x1) |
| Gas token | ETH |
| Supply | 1,000,000,000 · fixed, no mint function |
| Address | see the token page, and nowhere else |
The same chain the agents trade on. An earlier plan put the token on a separate network, because the trading chain at the time was closed to several large markets and a token there would have inherited that as a limit on who could ever buy it. On Ethereum that reason disappears, and with it the monthly bridge transfer the buyback would otherwise have needed.
Full mechanics, allocation and the risk section are on the token page.
Availability and risk
RunningWho can take part
The builder is open to everyone. No wallet, no account, no region check, because nothing is being traded. Booking an agent is not. Whether you may put capital behind an agent depends on where you live and on what that agent holds. Several jurisdictions restrict digital assets outright, and none of that is ours to waive on your behalf.
Risks, stated plainly
- Market risk. Agents lose money. Limits bound how far a loss goes; they do not prevent one.
- Strategy risk. Rules chosen against past data can fail against future data. This is the ordinary case, not the exception.
- Capacity risk. A strategy that works on a small book may not work on a large one.
- Execution risk. Modelled costs are an estimate. Real fills can be worse, particularly outside market hours.
- Smart contract risk. Not applicable today because nothing is deployed. It becomes the largest risk in stage three and is the reason an audit belongs there and not later.
- Us. This is an early project by a small team. It can stop.
Nothing in this documentation is an offer, a solicitation or financial advice, and past performance, including a recalculation of it, says nothing about future results.
FAQ
RunningWhy blocks and code instead of just code?
Because most people who have a good idea about markets do not write code, and most people who write code do not want to start from an empty file. Blocks are not a toy version: they compile to the same rule format, and the code view shows you exactly what your blocks meant.
Is ejecting to code really one-way?
Yes. Once a function replaces the blocks there is no reliable way back. Arbitrary code cannot be turned into a small set of if-then rules. The builder asks before it happens, and the limits stay above the code either way.
Can two agents have identical rules?
Nothing stops it, and rules are public, so copying is easy. What cannot be copied is the record: sixty days of decisions written down before anyone knew the outcome. A copy starts at 1200 with nothing behind it.
Why can an agent not place orders directly?
Because then the limits would be advisory. decide() returns a target
allocation and the system applies max trade, cooldown, safe floor and the drawdown
stop to it afterwards. No amount of cleverness inside the function gets around a
constraint applied outside it.
What happens if my agent’s code throws?
The run is reported as failed. The agent does not trade for that tick and does not silently fall back to holding. A failure that looks like a decision is worse than a failure that looks like a failure.
Why is the hold time in hours if the preview uses days?
Because the live engine ticks every five minutes and the rule format has to describe that. The preview runs on daily closes, so it rounds down to whole days and marks anything under 24 hours as having no effect there. The alternative. Showing a constraint that did not constrain anything. Would be worse.
Why start everyone at 1200 rather than 1500?
1500 is a claim that a brand new agent is average. 1200 says it has not shown anything yet and has to climb. It also means a low rating is unambiguous: it is either new or it lost.
Can I take my agent down?
Any time, and anyone who has booked it gets their capital back. Its record stays up. A record that could be deleted after a bad month would be worthless. That month is precisely what someone needs to see.
Glossary
A talent agency already has a word for each of these, so we use theirs rather than inventing a vocabulary.
- Sign
- To build and publish an agent. What most products call “deploy”.
- Roster
- The agents one builder has signed.
- Book
- To put capital behind someone else’s agent. Stage 2.
- Commission
- The builder’s share of the profit their agent makes for an allocator. 7 points.
- Division
- A declared intent: Defensive, Momentum, Carry, Market Neutral. It is a label and a board filter, not a separate ladder. See below.
- Board
- The ranking. It ranks; it does not allocate.
- Unsigned
- Published and running, but nobody has booked it. Every agent starts here.
- Provisional
- Fewer than thirty rated rounds. The rating moves faster and means less.
- Guard
- One of the four limits, applied after a decision and never negotiable by it.
- Tick
- One pass of the engine: revalue, decide, apply limits, execute, write the day down.
- Eject
- To convert a block agent into its
decide()function. One-way. - Rated round
- One day scored against the division reference. Rating changes only on these.