TwoMore Rating System — Complete Summary
Superseded (2026-07): folded into Rating System v2 — Specification. Kept for reference.
Status: Superseded Date: 2026-04-04 Source files: rating-system-v2.md · elo-tier-mapping.md · korean-tennis-divisions
Design Principles
- Evidence-based — Every formula traces to published research (Glicko-2, Kovalchik 2020, FIDE/USCF)
- Amateur-first — Designed for 동호인: mismatched pairings, draws, incomplete sets, RPS
- Gender-aware — One global ELO, but tier display adjusts by gender percentile
- Global, not per-club — One rating across all clubs. Rank is contextual per club.
- Non-punitive — Inactivity grows uncertainty (RD), doesn't decay rating
- Dynamic — Unlike Korean 신인부/오픈부 (one-way ratchet), our rating goes up AND down
1. Rating Pools
2 pools, both global and gender-neutral:
| Pool | What Counts | Why Separate |
|---|---|---|
| Singles ELO | Any 1v1 match | Individual skill, no partner variable |
| Doubles ELO | Any 2v2 match | Partner coordination is a separate skill |
Each player has: singlesElo, singlesRd, doublesElo, doublesRd
2. The Formula
Singles
delta = K × (actual - expected) × scoreFactor × outcomeWeightDoubles
effective_team = avg(r1, r2) - 0.08 × |r1 - r2| ← team variance penalty
expected = 1 / (1 + 10^(-(eff_A - eff_B) / 400))
delta = K × (actual - expected) × scoreFactor × outcomeWeightBoth teammates receive the full delta (not halved). Source: UTR.
Team Variance Penalty Examples
| Team Composition | Avg | Penalty | Effective |
|---|---|---|---|
| 1400 + 1400 | 1400 | 0 | 1400 |
| 1600 + 1200 | 1400 | -32 | 1368 |
| 1800 + 1000 | 1400 | -64 | 1336 |
3. Match Outcomes
| Outcome | actual | outcomeWeight | Rating change? |
|---|---|---|---|
| decisive (win) | 1.0 | 1.0 | Yes |
| decisive (loss) | 0.0 | 1.0 | Yes |
| draw (4-4, 5-5 etc.) | 0.5 | 1.0 | Yes — draws ARE informative |
| incomplete (leader) | 0.6 | 0.5 | Yes — partial signal |
| incomplete (tied) | 0.5 | 0.3 | Yes — minimal signal |
| abandoned | — | 0 | No |
| non_competitive (RPS) | — | 0 | No |
| walkover | — | 0 | No |
4. Score Factor (Margin of Victory)
| Winner's Game % | Factor | Label |
|---|---|---|
| ≥ 75% (e.g., 6-1) | 1.5 | Dominant |
| ≥ 60% (e.g., 6-3) | 1.2 | Clear |
| < 60% (e.g., 7-5) | 1.0 | Close |
Draws, incomplete, non-competitive: always 1.0
5. Adaptive K-Factor
| Condition | K | Source |
|---|---|---|
| First 20 matches (provisional) | 40 | USCF |
| Established (20+ matches) | 32 | Standard ELO |
| Diamond+ rating (2100+) | 24 | FIDE 2400+ rule |
| Miscalibrated seed (strike system) | 48 | Accelerated convergence |
Upset bonus: When underdog wins, K × 1.5
6. Rating Deviation (RD) — Glicko-2 Inspired
RD represents confidence in the rating. High RD = uncertain.
| Event | RD Change |
|---|---|
| Match played | new_RD = max(30, old_RD × 0.92) — shrinks ~8% |
| Month inactive | new_RD = min(350, √(old_RD² + 15²)) — grows |
No rating decay. Rating number stays constant during inactivity. Only uncertainty grows.
7. Safety Mechanisms
Rating Floor
floor = peak_rating × 0.80
new_rating = max(floor, computed_rating)Prevents catastrophic loss from bad streaks.
Inflation Monitor
Quarterly pool mean check. If drift > 50 from 1000, global correction applied.
Strike System (Dishonesty Detection)
After 5+ matches: if |current_elo - seed_elo| > 150, K accelerated to 48 for faster convergence.
8. Tier System
7 Tiers × 3 Sub-tiers = 21 Levels
| Tier | ELO Range | Sub-tiers | Color |
|---|---|---|---|
| Bronze | 400–799 | III (400) · II (534) · I (667) | 🟤 |
| Silver | 800–1199 | III (800) · II (934) · I (1067) | ⚪ |
| Gold | 1200–1699 | III (1200) · II (1367) · I (1534) | 🟡 |
| Platinum | 1700–2099 | III (1700) · II (1834) · I (1967) | 🔵 |
| Diamond | 2100–2399 | III (2100) · II (2200) · I (2300) | 💎 |
| Master | 2400–2799 | III (2400) · II (2534) · I (2667) | 🟣 |
| Grand Master | 2800+ | III (2800) · II (2934) · I (3067) | 🔴 |
Gold is the widest tier (500 ELO) because 70-80% of Korean 동호인 cluster in NTRP 3.0-3.5.
9. Cross-Rating Conversion Chart
ELO → NTRP → UTR → Korean Division → Women's Division
| Tier | Sub | ELO | NTRP | UTR | Korean (남성) | Korean (여성) | % KR Players |
|---|---|---|---|---|---|---|---|
| Bronze | III | 400-533 | 2.0 | 1-2 | 테린이 | 테린이 | <1% |
| Bronze | II | 534-666 | 2.0-2.5 | 2-3.5 | 테린이 | 테린이 | 2% |
| Bronze | I | 667-799 | 2.0-2.5 | 2-3.5 | 테린이 / 입문 | 테린이 | 5% |
| Silver | III | 800-933 | 2.5-3.0 | 3.5-4.5 | 신인부 하위 | 개나리��� 하위 | 8% |
| Silver | II | 934-1066 | 2.5-3.0 | 3.5-4.5 | 신인부 | 개나리부 하위 | 12% |
| Silver | I | 1067-1199 | 3.0 | 3.5-4.5 | 신인부 상위 | 개나리부 하위 | 15% |
| Gold | III | 1200-1366 | 3.0-3.5 | 4.5-6 | 신인부 ~ 오픈부 | 개나리부 | 14% |
| Gold | II | 1367-1533 | 3.0-3.5 | 4.5-6 | 오픈부 하위 | 개나리부 | 10% |
| Gold | I | 1534-1699 | 3.5 | 4.5-6 | 오픈부 | 개나리부 상위 ~ 국화부 | 8% |
| Platinum | III | 1700-1833 | 3.5-4.0 | 6-7.5 | ��픈부 상위 | 개나리부 상위 ~ 국화부 | 5% |
| Platinum | II | 1834-1966 | 4.0 | 6-7.5 | 오픈부 최상위 | 국화부 | 3% |
| Platinum | I | 1967-2099 | 4.0-4.5 | 6-7.5 | 오픈부 최상위 | 국화부 | 2% |
| Diamond | III | 2100-2199 | 4.5 | 7.5-10 | 선수급 | 슈퍼국화 | 1.5% |
| Diamond | II | 2200-2299 | 4.5-5.0 | 7.5-10 | 선수급 | 슈퍼국화 | 1% |
| Diamond | I | 2300-2399 | 5.0 | 7.5-10 | 선수급 | 슈퍼국화 | <0.5% |
| Master | — | 2400-2799 | 5.0-6.5 | 10-15 | 프로급 | — | ~0% KR rec |
| Grand Master | — | 2800+ | 6.5+ | 15+ | 프로급 | — | Theoretical |
Korean Division Terminology Notes
- 신인부 = 챌린저부 (KATA vs KATO naming — same tier)
- 오픈부 = 마스터즈부 (KATA vs KATO naming — same tier)
- 동배부/은배부/금배부 = regional (시도) equivalent system
- 개나리부/국화부 = women's flower-named divisions (KATA/KATO official)
- We use 신인부/오픈부 as the universal standard
10. New Player Seeding
| Onboarding Option | Korean Label | Seed | Starting Tier | NTRP |
|---|---|---|---|---|
| Complete Beginner | 테린이 | 500 | Bronze III | 1.5-2.0 |
| Beginner | 입문 | 700 | Bronze I | 2.0-2.5 |
| Newcomer | 신인부 수준 | 950 | Silver II | 2.5-3.0 |
| Open | 신인부 ~ 오픈부 | 1200 | Gold III | 3.0-3.5 |
| Advanced | 오픈부 | 1550 | Gold I | 3.5-4.0 |
| Competitive | 오픈부 상위 · 선수출신 | 2100 | Diamond III | 4.5+ |
Provisional K=40 for first 20 matches ensures fast convergence regardless of seed accuracy.
11. Gender-Adjusted Tier Display
Superseded (2026-07): the owner chose a pure-skill (gender-neutral) tier; gender-awareness moved to the leaderboards (consolidated + per-gender views), not the tier badge. Canonical model: rating-system-v2 §0. The gender-adjusted-display approach below is retained for historical reference only.
One global ELO (gender-neutral) for matchmaking. Tier display adjusts by gender so that the same percentile = same tier.
How It Works
z_in_gender = (player_elo - gender_mean) / gender_σ
adjusted_elo = combined_mean + z_in_gender × combined_σ
display_tier = getTier(adjusted_elo)Example (after pool data accumulates)
| Stat | Men | Women | Combined |
|---|---|---|---|
| Mean | 1150 | 980 | 1100 |
| σ | 180 | 160 | 200 |
| Scenario | Raw ELO | Percentile | Adjusted ELO | Display Tier |
|---|---|---|---|---|
| Man at male mean | 1150 | 50th | 1100 | Silver I |
| Woman at female mean | 980 | 50th | 1100 | Silver I |
| Man 1σ above | 1330 | 84th | 1300 | Gold III |
| Woman 1σ above | 1140 | 84th | 1300 | Gold III |
Leaderboard
Filter chips: 전체 (default) / 남성 / 여성
Non-binary/undisclosed: fall back to combined pool thresholds.
At launch (< 50 players per gender): identical thresholds for all.
12. Closed Pool Calibration
Rating Confidence (0.0–1.0)
| Action | Change |
|---|---|
| Self-assessment seed | 0.0 |
| Intra-club match | +0.02 (max contribution: 0.3) |
| Cross-club match | +0.05 |
| Match vs confident player (≥0.7) | +0.03 bonus |
Bridge Player Offset
When a player joins a second club (10+ matches in each), they become a calibration link. Weighted median of bridge player offsets corrects pool-level bias.
Strike System
After 5+ matches: if |current - seed| > 150, K accelerated to 48. If |current - seed| > 350 after 15 matches, admin alert for potential sandbagging.
13. Complete Calculation Example
Doubles: Team A (1600 + 1200) beats Team B (1400 + 1400), score 6-3.
1. Effective team ratings
Team A: avg(1600, 1200) - 0.08 × |400| = 1400 - 32 = 1368
Team B: avg(1400, 1400) - 0.08 × |0| = 1400
2. Expected score for Team A
1 / (1 + 10^(-(1368-1400)/400)) = 0.481
3. Score factor
6 / (6+3) = 66.7% → 1.2 (clear win)
4. K-factor = 32 (established), but this is an upset (1368 < 1400)
→ K = round(32 × 1.5) = 48 for Team A
5. Delta (Team A)
48 × (1.0 - 0.481) × 1.2 × 1.0 = 29.9 → 30
6. Apply
Team A player 1 (1600): → 1630
Team A player 2 (1200): → 1230
Team B player 1 (1400): → 1380 (K=32, no upset bonus)
Team B player 2 (1400): → 1380
7. Check floors — no player below 80% of peak ✓Same teams, draw (4-4):
actual = 0.5, weight = 1.0, scoreFactor = 1.0
delta = 32 × (0.5 - 0.481) × 1.0 × 1.0 = 0.6 → 1
// Tiny delta — draw between near-equal teams is expected.Same teams, decided by RPS:
outcome = 'non_competitive' → delta = 0. No rating change.14. Data Model
profiles
singles_elo, singles_rd, singles_peak, singles_matches_played
doubles_elo, doubles_rd, doubles_peak
rating_confidence, seed_singles_elo, seed_doubles_elomatches
outcome: 'decisive' | 'draw' | 'incomplete' | 'abandoned' | 'non_competitive' | 'walkover'
is_cross_pool: booleanelo_history
rating_pool: 'singles' | 'doubles'
rd_before, rd_after15. References
- Kovalchik (2020) — Margin-of-victory ELO. International Journal of Forecasting.
- Glickman (2001) — Glicko-2 rating system. Boston University.
- UTR Algorithm — universaltennis.com
- FIDE Handbook — K-factor rules
- USCF Rating System — uschess.org
- KATA (한국동호인테니스협회) — Division/ranking system
- KATO (한국테니스발전협의회) — Division/pair scoring system
- KTA 생활체육 — Recreational grading