research / June 19, 2026 / 9 min read

The Consolidation Filter That Didn't Work

252 chop-filter tests, one failed translation, and the move toward graded trade quality.


The problem I still think I’m solving

The previous study changed the way I was looking at Momentum V1.

I started that work looking for a better trend filter. The results pushed me toward expansion detection instead. Static trend strength was not that useful. Measuring whether volatility, range, or directional movement was expanding worked better.

That was useful, but it did not remove the thing that still bothers me.

The strategy still looks most vulnerable when price compresses, rotates, and produces low-quality sweeps. A lot of the bad trades still look like consolidation by eye. Price is not cleanly moving away from an area. It overlaps, hesitates, sweeps nearby highs or lows, then fails to follow through.

I still think that matters.

The hard part is getting the code to see what I see. A chart lets me compress a lot of small observations into one judgement. Code wants exact rules. This batch was my first serious attempt to write those rules down, and it did not go the way I wanted.

The obvious next step

After the expansion-filter work, the next idea was direct chop rejection.

If the strategy loses too much in compressed, indecisive price action, then a consolidation filter should help. That was the hypothesis.

The visual version is easy enough to describe. Price sits inside a local range. Bodies get smaller. Wicks overlap. Sweeps become shallow. The market looks busy, but it is not really going anywhere.

So I tried to convert that into filters.

The first version was binary. A trade would pass or fail.

That was the thing I wanted to test.

What I tested

I grouped the batch into three families.

The first was a local box state machine. It built a recent price box from the last few candles, then checked whether the signal candle had escaped that box in the trade direction. This was the idea I had the most confidence in because it was closest to how I manually think about consolidation.

The second was price density. This measured overlap by comparing the sum of recent candle ranges with the total high-low span. If candles keep covering the same area, density rises. In theory, that should catch rotational price action.

The third was SMA entanglement. This counted how often price touched or crossed the moving average. If price keeps passing through the mean, it may be stuck around it rather than expanding away.

Translating Visual Consolidation into Coded Filters

Visual readCoded proxyResult
Price trapped in a local rangeLocal box escapeToo close to existing sweep trigger
Lots of overlap, little progressPrice densityUseful idea, weak standalone signal
Price stuck around the meanSMA touch / cross countCut good and bad trades together
Compression + indecisionSingle binary vetoToo thin for the full pattern
The first attempt translated visual consolidation into three binary filter families: local boxes, candle overlap, and SMA entanglement.

All three ideas were reasonable. The issue was how much signal they actually carried.

The result

The results landed in an annoying middle ground.

A few numbers improved, but the system did not really change shape. The best local-box version lifted average profit factor slightly, yet it still retained most of the original trade flow. Price density was a bit more interesting in places, but still marginal. SMA touch and cross-count logic was weaker again.

Chop vs Carry-Forward Filters by Avg Profit Factor

The explicit chop-rejection filters improved some metrics, but none were strong enough to become carry-forward candidates.

That made the batch awkward to interpret. The filters were not random. They were measuring something. The problem was that the signal was too shallow.

They described pieces of consolidation, but they did not separate the loss clusters cleanly enough.

The first translation failed.

The local box problem

The local box was the one I expected the most from.

It matched the visual pattern I care about: price trapped inside a recent range, repeated back-and-forth movement, weak escape attempts, and sweeps forming before the structure has really broken.

The coded version ran into overlap with the entry logic.

Momentum V1 already trades sweep-style structures. A lot of entries naturally form near the edge of a recent range. By the time the local-box rule checks whether price has escaped, the setup has often already met a loose version of the same condition.

Local-Box Filter: Per-Asset PF Delta

The best local-box variant produced only small per-asset changes, suggesting the condition overlapped heavily with the existing entry logic.

That made the rule too close to the trigger it was meant to judge. It changed some trades, but not enough to become an independent read on consolidation.

This was frustrating because the idea still makes sense visually. The coded form was just too thin.

Price density

Price density was cleaner than the box rule in one way.

It did not need a specific breakout boundary. It looked at how much candle movement was being spent inside the same local span. That maps better to the feel of chop: lots of movement, not much progress.

The best density variant was one of the better direct chop filters. It helped some assets and produced a more convincing basket result than the SMA entanglement tests.

Still, the improvement was not strong enough. XPTUSD stayed weak. The filter could identify overlap, but overlap alone did not say enough about whether the next sweep had poor expectancy.

This one is probably worth keeping as an ingredient. As a standalone veto, it did not do enough.

SMA entanglement

The SMA touch and cross-count tests were weaker.

The idea was that repeated interaction with the moving average could identify a market trapped around the mean. That can be true during consolidation. It can also be true during normal pullbacks.

That ambiguity showed up in the results. The filter improved drawdown in some places, but it cut too many useful trades with the bad ones. UK100 and JP225 looked especially sensitive to this family.

This also makes sense in hindsight. Momentum V1 already uses the SMA as part of its structure. If I add another rule based on repeated SMA interaction, I risk penalising the strategy for behaving like itself.

SMA entanglement still describes a piece of indecision. It did not work as a standalone consolidation filter.

Where my first read was too strong

My first reaction to the chop batch went too far.

It is tempting to look at weak direct chop filters and say chop detection is the wrong direction. I do not think the evidence supports that.

The narrower conclusion is that the first binary versions were under-specified.

Consolidation looks like a cluster of weak signs: compression, low volatility, overlap, small candle bodies, poor escape, shallow sweeps, mean entanglement, repeated rejection from the same area, and indecision after the trigger.

Each sign can show up in good trades too.

A narrow range can become a good base. A small candle can appear before continuation. A shallow sweep can still work. Price near the mean is not automatically bad.

The combination seems to matter more than any one piece.

That is what this batch clarified. A box rule was too thin. Density was too thin. SMA entanglement was too thin. The thing I am trying to detect may need several weak pieces of evidence to stack together before it becomes useful.

What still counts as progress

This was not the progress I wanted.

I wanted a filter that obviously removed the bad clusters and left the good trades mostly intact. I wanted the research to validate the visual read cleanly.

It did not.

The useful part is smaller. The batch reduced the search space. The local-box version looks less attractive as a standalone filter. Pure SMA entanglement looks less attractive. Price density still has some life, but more as a component than as a production rule.

It also clarified the shape of the problem.

The bad trades I care about are not only compressed. They are compressed with weak escape. Low volatility with indecision. A sweep that technically satisfies the entry rules, but has very little quality behind it.

A single filter splits those into separate questions.

The chart does not.

The translation problem

When I review these trades manually, I am usually adding up evidence.

One small candle does not matter much. A narrow local range can become the base for a good move. A shallow sweep is not always bad. Price near the moving average can happen before strong continuation.

The same feature changes meaning depending on what surrounds it.

That makes a yes-or-no filter brittle. If it is loose, it barely changes anything. If it is strict, it starts cutting the trades that pay for the system.

That is where this batch got stuck.

The emotional part

This was a rough result to sit with.

The consolidation problem has been visible for a while. It is one of the main things I have been trying to remove from the strategy. When a pattern is obvious by eye, it is easy to assume the code version is one good idea away.

So far, that has not been true.

The gap between seeing a pattern and encoding a pattern is bigger than it looks. Discretionary recognition compresses a lot of small observations into one judgement. Code only does that if the structure is built explicitly.

This batch was a reminder of that.

The idea can be directionally right and still fail in its first mechanical form.

The next hypothesis

The next version will use a score.

Instead of asking whether a trade is inside consolidation, the next approach will score how much evidence exists for compression, low volatility, and price indecision.

This is not a half-risk model. I am not trying to scale position size by grade. The decision is still enter or skip. The score is there to describe trade quality on a 1 to 100 scale.

Early versions seem closer to what I was trying to detect manually. The most encouraging sign is that the score appears to break up some of the loss clusters that started this whole thread of research.

That does not solve the problem.

It gives me a better test.

The negative result

I failed to capture consolidation in a single filter.

That is the honest conclusion from this stage.

I still think consolidation is the target. The first encoding was too narrow. The visual pattern I am trying to avoid is probably not one variable. It is a collection of weak signals that only become useful together.

This article is the negative result.

The next one is the graded attempt.