Skip to content

Methodology

How Argus reaches — and proves — a decision

Everything below is implemented in the open-source code. Where this page and the code disagree, the code wins and this page is a bug.

Step 1

Market snapshot

Each run starts by capturing one snapshot of the asset. Spot price comes from CoinGecko (CryptoCompare as fallback). Around 210 days of daily closes and volumes are used to compute RSI-14 (Wilder), MACD(12, 26, 9), EMA-20/50/200, 7/30/90-day returns, annualized 30-day realized volatility, drawdown from the 90-day high and a 7-vs-30-day volume trend. The Crypto Fear & Greed index provides sentiment.

If a data class is unavailable the snapshot records why, and analysts that require it abstain instead of guessing. Only spot price is mandatory. Snapshots are cached for 60 seconds, so two runs a few seconds apart see identical data.

Step 2

The analysts

Each analyst is a versioned prompt plus a declared set of data inputs. An analyst only receives the snapshot keys it declares, must respond with schema-valid JSON (vote, confidence 0–100, reasoning, cited data points), and is retried once with the validation error if it doesn't. Invalid output is never patched into a vote — it is recorded as a failure, along with the raw provider response.

AnalystFrameworkInputs
Value HunterMargin of safety · relative valuationMarket cap, 90-day drawdown, long-horizon returns
Momentum TraderRSI · MACD · EMA trend · volume confirmationDaily technicals computed from ~210 days of closes
Macro AnalystRisk appetite · long-cycle regimeFear & Greed index, 90-day trend, EMA-200 positioning
On-chain SleuthMVRV · SOPR · exchange netflowsOn-chain metrics (abstains when no provider is connected)
Risk GuardianVolatility-adjusted conviction · drawdown controlRealized volatility, drawdown, RSI extremes, sentiment

Prompt texts are public at /api/prompts?ref=<agent>/<version>. Prompts are never edited in place; changes ship as a new version.

Step 3

Consensus

Votes are weighted by each analyst's confidence. For each direction d ∈ {BUY, SELL, HOLD}:

W_d          = Σ confidence_i   over analysts i that voted d
recommendation = argmax_d W_d
confidence     = W_recommendation / Σ_d W_d × 100
split          = (W_first − W_second) < 10% of Σ_d W_d

A run needs at least 3 valid votes (quorum) to be sealable. Runs where an analyst failed are labelled degraded; abstentions due to missing data are not.

Step 4

Hashes & sealing

All hashes are SHA-256 over canonical JSON (object keys sorted recursively, no whitespace), so anyone in any language gets the same bytes.

dataSnapshotHash  = sha256(canonical(snapshot.data))
promptHash_i      = sha256(prompt file text, utf-8)
promptVersionHash = sha256(canonical({ v: 1, prompts: [{ agentId, promptVersion, promptHash }] sorted by agentId }))
reasoningHash     = sha256(canonical({ v: 1, snapshotHash: dataSnapshotHash,
                      votes: [{ agentId, vote, confidence, reasoning, dataPointsCited }] sorted by agentId }))

Sealing calls recordDecision on the registry contract, which emits DecisionRecorded(asset, decision, confidenceBps, dataSnapshotHash, promptVersionHash, timestamp, sender). The contract stores nothing and holds no funds. You can seal with your own wallet (you become the on-chain signer) or via the Argus relayer. Wallet-signed transactions are fetched from the chain and checked field-by-field before Argus marks them sealed.

Trust

Verify a decision yourself

Every decision page has a Verify independently button that runs these checks in your browser, reading the chain directly from a public RPC:

  1. Recompute dataSnapshotHash from the published canonical snapshot bytes (stored verbatim, so no number is ever re-serialized).
  2. Download each prompt version and check it hashes to the vote's promptHash.
  3. Recompute promptVersionHash and reasoningHash from the votes.
  4. Fetch the transaction receipt and decode the DecisionRecorded event.

To do it without our UI at all:

curl -s https://<argus-host>/api/decisions/<id> > decision.json
node -e '
  const d = require("./decision.json"), c = require("crypto");
  const canon = (v) => v === null || typeof v !== "object" ? v
    : Array.isArray(v) ? v.map(canon)
    : Object.fromEntries(Object.keys(v).sort().map((k) => [k, canon(v[k])]));
  const bytes = d.snapshot.canonical;  // the exact bytes that were hashed
  const isCanonical = JSON.stringify(canon(JSON.parse(bytes))) === bytes;
  const h = c.createHash("sha256").update(bytes).digest("hex");
  console.log(isCanonical && h === d.dataSnapshotHash ? "snapshot OK" : "MISMATCH");'

Track record

Outcome scoring

Sealed decisions are scored automatically once their horizon has passed (7 days by default) by comparing the asset's price at decision time with its price at the horizon. A move beyond ±2% counts as directional:

BUY  is correct when  return >  +2%
SELL is correct when  return <  −2%
HOLD is correct when  |return| ≤ 2%

Each analyst's vote in a scored decision is graded the same way. The leaderboard reports hit rate and a confidence-weighted Brier score (lower is better), so an analyst that is confidently wrong is penalized more than one that hedged.

Honesty

Limitations

  • Analysts are large language models. They can be wrong, inconsistent across runs and confidently mistaken.
  • The On-chain Sleuth abstains until an on-chain metrics provider (MVRV, SOPR, netflows) is connected.
  • Market data comes from free-tier public APIs and may be delayed or briefly unavailable.
  • Sealing currently happens on Monad testnet.
  • Nothing here is financial advice. See the risk disclaimer.