Every figure on this site is a historical frequency measured from real price bars. This page explains how to read those figures, and is equally clear about the things the data cannot tell you.
Dukascopy bank-feed price history, aggregated into hourly (H1) bars. 1,742,350 hourly bars across 19 symbols sit behind the dashboard.
Coverage isn't uniform, because the instruments themselves aren't:
| Group | Symbols | History |
|---|---|---|
| FX majors | 4 | 2003 → 2026 |
| FX minors | 6 | 2003 → 2026 |
| Metals | 2 | 2003 → 2026 |
| Indices | 5 | 2011 / 2013 / 2020 → 2026 |
| Crypto | 2 | 2017 → 2026 |
Each symbol's real span is shown in the dashboard's "History depth" tile — never assume 23 years for an index or a coin.
The share of hourly candles in that bucket that closed above their open. Nothing more.
A 58% up-rate for "Wednesday 14:00" means: of every Wednesday 14:00 hourly candle in the history, 58% finished higher than they started. 50% is a coin flip.
It says nothing about how far price moved — that's the separate average-move figure, and the two often disagree.
The bars are bucketed in UTC because it has no daylight-saving jumps — an hour bucket always means the same hour.
The dashboard's timezone selector shifts every view to your zone. It applies a fixed offset, not full DST rules, so during the weeks when your local clock has changed and the reference zone hasn't, a bucket can be an hour off from your wall clock.
No — this is a history tool, not a quote feed. The dashboard's "as of now" panel simply looks up what this weekday-and-hour bucket has historically done; it isn't reading a live price.
The aggregates are rebuilt from the archive periodically. One more day of bars moves a 5,000-sample bucket by a rounding error, which is exactly the point of a large sample.
Yes. Every bucket carries its sample size n and its z-score, and the aggregates are plain JSON served from this site — the browser does the summing, so nothing is hidden server-side.
The z-score is the standard proportion test against a fair coin: z = (2·ups − n) / √n.
n, and how big is big enough?n is how many real hourly bars went into that percentage. It is the single most important number on the screen, and the one most people skip.
The noise floor shrinks with the square root of n, so:
| Sample size | Move needed to beat chance |
|---|---|
| n = 25 | ±20 pp |
| n = 300 | ±5.7 pp |
| n = 1,000 | ±3.1 pp |
| n = 5,000 | ±1.4 pp |
A 70% up-rate on n = 25 is noise. A 54% up-rate on n = 5,000 is real. Stacking filters (month and weekday and hour) shrinks n fast — the dashboard warns you when it drops too low.
It marks buckets where |z| ≥ 3 — the deviation from 50% is large enough, for that sample size, to be unlikely to come from chance alone.
That's a deliberately strict bar. It answers exactly one question: "is this pattern probably real?" It does not answer "is it big enough to trade?" — see below.
Because 80% was what our own early sample said too — before we tested it properly.
On a 20-month sample, EUR/USD Thursday 01:00 read 80.4% up on n = 56. Re-measured over a decade, the same bucket settled at 67.7% on n = 446. Every extreme reading shrank toward 50% the same way.
That's regression to the mean, and it is the normal fate of small-sample extremes. Anyone still advertising 80% is either using a tiny sample or not showing you one.
The strongest raw signals in the whole dataset cluster around the daily rollover (roughly 21:00–22:00 UTC). They're genuine price behaviour — but they sit in the thinnest liquidity of the day, where spreads widen sharply and swap is charged.
No — and this is the most important answer on the page.
The up-rate counts direction. Your broker charges you the spread. We checked every liquid weekday×hour bucket across the FX majors against a typical 1.0-pip spread:
The up-rate also says nothing about the size of the winners versus the losers, which is what actually decides an outcome. A 58% bucket whose losers are twice the size of its winners loses money.
No. Three separate reasons, any one of which is fatal:
| Payout | Win rate needed to break even |
|---|---|
| 70% | 58.8% |
| 80% | 55.6% |
| 90% | 52.6% |
We also tested our 5-minute data directly: across 288 slots per symbol, the average absolute drift is 0.08–0.11 pips — a fraction of the spread — and 0–1% of slots beat a 1.0-pip cost.
Not really, and we'd rather say so.
Everything here is built from hourly bars. The "seasonal by month" view therefore shows the up-rate of hourly bars within each calendar month — it does not tell you whether the month itself closed up.
Measured across the whole year, that spread is tiny: 2.6 percentage points for EUR/USD, 1.8 for gold. And 23 years gives only 23 samples of each calendar month, however large the hourly n looks.
A swing trader asking "does September usually close lower?" needs daily or monthly bars. That's a different dataset, and it isn't this one yet.
Intraday context on the H1 timeframe — as a filter, not an entry.
It is a decision-support layer for a strategy you already have. It is not a strategy.
Not to look around — the dashboard is currently open. An account saves your timezone, symbols and watchlist so they follow you between your phone and desktop.
Free covers the hour-of-day and weekday heatmaps on the FX majors, with the full history and the sample size and significance on every cell. Pro adds all 19 symbols, timezone-aware monthly and session views, the top-signals ranking with average move, alerts, CSV export and a saved watchlist. Current amounts are on the pricing section.
Pro checkout isn't switched on yet — while it's being set up, the full dashboard is open to everyone.
No to both. Perfect Indicators reports historical frequencies from past price data. It does not know the future, does not issue entries or exits, and is not licensed to advise you.
We don't sell signals, and we don't publish a number without the sample size sitting next to it.
The five-minute guide walks you through reading a real heatmap cell, start to finish.
Read the guide →