# Orus > Orus runs autonomous memecoin trading agents on Robinhood Chain (an Arbitrum Nitro L2, chain id 4663). A user defines a strategy — volume floors, dip depth, take profit, stop loss, holding time — and an agent scans the chain, buys the dip when every rule is met, and manages the position until a target, a stop or a time limit closes it. Everything the agents decide is published, refusals included. Orus lives at orusagent.xyz. `mickie` is the internal name and the database schema. This file is generated from the same table and constants as the documentation page, in the same build, so it cannot say something the page does not. ## What it is - An autonomous desk: strategies (rulebooks) and agents (one copy of a strategy, on a clock, in simulation or trading real ETH from the user's own wallet). - The desk's own agents run in the open at /live; users copy the desk's strategies or write their own, run them in simulation, then fund an embedded wallet and go live. - Every decision — every candidate looked at, every rejection with the measurement behind it, every entry and exit — is written to an event log the public desk reads. ## The chain - Robinhood Chain, an Arbitrum Nitro L2, chain id 4663, gas paid in ETH, ~100 ms blocks with first-come-first-served sequencing (no priority-fee auction). - Every price is in USD. USDG (0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168) is the dominant quote asset, not WETH; a "price in native" is meaningless across venues. - WETH (0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73) is the trading base: ETH is wrapped before a buy, and a sale returns WETH. Selling an ERC-20 needs an approval first. - Venues: Pons is the launchpad the desk trades; Uniswap, NOXA Fun and fomopad also exist. A strategy's venue list matches the venue key, its name or the launchpad, so "pons" admits a Pons token before and after graduation. - Volumes outside a handful of majors are an order of magnitude below Solana's; thresholds transposed from elsewhere return zero candidates. - Explorer: https://robinhoodchain.blockscout.com. ## The pipeline 1. **Scan** — The Orus screener narrows the chain to tokens above the strategy's volume, liquidity, market-cap and trade-count floors; the native coin and the two quote assets (WETH, USDG) are dropped. Each survivor gets one token-details read — price, market cap, launch date, pool, all-time high, holder concentration, bundler and sniper shares, launchpad state, security flags. Up to 200 candidates per run. 2. **Filter** — Every threshold is re-checked locally, including the ones the screener applied. Three checks are fixed: no pool, a honeypot, or a buy or sell tax above 10% is out. Then venue, bonding state, activity, holder concentration and the wash-trading floor. Missing data fails the check it is missing from — a token with no sniper figure fails a sniper ceiling — and the rejection carries a missing_* code; a threshold left unset asks nothing. 3. **Launch market cap** — The market cap one second after the token's first trade, with supply read from the token. Above the strategy's ceiling the token is excluded permanently: a launch at a high cap is usually sniped or bundled. Cached, so it costs one request per token, once. 4. **Radar** — Survivors are tracked across runs with their all-time high, the instant of that high, the current dip and the liquidity behind it. A token leaves the radar when it drops out of the scan, when its entry window expires, or on a launch-cap exclusion; it comes back when it reappears or, after an expired window, on a new all-time high. A blind scan (an outage, a rate limit) evicts nothing. 5. **Dip detection** — Five-minute candles, read only when the high moved. The analyser walks forward from the high to the first close below the threshold; that instant is the first dip, and with a window set it starts the clock. Depth, timing since the high and since launch, liquidity at entry and the high's market cap all have bounds. 6. **Signal** — One entry per dip regime: an agent's latest signal on a token blocks a new one only while it was raised at or after the high this dip is measured from; a held position blocks regardless. A pending signal expires on the strategy's window and on a ceiling of 60 minutes, and it is executed only while the dip still exists at execution time. 7. **Execution** — The guard rails first (stake above zero, the open-position cap, the rolling 24-hour spend cap). Then the token is quoted both ways — a buy of the strategy's size and the sale of what it returns — and rehearsed on-chain; no buy route, no sell route, or an immediate round trip losing more than 25% refuses the entry in every mode. The dip is measured once more on the price the buy quote implies, and the buy's own price impact is held under the strategy's cap: a dip the pool does not show, or an entry that would move the pool past the cap, retires the signal. The swap the quote built is the swap that is sent: ETH is wrapped, the router approved for the exact amount, the fill read from the transfer logs. The position row is written before the broadcast, and the entry records when it was decided, sent and included. 8. **Monitoring** — Every held position is re-marked each run; a quote more than 100× the entry is a bad print and the tick is skipped. Exits in order, first match wins: stop loss (confirmed by a second feed at 80% of the way to the stop), maximum hold (a clock, fires with or without a quote), take profit (for a real position, only if the router's fill delivers at least half of the promised gain and never less than the stake). A failed exit marks the position sell-failed and is retried up to 3 times; it never closes on paper what the wallet still holds. ## Strategy fields Every field of a strategy, with its type, its unit, its default and, for a user's strategy, its bounds: - name (string): What the strategy is called on your console and, for the house's, on the public desk. - description (string, optional): One line on what the strategy is for. Shown on the strategy card. - allowed_dexes (string[], optional) — default pons: Venue whitelist, e.g. pons, noxafun, uniswap-v3. Each entry is matched, case-insensitively and as a substring, against the venue key (uniswap-v4), the venue name (Uniswap) and the launchpad the token came from (pons-v2), so a launchpad name admits its graduated tokens on whichever DEX they now trade. Empty accepts any venue. - require_bonded (boolean, optional) — default unset: true admits graduated tokens only, false admits tokens still on their bonding curve only, unset admits both. - min_volume (number, $) — default 100,000 $ · ≥ 0: Minimum 24-hour volume in USD. A rolling 24 hours, not volume since launch. Passed to the screener and re-checked locally. - min_market_cap (number, $) — default 20,000 $ · ≥ 0: Minimum market cap in USD. Passed to the screener and re-checked locally. - max_launch_mcap (number, optional, $) — default 50,000 $ · ≥ 0: Ceiling on the market cap one second after the token's first trade. A launch at a high cap is usually sniped or bundled, and the dip pattern is unreliable on it; the exclusion is permanent. Supply is read from the token. Unset skips the check. - max_age_hours (number, hours) — default 168 hours · ≥ 0, ≤ 8760: Maximum token age, in hours since creation. A token with no creation date fails an age-bounded strategy. - min_age_hours (number, hours) — default 0.083 hours · ≥ 0, ≤ 8760: Minimum token age, in hours since creation. 0.083 is five minutes. - min_transactions_24h (int) — default 200 · ≥ 0: Minimum 24-hour trade count. Passed to the screener and re-checked locally. - min_volume_liquidity_ratio (number, optional) — default unset · ≥ 0: Floor on 24-hour volume divided by liquidity. High turnover on thin liquidity is a token being traded rather than parked. - max_volume_fees_ratio (number, optional) — default 2,000 · ≥ 1: Ceiling on 24-hour volume divided by the fees that volume paid. On an AMM the two are proportional — fees are a fixed share of every trade — so the ratio is one over the fee rate and sits near 220 on this chain whatever the token's size — measured as the median of 1,000 signalled tokens. That is the normal value, not a target: a ceiling belongs well above it, and at 2,000 it refuses about one token in twenty where 220 would refuse half. A far higher ratio is volume that reached no pool: wash trading, or an accounting that has lost track. Both figures are the same 24-hour window; dividing by the fees a pool has earned since launch would measure its age instead. A pool under three hours old can read high because the provider's fee counter lags its volume counter, and a token with no fee figure fails this check when it is set. - min_buys (int) — default 100 · ≥ 0: Minimum 24-hour buy count. - min_sells (int) — default 100 · ≥ 0: Minimum 24-hour sell count. A token that is only bought has nobody able to sell it. - min_total_fees (number, optional, $) — default unset · ≥ 0: Floor on the cumulative fees the pool has earned, in USD. A proxy for how much real trading the pool has seen. - max_bundled_buy_pct (number, %) — default 40 % · ≥ 0, ≤ 100: Ceiling on the share of supply held by bundler wallets — buys bundled into the launch transaction. - max_snipers_pct (number, optional, %) — default unset · ≥ 0, ≤ 100: Ceiling on the share of supply held by wallets that sniped the launch. A token with no sniper figure fails this check when it is set. - max_insiders_pct (number, optional, %) — default unset · ≥ 0, ≤ 100: Ceiling on the share of supply held by insider wallets. - max_dev_holdings_pct (number, optional, %) — default unset · ≥ 0, ≤ 100: Ceiling on the deployer's own holdings. - max_top10_holdings_pct (number, optional, %) — default unset · ≥ 0, ≤ 100: Ceiling on the top ten holders combined. - min_organic_volume_ratio (number, optional) — default unset · ≥ 0, ≤ 1: Floor on organic volume over reported volume, from 0 to 1 — the wash-trading floor. - min_holders (int, optional) — default unset · ≥ 0: Minimum holder count. A token with no holder figure fails this check when it is set. - dip_threshold_pct (number, %) — default 75 % · ≥ 1, ≤ 99: Minimum fall from the all-time high before an entry is considered. The analyser walks candles forward from the high to the first close below ATH × (1 − threshold/100); that instant is the first dip. - max_dip_pct (number, optional, %) — default unset · ≥ 1, ≤ 100: Ceiling on the dip at entry. A token down more than this from its high is treated as dead rather than dipped. Unset means no ceiling. - min_dip_timing_minutes (number, min) — default 5 min · ≥ 0: Floor on the time from the all-time high to the dip — the flash-crash guard. A dip that took ninety seconds is not a dip. - max_dip_timing_minutes (number, min) — default 600 min · ≥ 0: Ceiling on the time from the all-time high to the dip — the dead-token guard. 600 is ten hours. - min_dip_timing_launch_minutes (number, optional, min) — default unset · ≥ 0: Floor on the time from launch to the dip. - max_dip_timing_launch_minutes (number, optional, min) — default unset · ≥ 0: Ceiling on the time from launch to the dip. - max_first_dip_minutes (number, optional, min) — default 60 min · ≥ 1: How long the entry stays valid after the first crossing of the threshold. The crossing opens a window; past it the entry is written off, which is why a token can be rejected for being too late on a dip that is still deep. A pending signal expires on it too. This is the only bound on the AGE of a crossing — max_dip_timing_minutes bounds the ATH-to-crossing duration, which is a different quantity. Left empty the window never closes, and one all-time high keeps producing entries as the price falls away beneath it. - min_liquidity_at_dip (number, $) — default 5,000 $ · ≥ 0 · users: ≥ 1,000 $: Minimum USD liquidity in the pool at entry. Also passed to the screener as its liquidity floor. What decides whether you can get back out. - min_ath_market_cap (number, optional, $) — default unset · ≥ 0: Minimum market cap at the all-time high, in USD. A dip from a high that never meant anything is not a dip worth buying. - buy_amount_native (number, ETH) — default 0 ETH · ≥ 0 · users: ≤ 0.05 ETH: ETH to spend per entry. 0 means the strategy produces signals and never spends. The engine wraps it to WETH before the buy and keeps a gas reserve aside. - slippage_pct (number, %) — default 5 % · ≥ 0.1, ≤ 50 · users: ≤ 15 %: Slippage tolerance passed to the router, on both legs. - max_price_impact_pct (number, optional, %) — default 5 % · ≥ 0.1, ≤ 50 · users: ≤ 10 %: Ceiling on the price impact the router estimates for the entry itself. A buy whose own size would move the pool more than this is refused and its signal retired: the round trip would start from a hole no dip pays for. Unset disables the check. - max_open_positions (int, optional) — default unset · ≥ 1 · users: ≤ 25: Cap on positions held at once. Open, simulated-open and sell-failed positions all count, so a stuck exit occupies a slot rather than freeing one. Unset means no cap — the wallet becomes the limit. - max_daily_spend_native (number, optional, ETH) — default unset · ≥ 0: Cap on ETH committed to entries per rolling 24 hours, not per calendar day. Unset means no cap. - min_sell_multiplier (number, x) — default 2 x · ≥ 1.01, ≤ 100: Take profit at this multiple of the fill price. For a real position the router is asked what the exit would return first, and the sell proceeds only if it delivers at least half the promised gain and never less than the stake. - stop_loss_pct (number, optional, %) — default unset · ≥ 1, ≤ 99: Sell when the position is down this much from the fill — once a second price feed agrees the drawdown is real. Unset disables it. - stop_loss_max_hours (number, optional, hours) — default unset · ≥ 0.1, ≤ 720: Sell after holding this long, at whatever the market pays — quote or no quote. A clock, not a price, and the most common exit on the desk by a wide margin. Unset disables it. - website_regex (string, optional) — users: not available: A regular expression matched against the token's socials and description. Evaluated inside the cron, so it is reserved for the house: a pathological pattern would stall every agent's tick. - jev_entry_instructions (string, optional): Additional condition for Jev's Premium-only contextual entry review in simulation or live trading. Jev evaluates observed transactions and participant histories after the quantitative filters; missing evidence means waiting, never automatic approval. Enable Jev on the agent. - jev_exit_instructions (string, optional): Additional condition for Jev's Premium-only take-profit review in simulation or live trading. Jev may approve an exit or defer it for another observation; deferred exits are reviewed even below the original target. Stop loss, maximum hold and explicit manual exits remain outside Jev's veto. ## Limits the engine holds itself to - Round trip: an immediate buy-and-sell may lose at most 25% of the stake, or the token is refused as untradeable (no route, unsellable, round-trip loss). - Transfer tax: a buy or sell tax above 10% is refused outright. - Bad prints: a quote more than 100× the entry is ignored for the tick. - Stop loss: fires once a second price feed shows at least 80% of the way to the stop; proceeds if the second feed cannot answer. - Take profit: a real exit proceeds only if the router's fill delivers at least 50% of the promised gain, and never less than the stake. - Failed exits: retried up to 3 times; a position is never closed on paper while the wallet holds the tokens. - Pending signals: expire after 60 minutes at most, and are executed only while the dip still holds — on the screener's print and on the router's own price. - Price impact: an entry whose own size would move the pool past the strategy's max_price_impact_pct is refused and its signal retired. - Rehearsal: the exit is rehearsed on-chain before every entry; with the operator's rehearsal_fail_closed switch on, a real entry whose exit could not be rehearsed waits for the next cycle instead of proceeding. - Gas reserve: 0.0015 ETH is kept unwrapped so an exit can always pay for itself; going live needs the stake plus this margin. - Delegated wallets: Orus may wrap at most 0.05 ETH per transaction, approve only the listed routers for an exact amount, and call those routers — nothing else, on this chain only. - Performance fee: 3% of the realised profit of a winning real trade, net of gas; nothing on a losing one. - Accounts: 3 reports and 30 report-chat messages a day. Agents, strategies and the assistant are tiers, below. A user's strategy is bounded: min_liquidity_at_dip at least 1,000 $; buy_amount_native at most 0.05 ETH; slippage_pct at most 15 %; max_price_impact_pct at most 10 %; max_open_positions at most 25; website_regex is not available. - Cadence: not a setting. A user's agent runs at their tier's cadence — Free 60s, 1 agent, 1 strategy, Pro 30s, 3 agents, 10 strategies and the assistant on 1M $ORUS, Premium 10s, 20 agents, unlimited strategies and the assistant on 3M $ORUS — and never slower than every 60 seconds. The balance is read from the chain every few hours and the agent follows it up and down. The cron fires once a minute and ticks inside it at the fastest cadence running; an agent runs at each tick its own frequency has elapsed for. - AI reports: the agent report and the token report need Pro or above. ## What does not exist - No public trading API: strategies and agents are created in the console at /app, behind a sign-in. - No promise of returns: results on the desk are forward-tested and published as they come, losses included. - No other chain: agents trade Robinhood Chain only, and a delegated wallet's policy refuses anything else. ## Links - [Documentation](https://www.orusagent.xyz/docs): the reference, for people. - [Jev validation guide](https://www.orusagent.xyz/docs#what-is-jev): Premium entry and take-profit decisions, optional conditions, evidence and comparisons, in simulation or live trading. - [Partner scan API](https://www.orusagent.xyz/docs#partner-api): whitelist access through @Orus_agent on X; read-only token scans. - [Partner OpenAPI](https://www.orusagent.xyz/openapi/partner-v1.json): the v1 request and response contract. - [Partner guide for AI agents](https://www.orusagent.xyz/partner-api-agents.txt): auth, units, unknown data and integration rules. - [Full reference for machines](https://www.orusagent.xyz/llms-full.txt): this index plus every section of the documentation. - [The desk, live](https://www.orusagent.xyz/live): what the agents are doing right now, in real numbers. - [Leaderboard](https://www.orusagent.xyz/leaderboard): every wallet and strategy on Orus, ranked. --- # The documentation, in full ## 01 — Start here What the thing is, the objects you need to hold in your head, and how to get in. ### What Orus is *An autonomous desk for Robinhood Chain, running in the open.* Orus discovers tokens across the chain's DEXes and launchpads, waits for one to fall far enough from its all-time high, buys the dip, and manages the position until a target, a stop or a time limit closes it. No part of that requires anyone to be at a screen. It runs on Robinhood Chain — an Arbitrum Nitro L2, chain id 4663, gas paid in ETH. Two chain facts shape everything downstream. USDG, not WETH, is the dominant quote asset, so every price in the system is denominated in USD and a "price in native" is meaningless across venues. Blocks land in about 100 ms with first-come-first-served sequencing, so there is no priority-fee auction to win: the race is on data freshness, not on tips. Every decision an agent makes — every candidate looked at, every rejection and the measurement behind it, every entry and exit — is written to an event log. The public desk reads that log. Refusals and losses are published on the same page as the wins. ### Strategies and agents *A strategy is the rulebook. An agent is one copy of it, running on a clock.* A strategy is a row of parameters covering every step of the pipeline: what to screen for, which holder profiles to reject, how deep and how recent a dip has to be, how much to spend, and when to sell. It holds no wallet and takes no action on its own. Every one of its fields is documented in the pipeline sections below, at the step that reads it. An agent binds one strategy to a cadence, an execution mode and, optionally, a wallet. The cron fires every minute and ticks every thirty seconds inside it; an agent only runs when its own frequency has elapsed, and each run is claimed before it starts — the last-run timestamp is bumped under an optimistic lock — so a run that overruns its interval is never started twice by two concurrent ticks. Two agents on two strategy rows that share every entry rule and differ only in their exits attribute any difference in results to the exit policy alone. That is how the desk's strategies are compared. Pausing an agent stops new entries. It does not stop the exits: an agent that is paused or stopped but still holds positions gets a monitor-only pass on its own cadence, so the stop loss, the hold limit and the take profit keep working on what is already held. - `name` (Strategy Name): What the strategy is called on your console and, for the house's, on the public desk. - `description` (Description): One line on what the strategy is for. Shown on the strategy card. - `frequency_seconds`: How often the agent runs. The cron ticks every thirty seconds; the agent runs at the first tick this has elapsed for. - `execution_mode`: simulation, manual or automatic — see the next section. - `status`: running, paused or stopped. Paused and stopped agents still monitor what they hold. ### Execution modes *Simulation and automatic differ in exactly one thing: whether a transaction is sent.* Simulation needs no funds. The agent runs the full pipeline, including the guard rails and the round-trip check, and books each position at the fill the real routers quote — tokens received, price implied — not at the oracle price. Nothing is broadcast. A simulated exit is quoted out through the same router and booked at the native it would return. It is how a strategy earns the right to hold money. Automatic does the whole thing: quotes, wraps ETH, approves the router for the exact amount, swaps, and records the position from the fill it actually got. Switching an agent to automatic runs a pre-flight — a wallet, automated trading enabled on it, and enough ETH for one entry plus gas — and refuses with the numbers when one is missing. Manual, where a signal waits for a human to execute it, is the desk operator's mode. A user's agent is either simulating or automatic. - `simulation`: No funds. Positions booked at the routed quote, status simulated_open. - `automatic`: Quotes, wraps, approves, swaps, records the real fill. Needs automated trading enabled and a funded wallet. ### Wallets and keys *Your agents trade from a wallet you hold. Orus signs within a policy you can read, and revoke.* Your trading wallet is an embedded wallet on Robinhood Chain, created at your first sign-in and held for you by Privy: the key lives in Privy's enclave, never on Orus's servers and never in your browser. The wallet page shows its address and a QR code to fund it, lets you send ETH from a wallet you already own, and lets you withdraw — by signing yourself, through Privy's confirmation, to an address you choose. Sells return WETH; a withdrawal converts it on the way out. Automated trading is a delegation: with one click you add Orus's signer to your wallet, under a policy. The policy is the whole of what Orus may sign — wrap ETH up to 0.05 ETH per transaction, approve the listed routers for an exact amount, and call those routers. It has no rule for a transfer, for another chain, or for an approval to anyone else; a request outside it is refused by Privy before it is signed. The console records the delegation only after asking Privy that the signer is really there, and you can turn it off at any time. While it is off, an automatic agent can neither open nor close positions. Before any real entry the engine checks the wallet again: the delegation stands, the account is enabled, and the balance covers the stake plus gas for the round trip. A wrap keeps a gas reserve as ETH so the exit can always pay for itself. The house desk's own agents trade from a key the operator holds; a user's agent never touches it. Fund it with ETH, on Robinhood Chain, and with nothing else. Your wallet holds the same address on every EVM chain, so a deposit sent on Ethereum or Base does arrive — at an address where Orus has no router to trade it and no permission to move it, because the policy is refused on every chain but this one. The wallet page reads Robinhood Chain, and also asks Privy what the address holds elsewhere, so a deposit that went to the wrong network is named rather than silently absent. Getting it back is yours to do: export your private key from the wallet page, import it into a wallet of your own, and move the funds — that chain will want its own gas first. - `/app/wallet`: Address, balance, QR, fund from your own wallet, withdraw, export your key, automated trading on/off. - `fund with`: ETH, on Robinhood Chain only. Anything else reaches the same address and is stranded there. - `policy`: Wrap ≤ 0.05 ETH · approve and call listed routers · nothing else. Refused before signing otherwise. - `fees`: 3% of the net gain on each closed real trade, accrued to the token buyback. ### Access *Sign in, copy a strategy, run it in simulation, then fund your wallet and go live. The desk itself needs no account.* The console at /app sits behind a login: an email one-time code, or a wallet you already own. The first sign-in creates your account and your trading wallet — an embedded wallet held for you, on Robinhood Chain only. Pressing the button on that page is where you accept the terms it states: Orus runs the strategies you define on a volatile market, nothing here guarantees a profit, and funds you send to your wallet can be lost. Your console shows what is yours: your strategies, your agents, their radar, signals, positions, history and reports. The desk's own agents are not in it; they are on /live, and their strategies are the templates you can copy. Every account may generate 3 reports a day and send 30 messages a day to a report; how many agents it may run, how many strategies it may hold and whether it may ask its agent to write one are tiers — see $ORUS below. A user's strategy is bounded — min_liquidity_at_dip at least 1,000 $; buy_amount_native at most 0.05 ETH; slippage_pct at most 15 %; max_price_impact_pct at most 10 %; max_open_positions at most 25; website_regex is not available — by the same rules in the API and in a database check. An agent's cadence is its account's tier, and the tier is the $ORUS in its wallet: Free runs every 60 seconds, Pro every 30 seconds on 1M $ORUS held, Premium every 10 seconds on 3M $ORUS held. Nothing is chosen and nothing is bought with a card — the balance is read from the chain every few hours, and an agent follows it both ways: buy more and it speeds up, sell and it slows down. The thresholds are token amounts rather than dollar ones so a price move cannot take an account's tier away overnight. Going live is four steps, all in the console: copy or write a strategy, deploy an agent on it, fund the wallet on the wallet page and enable automated trading there, then set the agent to automatic. Changing the stake, the caps, the stop or the slippage under a live agent moves it back to simulation — it went live on the old numbers, and the new ones need a new decision. Nothing on the desk is a mock. What you read is the same database the engine writes to, on the same fifteen-second poll the operator sees. - `/app`: Your console. Sign in required. - `/app/wallet`: Your trading wallet: fund, withdraw, automated trading. - `/leaderboard`: Every wallet and every strategy on Orus, ranked, the house included. Every UTC day, the three best P&L, the house included, split half of the day's fees. No account needed. - `/live`: The public desk. No account needed. - `/pricing`: The three tiers and what each holds. No account needed. - `/docs`: This page. - `/llms.txt`: This documentation for machines — see Machine-readable docs below. ### $ORUS *The token does two things: it takes a share of what a winning real trade makes, and holding it sets what your account can do.* It earns. Orus keeps 3% of the realised profit of a winning real trade — the figure net of the gas both legs paid, read from the receipt — and nothing at all on a losing one; a loss never offsets a later win. Simulated positions and the house's own agents pay nothing. Every UTC day, half of that day's fees is paid out as prizes to the three best net P&L, and the rest buys back $ORUS. It opens. Your tier is the $ORUS in your wallet, and it is the only thing that sets how often your agents run: Free runs every 60 seconds, Pro every 30 seconds on 1M $ORUS held, Premium every 10 seconds on 3M $ORUS held. Pro and above also open the AI reports — the agent report and the token report, the two features that spend a model call rather than a database row. It also sets how many agents you may run at once (1 on Free, 3 on Pro, 20 on Premium), how many strategies you may hold (1 on Free, 10 on Pro, unlimited on Premium), and whether "Ask your agent" — the assistant that writes a strategy from a conversation — is open, which it is from Pro up, with no message count on it. Going over is never possible by surprise and never destructive — an account that drops a tier keeps every agent it built and simply cannot add another. Everything else is in every tier: every desk template to copy, simulation on live data, real trading, and your own tape. The thresholds are token amounts, not dollar ones, and deliberately so: a dollar threshold on a young token would take your tier away overnight without you selling anything. The consequence is the honest one — if the price runs, a tier costs more in dollars than it did; if it falls, less. The amounts are a constant we can recalibrate, and changing them is announced. Jev contextual validation is Premium only (3M $ORUS held), in simulation or live trading at the owner’s choice. Enable it per agent for entries, take-profit exits, or both, with optional written conditions. Below this tier, Jev reviews stop and delegated entries and take profits wait until access is restored or Jev is disabled; stop loss, maximum hold and manual exits remain available. Saved strategies and decision history are kept. Your balance is read from the chain every few hours and stored; your wallet page shows the figure your tier was decided on. Nothing is ever moved: the tokens stay in the same wallet your agent trades from, and Orus only ever reads the balance. It works both ways — buy more and your agents speed up within hours, sell and they slow to the tier you still hold, with a line on each agent's own tape saying so. - `Free`: 1 agent and 1 strategy, a run every 60 seconds. — no token - `Pro`: 3 agents and 10 strategies, a run every 30 seconds, Ask your agent, AI reports. — 1M $ORUS held - `Premium`: 20 agents and unlimited strategies, a run every 10 seconds, Ask your agent, AI reports, and Jev validation in simulation or live trading. — 3M $ORUS held ### What we measure about you *Google Analytics on the public pages, with advertising switched off, and nothing else.* The site runs Google Analytics 4. It records the pages you open, where you arrived from, and six events on the way to an account: a call to action pressed, the sign-in dialog opened, the sign-in completed, a sign-in stopped at the terms, an account created, and a returning sign-in. That is the whole list. Nothing about what your agents scan, hold or trade is sent anywhere — it lives in the database, and the parts of it that are public are on /live and /leaderboard because we chose to publish them. Advertising is off: the tag is configured with Google's advertising signals and ad personalisation both disabled, so the data is not used to build an advertising profile and no ad network is contacted. Once you are signed in, the console attaches your account's internal identifier so a funnel can be followed end to end. Never your email, never your wallet address, never your Privy identifier. Analytics sets cookies in your browser. To refuse them, use your browser's tracking protection, an ad blocker, or Google's own opt-out extension — none of it changes how the product works, and none of it is required to sign in, deploy an agent or trade. ### Where the numbers come from *One Orus market layer for screening, token observations and execution quotes.* Orus screens the chain's token list against the strategy's thresholds, then gathers token observations: price, market cap, launch date, pool, all-time high, holder concentration, bundler and sniper shares, launchpad state and security flags. The market layer also supplies candles, earliest-trade samples and execution quotes. Chain reads and transaction broadcasting use the chain RPC. Every provider sits behind one market module. The engine imports that module and nothing else, so replacing a provider means reimplementing one function, and every filter is re-checked locally even when the screener already applied it — a provider change can never silently weaken a rule. Every price is in USD. Execution quotes are normalised to the same economics before the engine compares them: expected output in token units, USD in and out, and price impact. ## 02 — The pipeline Scan, filter, launch check, radar, dip detection, signal, execution. Every stage can reject, and every rejection is logged with the test that failed and how far off it was. Each strategy field is listed at the step that reads it. ### Scan *Narrow the chain to a few hundred candidates, then enrich them.* The Orus screener narrows the chain's token list under the thresholds it can enforce server-side — 24-hour volume, liquidity, market cap, trade count. That is the cheap pass, and it exists to keep the expensive one small. The native sentinel and the two quote assets, WETH and USDG, are dropped here: the screener lists them as tokens, but they are not candidates. Each survivor gets one token-details read, which returns the observations the filter and chart analyser need in a single response. Details are shared across the agents running in one process, so nine agents screening the same chain cost one call per token, not nine. Output: up to 200 candidates per run. - `min_volume` (Min Volume ($)): Minimum 24-hour volume in USD. A rolling 24 hours, not volume since launch. Passed to the screener and re-checked locally. — default 100,000 $ · ≥ 0 - `min_market_cap` (Min Market Cap ($)): Minimum market cap in USD. Passed to the screener and re-checked locally. — default 20,000 $ · ≥ 0 - `min_transactions_24h` (Min Transactions 24h): Minimum 24-hour trade count. Passed to the screener and re-checked locally. — default 200 · ≥ 0 ### Filters and risk *Every check, applied locally to every candidate. Where most of them die.* Three checks are fixed and cannot be loosened: a token with no pool is out, a token that cannot be sold — a honeypot — is out, and a buy or sell tax above 10% is out. There is no mint or freeze authority on an ERC-20, so the Solana-era checks do not apply; taxes and honeypots are the equivalent traps, and they are rejected rather than scored. The venue whitelist matches the venue key, its name or the launchpad the token graduated from, so a strategy that names a launchpad admits its graduated tokens on whichever DEX they now trade. Bonding state can be required either way. The rest is activity and holder distribution. A token whose supply sits with bundler wallets, launch snipers, insiders or the deployer is a token whose price is somebody's decision rather than a market's. Each has its own ceiling, and a wash-trading floor compares organic volume against reported volume. Missing data fails the check it is missing from. A strategy that sets a threshold is asking a question, and "unknown" is not the answer it wants: a token with no creation date fails an age-bounded strategy, one with no sniper figure fails the sniper ceiling. These rejections carry their own codes — missing_age, missing_snipers, missing_holders — so the tape shows what was absent rather than what was exceeded. A strategy that leaves a threshold unset asks nothing and is unaffected. A candidate that fails a numeric test still produces an event with the value and the threshold. That distance is what the near-miss board on the activity page is built from. - `allowed_dexes` (Allowed Venues): Venue whitelist, e.g. pons, noxafun, uniswap-v3. Each entry is matched, case-insensitively and as a substring, against the venue key (uniswap-v4), the venue name (Uniswap) and the launchpad the token came from (pons-v2), so a launchpad name admits its graduated tokens on whichever DEX they now trade. Empty accepts any venue. — default pons - `require_bonded` (Launchpad State): true admits graduated tokens only, false admits tokens still on their bonding curve only, unset admits both. — default unset - `max_age_hours` (Max Age (hours)): Maximum token age, in hours since creation. A token with no creation date fails an age-bounded strategy. — default 168 hours · ≥ 0, ≤ 8760 - `min_age_hours` (Min Age (hours)): Minimum token age, in hours since creation. 0.083 is five minutes. — default 0.083 hours · ≥ 0, ≤ 8760 - `min_volume_liquidity_ratio` (Min Volume/Liquidity Ratio): Floor on 24-hour volume divided by liquidity. High turnover on thin liquidity is a token being traded rather than parked. — default unset · ≥ 0 - `max_volume_fees_ratio` (Max Volume/Fees Ratio): Ceiling on 24-hour volume divided by the fees that volume paid. On an AMM the two are proportional — fees are a fixed share of every trade — so the ratio is one over the fee rate and sits near 220 on this chain whatever the token's size — measured as the median of 1,000 signalled tokens. That is the normal value, not a target: a ceiling belongs well above it, and at 2,000 it refuses about one token in twenty where 220 would refuse half. A far higher ratio is volume that reached no pool: wash trading, or an accounting that has lost track. Both figures are the same 24-hour window; dividing by the fees a pool has earned since launch would measure its age instead. A pool under three hours old can read high because the provider's fee counter lags its volume counter, and a token with no fee figure fails this check when it is set. — default 2,000 · ≥ 1 - `min_buys` (Min Buys): Minimum 24-hour buy count. — default 100 · ≥ 0 - `min_sells` (Min Sells): Minimum 24-hour sell count. A token that is only bought has nobody able to sell it. — default 100 · ≥ 0 - `min_total_fees` (Min Total Fees ($)): Floor on the cumulative fees the pool has earned, in USD. A proxy for how much real trading the pool has seen. — default unset · ≥ 0 - `max_bundled_buy_pct` (Max Bundled Buy (%)): Ceiling on the share of supply held by bundler wallets — buys bundled into the launch transaction. — default 40 % · ≥ 0, ≤ 100 - `max_snipers_pct` (Max Snipers (%)): Ceiling on the share of supply held by wallets that sniped the launch. A token with no sniper figure fails this check when it is set. — default unset · ≥ 0, ≤ 100 - `max_insiders_pct` (Max Insiders (%)): Ceiling on the share of supply held by insider wallets. — default unset · ≥ 0, ≤ 100 - `max_dev_holdings_pct` (Max Dev Holdings (%)): Ceiling on the deployer's own holdings. — default unset · ≥ 0, ≤ 100 - `max_top10_holdings_pct` (Max Top-10 Holdings (%)): Ceiling on the top ten holders combined. — default unset · ≥ 0, ≤ 100 - `min_organic_volume_ratio` (Min Organic Volume Ratio): Floor on organic volume over reported volume, from 0 to 1 — the wash-trading floor. — default unset · ≥ 0, ≤ 1 - `min_holders` (Min Holders): Minimum holder count. A token with no holder figure fails this check when it is set. — default unset · ≥ 0 - `website_regex` (Website Regex): A regular expression matched against the token's socials and description. Evaluated inside the cron, so it is reserved for the house: a pathological pattern would stall every agent's tick. — users: not available ### Launch market cap and the radar *Survivors are tracked over time rather than judged in one frame.* A token's market cap one second after its first trade says something its current cap does not: a launch at a high cap is usually sniped or bundled, and the dip pattern is unreliable on it. The clock starts at the first trade, not at contract creation — on a launchpad the two coincide, on a DEX listing made after deployment they do not. Supply is read from the token. The value is cached, so the check costs one request per token, once. What survives lands on the radar — the watchlist — where it is tracked across runs with its last known all-time high, the instant of that high, the current dip and the liquidity behind it. Nothing is bought from the radar; it is the pool the chart analyser reads every cycle. A token leaves the radar for one of three reasons, and each is recorded: it dropped out of the scan, its entry window expired, or its launch cap exceeded the ceiling. It comes back on its own terms. One that dropped out returns when it reappears, keeping the dip it was tracking. One whose window expired, or that has already been signalled, returns only on a new all-time high — a new high starts a new dip — and only if nothing is still open on it. A launch-cap rejection, or a token hidden by hand, is permanent. Eviction only happens on a scan that observed the market. When the screener returns nothing — an outage, a rate limit — nothing is evicted, because a blind scan is indistinguishable from an empty market. - `max_launch_mcap` (Max Launch Market Cap ($)): Ceiling on the market cap one second after the token's first trade. A launch at a high cap is usually sniped or bundled, and the dip pattern is unreliable on it; the exclusion is permanent. Supply is read from the token. Unset skips the check. — default 50,000 $ · ≥ 0 ### Dip detection *The entry test, and the window it opens.* For each radar token the analyser takes the all-time high from the details it already has, pulls five-minute candles only when that high moved or no crossing is stored yet, and measures the current price against it. Depth alone is not enough. A dip that happened in ninety seconds is a flash crash, and one that took two days is a dead token — so timing is bounded on both sides, measured from the high and, optionally, from launch. Liquidity at entry and, optionally, the market cap at the high have floors of their own. A ceiling on the dip itself separates a discount from a rug. The first-dip rule is what makes an entry expire. The analyser walks candles forward from the high to the first close below the threshold; that instant starts the clock. With a window set, the entry is valid for that many minutes after the crossing and then written off — which is why a token can be rejected for being too late on a dip that is still deep. A crossing belongs to its high: a new high clears it. - `dip_threshold_pct` (Dip Threshold (%)): Minimum fall from the all-time high before an entry is considered. The analyser walks candles forward from the high to the first close below ATH × (1 − threshold/100); that instant is the first dip. — default 75 % · ≥ 1, ≤ 99 - `max_dip_pct` (Max Dip (%)): Ceiling on the dip at entry. A token down more than this from its high is treated as dead rather than dipped. Unset means no ceiling. — default unset · ≥ 1, ≤ 100 - `min_dip_timing_minutes` (Min Dip Timing Since ATH (min)): Floor on the time from the all-time high to the dip — the flash-crash guard. A dip that took ninety seconds is not a dip. — default 5 min · ≥ 0 - `max_dip_timing_minutes` (Max Dip Timing Since ATH (min)): Ceiling on the time from the all-time high to the dip — the dead-token guard. 600 is ten hours. — default 600 min · ≥ 0 - `min_dip_timing_launch_minutes` (Min Dip Timing Since Launch (min)): Floor on the time from launch to the dip. — default unset · ≥ 0 - `max_dip_timing_launch_minutes` (Max Dip Timing Since Launch (min)): Ceiling on the time from launch to the dip. — default unset · ≥ 0 - `max_first_dip_minutes` (Max Time After First Dip (min)): How long the entry stays valid after the first crossing of the threshold. The crossing opens a window; past it the entry is written off, which is why a token can be rejected for being too late on a dip that is still deep. A pending signal expires on it too. This is the only bound on the AGE of a crossing — max_dip_timing_minutes bounds the ATH-to-crossing duration, which is a different quantity. Left empty the window never closes, and one all-time high keeps producing entries as the price falls away beneath it. — default 60 min · ≥ 1 - `min_liquidity_at_dip` (Min Liquidity at Dip ($)): Minimum USD liquidity in the pool at entry. Also passed to the screener as its liquidity floor. What decides whether you can get back out. — default 5,000 $ · ≥ 0 · users: ≥ 1,000 $ - `min_ath_market_cap` (Min ATH Market Cap ($)): Minimum market cap at the all-time high, in USD. A dip from a high that never meant anything is not a dip worth buying. — default unset · ≥ 0 ### Signals *One entry per dip regime. A regime starts at an all-time high.* A buy signal carries the price at signal, the all-time high it was measured from, the dip depth and duration, the liquidity behind it and the venue it would trade on. An agent's latest signal on a token — executed, expired or dismissed — blocks a new one only while it was raised at or after the high this dip is measured from. A signal older than the high belongs to a previous regime: the token has since made a new high and dipped again, and the strategy that entered the first dip has the same case for entering this one. A held position blocks regardless. The lookups are batched, two per run rather than two per candidate. Once the signal row exists the radar entry moves to signal-generated and the desk operator is notified on Telegram. Sell signals are not produced here; they come from the position monitor when an exit condition fires. A pending signal does not live forever. It expires on the strategy's own window measured from the crossing, and on a global ceiling of 60 minutes regardless. And it is executed only while the dip still exists: every entry in a batch is re-priced from one refresh at execution time, then once more on the price the router's own buy quote implies, and a token that has bounced back above the threshold on either expires its signal with a dip-recovered event instead of being bought. ### Execution *Quote both ways, record before broadcasting, and read the fill rather than assume it.* With Jev enabled for entries, an eligible proposal also needs its contextual approval in the same cycle. Jev cannot restore a candidate rejected by the strategy. Its approval is short-lived and is checked again before execution; the price, quote, exposure and wallet checks below still apply. Three limits are asserted first — see guard rails below. Then the token is quoted both ways: a buy of the strategy's size, and the sale of what that buy would return. No buy route, no sell route, or an immediate round trip losing more than 25% refuses the entry outright. The signal is retired, not retried, and the reason — no route, unsellable, round-trip loss — goes on the tape. This runs in every mode, so a simulation declines what a real agent would decline. The provider's honeypot and tax flags are absent on many tokens; a router quote measures the trap directly. ETH is wrapped before a buy, because the router quotes ERC-20 legs only and rejects the native address. Selling an ERC-20 needs an approval first. The Orus execution layer compares available swap routes, signs the selected transaction and broadcasts it to the chain. The quote is taken before the wrap, so a pair with no route costs nothing. The position row is written before the transaction is broadcast, so a confirmed swap can never end up untracked; if the swap fails, the placeholder is deleted. The amount received is read from the transaction's transfer logs, not from the quote, and the entry price is the fill price in every mode — what was spent over what was received. The oracle price the signal was raised on stays on the signal. Multipliers, the stop and the target are all measured from the fill, so a fill a few percent above the oracle is drawdown the position carries from the start. An exit sells what the position holds, capped at the wallet balance for fee-on-transfer shortfalls — never the wallet's whole balance, which may hold the same token for another agent or for the operator. Every signed sequence on a wallet — a buy's wrap, approve and swap; a sell's approve, swap and unwrap — runs under a lease on that wallet held in the database, so two processes never sign against one nonce, and a position is re-read under the lease before it is sold. ## 03 — Running it Exits, the limits that bind before capital moves, and how to read the desk. ### Exits and position monitoring *Three conditions, checked in order, first match wins — and none of them trusts a single number.* At the end of every run, each position that still holds tokens has its price, multiplier and P&L refreshed. A quote more than 100× the entry is a bad print: that tick is skipped and recorded rather than acted on. Stop loss first. It fires when the drawdown reaches the strategy's stop — but only once a second feed agrees. The details provider is asked once, and the sell proceeds if it shows at least 80% of the way to the stop. Feeds differ by a few percent; a bad print differs by orders of magnitude. If the second feed cannot answer, the stop proceeds: capital protection does not wait on a vendor. Maximum hold second. This is a clock, not a price: it fires even when the feed has no quote for the token — liquidity pulled, pool abandoned — at a secondary-feed price or, failing that, the last mark, and the event says which. It is the most common exit on the desk by a wide margin. Take profit last, and for a real position the fill is checked before the sell: the router is asked what the exit would return, and the sell proceeds only if it delivers at least half the promised gain and never less than the stake. A fill that fails the check is neither an exit nor a failure; the position stays open and the next tick asks again. With Jev enabled for take-profit exits, that proposed exit needs its contextual approval. A deferral is reviewed again on a later cycle, even below the original target, and the real fill check still applies. Jev cannot veto a stop loss, the maximum holding deadline or an explicit manual exit. Exits run one at a time per wallet — they share a nonce, so concurrent swaps would collide. Agents on different wallets run concurrently. A failed exit does not close the position: if the swap reverts or is never confirmed, the position is marked sell-failed with the error and an attempt counter, and retried on later runs up to 3 times. Closing it would report a realised P&L for tokens the wallet still holds. When an exit settles, realised P&L is the native the swap returned against what was spent, less the gas both legs paid, including attempts that reverted. Not oracle prices. When a position closes on the hold limit with no usable quote at all, it closes with no P&L rather than a made-up one, and the desk skips it. - `min_sell_multiplier` (Min Sell Multiplier (x)): Take profit at this multiple of the fill price. For a real position the router is asked what the exit would return first, and the sell proceeds only if it delivers at least half the promised gain and never less than the stake. — default 2 x · ≥ 1.01, ≤ 100 - `stop_loss_pct` (Stop Loss (%)): Sell when the position is down this much from the fill — once a second price feed agrees the drawdown is real. Unset disables it. — default unset · ≥ 1, ≤ 99 - `stop_loss_max_hours` (Max Hold Duration (hours)): Sell after holding this long, at whatever the market pays — quote or no quote. A clock, not a price, and the most common exit on the desk by a wide margin. Unset disables it. — default unset · ≥ 0.1, ≤ 720 - `jev_exit_instructions` (Jev take-profit condition): Additional condition for Jev's Premium-only take-profit review in simulation or live trading. Jev may approve an exit or defer it for another observation; deferred exits are reviewed even below the original target. Stop loss, maximum hold and explicit manual exits remain outside Jev's veto. ### Guard rails *Checked before any capital is committed, in every mode.* Three limits are asserted on every buy, before the quote and before the wrap. The buy size must be greater than zero — set it to zero and the agent produces signals and never spends. The open-position cap counts open, simulated-open and sell-failed positions together, so a stuck exit still occupies a slot rather than quietly freeing one. The daily spend cap is a rolling 24-hour window, not a calendar day. They are strategy fields, so two agents on the same rules can carry different ceilings by running two strategy rows. Leaving one unset disables that particular limit, which is a choice worth making deliberately. A user's stake is capped at 0.05 ETH per entry by the same rule in the API and in the database. - `buy_amount_native` (Buy Amount (ETH)): ETH to spend per entry. 0 means the strategy produces signals and never spends. The engine wraps it to WETH before the buy and keeps a gas reserve aside. — default 0 ETH · ≥ 0 · users: ≤ 0.05 ETH - `slippage_pct` (Slippage (%)): Slippage tolerance passed to the router, on both legs. — default 5 % · ≥ 0.1, ≤ 50 · users: ≤ 15 % - `max_price_impact_pct` (Max Price Impact (%)): Ceiling on the price impact the router estimates for the entry itself. A buy whose own size would move the pool more than this is refused and its signal retired: the round trip would start from a hole no dip pays for. Unset disables the check. — default 5 % · ≥ 0.1, ≤ 50 · users: ≤ 10 % - `max_open_positions` (Max Open Positions): Cap on positions held at once. Open, simulated-open and sell-failed positions all count, so a stuck exit occupies a slot rather than freeing one. Unset means no cap — the wallet becomes the limit. — default unset · ≥ 1 · users: ≤ 25 - `max_daily_spend_native` (Max Daily Spend (ETH)): Cap on ETH committed to entries per rolling 24 hours, not per calendar day. Unset means no cap. — default unset · ≥ 0 - `jev_entry_instructions` (Jev entry condition): Additional condition for Jev's Premium-only contextual entry review in simulation or live trading. Jev evaluates observed transactions and participant histories after the quantitative filters; missing evidence means waiting, never automatic approval. Enable Jev on the agent. ### Reading the public desk *Everything above, live, without an account — and how each number is made.* The desk publishes the book, the trades table, the strategy board with every rule each strategy runs on, the analyses, and the decision tape — one row per decision the engine made, including the rejections and the measurement behind each one. Consecutive decisions with the same reason collapse into one row that says how many it stands for. The tape polls every eight seconds; the aggregates are computed over the whole closed book and cached for forty-five seconds. The book is an index. These trades never shared a wallet, so the line is what a single 12 ETH float would have done taking every one of them, indexed to 1,000 — 12 ETH because it is above the most the desk ever had deployed at once and above its deepest drawdown, so the floor holds and the slope is profit. Below 1,000 the desk is down. A closed trade whose only exit price was a quote more than 100× its entry is withheld from the book and from the trades table, and the note under the ribbon says how many. A trade that closed on its hold limit with no usable quote counts as closed and carries no P&L. Headline figures come from the receipt when there is one; a simulated trade is marked at the routed quote. Results are forward-tested, not backtested. A backtest with no stop loss and no maximum hold can only close a trade by hitting its target, so every closed trade is a winner by construction — which is why the numbers on the desk come from running it live instead. ## 04 — Your agent Writing a strategy with your agent, what you can do by hand while an agent runs, and where a machine can read all of this. ### Writing a strategy with your agent *Describe what you want; your agent drafts the rules onto the form. You read them, change what you like, and save.* On the strategies page, New strategy opens as a drawer with the form; Ask your agent unfolds a conversation beside it. You say what you are after — how much risk, how much per entry, launches or established tokens, how long you are willing to hold — and the agent answers in prose and hands back a complete strategy. It lands on the form field by field, each one marked until you edit it, and you can ask for a change as many times as you like: the next proposal replaces the last, and any earlier one can be put back with one click. The agent is briefed on exactly what this page describes: the pipeline and what each step refuses, the limits the engine holds itself to, every field with its meaning and its bounds, and the desk's own strategies with the results they have produced — as evidence, not as instructions. It is told to explain the three to five choices that matter, to say what the strategy will and will not catch, and to refuse a wish the engine cannot grant rather than invent a field for it. It answers in the language you write in. Nothing the agent says reaches the database on its own. What it proposes is validated field by field before it touches the form — a value the engine would refuse is dropped and named, a required field it left out is filled from the default and named, and a user's proposal is brought inside the same bounds as any other — and it is your Save, not the agent, that creates the strategy. Each message counts against the account's 30 chat messages a day. - `Write it`: The form on its own, every field editable, the same rules as always. - `Ask your agent`: Unfolds the conversation beside the form. The latest proposal is applied as it arrives. - `Apply to form`: On an earlier proposal's card: put that one back on the form. - `set by your agent`: The mark on a field the agent just filled; it clears the moment you edit the field. - `to fit your limits`: A value the agent proposed above a bound, and what it was brought down to. ### Sell a position by hand *Every held position has a Sell button. It runs the same exit the monitor runs on a stop loss, now.* On an agent's page and on the dashboard, a position that still holds tokens — open, simulated, or waiting on a failed exit — can be sold on demand. The sale is not a shortcut around the engine: it raises the sell signal, quotes the router, sends the swap, reads what came back from the receipt and books the P&L net of gas, exactly as an automatic exit would, with the reason recorded as manual. A simulated position is quoted out through the router and closed at what it would have returned. It is immediate — the request stays open while the swap confirms, which is seconds on a good day and a couple of minutes on a slow one — and it is safe alongside the cron because of the wallet lease: the sale takes the lease on the wallet, re-reads the position under it, and never signs against a nonce a running cycle is using nor sells tokens a cycle has just sold. A wallet that is still busy after forty-five seconds answers wallet busy, and the button offers a retry rather than a promise to sell later. A position whose exit already failed 3 times shows Retry exit instead: asking again resets its attempt budget. A user's real position sells through the delegated wallet, so automated trading must be enabled on the wallet page; the global kill switch does not stop an exit, and neither does the account's trading switch — a way out is never switched off. - `closed`: Settled on-chain; what came back was read from the receipt. - `pending`: Broadcast; the receipt has not arrived yet. The next pass reads it and closes the position. - `failed`: The swap did not settle. The position is still held; the agent retries on its next pass. - `wallet_busy`: Another transaction was being signed from the wallet. Nothing was tried; try again in a moment. ### Machine-readable docs *The same reference, written for a language model to read.* Everything on this page — the pipeline, the limits the engine holds itself to, every strategy field with its default, its unit and its bounds — is published at /llms.txt as a short index and at /llms-full.txt in full, following the llms.txt convention. Both are generated from the same table and the same constants as this page, in the same build, so they cannot say something this page does not. They exist so that an assistant helping you write a strategy, on Orus or elsewhere, describes the system that will actually run it: which fields exist, what each one means, what a user's strategy may not do, and what the engine refuses before any capital moves. - `/llms.txt`: The index: what Orus is, the chain, the pipeline in eight lines, every field in one line, the account limits, the links. - `/llms-full.txt`: The index plus every section of this page and the full field reference with defaults, ranges and user bounds. ## 05 — Jev validation What Jev adds to your strategy, when to use it, and how to read its decisions. Optional for Premium, in simulation or live trading at your choice. ### What is Jev? *An AI model that makes a specific decision from the observations it receives.* Jev is an evaluation model from TypeSafe AI, available through Vercel AI Gateway. It interprets observations against written criteria and returns one of a defined set of answers. In Orus, that answer can approve, refuse or delay an entry, or approve or defer a take-profit exit. Think of it as a contextual reviewer inside your agent. Your strategy first checks its numeric rules, such as dip depth, liquidity and position limits. If you enable Jev for the proposed trade, the agent waits for its decision in the same trading cycle. Only an approval can continue to execution, where price, quote and wallet checks still apply. The strategy assistant helps you write rules before you save them. Jev instead evaluates a trading opportunity while your agent runs. It does not rewrite your strategy, choose your stake, predict a target price or receive permission to sign transactions. [Jev model reference on Vercel](https://vercel.com/ai-gateway/models/jev) ### When is Jev useful? *When the order and persistence of trading activity matter more than another threshold.* Two tokens can pass the same volume and dip filters while showing different activity. In one, purchases follow an initial sell-off and remain held across observations. In the other, recent buyers quickly sell back out. A volume total hides that sequence; Jev can assess it against your entry criteria. At a take-profit trigger, you can ask whether observed purchases are still being retained while selling is absorbed. Jev may allow the exit or defer it for another review. Deferring keeps the position exposed: a later exit can be worse than taking the original profit. Use ordinary strategy fields for exact requirements such as minimum liquidity, maximum stake or a holding deadline. Use Jev for a question about the supplied sequence of events. If that question needs facts Orus does not provide, Jev should return insufficient evidence. More reviews or fewer trades do not by themselves mean a better strategy; any improvement needs a comparison. ### Enable Jev on an agent *Choose the decisions you delegate. Your execution mode remains your choice.* Jev is Premium only, unlocked by holding 3M $ORUS. In the agent form, open Jev contextual validation and choose Entries, Take-profit exits, or Entries and take-profit exits. Disabled keeps the ordinary strategy behavior. Save the form to apply your choice. Simulation uses simulated positions. Automatic uses real trades through your configured wallet. Enabling Jev does not switch between them or start an agent. New agents initially use simulation; changing an existing agent to Automatic follows the usual wallet setup. The operator's Manual mode leaves entry execution by hand and can review proposed take-profit exits. The switch belongs to each agent. Optional written conditions belong to its strategy, under Buy Position and Sell Criteria. Saving a condition does not activate Jev, and agents sharing that strategy read the same conditions. Leaving both conditions blank uses the standard review criteria, which you can expand in the form. Jev and Fly cannot be enabled together on the same agent. Changing a saved condition is a strategy risk change. For a user-owned strategy, its automatic agents return to simulation when that condition changes, just as when the stake or stop changes. Review the new criteria before choosing Automatic again. Simply changing the agent's Jev scope does not change its execution mode. You can turn Jev off to return to ordinary strategy decisions on subsequent cycles. This does not close positions or erase the journal. Pausing an agent stops new entries; held positions remain monitored. If Premium access is lost, Jev reviews stop and delegated entries and take profits wait until access returns or Jev is disabled. Stop loss, maximum holding time and manual exits remain available. ### Write an entry condition *Describe the evidence you want before accepting a dip that already passed your rules.* The standard entry review looks for demand that persists after initial selling. It can refuse an opportunity when purchases are rapidly reversed or selling continues, wait when an observed transition needs another sample, or report insufficient evidence when the available history cannot distinguish those readings. Example: “Require purchases after the initial sell-off to remain held across the available observations; rapidly reversed purchases should not count as persistent demand.” This asks about event order and changes in observed holdings, rather than repeating a volume threshold. Write one clear, observable requirement in the Jev entry condition field, up to 500 characters. It adds to the standard criteria. Avoid requests such as “only buy tokens that will double” or “prove the wallets are independent”: future returns and unknown wallet relationships are not evidence Jev has. A condition that cannot be established may leave an entry waiting until its window expires. ### Write a take-profit condition *State what would justify keeping the position after the profit target is reached.* The standard exit review validates the proposed take profit unless the observations sufficiently support continuing the position. Holding requires purchases retained over time and selling being absorbed; a higher price alone is not enough. Missing or contradictory evidence does not authorize the delegated exit. Example: “Defer the take profit only while successive observations show retained purchases and absorption of selling; do not defer on price strength alone.” Write this in Jev take-profit condition, up to 500 characters. The condition helps qualify a deferral; the stop-loss percentage and holding deadline still belong in their normal strategy fields. A deferred take profit is reviewed again on a later cycle, even if the price has fallen below the original target. A real sale must still pass the existing take-profit fill check. Stop loss, maximum holding time and an explicit manual exit bypass Jev's decision, while retaining their normal execution checks. Jev can delay a take profit, but it cannot veto those exits. ### Read the decision journal *A model decision and a completed trade are two separate events.* Open Jev on the agent page to see the latest reviews. Decision is the model's answer or the review's status. Applied action records what the engine subsequently did. An approval can still expire or be stopped by a changed setting, a price or quote check, unavailable funds or a failed transaction. A pending action is not a settled trade; No recorded action is not proof of execution. No reviews yet can mean there has been no eligible entry or take-profit trigger for the enabled scope. Jev does not run on every scanned token. When a review cannot run because of missing data, a timeout, unavailable service or a cycle's time budget, it never grants approval by default. Delegated entries wait within their existing window; delegated take profits remain open for a later review. Protective and manual exits remain available. View under Evidence opens the captured observations, saved criteria and structured answer. It lets you inspect what was actually available at decision time. Any returned choice probabilities describe the model's assessment of those choices, not the chance of making a profit. - `Entry approved`: The proposed entry may continue through execution checks. It is not yet a confirmed purchase. - `Entry refused`: This opportunity is retired. It does not permanently ban all future opportunities in the token. - `Waiting for another observation`: An observed transition needs another sample. The signal can be reconsidered while its entry window remains valid. - `Exit approved`: The proposed take profit may continue through the exit checks. - `Take profit deferred`: Keep the position for another review. Stop loss and maximum hold still apply. - `Insufficient evidence / insufficient data`: No delegated trade is approved. The observations cannot support the required decision. - `Unavailable / budget exhausted`: The review could not complete in this cycle. This is an operational outcome, not a negative judgment on the token. ### What evidence does Jev use? *Recent transactions and changes in observed holdings, with gaps kept visible.* Orus supplies a recent sequence of buys and sells with times, amounts and pseudonymous participant identifiers, a sample of participants' holdings and cumulative purchases and sales, and earlier observations when available. The proposed trade's context includes the current price, entry or dip information, and whether a take profit was already deferred. The sample is bounded and can miss trades or holders. A single balance cannot prove that someone retained a recent purchase; that requires observations over time. Unknown wallet relationships remain unknown, and different identifiers do not prove independent traders. Missing values are kept missing rather than treated as zero or a sign of safety. Jev only evaluates the observations supplied for that review. It does not independently browse social media, inspect private chats or see future trades. Your optional text cannot add a data source. The journal exposes coverage information so you can distinguish an uncertain market reading from incomplete input. ### Compare with and without Jev *Measure whether contextual decisions help your strategy, including the opportunities they miss.* Public agent, strategy and account pages identify the current JEV scope and how many agents use it. The With JEV leaderboard filter selects current configurations; it does not turn the historical P&L into a JEV performance measurement. Public activity covers the last 24 hours and follows the selected real/simulation filter, independently of the chart period. Public activity separates model responses, missing data before a review, and unavailable or expired reviews. Repeated reviews of one signal or held position count as one distinct opportunity. An approval is separate from a confirmed execution. Detailed examples are published only for ORUS agents; user instructions, tokens under review and individual observations remain private. For a comparison, create two agents using the same strategy, execution mode, cadence and starting conditions. Leave Jev disabled on one and enable a chosen scope on the other. Run them over the same period without changing the parameters midway. Simulation lets you do this without risking funds; it is a testing option, not a restriction on Jev access. Compare net realized results after trading costs, open exposure and drawdown, trade count, entries refused or missed, and exits deferred. Read the journal for unavailable or insufficient reviews and added latency. A higher average profit per completed trade can hide fewer opportunities or losses still held open. Different holdings can also make the agents encounter different later opportunities, despite identical rules. If a frozen experiment comparison is attached to the agent, its table also shows review errors, latency and reported inference costs. Open marks are estimates, and the displayed inference cost is not the total cost of market data. Frozen comparison agents remain in simulation to keep the experiment consistent; ordinary Premium agents may use live trading. Jev can misread context, miss an entry or postpone an exit that would have been better taken. Its availability and structured answers do not establish a performance benefit. Judge results over enough opportunities and different market conditions before attributing a difference to the model. # Orus Partner API v1 > Official read-only token scan API. Whitelisted partners only; request access at https://x.com/Orus_agent. Human reference: https://www.orusagent.xyz/docs#partner-api ## Endpoint & authentication GET https://www.orusagent.xyz/api/v1/scan Authorization: Bearer . Keep ORUS_PARTNER_API_KEY on your backend. No request body. ## Query parameters | Parameter | Type | Required | Default | Values | Description | | --- | --- | --- | --- | --- | --- | | chainId | integer | Yes | — | 4663 | Robinhood Chain mainnet (4663) only. Testnet (46630) returns 400 unsupported_chain. Never relabel a testnet contract as mainnet. | | token | string | Yes | — | 0x + 40 hexadecimal characters | Non-zero EVM contract address. Normalized to lowercase. | | include | string | No | chart | none · chart · launch · chart,launch · launch,chart | Optional chart and launch reads. Core data and agents are always included. | | dipThresholdPct | number | No | 30 | 1–99 inclusive | Percent decline from ATH that defines a dip. Used when chart is included. | | lookbackHours | number | No | 48 | 1–168 inclusive | Hours of five-minute candle history. Used when chart is included; does not change the fixed 24h agent window. | ## Include options | include | Chart/dip | Launch | Use case | | --- | --- | --- | --- | | none | No | No | Token cards: core data and agents only. | | chart | Yes | No | Default. Add dip timing and chart coverage. | | launch | No | Yes | Add the earliest-trade launch sample. | | chart,launch | Yes | Yes | Request all available indicators. launch,chart is equivalent. | ## Request examples Replace the illustrative contract with the token to scan. ### cURL ```sh curl --get 'https://www.orusagent.xyz/api/v1/scan' \ --header "Authorization: Bearer $ORUS_PARTNER_API_KEY" \ --data-urlencode 'chainId=4663' \ --data-urlencode 'token=0x1111111111111111111111111111111111111111' \ --data-urlencode 'include=chart,launch' \ --data-urlencode 'dipThresholdPct=30' \ --data-urlencode 'lookbackHours=48' ``` ### Node.js ```js // Run on your server. Replace token with the contract to scan. const url = new URL("https://www.orusagent.xyz/api/v1/scan"); url.search = new URLSearchParams({ chainId: "4663", token: "0x1111111111111111111111111111111111111111", include: "chart,launch", dipThresholdPct: "30", lookbackHours: "48", }).toString(); const response = await fetch(url, { headers: { Authorization: `Bearer ${process.env.ORUS_PARTNER_API_KEY}`, }, signal: AbortSignal.timeout(25_000), }); const result = await response.json(); if (!response.ok) { // On 429/503, honor Retry-After before a bounded retry. throw new Error(`${response.status}: ${result.error.code}`); } console.log(result.card.text, result.card.url); ``` ### Python ```python # Run on your server with requests installed. import os import requests response = requests.get( "https://www.orusagent.xyz/api/v1/scan", headers={ "Authorization": f"Bearer {os.environ['ORUS_PARTNER_API_KEY']}", }, params={ "chainId": 4663, "token": "0x1111111111111111111111111111111111111111", "include": "chart,launch", "dipThresholdPct": 30, "lookbackHours": 48, }, timeout=25, ) # On 429/503, honor Retry-After before a bounded retry. response.raise_for_status() result = response.json() print(result["card"]["text"], result["card"]["url"]) ``` ## Response example Complete synthetic 200 response for include=chart,launch; illustrative values, not a live scan. ```json { "apiVersion": "1.0", "requestId": "11111111-1111-4111-8111-111111111111", "chainId": 4663, "checkedAt": "2026-09-17T12:00:00.000Z", "cache": { "hit": false, "ageSeconds": 0, "maxAgeSeconds": 30 }, "token": { "address": "0x1111111111111111111111111111111111111111", "name": "Example token", "symbol": "EXAMPLE", "image": null, "createdAt": "2026-09-15T12:00:00.000Z", "decimals": 18, "ageSeconds": 172800, "totalSupply": 1000000000, "circulatingSupply": 1000000000 }, "market": { "priceUsd": 0.0006, "marketCapUsd": 600000, "fdvUsd": 600000, "liquidityUsd": 90000, "maxLiquidityUsd": null, "liquidityToMarketCapPct": 15, "volumeChange5mPct": null, "totalFeesUsd": null, "secondsSinceLastTrade": 5, "latestTradeAt": "2026-09-17T11:59:55.000Z", "priceUpdatedAt": null, "windows": { "1m": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "5m": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "15m": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "1h": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "4h": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "6h": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "12h": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null }, "24h": { "volumeUsd": null, "buyVolumeUsd": null, "sellVolumeUsd": null, "organicVolumeUsd": null, "organicBuyVolumeUsd": null, "organicSellVolumeUsd": null, "buys": null, "sells": null, "trades": null, "buyers": null, "sellers": null, "traders": null, "organicTrades": null, "organicTraders": null, "feesUsd": null, "priceChangePct": null } } }, "pool": { "address": null, "dex": null, "dexKey": null, "launchpad": null, "factory": null, "bonded": null, "bondingPct": null, "bondedAt": null, "bondingCurveAddress": null, "launchpadUrl": null }, "security": { "isHoneypot": false, "isProxy": false, "buyTaxPct": 0, "sellTaxPct": 0, "liquidityBurnPct": 99.8 }, "risk": { "bundlersPct": 4, "snipersPct": null, "insidersPct": null, "devHoldingsPct": null, "top10Pct": null, "top50Pct": null, "top100Pct": null, "top200Pct": null, "freshTradersPct": null, "proTradersPct": null, "smartTradersPct": null, "holdersCount": 1200, "bundlersCount": null, "snipersCount": null, "insidersCount": null, "laggedFields": [ "bundlersPct", "snipersPct", "insidersPct" ] }, "ath": { "priceUsd": 0.001, "at": "2026-09-17T10:00:00.000Z", "ageSeconds": 7200, "marketCapUsd": 1000000, "changeFromAthPct": -40, "drawdownPct": 40, "supplyBasis": "current_supply" }, "atl": { "priceUsd": null, "at": null }, "dip": { "thresholdPct": 30, "thresholdPriceUsd": 0.0007, "firstDipAgeSeconds": 3600, "athToFirstDipSeconds": 3600, "secondsSinceLastObservedDip": 3600, "requestedLookbackHours": 48, "candleCount": 24, "lastCandleAgeSeconds": 0, "windowLowUsd": 0.0005, "windowHighUsd": 0.001, "reboundFromWindowLowPct": 20, "isCurrentlyBelowThreshold": true, "firstDipAt": "2026-09-17T11:00:00.000Z", "lastObservedDipAt": "2026-09-17T11:00:00.000Z", "windowStart": "2026-09-17T10:00:00.000Z", "windowEnd": "2026-09-17T12:00:00.000Z", "historyStatus": "covers_ath", "hasGaps": false, "interval": "5m" }, "launch": { "firstTradeAt": "2026-09-15T12:00:00.000Z", "sampleWindowSeconds": 1, "priceUsd": 0.00001, "marketCapUsd": 10000, "sampledTrades": 100, "supplyBasis": "current_supply", "mayBeTruncated": true }, "deployer": { "status": "partial", "address": "0x2222222222222222222222222222222222222222", "launches": 3, "migrations": 1, "rugs": null, "reason": "Rug classification is unavailable." }, "socials": { "website": null, "twitter": null, "telegram": null, "discord": null, "description": null }, "agents": { "status": "available", "scope": "all_orus_agents", "coverage": "retained_history", "asOf": "2026-09-17T12:00:00.000Z", "windowHours": 24, "real": { "tradedAgents": 8, "holdingAgents": 3, "entries24h": 5, "exits24h": 2, "lastEntryAt": "2026-09-17T11:50:00.000Z", "lastExitAt": "2026-09-17T11:40:00.000Z" }, "simulation": { "tradedAgents": 12, "holdingAgents": 4, "entries24h": 7, "exits24h": 3, "lastEntryAt": "2026-09-17T11:55:00.000Z", "lastExitAt": "2026-09-17T11:45:00.000Z" } }, "availability": { "details": { "status": "available" }, "chart": { "status": "available" }, "launch": { "status": "available" }, "agents": { "status": "available" }, "security": { "status": "available", "missingFields": [], "conflictingFields": [] } }, "warnings": [ "rug_classification_unavailable", "price_timestamp_unavailable" ], "attribution": { "text": "checked by orus", "url": "https://www.orusagent.xyz/token/4663/0x1111111111111111111111111111111111111111" }, "card": { "text": "orus: no honeypot reported · tax 0/0 · bundled 4% · deployer 3 launches, rugs unknown · checked by orus ↗", "url": "https://www.orusagent.xyz/token/4663/0x1111111111111111111111111111111111111111" } } ``` ## Response fields Top-level keys are present on success. Child fields apply when their parent object is available. Nullable values may be unknown. Market {window} is one of 1m, 5m, 15m, 1h, 4h, 6h, 12h or 24h. ### envelope (object) Version, chain, collection time and request ID. | Field | Type | Description | | --- | --- | --- | | apiVersion | string | Response contract version (1.0). | | requestId | string | Request correlation ID; include this when contacting support. | | chainId | integer | Robinhood Chain mainnet: 4663. Testnet 46630 is unsupported. | | checkedAt | string | Collection start; not the quote timestamp. | ### cache (object) Cache hit and observation age. | Field | Type | Description | | --- | --- | --- | | cache.hit | boolean | True when this scan was served from the shared cache. | | cache.ageSeconds | integer | Elapsed seconds since checkedAt. | | cache.maxAgeSeconds | integer | Maximum cache lifetime: 30 seconds. | ### token (object) Identity, supply and creation time. | Field | Type | Description | | --- | --- | --- | | token.address | string | Requested contract, normalized to lowercase. | | token.name | string \| null | Token name. | | token.symbol | string \| null | Token ticker. | | token.image | string \| null | Public image URL, or null when the image cannot be published. | | token.createdAt | string \| null | Reported token creation timestamp. | | token.decimals | number \| null | Token decimal precision. | | token.ageSeconds | number \| null | Seconds since token creation. | | token.totalSupply | number \| null | Total supply in token units. | | token.circulatingSupply | number \| null | Circulating supply in token units. | ### market (object) USD price, capitalization, liquidity and rolling activity windows. | Field | Type | Description | | --- | --- | --- | | market.priceUsd | number \| null | Current reported token price in USD. | | market.marketCapUsd | number \| null | Reported circulating market capitalization in USD. | | market.fdvUsd | number \| null | Fully diluted valuation in USD. | | market.liquidityUsd | number \| null | Current reported liquidity in USD. | | market.maxLiquidityUsd | number \| null | Maximum reported liquidity in USD. | | market.liquidityToMarketCapPct | number \| null | Liquidity / market cap × 100. May exceed 100. | | market.volumeChange5mPct | number \| null | Current 5m volume versus the average of the preceding two 5m periods, derived from 15m volume. | | market.totalFeesUsd | number \| null | Cumulative reported pool fees in USD. | | market.secondsSinceLastTrade | number \| null | Seconds since latestTradeAt. | | market.latestTradeAt | string \| null | Timestamp of the latest reported trade, separate from quote freshness. | | market.priceUpdatedAt | null | Exact quote timestamp is unavailable; latestTradeAt is separate. | | market.windows.{window}.volumeUsd | number \| null | Total USD volume in this rolling window. | | market.windows.{window}.buyVolumeUsd | number \| null | Buy-side USD volume. | | market.windows.{window}.sellVolumeUsd | number \| null | Sell-side USD volume. | | market.windows.{window}.organicVolumeUsd | number \| null | USD volume classified as organic. | | market.windows.{window}.organicBuyVolumeUsd | number \| null | Organic buy-side USD volume. | | market.windows.{window}.organicSellVolumeUsd | number \| null | Organic sell-side USD volume. | | market.windows.{window}.buys | number \| null | Number of buys. | | market.windows.{window}.sells | number \| null | Number of sells. | | market.windows.{window}.trades | number \| null | Number of trades. | | market.windows.{window}.buyers | number \| null | Distinct buyers in the window. | | market.windows.{window}.sellers | number \| null | Distinct sellers in the window. | | market.windows.{window}.traders | number \| null | Distinct traders in the window. | | market.windows.{window}.organicTrades | number \| null | Trades classified as organic. | | market.windows.{window}.organicTraders | number \| null | Traders classified as organic. | | market.windows.{window}.feesUsd | number \| null | Fees in USD for this window. | | market.windows.{window}.priceChangePct | number \| null | Signed price change, in percentage points. | ### pool (object) Venue, launchpad and bonding state. | Field | Type | Description | | --- | --- | --- | | pool.address | string \| null | Dominant pool address. | | pool.dex | string \| null | Venue display name. | | pool.dexKey | string \| null | Venue identifier. | | pool.launchpad | string \| null | Originating launchpad. | | pool.factory | string \| null | Pool factory address. | | pool.bonded | boolean \| null | Whether the token has graduated from its bonding curve. | | pool.bondingPct | number \| null | Bonding-curve progress in percent. | | pool.bondedAt | string \| null | Reported graduation timestamp. | | pool.bondingCurveAddress | string \| null | Bonding-curve contract address. | | pool.launchpadUrl | string \| null | Launchpad token page URL. | ### security (object) Honeypot, proxy, taxes and liquidity burn observations. | Field | Type | Description | | --- | --- | --- | | security.isHoneypot | boolean \| null | Reported honeypot flag; null is unknown. false is not a safety guarantee or an execution simulation. | | security.isProxy | boolean \| null | Reported proxy-contract flag; null is unknown. | | security.buyTaxPct | number \| null | Reported token buy tax in percent: 1 means 1%. Excludes pool fees, hook fees, slippage and gas. null is unknown. | | security.sellTaxPct | number \| null | Reported token sell tax in percent: 1 means 1%. Excludes pool fees, hook fees, slippage and gas. null is unknown. | | security.liquidityBurnPct | number \| null | Reported liquidity burn percentage; null is unknown. Independent of honeypot and tax coverage. | ### risk (object) Holder concentration and wallet classifications. | Field | Type | Description | | --- | --- | --- | | risk.bundlersPct | number \| null | Supply held by wallets classified as bundlers. | | risk.snipersPct | number \| null | Supply held by wallets classified as launch snipers. | | risk.insidersPct | number \| null | Supply held by wallets classified as insiders. | | risk.devHoldingsPct | number \| null | Supply held by the developer. | | risk.top10Pct | number \| null | Supply held by the top 10 holders. | | risk.top50Pct | number \| null | Supply held by the top 50 holders. | | risk.top100Pct | number \| null | Supply held by the top 100 holders. | | risk.top200Pct | number \| null | Supply held by the top 200 holders. | | risk.freshTradersPct | number \| null | Supply held by wallets classified as fresh traders. | | risk.proTradersPct | number \| null | Supply held by wallets classified as pro traders. | | risk.smartTradersPct | number \| null | Supply held by wallets classified as smart traders. | | risk.holdersCount | number \| null | Reported number of holders. | | risk.bundlersCount | number \| null | Reported number of bundler wallets. | | risk.snipersCount | number \| null | Reported number of sniper wallets. | | risk.insidersCount | number \| null | Reported number of insider wallets. | | risk.laggedFields | string[] | Risk field names whose classifications can change after launch. | ### ath (object) All-time high, drawdown and elapsed time. | Field | Type | Description | | --- | --- | --- | | ath.priceUsd | number \| null | Reported all-time high price in USD. | | ath.ageSeconds | number \| null | Seconds elapsed since the ATH. | | ath.marketCapUsd | number \| null | ATH price × current circulating supply (total supply fallback). Approximation. | | ath.changeFromAthPct | number \| null | (current price / ATH − 1) × 100. Negative below the ATH. | | ath.drawdownPct | number \| null | Decline from the ATH in percent, clamped at zero. | | ath.at | string \| null | Timestamp of the reported ATH. | | ath.supplyBasis | string | current_supply: the market-cap approximation uses current supply. | ### atl (object) All-time low price and date. | Field | Type | Description | | --- | --- | --- | | atl.priceUsd | number \| null | Reported all-time low price in USD. | | atl.at | string \| null | Timestamp of the reported ATL. | ### dip (object | null) Candle-based dip timing; null when chart was not requested. | Field | Type | Description | | --- | --- | --- | | dip.thresholdPct | number \| null | Requested drawdown threshold; defaults to 30%. | | dip.thresholdPriceUsd | number \| null | ATH × (1 − thresholdPct / 100). | | dip.firstDipAgeSeconds | number \| null | Seconds elapsed since firstDipAt. | | dip.athToFirstDipSeconds | number \| null | Seconds between the ATH and firstDipAt. | | dip.secondsSinceLastObservedDip | number \| null | Seconds elapsed since lastObservedDipAt. | | dip.requestedLookbackHours | number \| null | Requested candle history window in hours. | | dip.candleCount | number \| null | Closed, valid five-minute candles in the window. | | dip.lastCandleAgeSeconds | number \| null | Seconds since the latest closed candle ended. | | dip.windowLowUsd | number \| null | Lowest candle low in the returned window. | | dip.windowHighUsd | number \| null | Highest candle high in the returned window. | | dip.reboundFromWindowLowPct | number \| null | (current price / window low − 1) × 100. | | dip.isCurrentlyBelowThreshold | boolean \| null | Whether the current reported price is at or below the threshold. | | dip.firstDipAt | string \| null | First qualifying closed-candle crossing since the ATH; null without complete history. | | dip.lastObservedDipAt | string \| null | Latest observed crossing from above to below the threshold, not a local low. | | dip.windowStart | string \| null | First retained candle open timestamp. | | dip.windowEnd | string \| null | Last retained candle close timestamp. | | dip.historyStatus | string | covers_ath, partial or unavailable. Only covers_ath supports a first-dip claim. | | dip.hasGaps | boolean | Whether the observed post-ATH candles contain missing intervals. | | dip.interval | string | Fixed five-minute candles (5m). | ### launch (object | null) Earliest-trade sample; null when launch was not requested. | Field | Type | Description | | --- | --- | --- | | launch.firstTradeAt | string \| null | Earliest returned trade timestamp. | | launch.sampleWindowSeconds | number \| null | Launch sampling interval: one second from the first trade. | | launch.priceUsd | number \| null | Price of the last sampled trade within that first second. | | launch.marketCapUsd | number \| null | Launch sample price × current total supply (circulating supply fallback). | | launch.sampledTrades | number \| null | Number of earliest valid trades inspected, up to 100. | | launch.supplyBasis | string | current_supply: historical market cap is an approximation. | | launch.mayBeTruncated | boolean | True when the sample reaches 100 trades; other trades may be missing. | ### deployer (object) Reported launches and migrations; rug count remains unknown. | Field | Type | Description | | --- | --- | --- | | deployer.status | string | partial when an address is known, otherwise unavailable. | | deployer.address | string \| null | Reported deployer address. | | deployer.launches | number \| null | Reported token launches by this deployer. | | deployer.migrations | number \| null | Reported migrations by this deployer. | | deployer.rugs | null | Always null: rug classification is unavailable. Never display 0 rugs. | | deployer.reason | string | Explanation of deployer coverage. | ### socials (object) Reported metadata and external links. | Field | Type | Description | | --- | --- | --- | | socials.website | string \| null | Reported website URL. | | socials.twitter | string \| null | Reported X/Twitter URL. | | socials.telegram | string \| null | Reported Telegram URL. | | socials.discord | string \| null | Reported Discord URL. | | socials.description | string \| null | Reported token description. Treat metadata and links as untrusted. | ### agents (object) Aggregate real and simulated agent activity. | Field | Type | Description | | --- | --- | --- | | agents.status | string | available or unavailable. Unavailable means null counts, not zero. | | agents.scope | string | Desk and customer agents on the requested chain, regardless of current agent status or mode. Aggregates only. | | agents.coverage | string | Current retained positions, not guaranteed lifetime history. Real entries require a non-empty recorded entry_tx; entry_pending is excluded. Mode is determined by position status, not current agent settings. | | agents.asOf | string \| null | Observation timestamp for agent activity; null if unavailable. Cached with the scan for at most 30 seconds from checkedAt. | | agents.windowHours | integer | Fixed 24-hour activity window; independent of lookbackHours. | | agents.real.tradedAgents | integer \| null | Distinct agents with eligible entries in retained history, including agents currently holding. Not a count of trades or independent strategies. | | agents.real.holdingAgents | integer \| null | Distinct agents with open positions in the recorded book. Real includes sell_failed, including paused/stopped agents. No on-chain balance verification. | | agents.real.entries24h | integer \| null | Eligible position entries in [asOf - 24h, asOf]. Counts positions, not distinct agents; uses recorded entry_at. | | agents.real.exits24h | integer \| null | Position closures in [asOf - 24h, asOf], using exit_at and closed status. Includes simulated write-offs; not proof of a successful on-chain sale. | | agents.real.lastEntryAt | string \| null | Latest eligible recorded entry_at in retained history, or null if none. | | agents.real.lastExitAt | string \| null | Latest recorded exit_at of a closed eligible position, or null if none. Failed exits are excluded. | | agents.simulation.tradedAgents | integer \| null | Distinct agents with eligible entries in retained history, including agents currently holding. Not a count of trades or independent strategies. | | agents.simulation.holdingAgents | integer \| null | Distinct agents with open positions in the recorded book. Real includes sell_failed, including paused/stopped agents. No on-chain balance verification. | | agents.simulation.entries24h | integer \| null | Eligible position entries in [asOf - 24h, asOf]. Counts positions, not distinct agents; uses recorded entry_at. | | agents.simulation.exits24h | integer \| null | Position closures in [asOf - 24h, asOf], using exit_at and closed status. Includes simulated write-offs; not proof of a successful on-chain sale. | | agents.simulation.lastEntryAt | string \| null | Latest eligible recorded entry_at in retained history, or null if none. | | agents.simulation.lastExitAt | string \| null | Latest recorded exit_at of a closed eligible position, or null if none. Failed exits are excluded. | ### availability (object) Availability of each requested data section. | Field | Type | Description | | --- | --- | --- | | availability.details.status | string | Core token details availability. available on a successful scan. | | availability.chart.status | string | available, unavailable or not_requested for the chart analysis. | | availability.launch.status | string | available, unavailable or not_requested for the launch sample. | | availability.agents.status | string | available or unavailable for agent activity; always requested. | | availability.security.status | string | Coverage of the five security fields: available = all known, partial = some known, unavailable = none known. Not a safety verdict. Always requested, including include=none. | | availability.security.missingFields | string[] | Names of security fields that are null. security_data_incomplete is emitted when this list is nonempty. | | availability.security.conflictingFields | string[] | Fields with conflicting observations, returned as null and also listed in missingFields. Raises security_data_conflict. Empty when no conflict was observed. | ### warnings (string[]) Coverage and freshness caveats. | Field | Type | Description | | --- | --- | --- | | warnings | string[] | Machine-readable caveats. May be nonempty on HTTP 200; clients should tolerate new codes. | ### attribution (object) Orus label and public token link. | Field | Type | Description | | --- | --- | --- | | attribution.text | string | Attribution label: checked by orus. | | attribution.url | string | Public Orus token intelligence URL, without a partner key. | ### card (object) Telegram-ready summary and attribution link. | Field | Type | Description | | --- | --- | --- | | card.text | string | Ready-to-display plain-text summary, preserving unknown values. | | card.url | string | Public token deep link for the card's attribution arrow. | ## HTTP errors | HTTP | Code | Action | | --- | --- | --- | | 400 | invalid_request / invalid_token / unsupported_chain | Fix the query. Unknown or repeated parameters are rejected. | | 401 | unauthorized | Missing, invalid, expired or revoked key, or inactive partner. Stop and contact Orus. | | 404 | token_not_found | Token is not indexed. This does not prove the contract is invalid. | | 429 | rate_limited | Partner quota exceeded. Wait the number of seconds in Retry-After. | | 503 | scan_unavailable / market_data_unavailable / unverified_token_data | Temporarily unavailable. Honor Retry-After; retry at most twice with jitter. | | 405 | Method not allowed | Use GET. This framework response does not use the JSON error envelope. | ## Headers | Header | Where | Meaning | | --- | --- | --- | | Authorization | Request | Bearer . Required; send from your backend over HTTPS. | | X-Request-Id | Response | Correlation ID on every GET response. | | X-RateLimit-Limit | Response | Partner minute quota, after admission. | | X-RateLimit-Remaining | Response | Remaining admitted requests this minute. | | X-RateLimit-Day-Remaining | Response | Remaining admitted requests this UTC day. | | Retry-After | 429 / 503 | Seconds to wait before retrying. | | Cache-Control | Response | private, no-store. Orus maintains the shared scan cache internally. | ## Data semantics & integration ### Access by invitation The Orus Partner API is available only to approved partners. Contact @Orus_agent on X with your product, expected traffic and integration use case. The team whitelists your partner account and delivers a private API key. There is no self-service signup. Send Authorization: Bearer from your backend over HTTPS. Never put a key in a URL, Telegram message, browser bundle, screenshot or AI prompt. Console login cookies do not grant API access. Keys expire, can be revoked individually, and share their partner's quota. ### One scan endpoint GET /api/v1/scan?chainId=4663&token=. Version 1 supports Robinhood Chain mainnet only. Unsupported chains and invalid, zero, repeated or unknown parameters return 400. Addresses are normalized to lowercase. Only Robinhood Chain mainnet (chainId=4663) is supported. Robinhood testnet (46630) returns 400 unsupported_chain. A bot running in testnet mode must not scan its testnet contracts as mainnet addresses. Enable live scans on mainnet cards; use the clearly labeled synthetic response examples to test the renderer offline. There is no testnet scan endpoint. include=chart is the default. Use include=none for a fast Telegram card, include=launch for the launch sample, or include=chart,launch for all available indicators. dipThresholdPct defaults to 30 (range 1–99). lookbackHours defaults to 48 (range 1–168). Candles use a fixed five-minute interval. All response sections are part of the Orus API and are organized by subject. Successful responses contain token, market, pool, security, risk, ath, atl, dip, launch, deployer, socials, agents, availability, warnings, attribution and card. Agent activity is always included, even with include=none; include controls only chart and launch reads. Optional sections can fail independently: a 200 response may contain unavailable data. Inspect availability and warnings. null always means unknown or unavailable, never zero, false or safe. ### Market and risk data token contains identity, creation time, age, decimals and supply. market contains USD price, circulating market cap, FDV, liquidity, total fees, liquidity-to-market-cap percentage and 1m/5m/15m/1h/4h/6h/12h/24h windows. Available window fields cover total/buy/sell volume, organic volume, buys, sells, trades, distinct buyers/sellers/traders, fees and price changes. latestTradeAt and secondsSinceLastTrade describe the last reported trade, separately from quote freshness. pool contains the dominant pool, venue, launchpad and bonding progress. security contains isHoneypot, buyTaxPct, sellTaxPct and liquidityBurnPct. risk contains holder and bundler/sniper/insider counts, supply percentages, developer holdings and top-10/50/100/200 concentration and fresh/pro/smart trader holdings. These observations do not constitute an execution simulation or a safety guarantee. Bundler, sniper and insider classifications can change after launch; risk.laggedFields identifies them. Security is always requested, including include=none. Orus combines token observations with a dedicated security check when available. Inspect availability.security.status: available means all five security fields are known, partial means some are known, and unavailable means none are known. None of these statuses is a safety verdict. missingFields names exactly which security values are null. security_data_incomplete means that list is nonempty, even if honeypot and taxes are known but liquidity burn is not. Coverage varies by token; Uniswap v4 does not by itself imply missing data or a safe contract. null means no usable observation, a timeout, or conflicting observations. conflictingFields names disagreements; those fields remain null and raise security_data_conflict. A missing check does not fail the entire scan. Display the known fields and preserve unknown values; never turn null into false or 0. buyTaxPct and sellTaxPct describe reported token taxes, not the total cost of a trade. They exclude pool fees, v4 hook fees, price impact, slippage and gas. A reported 0/0 therefore does not mean a free swap. isHoneypot=false means no honeypot was reported by the available checks, not that every wallet, route or future trade can sell. This endpoint does not simulate a specific trade, and checkedAt is collection time rather than the underlying audit time. deployer.address, launches and migrations contain available deployer observations, with status=partial. Rug classification is not available: rugs is always null. Missing deployer data has status=unavailable. Never render ‘0 rugs’ or ‘0 launches’ from null. ATL, social URLs and description are returned when supplied. Treat all token names, symbols, descriptions and external links as untrusted content. ### ATH, dips and launch All money values are USD. Percentage values use 0–100 units: tax 1 means 1%, not 100%. Durations use seconds; timestamps are ISO 8601 UTC. ATH changeFromAthPct = (price / ATH − 1) × 100 and is negative below ATH. drawdownPct is the positive decline, clamped at zero. An ATH below the current quote raises a warning. ATH and launch market caps use today's supply and are approximations when supply has changed. A dip is a closed five-minute candle at or after the reported ATH whose close is at or below ATH × (1 − dipThresholdPct / 100). Wicks and the unfinished candle do not qualify. firstDipAt is populated only when the history covers the ATH without gaps. athToFirstDipSeconds measures the ATH-to-first-crossing duration; firstDipAgeSeconds measures time elapsed since that crossing. lastObservedDipAt is the latest observed transition from above to below that same threshold. It is not the most recent local low. secondsSinceLastObservedDip measures its age. A later recovery does not erase the observation. A truncated window or a gap may hide other crossings: inspect historyStatus, hasGaps, windowStart, windowEnd and lastCandleAgeSeconds. Times label candle opens, with five-minute resolution. A missing crossing is null, not proof that no dip occurred. launch samples the last trade in the first second after the earliest returned trade, using at most 100 earliest trades. mayBeTruncated identifies samples reaching the cap. Its price and implied market cap follow the strategy engine's launch metric. No individual customer positions, strategy thresholds, wallets or private reports are included. ### Agent activity The Orus API groups its data by subject: market, security, risk, agents and other indicators. agents describes trading-agent activity. scope=all_orus_agents includes desk and customer agents on the requested chain. Only counts and timestamps are returned, never agent/customer IDs, wallets, transaction hashes, amounts, PnL or strategy settings. real and simulation each contain tradedAgents, holdingAgents, entries24h, exits24h, lastEntryAt and lastExitAt. tradedAgents counts distinct agents with eligible entries in retained history. holdingAgents counts distinct agents still holding according to the position book; it is a subset of tradedAgents, so do not add them. Multiple entries by the same agent count once in these two fields. Agents are not necessarily independent strategies or separate users. Real entries use position statuses open, closed or sell_failed and require a non-empty recorded entry transaction hash. This excludes pre-broadcast placeholders and real rows without an entry hash, even if their bookkeeping is incomplete after an actual purchase. entry_pending never counts, even with a hash. Simulation uses simulated_open or simulated_closed and does not require a hash. Mode comes from the position, not the agent's current execution setting. Paused and stopped agents still count. Holding includes sell_failed because the book still records tokens held. No receipt or current wallet balance is rechecked. entries24h counts eligible position entries, not distinct agents, with entry_at in the inclusive interval [asOf minus 24 hours, asOf]. exits24h counts eligible closed positions using exit_at in that same interval; failed exits do not count. A closure can be a simulated write-off and must not be described as proof of a successful on-chain sale. lastEntryAt and lastExitAt are the latest eligible recorded timestamps in retained history, not only the 24-hour window. Entry timestamps are bookkeeping times, not guaranteed block inclusion times. Future timestamps are excluded. asOf is the observation time for agent activity. coverage=retained_history means currently retained records, not a guaranteed lifetime history: deleting an agent can remove its history. With status=available, zero means no matching records; a null lastEntryAt/lastExitAt means no eligible timestamp was found. With status=unavailable, asOf, all counts and all dates are null; availability.agents.status is unavailable and warnings includes agent_activity_unavailable. Never convert this failure to zero. Rejection counts and acceptance rates are not exposed: existing decision logs mix strategy criteria with operational failures and do not capture every evaluation. Absence of an entry is not a refusal. Agent activity is not a consensus score, a safety verdict or a trading recommendation. ### Freshness and availability checkedAt is the start of data collection, not the timestamp of an on-chain audit or the last trade. market.priceUpdatedAt is null because the exact quote timestamp is unavailable. A successful scan, including agents, is cached for at most 30 seconds from checkedAt. cache.ageSeconds reports its age; agents.asOf remains the original observation timestamp on a cache hit. Authentication and quotas are enforced even on cache hits; HTTP responses are private, no-store. availability reports available, unavailable or not_requested for details, chart, launch and agents. Security has available, partial or unavailable coverage, with missingFields and conflictingFields. Security, chart, launch and agent activity may be incomplete while core token details succeed. When the scan cannot be served, the endpoint returns 503. The public token page refreshes observations for tokens already scanned or traded by Orus. It shows price candles, anonymous entry counts and clearly separated real/simulated agent activity. Refresh is requested every 30 seconds while visible; shared cached observations may be older. Collection timestamps and missing-data states are shown. The page uses a fixed 48-hour window and 30% dip threshold, without a partner key. ### Telegram integration Render card.text immediately above your buy/sell controls and link the arrow or ‘checked by orus’ label to card.url. Use plain text, or escape all dynamic values for your Telegram parse mode. The URL deep-links to /token/4663/
, the public Orus token intelligence page without a partner key. Chart markers count entries in five-minute buckets, not execution prices; customer identities, sizes and rules remain private. When retained public desk reports exist, the token page lists dated snapshots with their UTC collection time. Open a report to see its saved market figures, chart and available analysis. Historical data is not refreshed when opened; private customer reports and strategy context are excluded. A typical line is: orus: no honeypot reported · tax 0/0 · bundled 4% · deployer 3 launches, rugs unknown · checked by orus ↗. This is an illustration, not a live scan. The API emits ‘honeypot unknown’, ‘tax unknown/unknown’ and ‘bundled unknown’ whenever the source lacks those fields. card.text keeps its existing format. You may add a separate activity line when agents.status=available: ‘Agents (real): 8 traded · 3 holding · 5 entries / 24h’. These numbers are illustrative. Use agents.real.tradedAgents, agents.real.holdingAgents and agents.real.entries24h respectively; label simulated activity separately. Show the observation time and preserve attribution. If activity is unavailable, omit its counts or show ‘Agent activity unavailable’ while retaining the valid market scan. If the scan fails, show ‘orus: scan unavailable’ or omit the line. Do not reuse a successful badge without its age. For the two-week pilot Orus can report admitted requests, distinct tokens, completed status codes, cache hits and median/p95 server time. The partner must measure card impressions and referral clicks; scan calls are not impressions. ### Limits and errors Default quotas are 30 admitted requests per minute and 5,000 per UTC day, shared across all of a partner's keys and all server instances. Operators can configure them per partner. Validation failures and upstream failures consume admitted requests. X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Day-Remaining report quota state. 400: fix parameters. 401: missing, invalid, expired or revoked key, or inactive partner; stop and contact Orus. 404: token not indexed. 429: wait Retry-After. 503: retry with jitter after Retry-After, at most twice. An unindexed token is not necessarily an invalid contract. Unsupported methods return 405. Next.js also supports HEAD (same authentication and quota as GET) and automatic OPTIONS. GET errors have { error: { code, message }, requestId }. Every GET response has X-Request-Id for support. Do not send your key to support. JSON additions may appear within v1; clients should ignore unknown fields and keep null handling. Breaking changes require a new API version. ## Machine-readable contract - OpenAPI: https://www.orusagent.xyz/openapi/partner-v1.json - Agent integration guide: https://www.orusagent.xyz/partner-api-agents.txt --- # Strategy field reference Defaults, ranges and, where they apply, the bounds a user's strategy lives under. ### Identity | Field | Default | Description | |---|---|---| | `name` | — | What the strategy is called on your console and, for the house's, on the public desk. | | `description` | — | One line on what the strategy is for. Shown on the strategy card. | ### Venue | Field | Default | Description | |---|---|---| | `allowed_dexes` | pons | Venue whitelist, e.g. pons, noxafun, uniswap-v3. Each entry is matched, case-insensitively and as a substring, against the venue key (uniswap-v4), the venue name (Uniswap) and the launchpad the token came from (pons-v2), so a launchpad name admits its graduated tokens on whichever DEX they now trade. Empty accepts any venue. | | `require_bonded` | unset | true admits graduated tokens only, false admits tokens still on their bonding curve only, unset admits both. | ### Activity | Field | Default | Description | |---|---|---| | `min_volume` | 100,000 $ | Minimum 24-hour volume in USD. A rolling 24 hours, not volume since launch. Passed to the screener and re-checked locally. Bounds: ≥ 0. | | `min_market_cap` | 20,000 $ | Minimum market cap in USD. Passed to the screener and re-checked locally. Bounds: ≥ 0. | | `max_launch_mcap` | 50,000 $ | Ceiling on the market cap one second after the token's first trade. A launch at a high cap is usually sniped or bundled, and the dip pattern is unreliable on it; the exclusion is permanent. Supply is read from the token. Unset skips the check. Bounds: ≥ 0. | | `max_age_hours` | 168 hours | Maximum token age, in hours since creation. A token with no creation date fails an age-bounded strategy. Bounds: ≥ 0, ≤ 8760. | | `min_age_hours` | 0.083 hours | Minimum token age, in hours since creation. 0.083 is five minutes. Bounds: ≥ 0, ≤ 8760. | | `min_transactions_24h` | 200 | Minimum 24-hour trade count. Passed to the screener and re-checked locally. Bounds: ≥ 0. | | `min_volume_liquidity_ratio` | unset | Floor on 24-hour volume divided by liquidity. High turnover on thin liquidity is a token being traded rather than parked. Bounds: ≥ 0. | | `max_volume_fees_ratio` | 2,000 | Ceiling on 24-hour volume divided by the fees that volume paid. On an AMM the two are proportional — fees are a fixed share of every trade — so the ratio is one over the fee rate and sits near 220 on this chain whatever the token's size — measured as the median of 1,000 signalled tokens. That is the normal value, not a target: a ceiling belongs well above it, and at 2,000 it refuses about one token in twenty where 220 would refuse half. A far higher ratio is volume that reached no pool: wash trading, or an accounting that has lost track. Both figures are the same 24-hour window; dividing by the fees a pool has earned since launch would measure its age instead. A pool under three hours old can read high because the provider's fee counter lags its volume counter, and a token with no fee figure fails this check when it is set. Bounds: ≥ 1. | | `min_buys` | 100 | Minimum 24-hour buy count. Bounds: ≥ 0. | | `min_sells` | 100 | Minimum 24-hour sell count. A token that is only bought has nobody able to sell it. Bounds: ≥ 0. | | `min_total_fees` | unset | Floor on the cumulative fees the pool has earned, in USD. A proxy for how much real trading the pool has seen. Bounds: ≥ 0. | ### Who holds it | Field | Default | Description | |---|---|---| | `max_bundled_buy_pct` | 40 % | Ceiling on the share of supply held by bundler wallets — buys bundled into the launch transaction. Bounds: ≥ 0, ≤ 100. | | `max_snipers_pct` | unset | Ceiling on the share of supply held by wallets that sniped the launch. A token with no sniper figure fails this check when it is set. Bounds: ≥ 0, ≤ 100. | | `max_insiders_pct` | unset | Ceiling on the share of supply held by insider wallets. Bounds: ≥ 0, ≤ 100. | | `max_dev_holdings_pct` | unset | Ceiling on the deployer's own holdings. Bounds: ≥ 0, ≤ 100. | | `max_top10_holdings_pct` | unset | Ceiling on the top ten holders combined. Bounds: ≥ 0, ≤ 100. | | `min_organic_volume_ratio` | unset | Floor on organic volume over reported volume, from 0 to 1 — the wash-trading floor. Bounds: ≥ 0, ≤ 1. | | `min_holders` | unset | Minimum holder count. A token with no holder figure fails this check when it is set. Bounds: ≥ 0. | ### The entry | Field | Default | Description | |---|---|---| | `dip_threshold_pct` | 75 % | Minimum fall from the all-time high before an entry is considered. The analyser walks candles forward from the high to the first close below ATH × (1 − threshold/100); that instant is the first dip. Bounds: ≥ 1, ≤ 99. | | `max_dip_pct` | unset | Ceiling on the dip at entry. A token down more than this from its high is treated as dead rather than dipped. Unset means no ceiling. Bounds: ≥ 1, ≤ 100. | | `min_dip_timing_minutes` | 5 min | Floor on the time from the all-time high to the dip — the flash-crash guard. A dip that took ninety seconds is not a dip. Bounds: ≥ 0. | | `max_dip_timing_minutes` | 600 min | Ceiling on the time from the all-time high to the dip — the dead-token guard. 600 is ten hours. Bounds: ≥ 0. | | `min_dip_timing_launch_minutes` | unset | Floor on the time from launch to the dip. Bounds: ≥ 0. | | `max_dip_timing_launch_minutes` | unset | Ceiling on the time from launch to the dip. Bounds: ≥ 0. | | `max_first_dip_minutes` | 60 min | How long the entry stays valid after the first crossing of the threshold. The crossing opens a window; past it the entry is written off, which is why a token can be rejected for being too late on a dip that is still deep. A pending signal expires on it too. This is the only bound on the AGE of a crossing — max_dip_timing_minutes bounds the ATH-to-crossing duration, which is a different quantity. Left empty the window never closes, and one all-time high keeps producing entries as the price falls away beneath it. Bounds: ≥ 1. | | `min_liquidity_at_dip` | 5,000 $ | Minimum USD liquidity in the pool at entry. Also passed to the screener as its liquidity floor. What decides whether you can get back out. Bounds: ≥ 0, users: ≥ 1,000 $. | | `min_ath_market_cap` | unset | Minimum market cap at the all-time high, in USD. A dip from a high that never meant anything is not a dip worth buying. Bounds: ≥ 0. | ### The size | Field | Default | Description | |---|---|---| | `buy_amount_native` | 0 ETH | ETH to spend per entry. 0 means the strategy produces signals and never spends. The engine wraps it to WETH before the buy and keeps a gas reserve aside. Bounds: ≥ 0, users: ≤ 0.05 ETH. | | `slippage_pct` | 5 % | Slippage tolerance passed to the router, on both legs. Bounds: ≥ 0.1, ≤ 50, users: ≤ 15 %. | | `max_price_impact_pct` | 5 % | Ceiling on the price impact the router estimates for the entry itself. A buy whose own size would move the pool more than this is refused and its signal retired: the round trip would start from a hole no dip pays for. Unset disables the check. Bounds: ≥ 0.1, ≤ 50, users: ≤ 10 %. | | `max_open_positions` | unset | Cap on positions held at once. Open, simulated-open and sell-failed positions all count, so a stuck exit occupies a slot rather than freeing one. Unset means no cap — the wallet becomes the limit. Bounds: ≥ 1, users: ≤ 25. | | `max_daily_spend_native` | unset | Cap on ETH committed to entries per rolling 24 hours, not per calendar day. Unset means no cap. Bounds: ≥ 0. | | `jev_entry_instructions` | — | Additional condition for Jev's Premium-only contextual entry review in simulation or live trading. Jev evaluates observed transactions and participant histories after the quantitative filters; missing evidence means waiting, never automatic approval. Enable Jev on the agent. | ### The exit | Field | Default | Description | |---|---|---| | `min_sell_multiplier` | 2 x | Take profit at this multiple of the fill price. For a real position the router is asked what the exit would return first, and the sell proceeds only if it delivers at least half the promised gain and never less than the stake. Bounds: ≥ 1.01, ≤ 100. | | `stop_loss_pct` | unset | Sell when the position is down this much from the fill — once a second price feed agrees the drawdown is real. Unset disables it. Bounds: ≥ 1, ≤ 99. | | `stop_loss_max_hours` | unset | Sell after holding this long, at whatever the market pays — quote or no quote. A clock, not a price, and the most common exit on the desk by a wide margin. Unset disables it. Bounds: ≥ 0.1, ≤ 720. | | `jev_exit_instructions` | — | Additional condition for Jev's Premium-only take-profit review in simulation or live trading. Jev may approve an exit or defer it for another observation; deferred exits are reviewed even below the original target. Stop loss, maximum hold and explicit manual exits remain outside Jev's veto. | ### Metadata | Field | Default | Description | |---|---|---| | `website_regex` | — | A regular expression matched against the token's socials and description. Evaluated inside the cron, so it is reserved for the house: a pathological pattern would stall every agent's tick. Bounds: users: not available. |