Skip to content

Commit 0d8b9e5

Browse files
docs(ftso): add Fast Updates Analytics page (#1157)
2 parents 6c7f435 + 1e4f9f3 commit 0d8b9e5

File tree

4 files changed

+327
-0
lines changed

4 files changed

+327
-0
lines changed

automations/feed_stability.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
[
2+
{ "name": "AAVE/USD", "stability": 99.09 },
3+
{ "name": "ADA/USD", "stability": 99.06 },
4+
{ "name": "ALGO/USD", "stability": 98.96 },
5+
{ "name": "APT/USD", "stability": 98.98 },
6+
{ "name": "ARB/USD", "stability": 98.67 },
7+
{ "name": "ATOM/USD", "stability": 99.48 },
8+
{ "name": "AVAX/USD", "stability": 99.30 },
9+
{ "name": "BCH/USD", "stability": 99.25 },
10+
{ "name": "BERA/USD", "stability": 96.83 },
11+
{ "name": "BNB/USD", "stability": 99.71 },
12+
{ "name": "BONK/USD", "stability": 97.42 },
13+
{ "name": "BTC/USD", "stability": 99.77 },
14+
{ "name": "DOGE/USD", "stability": 99.14 },
15+
{ "name": "DOT/USD", "stability": 99.31 },
16+
{ "name": "ENA/USD", "stability": 97.34 },
17+
{ "name": "ETC/USD", "stability": 99.41 },
18+
{ "name": "ETH/USD", "stability": 99.55 },
19+
{ "name": "ETHFI/USD", "stability": 97.56 },
20+
{ "name": "FET/USD", "stability": 96.72 },
21+
{ "name": "FIL/USD", "stability": 98.60 },
22+
{ "name": "FLR/USD", "stability": 97.58 },
23+
{ "name": "HBAR/USD", "stability": 98.99 },
24+
{ "name": "HNT/USD", "stability": 94.54 },
25+
{ "name": "HYPE/USD", "stability": 97.10 },
26+
{ "name": "ICP/USD", "stability": 98.31 },
27+
{ "name": "JOULE/USD", "stability": 62.15 },
28+
{ "name": "JUP/USD", "stability": 98.68 },
29+
{ "name": "LEO/USD", "stability": 80.56 },
30+
{ "name": "LINK/USD", "stability": 99.31 },
31+
{ "name": "LTC/USD", "stability": 99.34 },
32+
{ "name": "MON/USD", "stability": 95.42 },
33+
{ "name": "NEAR/USD", "stability": 98.98 },
34+
{ "name": "NOT/USD", "stability": 94.24 },
35+
{ "name": "ONDO/USD", "stability": 98.96 },
36+
{ "name": "OP/USD", "stability": 98.98 },
37+
{ "name": "PAXG/USD", "stability": 99.70 },
38+
{ "name": "PENGU/USD", "stability": 96.02 },
39+
{ "name": "PEPE/USD", "stability": 98.37 },
40+
{ "name": "POL/USD", "stability": 98.95 },
41+
{ "name": "PUMP/USD", "stability": 94.74 },
42+
{ "name": "PYTH/USD", "stability": 98.38 },
43+
{ "name": "QNT/USD", "stability": 98.85 },
44+
{ "name": "RENDER/USD", "stability": 98.46 },
45+
{ "name": "RUNE/USD", "stability": 95.55 },
46+
{ "name": "S/USD", "stability": 97.63 },
47+
{ "name": "SGB/USD", "stability": 77.25 },
48+
{ "name": "SHIB/USD", "stability": 99.45 },
49+
{ "name": "SOL/USD", "stability": 99.31 },
50+
{ "name": "SUI/USD", "stability": 98.87 },
51+
{ "name": "TAO/USD", "stability": 98.24 },
52+
{ "name": "TON/USD", "stability": 99.29 },
53+
{ "name": "TRUMP/USD", "stability": 98.64 },
54+
{ "name": "TRX/USD", "stability": 99.81 },
55+
{ "name": "UNI/USD", "stability": 98.88 },
56+
{ "name": "USDC/USD", "stability": 99.95 },
57+
{ "name": "USDS/USD", "stability": 98.78 },
58+
{ "name": "USDT/USD", "stability": 99.95 },
59+
{ "name": "USDX/USD", "stability": 99.94 },
60+
{ "name": "WIF/USD", "stability": 96.85 },
61+
{ "name": "XDC/USD", "stability": 98.84 },
62+
{ "name": "XLM/USD", "stability": 99.17 },
63+
{ "name": "XPL/USD", "stability": 95.27 },
64+
{ "name": "XRP/USD", "stability": 99.26 }
65+
]
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
slug: feed-stability-and-risks
3+
title: Feed Stability & Risks
4+
description: Understand how block-latency feed stability and accuracy metrics are calculated and monitored.
5+
keywords:
6+
[
7+
ftso,
8+
oracle,
9+
flare-time-series-oracle,
10+
flare-network,
11+
analytics,
12+
feed-stability,
13+
accuracy,
14+
fast-updates,
15+
]
16+
sidebar_position: 3
17+
---
18+
19+
import FeedStability from "@site/src/features/DataTables/FeedStability";
20+
import Tippy from "@tippyjs/react";
21+
22+
:::tip Last Updated
23+
Stability and risk data is updated every ~2 weeks. The metrics below reflect the most recent reporting window.
24+
:::
25+
26+
FTSOv2 block-latency feeds are continuously monitored for accuracy and stability.
27+
This page defines how the feed stability metrics are calculated and provides the latest analytics data for all block-latency feeds.
28+
29+
## Feed Stability Metrics
30+
31+
**Feed stability** is the percentage of observations where a block-latency feed stays within a specified deviation band of a reference price.
32+
This metric helps users understand the reliability and accuracy of each feed over time.
33+
34+
### Metric definition
35+
36+
Stability is calculated by comparing on-chain data against external reference sources (such as aggregated CEX prices) at specific observation times (`t`).
37+
38+
- **Onchain Price (`P_onchain`)**: The price delivered by FTSOv2 Fast Updates.
39+
- **Reference Price (`P_ref`)**: The benchmark price from external sources.
40+
- **Deviation**: Calculated as the absolute percentage difference `deviation(t) = abs(P_onchain(t) - P_ref(t)) / P_ref(t)`
41+
42+
Stability is tracked against a **0.2% deviation band**, which is the primary metric displayed in the analytics table below.
43+
44+
### Calculation methodology
45+
46+
For a specific feed and deviation band `B`:
47+
48+
1. Collect time-aligned observations of `(P_onchain(t), P_ref(t))` over the reporting window.
49+
2. Mark each observation as “in band” if `deviation(t) <= B`.
50+
3. Compute stability as: `stability(B) = (in_band_observations / total_observations) * 100`
51+
52+
:::info
53+
54+
Stability measures _frequency_ (how often the price is accurate).
55+
It does not measure the _magnitude_ of the error when the price is inaccurate.
56+
57+
:::
58+
59+
### Interpreting stability scores
60+
61+
| Stability Range | Status | Description |
62+
| --------------- | ------------ | ------------------------------------------------------------------------ |
63+
| ≥99% | 🟢 Excellent | Feed maintains exceptional accuracy relative to reference. |
64+
| 97-99% | 🟢 Good | Feed demonstrates strong accuracy with minimal deviation. |
65+
| 94-97% | 🟡 Moderate | Feed shows acceptable accuracy but may experience occasional deviations. |
66+
| 80-94% | 🔴 Low | Feed experiences notable deviations; consider additional validation. |
67+
| &lt;80% | ⚫ Very Low | Feed shows significant instability; exercise caution when using. |
68+
69+
## Risk Classification
70+
71+
Feeds are categorized into risk levels based on their underlying market integrity.
72+
73+
**Assignment Logic**: This is a waterfall classification system. To qualify for a lower risk tier (e.g., Low Risk), a feed must meet **all** criteria in that column. If it fails even one criterion, it falls to the next risk level.
74+
75+
| **Aspect** | 🟢 **Low Risk** | 🟡 **Medium Risk** | 🔴 **High Risk** |
76+
| --------------------------- | ----------------------------------------- | ------------------------------------------- | ------------------------------------------------------ |
77+
| **Intrinsic Volatility** | Low, stable price trends | Moderate price fluctuations | High, frequent price swings |
78+
| **Liquidity Variation** | Abundant and consistent | Sufficient but variable | Limited and inconsistent |
79+
| **Liquidity Concentration** | Broad and well-distributed across venues | Somewhat concentrated | Highly concentrated in a few sources |
80+
| **Asset Spread Risk** | Tight spreads, minimal bid-ask gaps | Moderate spreads, acceptable bid-ask gaps | Wide spreads, significant bid-ask gaps |
81+
| **Cross Rate Risk** | Low correlation, direct pricing available | Moderate correlation, indirect pricing used | High correlation, dependent on multiple intermediaries |
82+
83+
**Other risk categories:**
84+
85+
-**New Feed**
86+
New tokens lack historical data for proper risk assessment and stable price discovery.
87+
Users must recognize these assets carry higher volatility risks and verify feed reliability independently.
88+
After a monitoring period, feeds will be assigned risk levels or potentially discontinued.
89+
90+
Each feed undergoes a rigorous assessment process prior to deployment. The evaluation criteria may vary depending on the specific type of feed being implemented and can evolve over time as our understanding of market integrity risks improves.
91+
92+
:::note
93+
94+
Risk assessments are conducted prior to deployment and may be updated as market conditions or liquidity profiles change.
95+
96+
:::
97+
98+
## Current Feed Stability
99+
100+
The table below displays latest stability metrics for all FTSOv2 block-latency feeds.
101+
102+
- **Stability**: Percentage of observations within **0.2%** of the reference price.
103+
- **Status**: Based on the stability interpretation table above.
104+
105+
<FeedStability />

sidebars.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ const sidebars: SidebarsConfig = {
100100
items: [
101101
"ftso/getting-started",
102102
"ftso/feeds",
103+
"ftso/feed-stability-and-risks",
103104
{
104105
type: "category",
105106
label: "FTSOv2 Guides",
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import React from "react";
2+
import Tippy from "@tippyjs/react";
3+
import "tippy.js/dist/tippy.css";
4+
import stabilityData from "@site/automations/feed_stability.json";
5+
import riskData from "@site/automations/ftso_risk.json";
6+
import styles from "../tableStyles.module.css";
7+
8+
type StabilityRow = {
9+
name: string;
10+
stability: number;
11+
};
12+
13+
type RiskRow = {
14+
name: string;
15+
risk: 0 | 1 | 2 | 3 | 4;
16+
};
17+
18+
const getStabilityIcon = (value: number) => {
19+
if (value >= 99) {
20+
return {
21+
icon: "🟢",
22+
tooltip:
23+
"Excellent stability: Feed maintains ≥99% accuracy within 0.2% of reference.",
24+
};
25+
} else if (value >= 97) {
26+
return {
27+
icon: "🟢",
28+
tooltip:
29+
"Good stability: Feed maintains 97-99% accuracy within 0.2% of reference.",
30+
};
31+
} else if (value >= 94) {
32+
return {
33+
icon: "🟡",
34+
tooltip:
35+
"Moderate stability: Feed maintains 94-97% accuracy within 0.2% of reference.",
36+
};
37+
} else if (value >= 80) {
38+
return {
39+
icon: "🔴",
40+
tooltip:
41+
"Low stability: Feed maintains 80-94% accuracy within 0.2% of reference.",
42+
};
43+
} else {
44+
return {
45+
icon: "⚫",
46+
tooltip:
47+
"Very low stability: Feed maintains <80% accuracy within 0.2% of reference. Exercise caution.",
48+
};
49+
}
50+
};
51+
52+
const getRiskIcon = (risk: RiskRow["risk"]) => {
53+
const riskMap: Record<RiskRow["risk"], { icon: string; tooltip: string }> = {
54+
0: {
55+
icon: "🟢",
56+
tooltip:
57+
"Low risk: Feeds demonstrating low volatility and generally stable price trends.",
58+
},
59+
1: {
60+
icon: "🟢",
61+
tooltip:
62+
"Low risk: Feeds demonstrating low volatility and generally stable price trends.",
63+
},
64+
2: {
65+
icon: "🟡",
66+
tooltip: "Medium risk: Feeds demonstrating moderate price fluctuations.",
67+
},
68+
3: {
69+
icon: "🔴",
70+
tooltip:
71+
"High risk: Feeds demonstrating high volatility with frequent price swings.",
72+
},
73+
4: {
74+
icon: "⚫",
75+
tooltip:
76+
"New Feed: Recently launched feeds with high volatility risk. Users must verify reliability.",
77+
},
78+
};
79+
return riskMap[risk];
80+
};
81+
82+
export type FeedStabilityProps = {
83+
data?: StabilityRow[];
84+
showRisk?: boolean;
85+
};
86+
87+
const FeedStability: React.FC<FeedStabilityProps> = ({
88+
data = stabilityData as StabilityRow[],
89+
showRisk = true,
90+
}) => {
91+
const riskMap = new Map((riskData as RiskRow[]).map((r) => [r.name, r.risk]));
92+
93+
const sortedData = [...data].sort((a, b) => b.stability - a.stability);
94+
95+
return (
96+
<table className={styles.table}>
97+
<thead>
98+
<tr className={styles.header}>
99+
<th>Feed</th>
100+
<th>Stability (0.2%)</th>
101+
<th>Status</th>
102+
{showRisk && <th>Risk</th>}
103+
</tr>
104+
</thead>
105+
106+
<tbody>
107+
{sortedData.map((row) => {
108+
const { icon: stabilityIcon, tooltip: stabilityTooltip } =
109+
getStabilityIcon(row.stability);
110+
const risk = riskMap.get(row.name) ?? 2;
111+
const { icon: riskIcon, tooltip: riskTooltip } = getRiskIcon(
112+
risk as RiskRow["risk"],
113+
);
114+
115+
return (
116+
<tr key={row.name} className={styles.row}>
117+
<td className={styles.regularFont}>{row.name}</td>
118+
119+
<td className={styles.monoFont}>{row.stability.toFixed(2)}%</td>
120+
121+
<td className={styles.regularFont}>
122+
<Tippy
123+
content={stabilityTooltip}
124+
theme="custom"
125+
arrow
126+
animation="fade"
127+
maxWidth={250}
128+
interactive
129+
>
130+
<span className={styles.pointer}>{stabilityIcon}</span>
131+
</Tippy>
132+
</td>
133+
134+
{showRisk && (
135+
<td className={styles.regularFont}>
136+
<Tippy
137+
content={riskTooltip}
138+
theme="custom"
139+
arrow
140+
animation="fade"
141+
maxWidth={250}
142+
interactive
143+
>
144+
<span className={styles.pointer}>{riskIcon}</span>
145+
</Tippy>
146+
</td>
147+
)}
148+
</tr>
149+
);
150+
})}
151+
</tbody>
152+
</table>
153+
);
154+
};
155+
156+
export default FeedStability;

0 commit comments

Comments
 (0)