This is a write-up of our own bug. It lived in the analogue search for months, we found it, measured it, and fixed it. The numbers below are from that measurement, not from a brochure.
We publish it because a method with no known weaknesses is a method nobody measured properly.
The symptom
A match at 88 percent similarity. The overall outline follows the sample closely. And the last ten candles run the other way: the sample's tail goes up, the matched window's tail goes down.
The algorithm is not wrong — similarity really is high. The match is still harmful. If you are looking at an analogue to understand the situation you are in, the tail is precisely where that situation currently sits.
Why it happens
The cause is arithmetic and rather dull.
DTW distance is the sum of disagreements along the alignment path, divided by the sample length. Every candle contributes equally. In a fifty-candle sample, a disagreement across the final ten is one fifth of the sum, averaged against forty candles that agree.
We measured the effect directly. Replace a candidate's tail with one that matches the sample perfectly and overall similarity rises by only 0.3 to 5.3 points, depending on the case. In other words, a completely inverted ending costs a candidate roughly one and a half points out of a hundred.
One and a half points is not filtered by anything. A candidate at 88 with an inverted tail passes every threshold that admits a candidate at 90 with a correct one.
Why the existing filters missed it
The pipeline already had an amplitude gate: the window's total move must be within ten percent, relatively, of the sample's total.
It does not help. That gate looks at the outcome — first candle to last. A window can reach the same outcome by a different route, rising further than the sample mid-way and giving part of it back at the end. Outcome matches, ending inverted, gate passes.
None of the other filters inspects the shape of the ending separately. That was the hole.
The measurement
To avoid fixing by feel, we built a sample: 24 windows across three instruments — twelve on BTC/USDT 4H, six on EUR/USD 4H, six on AAPL 1D. Price-based comparison, similarity threshold 80, sample length 50 candles, forward horizon 10 candles.
The run produced 624 matches. For each we computed the change across the final ten candles, separately for the sample and for the candidate.
| Metric | Value |
|---|---|
| Matches total | 624 |
| Tail signs opposite | 115 |
| …and both tails pronounced | 82 |
| …and gap above 5 pp | 5 |
One hundred and fifteen of six hundred and twenty-four — eighteen percent of the output — had an ending pointing the wrong way. Five were gross, with the two endings more than five percentage points apart.
The rule
Discarding everything with opposing tail signs is not an option. On FX, ten candles often move less than half a percent, and the sign there is decided by noise. So the rule requires three conditions at once.
One. The signs of the final ten candles' change differ between sample and candidate.
Two. Both tails are pronounced. "Pronounced" is defined by the same meaningful-move threshold the site uses for outcome statistics, rescaled to the tail length: ten candles out of fifty is one fifth of it.
Three. The gap between the two tail moves exceeds three percentage points.
A fourth condition sits outside the three: if the sample's own tail is not pronounced, the rule does not apply at all. Judging candidates by a direction the sample does not have is a way to delete half your output for nothing.
Why three points
The threshold was picked from a sweep over the same sample, not by feel.
| Threshold, pp | Cuts of 82 | Gross of 5 |
|---|---|---|
| 1.0 | 27 | 5 |
| 2.0 | 21 | 5 |
| 3.0 | 16 | 5 |
| 4.0 | 9 | 5 |
| 5.0 | 5 | 5 |
All five gross cases are caught at any threshold up to five. The question is how many mid-range cases you take with them. Three points adds eleven to the five and leaves sixty-six borderline ones alone, where the disagreement is already comparable to tail noise. At 2.0 and 1.0 the rule starts removing windows that look similar to the eye.
What changed
| Before | After | |
|---|---|---|
| Matches | 624 | 608 |
| Empty windows | 3 of 24 | 3 of 24 |
Sixteen matches removed out of the eighty-two eligible — under three percent of total output. All five gross cases among them. No window lost its results because of the new rule: three of twenty-four were empty before, three after.
By instrument the picture differs sharply:
| Instrument | Matches | Cut |
|---|---|---|
| BTC/USDT 4H | 144 | 9 |
| AAPL 1D | 20 | 7 |
| EUR/USD 4H | 460 | 0 |
On FX the rule never fired, which is the expected result. Ten four-hour candles on EUR/USD rarely move half a percent, the significance threshold there is correspondingly low, and a three-point gap barely occurs. We did not tune anything to make it fire — a rule that stays quiet where it should stay quiet is working.
What the rule does not do
It looks at the direction of the ending, not its shape. A candidate whose tail runs the same way but twice as steeply passes.
That is a deliberate limit. Tail shape is a separate problem and we will not touch it without the same kind of measurement.
The point
The interesting question about any matching engine is not how good it looks on a demo, but what it gets wrong and by how much. Ours got this wrong by eighteen percent of output, five cases of it badly, and now cuts sixteen matches in six hundred to fix it.
The full protocol, with constants and a documented way to switch the rule off, lives in the project repository.