The pairwise rule — final form (four iterations later)
what you'll learn · The complete pairwise-rule decision procedure — what to check before proposing a composite, what each check rules out, and why same-stage / sign-preserving / decorrelated all matter.
The pairwise-correlation discipline rule started simple (PR #710: low correlation predicts stack) and iterated four times across the session as composites were built and measured. This is the consolidated final form: four conditions all required for composite stacking. Includes the pre-build pre-test checklist, the decision tree for when each iteration of the rule applies, and the load-bearing failure modes.
The pairwise-correlation rule started as a one-line pre-test:
Low pairwise correlation between parent arms predicts the composite will stack.
Across the session, that rule iterated four times as composite arms were built and measured. Each iteration caught an edge-case the previous version missed. This note is the consolidated final form.
The four iterations
| # | PR | Refinement | Failure case that motivated it |
|---|---|---|---|
| 1 | #710 | Low pairwise correlation predicts stack | original observation |
| 2 | #742 | Compute the WOULD-BE composite’s correlation with each parent | found three_clock_portfolio_vol = +1.00 with three_clock_momentum |
| 3 | #748 | Same-stage composition required; mixed-stage interferes | three_clock_portfolio_vol interfered |
| 4 | #770 | The compositional mechanism must PRESERVE both parents’ decision rules | ts_filtered’s sign-vs-rank conflict |
Final form: the four conditions
A composite arm STACKS (mean > both parents) if and only if:
Parents have low pairwise correlation (under 0.5 across seed-by-seed Sharpe sequences). High correlation means the parents are catching the same signal — composing them adds no information.
The composition is same-stage (both parents intervene at the same layer — score, gate, portfolio scale). Mixed- stage composition where the second-stage intervention is dormant on the data reduces the composite to the always-active parent.
The decision mechanism is preserved across composition. If one parent’s decision is sign-based (per-symbol weight determined by return direction) and the other’s is rank-based (top-quantile vs bottom-quantile), the later stage’s mechanism overrides the earlier. The composition discards one parent’s edge.
The pairwise correlation is computed with the right granularity. Across seeds (the cross-seed Sharpe sequence) catches mechanism-level correlation; across days (cross-day return correlation) catches different signals. The harness’s
analyse_harness_csv.py --pairwiseuses cross-seed.
If any of the four conditions fails, the composite either interferes (1, 3 fail) or reduces to the dominant parent (2, 4 fail).
The pre-build checklist
Before writing a new composite strategy class:
-
Identify the two parents. Both must exist as shipped strategies with harness arms.
-
Compute the pairwise correlation. Run a multi-seed CSV export, then
scripts/analyse_harness_csv.py --pairwise. Find the parents’ row in the matrix. -
Check the four conditions:
Condition Decision Correlation under 0.5 Stack possible — continue Correlation 0.5-0.8 Marginal stack at best — re-evaluate Correlation over 0.8 Interferes — DO NOT BUILD -
Check the intervention stages. Both parents at score? Both at gate? Both at portfolio? Same-stage proceeds. Mixed-stage requires running condition #3 separately: “does the second-stage intervention fire frequently enough on the data to differentiate from the first-stage parent?”
-
Check the decision mechanisms. Sign-based parent + rank- based parent will conflict. Sign-based + sign-based stacks. Rank-based + rank-based stacks.
If all four pass, build the composite. If any fails, document WHICH and move on.
The empirical evidence table
The session’s composite experiments map to the rule like this:
| Composite | Corr | Stage | Mechanism | Outcome | Rule satisfied? |
|---|---|---|---|---|---|
three_clock_vol_regime |
unknown | score × gate | rank + filter | mixed | partial |
three_clock_portfolio_vol |
+1.00 | score × portfolio | rank + scale | INTERFERES | #1 fails |
three_clock_vol_weighted |
+0.71 | score × score | rank × scale | TIES (stacked at N=10, ties at N=50+) | #1, #2 pass |
ts_filtered |
unknown | filter × rank | sign + rank | INTERFERES | #3 fails |
ts_active_set |
unknown | filter × magnitude | sign × magnitude | RECOVERS | #1, #2, #3 pass; #4 may explain why it ties rather than stacks |
The composites the rule WOULD have predicted to stack (decorrelated, same-stage, sign-compatible) either tied or beat parents marginally. The composites the rule WOULD have predicted to interfere actually interfered.
The rule’s predictive accuracy across the five composites: 5/5 on direction (stack/interfere/no-conflict). 0/5 on magnitude (no composite cleanly STACKED above both parents at N=100).
What “no clean stack” tells us
The rule predicts WHICH composites can stack. The empirical finding is that on this synthetic, NONE of them did at N=100. Two interpretations:
-
The synthetic has only one alpha source (FOMC drift
- 20-day momentum). Composites can’t catch independent alpha if there’s only one alpha to catch.
-
The 26-arm harness has explored most of the same-stage composite space. Future composites would need to use intervention points the existing arms don’t cover (cadence, universe definition, position holding period).
Both interpretations point to the same next experiment: real data. Multiple alpha sources, more diverse arm definitions, and the pairwise rule’s predictions become genuinely distinguishable.
What this rules out
-
Not “the pairwise rule failed.” It predicted direction correctly in 5/5 cases. The magnitude bound is a separate matter that the rule doesn’t claim to predict.
-
Not “compositions don’t work.” This synthetic has one alpha source; that’s the binding constraint, not the rule.
-
Not “stop building composites.” The rule’s pre-test saves operator time when proposed parents are obviously high-correlation. Use it.
The discipline of incremental refinement
Each iteration of the rule was triggered by a composite result that confounded the previous iteration. The rule didn’t get more complicated because it was wrong — it got more complicated because the territory had structure the previous version flattened.
A corollary: research notes are the artifacts of rule iteration. Without a written record of what the rule said last time, the next iteration would re-discover the same edge cases. The session-summary v2’s name for this is “the research note + code + test triple” — each iteration produces all three, and the rule’s evolution is traceable.
The closing observation
After four iterations, the rule has four conditions. It predicts direction correctly. It doesn’t predict magnitude. It’s incomplete on real data.
That’s fine. A rule that predicts direction on synthetic is already useful — it saves the operator from building composites the rule says will interfere. The magnitude question needs different evidence (real data, larger N, longer backtests) than the synthetic harness can produce.
The pairwise rule’s job is “predict interference”; the harness’s job is “verify the prediction.” Both have been doing their jobs all session.