Methodology
This page shows, without hiding anything, how we validate our rules and what their limits are.
How we validate
- Walk-forward: scores use only data available up to the rebalance date, and results are checked only against what actually happened afterward.
- Out-of-sample testing: performance is measured on periods not used to set the rules.
- No lookahead: data not yet available at that point in time (e.g. the next day's close) is never used in the calculation.
- Transaction cost assumptions: minimum validation window 3 years, commission 0.005/share, minimum commission 1.0, slippage 5bp, minimum paper-trading period 90 days.
Survivorship bias
Backtesting only with stocks that are alive today inflates results, since delisted stocks are excluded. So the goal is to store the universe (candidate list) as a weekly snapshot of what actually existed at that time. The buy-fitness table doesn't have that snapshot yet (partial coverage), so it uses today's universe even for past periods — stocks that were delisted or newly added in between aren't reflected.
Rules & parameters (fixed in advance)
The numbers below were fixed when the strategy was designed, not fitted after looking at the data. By default, buy candidates exclude companies with a caution signal in revenue, profit, or debt (e.g. ongoing losses, high debt) — this can be turned off per strategy.
| Parameter | value |
|---|
| top_k | 20 |
| horizon_days | 21 |
| max_position_pct | 10.0% |
| weight · trend_120 | 1.0 |
| weight · momentum_12_1 | 1.0 |
| weight · zscore_20 | -0.5 |
| weight · vol_regime | -0.5 |
| weight · dist_high_252 | 0.5 |
| exit.balanced | stop 8% · trail 10% · take-profit 25% · max 120d |
| exit.trend | stop 10% · trail 15% · take-profit 40% · max 180d |
| exit.dip | stop 6% · trail 8% · take-profit 15% · max 60d |
| exit.stable | stop 5% · trail 7% · take-profit 12% · max 90d |
Parameter sensitivity
We check that small changes to the stop-loss level or the trend lookback window don't swing the results wildly (an overfitting check).
US
| Parameter | Avg return | Hit rate | Sample |
|---|
| trend_120 = 100d | +3.13% | 59% | 35 |
| trend_120 = 120d | +3.38% | 60% | 35 |
| trend_120 = 150d | +4.28% | 60% | 35 |
| stop = 6% | +1.15% | 44% | 700 |
| stop = 8% | +1.40% | 50% | 700 |
| stop = 10% | +1.60% | 53% | 700 |
Korea
| Parameter | Avg return | Hit rate | Sample |
|---|
| trend_120 = 100d | +3.65% | 53% | 34 |
| trend_120 = 120d | +4.34% | 54% | 34 |
| trend_120 = 150d | +4.43% | 53% | 34 |
| stop = 6% | +4.66% | 41% | 680 |
| stop = 8% | +4.89% | 45% | 680 |
| stop = 10% | +5.32% | 50% | 680 |
Japan
| Parameter | Avg return | Hit rate | Sample |
|---|
| trend_120 = 100d | +2.23% | 55% | 34 |
| trend_120 = 120d | +1.54% | 55% | 34 |
| trend_120 = 150d | +2.41% | 57% | 34 |
| stop = 6% | +2.24% | 48% | 680 |
| stop = 8% | +2.46% | 54% | 680 |
| stop = 10% | +2.52% | 57% | 680 |
Hong Kong
| Parameter | Avg return | Hit rate | Sample |
|---|
| trend_120 = 100d | +1.39% | 55% | 34 |
| trend_120 = 120d | +1.57% | 56% | 34 |
| trend_120 = 150d | +1.81% | 57% | 34 |
| stop = 6% | +1.61% | 48% | 680 |
| stop = 8% | +1.81% | 53% | 680 |
| stop = 10% | +1.62% | 54% | 680 |
Crypto
| Parameter | Avg return | Hit rate | Sample |
|---|
| trend_120 = 100d | +2.20% | 45% | 57 |
| trend_120 = 120d | +2.07% | 45% | 57 |
| trend_120 = 150d | +2.25% | 45% | 57 |
| stop = 6% | +1.11% | 27% | 1135 |
| stop = 8% | +0.84% | 31% | 1135 |
| stop = 10% | +0.50% | 33% | 1135 |
Buy fitness
In past walk-forward validation, the share of stocks that rose 21 trading days (about a month) later when a (market weather stage) × (that day's rank bucket) × (caution flag present/absent) condition held. No arbitrary weights. Weather-stage labels are today's rules applied retroactively to the whole history (an approximation — those rules didn't necessarily exist back then).
US
| Weather stage | Rank bucket | Caution flag | Share up | Avg return | Sample (stock-days) | Sample (trading days) |
|---|
| Storm | 1-5 | No | 51.8% | +1.03% | 382 | 88 |
| Storm | 1-5 | Yes | 53.4% | +6.58% | 58 | 36 |
| Storm | 6-10 | No | 53.0% | +1.57% | 364 | 88 |
| Storm | 6-10 | Yes | 55.3% | +1.08% | 76 | 50 |
| Storm | 11-20 | No | 57.2% | +1.92% | 715 | 88 |
| Storm | 11-20 | Yes | 58.8% | +1.16% | 165 | 59 |
| Storm | 21-50 | No | 55.7% | +1.15% | 2075 | 88 |
| Storm | 21-50 | Yes | 58.6% | +2.64% | 565 | 81 |
| Rain | 1-5 | No | 55.5% | +2.33% | 1386 | 310 |
| Rain | 1-5 | Yes | 58.6% | +4.24% | 169 | 115 |
| Rain | 6-10 | No | 52.1% | +1.19% | 1289 | 311 |
| Rain | 6-10 | Yes | 62.8% | +3.63% | 266 | 167 |
| Rain | 11-20 | No | 55.7% | +1.78% | 2580 | 311 |
| Rain | 11-20 | Yes | 55.1% | +2.56% | 530 | 220 |
| Rain | 21-50 | No | 56.7% | +1.80% | 7477 | 311 |
| Rain | 21-50 | Yes | 56.9% | +2.12% | 1853 | 290 |
| Cloudy | 1-5 | No | 58.4% | +2.99% | 979 | 223 |
| Cloudy | 1-5 | Yes | 61.0% | +6.47% | 136 | 87 |
| Cloudy | 6-10 | No | 57.6% | +2.66% | 935 | 223 |
| Cloudy | 6-10 | Yes | 60.0% | +2.78% | 180 | 110 |
| Cloudy | 11-20 | No | 59.2% | +2.95% | 1827 | 223 |
| Cloudy | 11-20 | Yes | 62.0% | +2.34% | 403 | 146 |
| Cloudy | 21-50 | No | 58.8% | +2.65% | 5454 | 223 |
| Cloudy | 21-50 | Yes | 59.6% | +2.14% | 1236 | 191 |
| Sunny | 1-5 | No | 63.8% | +3.74% | 461 | 101 |
| Sunny | 1-5 | Yes | 59.1% | +3.18% | 44 | 23 |
| Sunny | 6-10 | No | 60.4% | +3.57% | 465 | 101 |
| Sunny | 6-10 | Yes | 57.5% | +3.43% | 40 | 32 |
| Sunny | 11-20 | No | 62.6% | +3.60% | 890 | 101 |
| Sunny | 11-20 | Yes | 55.8% | +3.09% | 120 | 53 |
| Sunny | 21-50 | No | 66.4% | +4.49% | 2669 | 101 |
| Sunny | 21-50 | Yes | 61.8% | +3.03% | 361 | 83 |
Korea
| Weather stage | Rank bucket | Caution flag | Share up | Avg return | Sample (stock-days) | Sample (trading days) |
|---|
| Storm | 1-5 | No | – | – | 100 | 2 |
| Storm | 1-5 | Yes | – | – | 100 | 2 |
| Storm | 6-10 | No | – | – | 100 | 2 |
| Storm | 6-10 | Yes | – | – | 100 | 2 |
| Storm | 11-20 | No | – | – | 100 | 2 |
| Storm | 11-20 | Yes | – | – | 100 | 2 |
| Storm | 21-50 | No | – | – | 100 | 2 |
| Storm | 21-50 | Yes | – | – | 100 | 2 |
| Rain | 1-5 | No | 43.1% | -1.77% | 360 | 77 |
| Rain | 1-5 | Yes | 42.9% (Small sample · merged with a broader condition) | -2.36% | 385 | 77 |
| Rain | 6-10 | No | 47.3% | -0.89% | 353 | 77 |
| Rain | 6-10 | Yes | 46.9% | +0.34% | 32 | 25 |
| Rain | 11-20 | No | 53.6% | +1.00% | 686 | 77 |
| Rain | 11-20 | Yes | 59.5% | +5.54% | 84 | 41 |
| Rain | 21-50 | No | 48.3% | +0.10% | 2096 | 77 |
| Rain | 21-50 | Yes | 38.3% | -0.50% | 214 | 62 |
| Cloudy | 1-5 | No | 59.8% | +5.31% | 1491 | 332 |
| Cloudy | 1-5 | Yes | 51.4% | +1.05% | 179 | 114 |
| Cloudy | 6-10 | No | 60.7% | +5.66% | 1435 | 334 |
| Cloudy | 6-10 | Yes | 52.8% | +6.04% | 235 | 156 |
| Cloudy | 11-20 | No | 59.1% | +4.60% | 2838 | 334 |
| Cloudy | 11-20 | Yes | 57.6% | +4.68% | 502 | 228 |
| Cloudy | 21-50 | No | 56.9% | +3.38% | 8443 | 334 |
| Cloudy | 21-50 | Yes | 52.9% | +4.11% | 1577 | 305 |
| Sunny | 1-5 | No | 57.7% | +6.09% | 1169 | 281 |
| Sunny | 1-5 | Yes | 58.9% | +8.24% | 236 | 151 |
| Sunny | 6-10 | No | 61.4% | +7.72% | 1103 | 281 |
| Sunny | 6-10 | Yes | 63.9% | +11.23% | 302 | 174 |
| Sunny | 11-20 | No | 57.5% | +5.03% | 2247 | 281 |
| Sunny | 11-20 | Yes | 59.0% | +9.52% | 563 | 226 |
| Sunny | 21-50 | No | 58.2% | +4.55% | 6485 | 281 |
| Sunny | 21-50 | Yes | 54.9% | +6.73% | 1945 | 272 |
Japan
| Weather stage | Rank bucket | Caution flag | Share up | Avg return | Sample (stock-days) | Sample (trading days) |
|---|
| Storm | 1-5 | No | 57.8% | +2.26% | 232 | 55 |
| Storm | 1-5 | Yes | 48.8% | +0.87% | 43 | 22 |
| Storm | 6-10 | No | 59.4% | +3.05% | 229 | 55 |
| Storm | 6-10 | Yes | 58.7% | +3.36% | 46 | 28 |
| Storm | 11-20 | No | 57.7% | +3.29% | 430 | 55 |
| Storm | 11-20 | Yes | 53.3% | +1.12% | 120 | 46 |
| Storm | 21-50 | No | 59.6% | +3.62% | 1302 | 55 |
| Storm | 21-50 | Yes | 47.4% | +0.26% | 348 | 54 |
| Rain | 1-5 | No | 55.6% | +2.52% | 1871 | 431 |
| Rain | 1-5 | Yes | 59.2% | +5.37% | 289 | 175 |
| Rain | 6-10 | No | 57.5% | +2.23% | 1801 | 432 |
| Rain | 6-10 | Yes | 59.6% | +3.23% | 359 | 211 |
| Rain | 11-20 | No | 55.9% | +1.77% | 3579 | 430 |
| Rain | 11-20 | Yes | 56.3% | +1.69% | 741 | 303 |
| Rain | 21-50 | No | 55.9% | +1.56% | 10516 | 432 |
| Rain | 21-50 | Yes | 51.7% | +0.63% | 2444 | 408 |
| Cloudy | 1-5 | No | 61.7% | +4.29% | 847 | 193 |
| Cloudy | 1-5 | Yes | 64.7% | +5.76% | 133 | 78 |
| Cloudy | 6-10 | No | 62.3% | +4.68% | 818 | 195 |
| Cloudy | 6-10 | Yes | 64.2% | +4.64% | 162 | 89 |
| Cloudy | 11-20 | No | 62.8% | +3.57% | 1655 | 194 |
| Cloudy | 11-20 | Yes | 65.6% | +4.40% | 305 | 108 |
| Cloudy | 21-50 | No | 64.6% | +3.82% | 4838 | 196 |
| Cloudy | 21-50 | Yes | 61.3% | +3.01% | 1042 | 156 |
| Sunny | 1-5 | No | 63.0% | +5.65% | 46 | 14 |
| Sunny | 1-5 | Yes | 65.7% (Small sample · merged with a broader condition) | +8.48% | 70 | 14 |
| Sunny | 6-10 | No | 62.7% | +4.45% | 51 | 13 |
| Sunny | 6-10 | Yes | 60.0% (Small sample · merged with a broader condition) | +3.75% | 70 | 14 |
| Sunny | 11-20 | No | 58.7% | +2.81% | 109 | 14 |
| Sunny | 11-20 | Yes | 41.9% | +1.78% | 31 | 10 |
| Sunny | 21-50 | No | 62.1% | +2.96% | 298 | 14 |
| Sunny | 21-50 | Yes | 66.4% | +4.12% | 122 | 14 |
Hong Kong
| Weather stage | Rank bucket | Caution flag | Share up | Avg return | Sample (stock-days) | Sample (trading days) |
|---|
| Storm | 1-5 | No | 53.0% | -0.57% | 164 | 39 |
| Storm | 1-5 | Yes | 32.3% | -2.58% | 31 | 21 |
| Storm | 6-10 | No | 52.8% | -0.55% | 159 | 39 |
| Storm | 6-10 | Yes | 41.7% | -2.93% | 36 | 17 |
| Storm | 11-20 | No | 52.1% | +0.37% | 303 | 39 |
| Storm | 11-20 | Yes | 41.4% | -1.60% | 87 | 30 |
| Storm | 21-50 | No | 45.3% | -0.26% | 896 | 39 |
| Storm | 21-50 | Yes | 49.6% | -0.56% | 274 | 38 |
| Rain | 1-5 | No | 48.5% | -0.27% | 1525 | 357 |
| Rain | 1-5 | Yes | 50.6% | +1.55% | 265 | 169 |
| Rain | 6-10 | No | 48.9% | +0.03% | 1410 | 355 |
| Rain | 6-10 | Yes | 50.8% | -0.38% | 380 | 204 |
| Rain | 11-20 | No | 49.0% | +0.39% | 2849 | 358 |
| Rain | 11-20 | Yes | 51.6% | +0.44% | 731 | 272 |
| Rain | 21-50 | No | 50.0% | +0.22% | 8695 | 358 |
| Rain | 21-50 | Yes | 46.4% | -0.43% | 2045 | 312 |
| Cloudy | 1-5 | No | 55.9% | +2.13% | 1316 | 289 |
| Cloudy | 1-5 | Yes | 65.9% | +3.59% | 129 | 83 |
| Cloudy | 6-10 | No | 60.5% | +1.82% | 1244 | 288 |
| Cloudy | 6-10 | Yes | 60.2% | +2.40% | 201 | 133 |
| Cloudy | 11-20 | No | 61.4% | +3.10% | 2444 | 289 |
| Cloudy | 11-20 | Yes | 59.0% | +2.40% | 446 | 181 |
| Cloudy | 21-50 | No | 55.7% | +2.67% | 7605 | 289 |
| Cloudy | 21-50 | Yes | 61.6% | +3.82% | 1065 | 220 |
| Sunny | 1-5 | No | 78.6% | +7.05% | 56 | 14 |
| Sunny | 1-5 | Yes | 82.9% (Small sample · merged with a broader condition) | +9.49% | 70 | 14 |
| Sunny | 6-10 | No | 74.6% | +4.96% | 59 | 14 |
| Sunny | 6-10 | Yes | 78.6% (Small sample · merged with a broader condition) | +5.59% | 70 | 14 |
| Sunny | 11-20 | No | 71.2% | +5.21% | 111 | 14 |
| Sunny | 11-20 | Yes | 72.1% (Small sample · merged with a broader condition) | +5.92% | 140 | 14 |
| Sunny | 21-50 | No | 63.6% | +3.57% | 385 | 14 |
| Sunny | 21-50 | Yes | 80.0% | +10.77% | 35 | 13 |
Crypto
| Weather stage | Rank bucket | Caution flag | Share up | Avg return | Sample (stock-days) | Sample (trading days) |
|---|
| Storm | 1-5 | No | 41.1% | -3.08% | 392 | 87 |
| Storm | 1-5 | Yes | 41.9% | -0.14% | 43 | 30 |
| Storm | 6-10 | No | 34.9% | -3.55% | 384 | 86 |
| Storm | 6-10 | Yes | 29.4% | -5.25% | 51 | 28 |
| Storm | 11-20 | No | 36.6% | -4.25% | 784 | 86 |
| Storm | 11-20 | Yes | 18.3% | -7.00% | 82 | 23 |
| Storm | 21-50 | No | 31.3% | -4.44% | 281 | 78 |
| Storm | 21-50 | Yes | 30.8% (Small sample · merged with a broader condition) | -4.84% | 305 | 82 |
| Rain | 1-5 | No | 48.3% | -0.18% | 2378 | 512 |
| Rain | 1-5 | Yes | 41.2% | -1.29% | 182 | 124 |
| Rain | 6-10 | No | 47.6% | +0.43% | 2364 | 509 |
| Rain | 6-10 | Yes | 35.7% | -0.08% | 196 | 117 |
| Rain | 11-20 | No | 47.0% | -0.30% | 4670 | 510 |
| Rain | 11-20 | Yes | 30.1% | -4.20% | 412 | 167 |
| Rain | 21-50 | No | 37.2% | -3.01% | 1803 | 472 |
| Rain | 21-50 | Yes | 23.1% | -8.13% | 156 | 80 |
| Cloudy | 1-5 | No | 52.4% | +4.58% | 1893 | 453 |
| Cloudy | 1-5 | Yes | 53.9% | +5.79% | 382 | 217 |
| Cloudy | 6-10 | No | 48.9% | +4.87% | 1804 | 442 |
| Cloudy | 6-10 | Yes | 56.1% | +8.23% | 471 | 218 |
| Cloudy | 11-20 | No | 48.0% | +3.87% | 3514 | 447 |
| Cloudy | 11-20 | Yes | 57.5% | +11.81% | 944 | 251 |
| Cloudy | 21-50 | No | 36.5% | -2.78% | 1269 | 352 |
| Cloudy | 21-50 | Yes | 42.0% | +1.48% | 317 | 142 |
| Sunny | 1-5 | No | 92.7% | +18.53% | 55 | 18 |
| Sunny | 1-5 | Yes | 56.0% | +6.83% | 50 | 15 |
| Sunny | 6-10 | No | 79.3% | +21.88% | 58 | 17 |
| Sunny | 6-10 | Yes | 55.3% | +18.83% | 47 | 15 |
| Sunny | 11-20 | No | 91.0% | +22.87% | 111 | 17 |
| Sunny | 11-20 | Yes | 59.4% | +32.97% | 96 | 14 |
| Sunny | 21-50 | No | 84.8% | +30.36% | 46 | 15 |
| Sunny | 21-50 | Yes | 51.3% | +18.65% | 39 | 11 |
Sample (stock-days) is the count of stock-date pairs meeting the condition; sample (trading days) is the number of distinct trading days among them. If either falls short of the minimum (30 stock-days, 10 trading days), we show '–' instead of a value.
Testing the company-financials filter
We re-ran the rule 'drop companies with risky financials from the candidate list' using only the figures that were already filed on each day (point-in-time — no later restatements, nothing not yet published). For every trading day we take the 20 candidates and compare their return 21 trading days later against the index. Because holding periods overlap, days are not independent, so the 95% interval comes from a 21-day block bootstrap (1,000 resamples). The bar for 'adopted' was set before looking at the results: the lower bound must be above 0 and the sign must agree in at least two half-year periods.
US
Sample: 2025-08-11 to 2026-08-06, 249 trading days, 4960 stock-days. Financial verdict available for 100% of candidates.
| Financial summary | 21-day mean | Share that rose | vs index | Cases (stock x day) |
|---|
| Solid | +5.16% | 55% | +4.00% | 732 |
| Average | +2.12% | 58% | +0.44% | 2938 |
| Caution | +2.02% | 51% | +0.15% | 1290 |
| No data | – | – | – | 0 |
| How candidates are picked | vs index | Difference vs default | 95% interval | Verdict |
|---|
| Default (by score) | +0.89% | – | – | – |
| Exclude caution companies | +1.27% | +0.38% | [-0.17%, +1.25%] | On hold (not enough evidence) |
| Solid companies first | +1.90% | +1.01% | [-0.24%, +2.51%] | On hold (not enough evidence) |
Korea
Sample: 2025-07-28 to 2026-08-06, 250 trading days, 5000 stock-days. Financial verdict available for 100% of candidates.
| Financial summary | 21-day mean | Share that rose | vs index | Cases (stock x day) |
|---|
| Solid | +7.61% | 63% | -0.57% | 826 |
| Average | +6.04% | 56% | -1.22% | 3314 |
| Caution | +2.73% | 55% | -4.16% | 854 |
| No data | -11.67% | 17% | -11.97% | 6 |
| How candidates are picked | vs index | Difference vs default | 95% interval | Verdict |
|---|
| Default (by score) | -1.63% | – | – | – |
| Exclude caution companies | -1.37% | +0.26% | [-0.33%, +0.96%] | On hold (not enough evidence) |
| Solid companies first | -1.71% | -0.08% | [-1.43%, +1.03%] | On hold (not enough evidence) |
Limits: industry labels and the stock list are today's, applied backwards, so companies that disappeared in between are missing. The test window is about a year, giving only a dozen or so non-overlapping one-month periods - too few for a strong statistical conclusion. Trading costs are not included.
How to read the statistics
- If the sample (n) is under 30, chance is too likely a factor — we don't draw conclusions.
- Don't look at average return alone; check hit rate and sample size together.
- Past performance does not guarantee future returns.
Limits & regimes where this doesn't work well
- Being rule-based, it reacts slowly to sudden news or policy shocks.
- For thinly traded stocks/markets, the slippage assumption may not match reality.
- Markets with a short history (e.g. crypto) have lower validation confidence.
Data sources & license
Price data comes from public market data providers and is provided only as statistical information, not investment advice.
All figures on this page are statistical information, not investment advice.