Pricing Methodology
How we derive prices from on-chain DEX trades, dispenser sales, and multi-hop routing through quote currencies.
Three layers, one displayed price
For any tracked asset, CounterTools may have up to three independent price signals at any moment:
- Direct DEX price β recent on-chain trades against XCP (or PEPECASH, or BTC).
- Multi-hop derived price β recent trades against another asset that itself has a fresh price.
- Dispenser anchor β open dispenser listings selling for BTC, MAD-filtered to reject outliers.
Each signal carries a confidence tier (HIGH/MEDIUM/LOW) based on its source, recency, and the volume of the underlying trade. The chart endpoint exposes all three series independently; the headline floor displayed elsewhere uses the most conservative qualifying value.
Direct DEX price
Counterparty's on-chain DEX matches buy and sell orders directly between addresses. When an order matches against XCP, the resulting trade gives us a per-unit XCP price for the asset. We multiply by the current XCP/USD rate to express it in dollars.
Per-trade rate
We require trades to meet a minimum volume threshold (per-asset, e.g. 5000 BITCORN, 10000 PEPECASH) to filter dust. Volume thresholds are documented per-currency and can be overridden when a market has shifted enough to need recalibration.
Multi-hop pricing
Many Counterparty assets don't trade against XCP β they trade against PEPECASH, BITCRYSTALS, other currencies, or sub-assets. For those, we derive an XCP price by routing through whichever counterparty has a fresh anchor.
Concretely, if BITCORN trades against PEPECASH at a known rate, and PEPECASH itself has a recent direct XCP price, then:
One-hop derivation
The BTCβXCP conversion (when going through a BTC-denominated dispenser anchor) always uses the live global rate, so the error in one hop doesn't snowball with the error in another. We don't chain more than one hop β two-hop derivations multiply too much noise.
Time tolerance for anchor lookup
Quote-currency anchors aren't available at every block. When we need a PEPECASH/XCP rate at a given moment, we look for the nearest anchor within bands:
- Β±24 hours β HIGH confidence on the derived rate
- Β±7 days β MEDIUM (median of anchors in window)
- Β±30 days β LOW (median of anchors in window)
- Beyond 30 days β no derivation, mark stale
Dispenser anchor β MAD outlier rejection
Dispensers are posted-price listings β anyone can deploy a dispenser at any rate. Some are clearly accidental (a wallet leftover at a 1000Γ off rate), some are scams, and most are genuine market prices. We use a statistical filter to reject outliers without manual curation.
MAD explained in plain English
We compute MAD on the 90-day rolling window of dispenser sales. The 90-day scope matters: it lets us detect outliers at the current price level rather than rejecting today's legitimate price as "wrong" because it happens to be 10Γ different from a 2022 value. Sample-size tiers:
| Sample size | Method |
|---|---|
| β₯ 20 sales | MAD-trim on log-prices, accept band β Β±3 MAD around median |
| 5β19 sales | IQR-trim (drop top + bottom quartile), take median of remainder |
| < 5 sales | Fall back to lowest qualifying price (conservative floor) |
Why log-space?
DEX floor β the $10 minimum order filter
Separately from the historical-price methodology, when we compute the current floorfor an asset (the lowest available ask any buyer could hit right now), we ignore DEX orders whose total "get-side" value is under $10 USD.
Order USD value
This single threshold replaces a much hairier per-asset volume-threshold system. It's self-adjusting as prices drift β what counts as "dust" in PEPECASH terms changes as PEPECASH/USD changes β and it works identically for every asset on the platform without hand-curated overrides.
Confidence tiers
Every stored rate carries a confidence label so consumers (the API, the chart, your portfolio) can decide how much weight to give it.
| Tier | Source | Age |
|---|---|---|
| HIGH | Direct XCP-DEX, MAD-anchor with nβ₯20 | Within 24h |
| MEDIUM | 1-hop multi-hop, dispenser anchor, IQR (n 5β19) | Within 7d |
| LOW | 1-hop with stretched tolerance, sparse dispenser | Within 30d |
| STALE | Any path > 30d old or single <5 dispenses | Older or thin |
Spot something wrong?