Build a strategy
Set the 21 settings with sliders, read what the strategy will do in plain English, and copy a valid genome.
Not evidence. A hand-made strategy tested on history proves nothing, because you have seen that history. The forward test is the only test that counts. See the full note below.
The 21 settings, at their defaults (textbook momentum)
The interactive builder needs JavaScript, which is off or blocked here. This table shows the defaults. Turn JavaScript on to move the sliders.
What it does: Every 21 trading days buys the 10 S&P 500 stocks that rose most over the past year (skipping the last month), in equal amounts. No stop-loss.
| Group | Setting | Default | Unit | What it does |
|---|---|---|---|---|
| Core | Index-fund corecore.pct | 0% | percent of money | Share of the money always held in the arena's index fund. |
| Market filter (regime) | Market filterregime.enabled | no | Turn the market filter on: move to a safe haven when the index is weak. | |
| Market filter (regime) | Filter lengthregime.ma_days | 200 days | trading days | Length of the index moving average the market filter compares against. |
| Market filter (regime) | Safe havenregime.safe_haven | bonds | Where the money goes when the market filter says the market is weak. | |
| Market filter (regime) | Filter moves the coreregime.apply_to_core | no | Also move the index-fund core to the safe haven, not just the strategy money. | |
| Selection | Poolselection.pool | stocks | What the strategy money buys: stocks, sector funds or other asset funds. | |
| Selection | Ranking ruleselection.rule | momentum | How candidates are ranked (momentum, trend, pullback, low volatility, reversal or hold safe). | |
| Selection | Lookbackselection.lookback_days | 252 days | trading days | How far back the ranking rule looks to measure returns or volatility. |
| Selection | Skip recent daysselection.skip_days | 21 days | trading days | Most recent days ignored when measuring momentum (0 = none). |
| Selection | Fast averageselection.sma_fast | 50 | trading days | Short moving average used by the pullback rule; must be below the slow one. |
| Selection | Slow averageselection.sma_slow | 200 | trading days | Long moving average used by the trend rule and trend filter. |
| Selection | Trend filterselection.trend_filter | no | Only buy candidates trading above their long moving average. | |
| Selection | Volume filterselection.min_volume_rank | off | fraction of pool | Skip the least-traded share of the pool (0 = no volume filter). |
| Selection | How many to holdselection.top_n | 10 | positions | How many of the best-ranked candidates to hold. |
| Rebalance | Rebalance everyrebalance.every_days | 21 days | trading days | Days between rebalances (1 = daily, 5 = weekly, 21 = about monthly). |
| Sizing | Sizingsizing.method | equal | Equal weights, or weights that shrink for more volatile holdings. | |
| Sizing | Volatility windowsizing.vol_lookback_days | 63 days | trading days | Days of price history used to measure volatility when sizing. |
| Exits | Stop-lossexit.stop_loss_pct | off | percent | Sell a position that falls this far below its purchase price (0 = off). |
| Exits | Trailing stopexit.trailing_stop_pct | off | percent | Sell a position that falls this far below its highest price since purchase (0 = off). |
| Exits | Take-profitexit.take_profit_pct | off | percent | Sell a position that rises this far above its purchase price (0 = off). |
| Exits | Max holdexit.max_hold_days | off | trading days | Sell a position held this long (0 = off). |
Default genome as YAML
id: my-strategy parent: null core: pct: 0.0 regime: enabled: false ma_days: 200 safe_haven: bonds apply_to_core: false selection: pool: stocks rule: momentum lookback_days: 252 skip_days: 21 sma_fast: 50 sma_slow: 200 trend_filter: false min_volume_rank: 0.0 top_n: 10 rebalance: every_days: 21 sizing: method: equal vol_lookback_days: 63 exit: stop_loss_pct: 0.0 trailing_stop_pct: 0.0 take_profit_pct: 0.0 max_hold_days: 0
Start here
What this strategy will do
Your genome (YAML)
One-line version (for the GitHub box)
How to test it
- Set the sliders above, then press Copy one-line version. GitHub's box takes one line, and this version is the same genome written on a single line.
- Open this project's repository on GitHub and click Actions.
- Pick honest-run in the list on the left, then click Run workflow.
- Paste the one-line version into the genome_yaml field. Type the same arena you chose here into the arena field. Leave the other fields as they are, then click the green Run workflow button.
- Wait about 5 minutes. The report appears in Discord and under Hand-made and single-strategy tests on the Evolution runs page.
The run uses paper money and real prices from the last 2 years. Only the final 6 months are the test; the earlier part is context. The report compares your strategy with the index fund, textbook momentum and 100 fair random portfolios. If the YAML is not a valid genome, the run stops at once with a message naming the setting.
Read this before you trust a number
A strategy you build here and test on history is not evidence. You have already seen that history, so any tuning you do is fitted to it. The history test only catches broken ideas. Only the forward test counts: days after the strategy was locked, which nobody can know in advance.