Analisi avanzate

La metodologia di Poliwave

Una descrizione dettagliata di come viene costruita ogni proiezione, dai dati storici grezzi fino alla previsione finale riconciliata.

15

Stages every constituency passes through

4

Levels you can set targets at, national down to sub-region

40,000

Monte Carlo draws per formal projection

47

Elections the formula was backtested against

01In parole semplici

Fornisci a Poliwave una serie di valori obiettivo. Possono essere dati dei sondaggi, scenari ipotetici o una combinazione dei due. Puoi impostare gli obiettivi a quattro livelli: intero paese (generale), regione (come il Canada atlantico), provincia (subnazionale) o una sottoregione più piccola (subregionale, come Calgary).

Per l'elezione che vuoi proiettare, Poliwave carica il risultato dell'elezione precedente con gli attuali confini dei collegi (la stessa redistribuzione, indicata da rep_order nel database). Quell'unica elezione precedente costituisce la base di riferimento per ogni collegio. Le elezioni più vecchie intervengono solo nella fase di ricostruzione storica, che completa le basi di riferimento per i partiti che non si erano presentati nel ciclo precedente.

Poliwave applica quindi una formula di variazione elettorale a ogni collegio. Calcola due previsioni classiche, le moltiplica tra loro e ne estrae la radice quadrata, cioè la media geometrica. Il risultato si trova sempre tra le due e tende verso quella più piccola, così un collegio non può essere spinto sotto zero quando il partito perde e un collegio di fascia intermedia conserva spazio per crescere quando il partito guadagna.

Una volta applicata la variazione, il modello può aggiungere altri effetti: elettori che si spostano tra i partiti, voto tattico nelle competizioni serrate, correttivi demografici e modifiche regionali manuali. La maggior parte è facoltativa. In particolare, il voto tattico è disattivato per impostazione predefinita nelle proiezioni ufficiali pubblicate su questo sito (il comportamento reale degli elettori è complesso e difficile da prevedere tramite regole); è disponibile soprattutto come controllo con cui sperimentare nel simulatore interattivo. Alla fine il modello ridimensiona ogni collegio affinché le medie geografiche si avvicinino ai tuoi obiettivi. Se i dati non concordano del tutto (per esempio, un obiettivo nazionale che non coincide con la media degli obiettivi regionali), prevale l'obiettivo più ampio.

Per le proiezioni ufficiali pubblicate sul sito eseguiamo inoltre una simulazione Monte Carlo, così da ottenere probabilità di vittoria e intervalli di confidenza. Ogni esecuzione richiede circa cinque minuti, quindi il calcolatore interattivo dei seggi non la esegue sui tuoi scenari; ottieni soltanto la stima puntuale.

Il resto della pagina esamina in dettaglio ogni componente.

02Il modello in un paragrafo

Poliwave fa passare ogni collegio attraverso un processo in quindici fasi. Ogni fase svolge un solo compito: leggere il risultato precedente, completare i candidati mancanti, applicare la variazione elettorale, spostare voti tra i partiti, aggiungere correttivi demografici e geografici e infine ridimensionare tutto per rispettare gli obiettivi forniti. La formula di variazione al centro è il nucleo matematico, ma da sola non sarebbe sufficiente. Sono le fasi circostanti a trasformare un sondaggio nazionale in una previsione per collegio di cui ci si può davvero fidare.

03Core projection formula

There are two classical ways to convert a national swing into a constituency-level projection, and each one breaks in a different way.

Proportional swing multiplies every constituency by the same ratio. If a party doubles nationally, every constituency doubles too. This is fine most of the time but breaks during big swings in either direction. A party that was already at 55% in a constituency has nowhere to go when you double it, and the formula tries to push it past 100%. More damagingly, when a party collapses nationally (think NDP 2025 going from 17.8% to 6%), pure proportional brutalises strongholds, Edmonton Strathcona's 60.7% gets scaled down to 20% even though incumbent personal vote and local brand strength should preserve much more than that.

Uniform swing adds the same number of points to every constituency. If the party drops 10 points nationally, every constituency drops 10 points. This breaks the other way: a party at 3% in a constituency drops to negative 7%, which is not a thing. Pure uniform also has the opposite collapse problem: a constituency where the party had almost no presence keeps a non-zero share that's basically noise.

Poliwave's projection formula takes the geometric mean of both, it multiplies the two predictions together and takes the square root. The proportional prediction is computed in log-odds space instead of by plain multiplication, which is the part that stops a stronghold from being pushed past 100% when a small party surges nationally (more on that below). Each prediction is floored at zero first so the inputs to the square root can't be negative:

logit(Pprop)=logit(R)+logit(Pc)logit(Bc),logit(x)=lnx100x
Puni=R+(PcBc)
P=max(0,Pprop)max(0,Puni)

The geometric mean is the natural average for percentages. It always sits between the two predictions, and it gets pulled toward whichever one is smaller. That single mathematical property fixes both classical failure modes at once: when proportional runs high, the smaller uniform value pulls the answer down; when uniform crashes to zero, geometric mean returns zero too (because square root of anything-times-zero is zero), which is the correct answer for a constituency where the party has effectively vanished.

The proportional component uses log-odds so it can never break past 100%. Plain proportional swing multiplies a seat's share by the national ratio, so if a small party doubles or triples across the country, a seat where it was already strong gets multiplied straight off the chart (a 40% Green seat scaled by a tripling would land at 120%, which is not a real result). Log-odds works on a curved scale that has 0% and 100% as walls you can approach but never cross. We measure how far the national share moved on that curved scale, shift the seat by the same amount, and convert back. The seat still climbs when the party surges, it just climbs toward the 100% wall and flattens instead of shooting through it.

Variable definitions

P
The party's projected vote share in this constituency. This is the output. Later pipeline steps adjust it further.
R
What the party got in this constituency in the previous election. Normally the model uses only this one prior election. Earlier elections come in only via the historical-reconstruction step when this number is missing or unreliable.
Pc
Your input target for the party (from polls or scenarios), picked at the most specific level that applies to this constituency. The model checks subregional input first, then subnational, then regional, then the general (national) input.
Bc
The matching baseline. If the current input is regional, the baseline is what the party got in that same region in the last election. The two have to be at the same geographic level; otherwise the swing ratio means nothing.

04The fifteen-stage pipeline

Every constituency goes through the same ordered set of steps. The swing formula above is one of them. The others clean up the input to the formula and make the output line up with everything else the model has to respect.

  1. Input parsing. The model loads each constituency's previous result, the geographic hierarchy (which constituency belongs to which sub-region, province, region), and any referendum results for the target election's redistribution (rep_order). Your hierarchical input is flattened into a lookup so each constituency picks the most specific target that applies to it.
  2. Historical normalisation. Missing or unreliable prior results get filled in. A party that did not nominate a candidate at all (a recent Canadian example: Conservatives in Québec Centre, 2025), or that ran so far below its own national share for the cycle that the result reads as a late-withdrawal residue rather than a real campaign, gets rebuilt by one of three methods described in the next section. This step runs on whatever prior-cycle baseline the database holds for the constituency, including transposed results from older boundaries (a 2025 federal projection's main baseline is the 2021 result transposed onto the 2023 rep_order, for instance).
  3. Swing projection. The core formula runs on every constituency and every party. Special cases handle brand-new parties and parties running nationally but absent from this constituency.
  4. Simple normalisation. The constituency's projected percentages are rescaled to add up to 100%. Anything negative is set to zero.
  5. Vote flow. Loss-only redistribution. When a party is projected to lose share, the lost share is handed to other parties according to a flow matrix you supply.
  6. Vote intake. Vote transfers that don't depend on whether a party is winning or losing. The formula is in the redistribution section below.
  7. Tactical voting. Strategic defection in FPTP races, scaled by how close the local race is. Two rule types: block-target voting (anti-X coordination) and the top-two squeeze (wasted-vote logic). This stage is off by default in the formal projections published on the site and is enabled only when you turn it on in the interactive simulator.
  8. Regional adjustments. Manual knobs. You give the model two tables, one for additive shifts and one for percent multipliers, organised by level (subregional, subnational, regional) and by party. Each cell is the change you want applied at that level for that party. The model just applies what you wrote; nothing is auto-computed here.
  9. Demographics. Per-category adjustments scaled to the party's existing support. You set a boost for a (party, demographic) pair; the model multiplies it by how far the constituency deviates from the national average for that demographic and by the party's current vote share in the constituency, so the effect can't blow past what the party actually has to move.
  10. Incumbent boost. An automatic multiplicative boost goes to the party of any candidate identified as a running incumbent in the constituency (sitting MP seeking re-election). A symmetric deboost of the same size goes to the previous-winner party when the sitting MP is known to be retiring or otherwise not on the ballot. Both magnitudes are calibrated from a backtest sweep across 38 Canadian elections since 2000; see the dedicated section below.
  11. Constituency boosts. Per-constituency manual overrides, either additive or multiplicative. Useful for unusually strong or weak local candidates beyond the auto-incumbent effect, well-known local figures, or one-off scenario tweaks. User boosts stack on top of the auto-incumbent boost.
  12. Hierarchical normalisation. The rescaling step. Every constituency is rescaled level by level (subregional first, general last) so the vote-weighted average at each level matches your input for that level. The general (national) level runs last and is the binding rule the result has to respect.
  13. Threshold capping. Damps any party that's running hot in a constituency compared to its cohort. When the projected share exceeds a set multiple of the regional or national average, the excess gets reduced by a set rate. Both the multiple and the rate are configurable. The constituency is then renormalised to 100%, and hierarchical normalisation is re-run so the capping doesn't break the geographic totals. This isn't a small-party squelch; it applies to any party that runs hot.
  14. Aggregation. Constituency winners are picked, seat totals are added up by party, and geographic summary tables are built for each level of the hierarchy.
  15. Output. Everything is packaged into the JSON response used by the website and by the Monte Carlo layer further down this page.

05Historical reconstruction

Inside that history window, the most important prep step is filling in missing or unreliable prior results. A naive model would take "the party got 0% here" at face value and project from that. Poliwave does not, for two reasons.

The first reason is candidate withdrawal. A party might just not have nominated a candidate at all in the last cycle. There are real Canadian cases: the Conservatives did not run a candidate in Québec Centre in 2025, so the prior result is structurally zero, and treating it as a real voter preference would be wrong.

The second reason is late withdrawals that still leave a name on the ballot. The 2019 Brexit Party stand-down in Conservative-held UK seats is the classic example, but the same thing happens in Canada when a candidate withdraws after the nomination deadline. The resulting tenths of a percent look like a vote share, but they don't reflect a real campaign. Either way, this needs to be cleaned up before the swing formula sees the baseline.

When the model has to fill a baseline in, it picks one of three branches depending on what data is available. Note that transposed prior results (for example the 2021 federal result mapped onto the 2023 rep_order) are treated as the real prior result for the constituency and go through this stage like any other baseline. They're the main input the projection runs on, not an exceptional case.

Branch 1: footprint-matched proportional swing

The default. The missing value is filled by taking the most-specific available geographic average for the party and applying proportional swing from the historical version of that average to the current version. The averages on both sides of the swing ratio only count constituencies where the party ran in both the old and the new cycle. That restriction kills off a whole class of errors. If you didn't restrict it, a party that stood down in a region last cycle but is running fully this cycle would produce a huge swing ratio against a tiny prior denominator, and the rebuilt number would blow past 100%.

R=Rt1Ar,tAr,t1,where Ar,=regional average over ridings the party contested in both years

The "level" in the formula is picked most-specific-first: subregional, then subnational, then regional, then general (national). This matches the same hierarchy the user-input lookup uses elsewhere in the pipeline. The reasoning is the same too: a constituency's behaviour is better predicted by its actual local cohort than by a national rollup.

Branch 2: zero-swing fall-through

When the party has a historical result for the constituency but no current-cycle average at any level (usually because the party isn't running this cycle), the swing ratio is zero and the rebuilt baseline collapses to zero. The constituency gets a clean zero instead of some arbitrary leftover.

Branch 3: regional-average fallback

When there's no historical result at all (the party is genuinely new), the constituency gets a damped version of the current-cycle regional average. The damping factor is set so brand-new parties start meaningfully below their headline regional number, which leaves room for the swing formula to grow them in surge constituencies and shrink them where they don't catch on.

Rebuilt baselines are not treated as if they were real. Each baseline carries a confidence weight depending on where it came from: a real result from the database is trusted fully, a branch-1 reconstruction less, and the branch-3 regional fallback least of all. Before the swing formula reads the baseline, low-confidence baselines get pulled toward the regional mean by a weighted average:

R~=cR+(1c)A,0<c1

The effect is a careful pull toward the average. When the model trusts the baseline, it respects the constituency's individual character. When it doesn't, the constituency behaves more like its regional cohort. That keeps a single noisy or guessed number from contaminating the rest of the pipeline.

06Three families of vote redistribution

Voters move between parties in three different ways, and Poliwave handles each one separately. The three run in order, with each one working on what the previous one produced.

Vote flow (only when a party is losing)

When a party is projected to lose share in a constituency compared to its previous result, the lost share gets handed out to other parties using a flow matrix you supply. Each row tells the model, for one source party, what fraction of its losses go to each other party. The rows don't have to add up to 100%; whatever's left over is treated as abstention or as going to parties outside the projection.

Vote intake (always-on transfer)

Vote intake exists for cases where the "only when losing" condition of vote flow doesn't apply. A party can be gaining nationally and still be drained locally by a new entrant. Each row in the intake matrix tells the model, for one receiving party, what fraction of each source party's current share it pulls in:

ΔPts=wtsPs

This is the case vote intake was built for. Imagine you want to model a new right-wing party (call it Restore) taking voters from Reform UK. Vote flow can't handle this if your projection has Reform gaining or holding steady nationally, because vote flow only fires when the source is losing. But Reform can be up nationally and still bleed support locally to a fresh competitor on the same side of the spectrum. Vote intake lets you say "for every constituency, Restore takes a fixed fraction of Reform's current share" regardless of whether Reform itself is up or down. That's why the formula has no loss-condition: it works in both directions.

Within a single constituency, all the rules look at the same starting snapshot, so the order of rules in the matrix doesn't matter. Multiple targets pulling from the same source add up. If the total drain would take the source below zero, the rules are scaled down proportionally so the source ends at zero instead of negative.

Tactical voting (close-race-sensitive)

In first-past-the-post systems, voters often abandon their first-choice party when it has no real chance of winning the local seat. Poliwave models this directly. There are two rule types. A block-target rule names a party that tactical voters want to keep out, a pool of parties whose supporters will defect, and a list of acceptable alternatives. The rule fires in a constituency only if the target is in the top two; the pool's voters then move to whichever named blocker is strongest locally. A top-two squeeze rule doesn't name a target. It just drains every party below third place toward the top two, with the destination split decided by the squeezed party's own vote-flow preferences.

Both rule types are damped by how close the race is. The effect scales linearly with the local margin and disappears at a cutoff you can set:

ϕ(m)=max(0,1mm),m=|P(1)P(2)|

This is what keeps safe seats from moving while close seats get realistic tactical-voting behaviour. The model penalises parties below second place exactly in proportion to how much the local race matters.

07Demographic adjustments

Demographic effects in real elections are relative, not absolute. If a party does ten points better with renters, that doesn't mean it picks up ten points everywhere. It picks up ten points in constituencies that have a lot more renters than the national average, almost nothing in average constituencies, and loses ten points in constituencies with way fewer renters than average. Poliwave handles this directly. For each (party, demographic) boost you set, the model multiplies your boost by how far the constituency deviates from the national average for that demographic, and by the party's current support in that constituency:

Δp,d,i=(xd,iμd)βp,d100Pp,i100

The deviation term is what makes the adjustment relative. Above-average constituencies get a push proportional to how far above average they are; average constituencies barely move; below-average constituencies get pushed the opposite way. Multiplying by the party's current support is what keeps the formula honest: a party with no vote share in a constituency gets no demographic shift (a 0% party times anything is still 0), and a party already strong in the constituency has more vote share available to move. A party sitting at 3% can drift by a few tenths of a point per category; a party at 30% shifts ten times more in absolute terms but the same in relative terms. That self-bounding shape is what stops a small input ever amplifying into an unintended seat flip downstream.

08Incumbent boost

Incumbent candidates outperform their party's swing. The pattern is robust across systems and shows up in almost every academic study of personal-vote effects: name recognition, constituency casework, media presence during the prior term, and a ready-made local volunteer base all add up to a few percentage points of advantage that pure party-level swing math will miss. The flip side is sophomore-surge loss: when a sitting MP retires, the same seat loses the personal vote that helped prop it up, and the party usually slips back toward its normal baseline.

Poliwave applies both effects directly. After demographics and before any user-supplied constituency overrides, the model classifies every constituency into one of three states and adjusts the projected vote share of the relevant party:

  • Incumbent running. A multiplicative boost to the incumbent's party.
  • Incumbent retiring. A multiplicative deboost of the same magnitude to the previous-winner party. The seat may still be safe, but the personal vote is gone.
  • No prior history available. No adjustment.
Pw,i=Pw,i(1±b100),w=argmaxpRp,i

In the formula, Rp,i is party p 's raw baseline result in constituency i , so w picks out the previous winner; Pw,i is that party's currently-projected share after the swing and all the redistribution steps above. The boost factor (1 ± b/100) is positive for running incumbents and negative for retiring ones. The constituency is then renormalised back to 100% so the within-constituency shares still sum cleanly, and the broader hierarchical reconciliation downstream re-anchors regional and national vote-weighted averages to the user's input, so the boost shifts the within-region distribution, not the regional totals.

Identifying the incumbent

Each constituency is classified by walking a priority cascade. The model looks at the election we're projecting to (when its candidate data is in the database) and tags each constituency using the first signal that fires:

  1. Explicit incumbent flag. The target-election row carries an incumbent flag, set when a sitting MP appears on the next ballot. Boost their party.
  2. Candidate-name match. If no flag was set, compare candidate names between the baseline election and the target. A target candidate whose name also appears in the same constituency's baseline ballot is treated as an incumbent. Catches cases where the flag was missed during data entry.
  3. Retiring fallback. When the baseline winner's candidate name does NOT appear in the target's candidate list, the seat is marked as a retiring-incumbent case and gets the negative deboost.
  4. Baseline-winner heuristic. When no target candidate data is available at all (live forward projection of an upcoming race), the model falls back on the party of the baseline winner and applies the positive boost only. Without target data the model can't tell running from retiring, so the deboost arm is disabled for these runs.

Parties classified as "Other," independent, or Speaker are excluded. The first is a mathematical lump rather than a real party with a sitting MP, and the latter two have their own special-case handling elsewhere in the pipeline.

Manual constituency boosts in the next step stack on top of this. If you know a specific candidate is exceptionally strong or unusually weak beyond what the party-level incumbency boost captures, you can add a per-constituency additive or multiplicative adjustment that runs after the automatic step. The two stack rather than override: the auto-boost lifts (or trims) the projected winner first, your manual boost adjusts further on top.

09Hierarchical reconciliation

Every projection has to answer a question you asked, like "what does the country look like if the Liberals are at 26% nationally and the Bloc is at 30% in Quebec?" The reconciliation step is what makes those targets actually stick. For each geographic group at each level, the model takes the current vote-weighted average of the group, compares it to your target for that group, and multiplies every constituency in the group by one correction factor:

Pi=PiTgPg,Pg=igviPiigvi

The v in the formula is the constituency's total vote count. It weighs each constituency's contribution to the group average, so larger constituencies have more influence. The four levels run in this fixed order: subregional first, then subnational, then regional, then general (national) last.

This top-down setup has a useful property. The geographic variation that earlier steps built in is preserved, because every rescale is just multiplication: if a constituency was double its regional average before reconciliation, it's still double afterwards. Only the absolute level changes. That's what lets the model honour any national target without flattening the constituency-by-constituency texture that makes the projection useful. It also means that if you genuinely want one province at 10% while the country is at 50%, you have to drop one of the inputs. The two don't agree with each other, and the model trusts the broader target.

This also matters when pollsters get their regional weighting wrong. A pollster's regional crosstabs don't always weight back up to the national headline they reported. If you fed those inconsistent regional numbers in as hard ceilings, the national total in the projection would drift away from the topline. Because Poliwave runs the national level last and rescales whatever the regions produced, the topline you trust the most stays the binding number, and a regionally mis-weighted poll still produces a sensible projection.

10Elezioni a doppio turno (legislative francesi e sistemi simili)

Per le elezioni a doppio turno, come le legislative francesi, fino a questo punto la proiezione ha calcolato soltanto le quote di voto del primo turno. Una seconda fase del processo usa quindi questi risultati per proiettare il secondo turno di ogni collegio, stabilendo quali candidati si qualificano e come si distribuiscono tra loro gli elettori dei candidati eliminati. Questa intera sezione viene eseguita solo quando le elezioni sono contrassegnate come a doppio turno. Il maggioritario uninominale a turno unico, MMP, PR, STV e gli altri sistemi la ignorano completamente.

Selezione dei candidati qualificati

La legge francese consente a ogni candidato che al primo turno supera il 12,5% degli elettori iscritti di accedere al secondo turno. I primi due si qualificano sempre, anche quando meno di due candidati superano la soglia. Applichiamo la stessa regola: la soglia di qualificazione di un candidato equivale al 12,5% degli elettori iscritti nel collegio, convertito nella percentuale equivalente di voti validi usando la partecipazione specifica di ciascun collegio. In un collegio con 87.000 iscritti e 60.000 voti validi (circa il 69% di partecipazione), un candidato deve quindi ottenere all’incirca il 18% dei voti validi per superare la soglia, non il 12,5%. Questa conversione produce una combinazione realistica di duelli e triangolari; applicare direttamente il 12,5% ai voti validi farebbe qualificare il triplo dei candidati e renderebbe le quadrangolari molto più frequenti di quanto si osservi nella realtà.

Se un candidato ottiene più del 50% dei voti validi al primo turno, il collegio viene assegnato immediatamente e per quel seggio il secondo turno non si svolge.

Trasferimento dei voti tra i turni

Gli elettori di ciascun partito eliminato si distribuiscono tra i candidati qualificati secondo una matrice di trasferimento. Ogni cella della matrice rappresenta, su una scala da 0 a 100, l’affinità degli elettori di un partito verso un altro. I valori iniziali delle celle derivano dalla distanza ideologica secondo

affinity(s,q)=e|isiq|/τ100

dove is,iq sono i punteggi ideologici dei partiti di origine e di destinazione su un asse da -10 a +10 e τ è una costante di decadimento (3,0 per impostazione predefinita). Due partiti con la stessa ideologia ottengono un’affinità di 100; due partiti distanti 7 punti ottengono circa 10. Gli utenti possono sostituire i valori delle singole celle nella scheda Matrice di trasferimento, e queste modifiche manuali hanno la precedenza sul valore ideologico predefinito. Per ogni partito eliminato in ciascun collegio, il modello prende soltanto le celle della riga relative ai candidati effettivamente qualificati in quel collegio, le normalizza, le moltiplica per la quota di voti del primo turno del blocco di origine e aggiunge il risultato al totale del secondo turno di ciascun qualificato. Le celle relative ai non qualificati vengono ignorate: una regola come «agli elettori dell’NFP non piace LR» conta solo in un collegio in cui LR ha effettivamente raggiunto il secondo turno.

Astensione per blocco di origine

Non tutti gli elettori di un candidato eliminato si presentano al secondo turno. Un elettore la cui prima scelta era un candidato di estrema sinistra e che si trova davanti a un ballottaggio tra estrema sinistra ed estrema destra ha una buona alternativa, quindi la maggior parte di questi elettori vota. Lo stesso elettore, davanti a un ballottaggio tra centro ed estrema destra, non ha una buona alternativa e l’astensione cresce nettamente. Il modello rappresenta questo comportamento con un tasso di astensione per blocco di origine

αs=β+(1maxqaff(s,q))σ

β è la quota minima, applicata anche quando il candidato qualificato preferito dall’elettore è sulla scheda, mentre il secondo termine è la sensibilità alla competizione, che determina quanto aumenta l’astensione quando nessun qualificato risulta interessante. Entrambi sono configurabili. Il trasferimento da ciascun blocco di origine a ciascun qualificato viene poi moltiplicato per (1 − astensione) prima di essere aggiunto alla quota del secondo turno del qualificato. Dopo aver applicato tutti i trasferimenti, le quote dei qualificati vengono rinormalizzate affinché sommino al 100%, così da corrispondere al modo in cui vengono pubblicati i risultati francesi del secondo turno (la quota degli astenuti non viene mostrata come punto percentuale di alcun partito, proprio come nelle tabelle reali del secondo turno).

Entrambi i parametri sono disponibili come cursori nella scheda Matrice di trasferimento del simulatore.

Aggregazione in due passaggi

La fase di aggregazione viene eseguita due volte. Prima sulle quote di voto proiettate del primo turno, producendo la vista precedente al ballottaggio (chi vincerebbe ogni collegio con la maggioranza relativa, chi è in testa in ogni regione al primo turno). I valori del primo turno vengono quindi salvati nei campi round1_*, il modello sovrascrive projected_percentages con il risultato del secondo turno, esegue una seconda volta l’aggregazione e memorizza i risultati come riepilogo del turno finale. Il selettore R1/R2 nelle schede Riepilogo, Mappa e Tabella dei risultati del simulatore cambia semplicemente il gruppo di campi visualizzato.

Per questo motivo i collegi in cui chi era in testa al primo turno perde il ballottaggio (la classica dinamica del front républicain, in cui un candidato di estrema destra è in testa con la maggioranza relativa ma perde quando il centro e la sinistra si uniscono contro di lui) sono contrassegnati dall’etichetta «RIBALT.» nella scheda Trasferimenti per collegio.

11Uncertainty and scenario probabilities

Getting a single point estimate is the easy part of a forecast. The hard part is what could happen around it. For formal projections, Poliwave runs Monte Carlo on top of the base projection (40,000 draws by default, more if set higher via the CLI) using a correlated error model. Polling error is split into three pieces: a national piece that moves every constituency the same way, a regional piece that moves constituencies inside one region together, and a per-constituency piece that's independent and whose size depends on the constituency's population.

P~i=Pi+εnat+εr(i)+εi,ε𝒩(0,σ2)

The split exists because real polling misses aren't independent across constituencies. They're usually systemic and regional. If you treated every constituency as an independent draw, the confidence intervals would be way too narrow and the seat distributions would be too tight around the centre. The correlated split gives back the realistic spread an honest forecast needs.

The third piece, the per-constituency term, has its variance scaled inversely by the constituency's elector count. A small northern constituency with 35,000 electors really is noisier than a Toronto-area constituency with 110,000, because a smaller electorate gives more leverage to single events (a popular local candidate, a scandal, a local issue):

σi2=σ02NrefNi

σ0 is the calibrated noise level at the reference population Nref (the median constituency size in the jurisdiction), and Ni is the constituency's own elector count. This is what gives small constituencies wider win-probability ranges than large ones, and any honest forecast model has to behave this way.

What the simulation actually produces:

  • Per-constituency win probabilities and 95% confidence intervals for every party.
  • Seat distributions at the regional and national level.
  • Government formation probabilities: majority, minority, plurality, hung. Each gets its own simulated frequency, based on your inputs and the correlated error structure above.

12Does it work?

Methodology is only as good as the track record it produces. On the 2025 Canadian federal election, Poliwave produced the closest absolute seat-count projection among Canadian forecasters: the smallest total gap between projected and actual seats for the top four parties. On constituency-level accuracy (the share of seats where the model picked the right winner), Poliwave landed within one percentage point of the long-established national benchmark, despite being a much newer project run by one person instead of an institutional team.

Performance on every prior election the project has covered is published in full on the accuracy page: projected seats next to actual seats, no curation, no cherry-picking.

One caveat worth stating plainly: those results, including the 2025 federal projection, were produced with the Excel model that preceded this website. The first interactive web simulator went live in August 2025, after all of them. The pipeline described on this page is a direct descendant of that model and follows the same approach, but it has not yet been scored against a general election of its own.

See the full track record

In summary

Geometric-mean swing

Every projection combines proportional and uniform swing by taking the geometric mean, multiply both predictions, square-root the product. No tuning parameters. Naturally pulls toward whichever component is smaller, which fixes both classical failure modes at once: runaway proportional projections get damped, near-zero parties cleanly zero out. Wins more elections than it loses against every other formula tested in head-to-head backtests across 47 CA elections since 2000.

Footprint-matched historical averaging

When the model needs a prior baseline for a party whose footprint changed between cycles, it only compares constituencies the party ran in both times. That kills off the distortion that would otherwise happen when a party stood down one cycle and runs fully the next.

Three-family vote redistribution

Loss-only flows, always-on intakes, and close-race tactical defection are three separate pipeline steps that add up cleanly without double-counting. Real voters move in different ways, and the model handles each one separately.

Margin-sensitive tactical voting

How much tactical voting happens depends on how close the local race is. A safe seat sees none; a tight seat sees the full effect. The cutoff and the pool of defecting voters are both user-configurable, so the same engine handles anti-Conservative coordination, anti-Reform coordination, or any future strategic alignment without code changes. Off by default in the formal projections; available as a knob in the interactive simulator.

Demographic integration

Each (party, demographic) boost is applied as a deviation-weighted adjustment scaled by the party's current vote share, so the size depends both on how far the constituency is from the national average and on how much support the party has to move. Above-average constituencies get a positive shift; below-average constituencies the opposite; a party at 0% gets nothing because there's nothing to multiply. Relative, not absolute.

Symmetric incumbent boost

Running incumbents get a multiplicative boost; retiring incumbents trigger a symmetric deboost of the same size to the previous-winner party. Incumbency is read from the target election's incumbent flag, falling back to candidate-name matches and finally to the baseline winner when no target candidate data exists. Both magnitudes were tuned by backtest sweeps across 38 Canadian elections since 2000.

Vote-weighted hierarchical reconciliation

The final stage rescales every constituency so that the vote-weighted averages at each geographic level land as close as possible to the user's input. Clamping at 0 and 100, two-decimal rounding, and single-constituency-group skips mean the match is approximate rather than exact; the broadest target acts as the binding constraint and everything upstream provides the per-constituency shape the rescale preserves.

Correlated-error Monte Carlo

Polling error is split into national, regional, and per-constituency pieces. This captures the fact that polling misses are usually systemic, not random, and produces realistic seat distributions instead of the implausibly tight ones you get from treating every constituency as independent.

Boundary-matched historical foundation

Every projection is anchored on the prior election held under today’s constituency boundaries. Earlier cycles can be brought in when their results have been mathematically transposed onto current boundaries by the database upload scripts. No constituency gets a generic baseline; each one starts from its own political history under the boundaries it has today.

Questa pagina descrive come è costruito il modello e quali equazioni utilizza. I valori specifici di calibrazione, le regolazioni per ciascuna giurisdizione e i dettagli operativi restano interni.