Part 01The basics — what you mine, and what the main window shows
What an alpha is, what one round does, how history is split, and what every card on the main window shows. Nothing here is a knob to tune.
1.01A formula (an "alpha")
A short maths expression over the price tables, such as ema:20(ts_delta:14(cs_zscore(cs_demean(add(ts_max:30(volume),ret))))). The number after a colon is a lookback in bars. It is evaluated once per coin per bar: positive means long, negative short, a bigger number a bigger share of the book. It can read 12 features (close, open, high, low, volume, ret, vwap, range, body, dvol, logret, funding) through 25 operators: arithmetic, shape-benders (neg, sign, abs, slog, tanh), lookbacks over one coin's history (ts_mean, ts_std, ts_zscore, ts_min, ts_max, ts_delta, ts_delay, ts_sum, ts_roc, ema) and cross-sectional ones that compare all coins on the same bar (cs_rank, cs_zscore, cs_demean, cs_scale). Everything after that is fixed for every alpha: divide by each coin's volatility, normalise to 100% of the book, scale to the target vol, hold through a 10% no-trade band, pay fees on turnover.
Watch out. Absolute scale is a no-op: add(x,x) is exactly the strategy x. Cross-sectional operators need five or six coins to mean anything; with one pair cs_demean is zero.
1.02A round
default population 200 · 25 generations · Hall of Fame 15 · pause 5 s · explore every 4th roundOne complete evolutionary search: build 200 candidate formulas, score them, breed the survivors for 25 generations, fine-tune the lookback windows of the top 5, then hand back up to 15 champions kept deliberately unalike. New ones are appended to your library, the node pauses and starts again with a new seed. Rounds are the unit of progress: let tens of them run before judging anything.
Watch out. Warm-start only sees champions of the current session, and only the top "Leaderboard size" (20) of them. Before activation everything on disk is sealed, so refine may never run.
1.03TRAIN / VAL / TEST
default a window measured back from today — TRAIN 50% / VAL 20% / TEST 30% of the bar size's budgetHistory cut into three consecutive ranges. TRAIN is where evolution works. VAL is a second era that breeding never optimises directly; it catches formulas that merely memorised TRAIN. TEST is held out entirely: fitness, selection and seeding never read it, and its numbers exist only so you can look afterwards. The moment you pick alphas because their TEST is high, it stops being out-of-sample. That is what every ⚠ on a TEST-flavoured action means. By default the four dates follow today, so on 1d TEST is the last two years; type a date to pin it (Part 05).
Watch out. A library row was scored on the window of the day it was mined; the chart and the computed columns use today's window. A stored TEST Sharpe and a freshly drawn TEST curve are not the same measurement.
1.04Fitness — the number the search maximises
default min(TRAIN, VAL) Sharpe · complexity 0.010/node · correlation 0.70 · similarity 0.5 · concentration 0.3 under 3 positions · activity floor 10%The worse of the TRAIN and VAL Sharpe, so a formula is only as good as its weakest era. While breeding, the search also subtracts formula size, correlation above 0.70 with a champion already found, and concentration when the book averages fewer than 3 positions. A formula in the market on under 10% of TRAIN or VAL bars is discarded unscored. Fitness is the only score TEST never touched, but a high one is no promise: rows above +2 go on to a negative TEST all the time.
Watch out. The fitness you see carries only the concentration penalty; size and diversity steer breeding and are then dropped. That is why the log's green ★ line reads lower than the round summary for the same formula.
1.05▶ Start node
Saves your settings, then checks the market-data snapshot: if it is missing, lacks one of your pairs or is over 5 days old, a console window downloads your pairs from Binance and Start resumes by itself. Then it launches the node as a separate process and polls its status every 1.5 s. Two gates run first: the date segments must be in order, at least 30 bars each and inside the bar size's ceiling; and if this timeframe's library is not empty, the ★ settings must match the session contract (5.07). A mismatch opens a dialog with two ways out: revert to the recorded settings, or clear the node. While the node runs the settings panel is read-only.
Watch out. Only the ★ fields are frozen by the contract. Population, generations, CPU share and the breeding knobs may change between runs: they change how hard the next round looks, not what a score means.
1.06■ Stop
Sends the node an interrupt. It notices at the next generation boundary, writes its final status and exits, within seconds to a couple of minutes. Stop before anything that rewrites your library: activating, loading a session and clearing history refuse to run while a miner is writing. Nothing already written is lost.
Watch out. The round in flight is abandoned and its Hall of Fame discarded. If the log shows a ★ new best, wait for the "✓ round N" line before stopping.
1.07● stopped / running (the state pill)
What the node itself reports: grey stopped, green running. The node writes its status file only once the search is under way, so while it boots the pill still shows what the previous run left. The button pair tells the truth meanwhile: Start greys out and Stop goes live the moment the process exists. Beside the pill sits a one-line resource summary, prefixed "last run —" when nothing runs.
Watch out. The pill mirrors the status file, not the process. After a hard kill it keeps saying running; the giveaway is a clickable Start button.
1.08⚙ Settings
default hidden on a fresh installShows and hides the left-hand panel with every knob the engine understands. Hidden on a fresh install, remembered between launches, always exactly as wide as its content. Every field has a tooltip; at the bottom sit "Reset to defaults" and the red "Clear all history". Fields marked ★ are locked to the session (5.07). The panel is disabled while the node mines. Leave it closed for normal use: the defaults are what the engine was tuned with.
Watch out. Reset keeps your theme and whether the panel is open. "Clear all history" deletes every timeframe's library at once and nothing is backed up first.
1.09⧉ Sessions
Your whole workspace as one .tar.gz: every timeframe's library, the round history, the forward track, the built portfolio, your ★ favourites, the run status and your settings. Left out on purpose: market data (it re-downloads), your subscription key, and the list of running signal services. The archive's 6-character ID is the session id from the window header. Loading replaces the current workspace, with one exception: the forward track is merged, never replaced, because its steps happen in real time and cannot be recomputed. Loading refuses while the node, a forward step or a portfolio build is working. Double-click a row to see what is inside before loading.
Watch out. Loading takes no checkpoint, and an ordinary Stop makes no automatic snapshot either; the one automatic snapshot is the Autopilot's (3.13). If you want a way back, save the current session yourself first.
1.10Light / Dark
default follows the operating system on the very first launchRepaints the palette and rebuilds the window from scratch, so that the table, the equity images and the chart canvas come back in the right colours. The flicker is by design. Harmless to flip at any time, including mid-search.
Watch out. "Follow the OS" happens once, at startup, and Reset preserves the theme. The only way back to following the OS is editing gui_settings.json by hand.
1.11Activate node / Unlock
Every formula the node mines is sealed before it touches your disk: the library stores encrypted text plus a public id, and the row shows its stored metrics but not the maths. Activate takes your subscription key once, claims a machine seat and unlocks every sealed formula in every local library; from then on the node mines in the open, re-checked at each Start. The button lives in the header, next to Settings. The key belongs to the machine (~/.config/AlphaNode/licence.json on Linux, the application-support folder on Windows and macOS), so every other install on the box adopts it. An un-activated node is not blind: a sealed row reads "locked · Sharpe +1.04 · win 54% · PnL +29%" and the Portfolio card builds a sealed preview (7.15). What needs the plain text stays shut: the computed columns, Serve, the signal CSV, the PDF report and the forward track.
Watch out. Activation rewrites the library files, so it refuses while the node mines. The per-row "Unlock" is session-only. A key that has lapsed by the next Start makes the node seal again, silently.
1.12The tiles: ROUNDS · FORMULAS TRIED · ALPHAS FOUND · BEST FITNESS
All read from the node's status file. ROUNDS is how many complete searches have finished, resumed across restarts. FORMULAS TRIED is the lifetime count of distinct formulas evaluated, shared across timeframes. ALPHAS FOUND is how many distinct formulas sit in the library being mined into; in a mature library whole rounds keeping nothing is normal. BEST FITNESS is the current champion's min(TRAIN, VAL): it moves only at round boundaries and never shows a TEST number. A long flat stretch means the easy structure is exhausted at these settings.
Watch out. Switching timeframe moves nothing until settings are saved (Start saves them). During the first round of a run BEST FITNESS has no objective tag yet, so a win-rate figure can read as "+0.56" instead of "56%".
1.13The live log
Seven colour-coded lines from the node's event feed: round starts and finishes in normal ink, ★ new bests in green, forward-track steps in blue, warnings and errors in red. "▶ round N: explore" or "refine" names the mode; "✓ round N · 47s · 4,812 formulas tried · +3 champions kept · best fitness +1.81 · held-out TEST −0.26" gives a round's cost and yield in one line. The best single place to see whether the node is healthy.
Watch out. While the library is sealed, formula text is stripped from the log on purpose: the ★ line keeps its numbers, the maths is cut.
1.14SIGNAL API — running services
Appears once you are serving something. "Serve" starts a small local web service that recomputes a strategy's live target positions and hands them out as JSON on the next free port from 8799; each gets a row with its URL, log, health and a way to shut it down. This is the hand-off to your own execution code. The services are detached: they keep serving after you close AlphaNode, and the app re-adopts them next launch by probing ports 8799–8818.
Watch out. A stale service from a previous session can still answer on 8799 with an old strategy. Check the row's label and started time before blaming the formula.
1.15LEADERBOARD
default every alpha at this timeframe, sorted by fitness, families-only offThe library as a table: every formula ever mined at this timeframe, re-read whenever the file changes. Click a header to sort, double-click a row for its equity chart, right-click for copy, CSV export and the column picker. The search box filters by id or formula text; "families only" collapses the table to one representative per formula shape. Rows are tinted green only when their TEST Sharpe is at least zero; in a healthy library that is a minority, and that is the honest picture.
Watch out. Clicking "fitness" or "TEST OOS" re-selects which alphas are loaded from the library, and the heading says so. On a sealed library the recomputed columns show "—".
1.16PORTFOLIO — top-N combined
default top 6, by TEST · 2–20 (a widget default: not stored in settings, untouched by Reset)Runs N alphas together and plots the combined equity with its Sharpe on TRAIN, VAL and TEST, TEST CAGR and max drawdown, against buy-and-hold. This is where mining hundreds of alphas pays off: the combined curve is usually far better than any member, because their mistakes are uncorrelated. The "by" selector picks the members (5.06). Daily uses the full simulator (one to two minutes), intraday the fast approximation; the line under the chart names the engine. The member list shows each alpha's ID, solo TEST Sharpe, fitness and TEST OOS; a tinted row is one the combined Sharpe beat. On a sealed library the card builds a preview (7.15).
Watch out. "by TEST" is the dishonest pick and the card says so: the window that chose the members is the window being scored. Prefer fitness or combo.
1.17FORWARD TRACK — paper steps
default starts at $10,000 · one step per closed bar · checked every 5 minutesThe honest verdict machine. Enrol a portfolio or a single formula and it is frozen (formulas, universe, target vol, fee), then paper-traded forward from $10,000, one step per closed bar: fetch the latest closed candles, recompute targets with the real engine, mark to market, rebalance, charge fees. History is append-only. No peeking can contaminate this number, because the bars did not exist when the formula was mined. The node steps the track every 5 minutes while it mines and the app re-checks as often; both stop when you close the window. A missed bar is a rebalance that never happened, not lost money, but long gaps leave the track sparse. The track outlives sessions: "Clear all history" spares it and a loaded session merges into it.
The buttons: Signals (the step log of the selected entry, exportable as CSV), Serve (7.04), AlphaHub (host the row on the Network, Part 9; its kind then reads "· hub") and the red Delete. Tick several rows and Delete and AlphaHub act on the ticked set. Double-click a row for its forward chart. Three columns watch the strategy age: SEALED is the TEST Sharpe it carried at enrolment, AGE the days since, and HEALTH the forward Sharpe against the sealed one in standard errors: ok (z +0.3), watch under −1, retire under −2, young under 30 steps. The leash tightens with age: a flat two-month track reads watch at worst, a flat year reads retire.
Watch out. Delete is permanent and takes the paper history with it; re-enrolling starts a fresh $10,000 track. There is no "step now": steps happen by themselves, once per closed bar.
Part 02Pairs, timeframe and market data
The only settings that change the data rather than how it is searched. Get them right first. AlphaNode downloads its own history from Binance USD-M perps; there is no file to point it at.
2.01Which pairs to trade
default BTCUSDT, ETHUSDT, SOLUSDT, XRPUSDT, BNBUSDTrange 1–20 pairsThe exact basket the whole app runs on. Full Binance USDT-perpetual tickers only (BTCUSDT, not BTC). Type up to 20 pairs separated by commas or spaces and press Enter: the box turns into chips. ✕ removes a chip, clicking a chip's text pulls it back into the box. Below about 5–6 pairs the cross-sectional operators stop meaning anything; that is the practical floor. Wider buys a broader cross-section and costs download, memory and time in proportion. A recently listed coin is safe: its pre-listing bars are masked out.
Watch out. A one-pair universe looks like it works and does not: the weight is always ±1, so only the sign is traded. Library rows do not record their basket: change the pairs and a row's stored numbers come from the old basket while its recomputed columns come from the new one.
2.02Timeframe (bar size)
default 1drange 1d | 4h | 1h | 15mThe bar size for the entire pipeline: every window in a formula is counted in bars of this size, and Sharpe is annualised over 365 days. Each timeframe is a separate world with its own snapshot, library, round history and session contract. Start on 1d: longest history, lightest download, fastest generations, and the only snapshot that ships with the app. Intraday bars give more bars per year but shorter history, a far heavier download and fees that eat a larger share of each move. The choice takes effect when settings are written: press Start, or collapse the settings pane.
Watch out. Picking from the dropdown overwrites all four date fields with that bar size's window; hand-pinned dates are lost silently. Pick the bar size first, then pin.
2.03Market data (the automatic download at Start)
Start downloads first if the snapshot is missing, unreadable, missing a pair, or over 5 days old. A console window streams the downloader, and Start resumes when it exits cleanly. If Binance's live API is unreachable, it falls back to the public data archive: the same bars, 10–30 hours behind. The download is deliberately slow to stay under the rate limit. Closing the console cancels safely. History begins at the timeframe's recommended date or the pair's listing date, whichever is later, so an earlier TRAIN start buys no extra data. Funding-rate history comes with the candles.
Watch out. In the app this is a replacement, not a top-up: adding one pair re-downloads all of them, and a removed pair loses its stored history. A headless node does the opposite: it adds pairs to the snapshot and never shrinks it.
2.04Data and state on disk
Everything writable lives in one folder: ~/.local/share/AlphaNode on Linux, %APPDATA%\AlphaNode on Windows, ~/Library/Application Support/AlphaNode on macOS. It holds the price snapshots, gui_settings.json, exports/ and state/ with the libraries (library.jsonl, library_4h.jsonl …), the round history, status.json, the portfolio, the forward track, favourites, sessions, the session contract and the cached return series. Your alphas are just the library*.jsonl files: back them up, or use Sessions → Save current…. Deleting a data_*.pickle is harmless; the next Start downloads it again.
Watch out. Closing the window does not save: a pairs or timeframe edit followed straight by quitting is lost. Start, a theme switch and collapsing the settings pane are what save.
Part 03The search settings — how hard and how long it looks
How hard the app hunts, for how long, and how it splits its time between finding new ideas and polishing old ones. All of it is read once, at Start. None of it touches the honesty of the result: TEST is held out whatever you set here.
3.01Resources (CPU share)
default 50%range 5–95 (slider only)The share of your processor handed to the search; the line above the slider does the arithmetic live ("50% → 4 of 8 cores"). The biggest lever on wall-clock speed. It costs memory, heat and a sluggish machine; lower it to about a third to keep working on the same computer.
Watch out. The worker pool is rebuilt every round, so a big core share buys little when Generations is very small.
3.02Population
default 200range 20–2,000How many candidate formulas exist side by side in one generation. Raise it for a wider sweep of formula space; the cost is close to linear. If you want more total search, raise Population before Generations: breadth protects you from settling on the first decent idea.
Watch out. Elitism + Random/generation must stay below Population and Tournament size below a quarter of it: the boxes turn red and Start refuses with the reason. A number typed past a field's range snaps back to the nearest bound.
3.03Generations
default 25range 1–200How many cycles of scoring, selection and breeding happen inside one round. After the last one a short polish pass tries each lookback window of the top five at 0.8× and 1.25×. Raise it to dig deeper into what a round has found; the returns flatten, and you can watch them flatten in the log. Lower it for more, shorter rounds. Below about 10, evolution barely has time to combine anything.
Watch out. evolution/config.ini says generations = 30 and the app never uses it: the panel's numbers win (200 / 25 headless). The rest of the file is live, re-read every round, and holds the knobs the panel has no box for.
3.04Seed (0 = auto)
default 0range 0–2,147,483,647The starting number for the random generator. Each round runs on this number plus its round number, so the same seed reproduces a run only on a machine with the same number of rounds behind it. At 0 the app mints a seed once per install, so no two installs mine identical libraries. Leave it at 0; set a number only for repeatability. There is no quality difference between seeds.
Watch out. A shared number is a shared search: the same integer on the same settings and data mines the same formulas. Reproducibility holds for explore rounds only.
3.05Pause, sec
default 5range 0–600How long the node idles between rounds. Raise it on a laptop to let the fans catch up; it is lost mining time and changes nothing in what is found. 0 chains rounds back to back.
Watch out. Not a load limiter: during a round the node uses every core the slider gave it. If the machine is too loud, lower Resources.
3.06Status port
default 8787range 1024–65535The TCP port of the node's own small web page at http://localhost:PORT: the top formulas, the round log and the forward track, raw numbers at /status.json. The desktop window does not use it, so the page is a bonus for checking a mining machine from a phone. Leave it alone unless something else owns 8787 or you want two nodes at once.
Watch out. No login, and once activated it shows your formulas, so it listens on 127.0.0.1 only; ALPHANODE_STATUS_HOST=0.0.0.0 publishes it, port 0 turns it off. A taken port fails silently. Keep clear of 8799 and the fifty ports above it, where the signal services live.
3.07Optimize by win rate
default offSwitches what the search maximises. Off, Sharpe. On, the per-bar win rate: of the bars where the strategy held a position, the share that closed in the black, still the worse of TRAIN and VAL. Rarely active formulas are pulled toward 50% and docked a standard error, so a perfect 5-of-5 reads as luck; under 30 active bars the formula leaves the round. Use it for an equity curve that feels steady day to day, or as a second opinion.
Watch out. Win rate is blind to size: 65% small green bars against 35% catastrophic red ones ranks first here, so judge what it mines by TEST Sharpe and maxDD. In this build the node's own top list stays Sharpe-ordered, so mine win-rate alphas into a fresh library.
★ Part of the session contract (5.07): frozen once this timeframe's library holds a row.
3.08Explore every N-th
default 4range 2–20The mix between hunting and polishing. Every round whose number divides by N explores from a fresh random population; every other round refines from the node's top list. Lower N gives a broader library and a best fitness that creeps; higher N climbs the headline faster but converges onto one or two ideas. If the top of your leaderboard has been the same shape for hours, lower it; if you have hundreds of scattered mediocre alphas, raise it.
Watch out. N = 1 turns refinement off: every round explores and warm-start stops doing anything.
3.09Max. rounds (0 = ∞)
default 0range 0–10,000Stops the node after this many rounds; 0 never stops on its own. Use a finite number for a bounded experiment or an overnight budget. It counts rounds, not time.
Watch out. The count is lifetime, restored from your history: with 120 rounds recorded and Max rounds 50 the node stops without mining. Set it above the ROUNDS tile.
3.10Leaderboard size
default 20range 5–100How many champions the running node keeps in its own top list: what the :8787 page shows, what the best-fitness tile reads, and the exact pool a refine round warm-starts from. 5–10 hammers a handful of formulas, 50+ gives a broad starting pool. Keep it well below Population.
Watch out. It does not limit your library and never deletes anything; the app's table reads the library file, not this list.
3.11Warm-start from library
default onThe master switch for refine rounds. On, a non-explore round starts with your top-list champions dropped into generation 0 unchanged. Off, every round is a from-scratch exploration. Leave it on: this is what turns a series of independent searches into something that compounds.
Watch out. A champion larger than the current Max. nodes is skipped silently when the round seeds itself, so lowering Max. nodes after mining large formulas quietly turns your warm start into a random start.
3.12Stop when stalled (early stopping)
default 12 rounds · 0 = neverThe node's own sense of "done". After every round it asks two questions: did the mean fitness of the library's top ten rise by at least 0.02, and did the round add a new family above the library floor (4.16)? A yes to either resets the counter; after this many barren rounds in a row the node stops and says so in the log. Twelve is three explore cycles at "explore every 4th". The round ticker shows "stall 3/12". The Autopilot of the next item relies on this rule.
Watch out. The rule reads fitness, never TEST. A tiny population makes rounds barren for the wrong reason; raise the budget before raising the patience. A Docker node with this on exits when converged, by design.
3.13Autopilot — the hands-off run
default off · the AUTOPILOT section of the settingsOne tick, and the node does the whole job by itself. The search runs with a fixed table of knobs for your bar size instead of the boxes above, which grey out. 1d: population 200, 25 generations, explore every 4th, robustness penalty 0.5, library floor 0.5, stop after 12 stalled rounds. 4h: the same with 10 stalled rounds. 1h: 160 / 20 / 10. 15m: 120 / 15 / 8. A table rather than a tuner, because none of these knobs moves the out-of-sample result beyond noise.
When the search stops by itself (the stall rule or Max. rounds), the tail runs. The portfolio is built as the best combination on TRAIN+VAL ("combo", auto size). The forward track is filled from the library's families by a pre-registered rule: fitness above zero, the four robustness probes (6.15) keeping at least half of it, both pair halves positive, at least two independent bets, one row per family, TEST never consulted. Three to ten entries: every family that passes, at most ten; when fewer than three pass, the best of the rest fill up to three and are named as fillers. The portfolio joins as one more book, every new entry takes its first step, "Host them on AlphaHub" hands each to the hub (Part 9), and a session snapshot is taken. From the terminal: alphanode --role cli autopilot on a stopped node, run --autopilot for a headless one.
Watch out. Your Stop runs nothing: the tail belongs to a search that finished on its own. It needs open formulas, so an un-activated node enrols only what it found in this run. The rule never reads TEST, so an enrolled row may carry a poor TEST Sharpe; that is the forward track's question. Ten forwards from one library are ten tests: judge the panel by the rule, not by picking the best-looking track afterwards.
Part 04The engine knobs — simulation, formula shape, breeding, fitness
How the simulator trades a formula, how big a formula may get, how the next batch is bred, and how candidates are scored. Every value here is read at Start and overrides config.ini.
4.01Target-vol (ann.)
default 0.25range 0.05–1.50The annual volatility the simulated book is steered to: the engine scales every position so the book's running volatility lands on this number. It is the leverage knob. Because the score is a Sharpe ratio it barely changes which formulas win; what it changes is the risk you would run, and the max drawdown scales with it. Set it to the risk you are willing to hold, not as a tuning dial.
Watch out. No margin model and no liquidation, so the high end is arithmetic, not a tradeable setting. At 1.50 the same formula keeps its Sharpe and compounds to a loss.
★ Part of the session contract (5.07): frozen once this timeframe's library holds a row.
4.02Fee, bps
default 10 bpsrange 0–50What trading costs, in basis points of the notional that changes hands, charged on the change in a position; a formula that sits still pays nothing. Recommended all-in figures on Binance perps: 15m 10, 1h 8, 4h 7, 1d 6. This is the only brake the search has on churn. Set it at or above your real all-in cost, fee plus slippage, and the search will refuse to hand you signals that only work for free.
Watch out. Setting it to 0 changes what wins, not just the numbers: a whole family of high-churn formulas becomes "profitable" and the search hands you those.
★ Part of the session contract (5.07): frozen once this timeframe's library holds a row.
4.03Max. depth
default 6range 2–10How many operators may be stacked before a branch must end in a raw feature. 19 of the 25 operators take a single argument, so formulas grow as long chains, and depth rather than Max. nodes is usually what caps them. Drop it to 3–4 for formulas you can read at a glance; raise it to 8 for longer chains.
Watch out. Depth is enforced by pruning: an over-deep branch is replaced with a random raw feature and the damaged child is evaluated anyway. Lowering this after mining deep formulas grafts random leaves into every child bred from them.
4.04Max. nodes
default 22range 3–64The total count of operators and features in a formula; ts_mean:30(close) is 2 nodes. Small (10–15) gives simple, readable, harder-to-overfit formulas; large (40–64) gives expressive combinations and many more ways to memorise TRAIN. If you raise it, raise Complexity penalty too.
Watch out. The limit leaks: children over the limit are rejected and retried, but the fresh random injections are added with no size check. Negligible at the default, visible at small limits.
4.05Tournament size
default 5range 2–50How a parent is chosen: draw this many candidates at random and keep the best. The single dial for selection pressure. Low (2–3) makes mating nearly random: diverse, slow to improve. High (15–50 against 200) lets the top few per cent dominate and the population becomes copies of one lineage. If the "uniq" count in the log stops growing, pressure is too high.
Watch out. The fitness compared here is the penalised one, so a formula can lose for being large or for resembling a champion rather than for trading worse.
4.06Elitism
default 6range 0–50How many of the best formulas are copied into the next generation untouched, so the best thing found cannot be destroyed by the mutation meant to improve it. 6 of 200 is sane. At 0 progress can go backwards; above roughly 10% of the population the same handful keeps winning and the search stalls.
Watch out. Elites are picked by the penalised fitness of that moment, so a formula can drop out of the elite without changing, because a champion resembling it entered the Hall of Fame.
4.07Random/generation
default 10range 0–200How many brand-new random formulas are dropped into each generation. Crossover recombines what the population already holds; injection adds whole new formulas, so it is the knob for a pool that has narrowed onto one family. Try 20–40 when the unique-formula count flattens early. Every injection is a full evaluation and nearly all are junk: a direct CPU tax.
Watch out. When Elitism + Random/generation reach Population no breeding happens at all; the panel refuses such a combination at Start.
4.08Crossover share
default 0.60range 0.00–1.00Of the children bred each generation, the fraction made by crossover: a branch cut from one parent, grafted into a copy of another. The rest are mutations of a single parent: replace a branch, swap an operator for another of the same kind, or nudge a lookback window. Crossover recombines whole ideas; mutation does the fine work and is the only thing that tunes windows.
Watch out. At 1.00 window tuning is off entirely; only the polish pass on the top 5 champions remains.
4.09Complexity penalty
default 0.010 per noderange 0.000–0.100Subtracted in proportion to node count. At the default the spread from the smallest formula to a 22-node one is about 0.2 Sharpe: meaningful, not decisive. At 0.05 the search collapses toward stumps. Raise it when champions come out unreadable and their TEST lags their fitness; lower it when you have raised Max. nodes and want the room used.
Watch out. It steers selection, not the output: the Hall of Fame is sorted on the raw score, so a bloated formula with the best raw score still tops your library. Under "Optimize by win rate" it is multiplied by 0.1.
4.10Correlation threshold
default 0.70range 0.30–0.99How alike two formulas' results must be before the app calls them the same alpha: the correlation of their per-bar TRAIN+VAL returns, ignoring sign. It triggers the similarity penalty and is the deduplication rule of the Hall of Fame. Lower it (0.5–0.6) when the library fills with variants of one idea; raise it (0.8–0.9) when too few distinct families come back.
Watch out. Because sign is ignored, a formula and its inverse count as duplicates. Near 1.00 dedup never fires and the Hall of Fame fills with twins of one formula.
4.11Similarity penalty
default 0.5range 0.0–2.0How hard a candidate is punished for resembling a champion already in the Hall of Fame: penalty × (correlation − threshold) against the most similar one. Raise it when every round returns variations of the same alpha; set 0 when you are deliberately refining one family.
Watch out. At the defaults it is close to cosmetic: the largest possible subtraction is 0.15 Sharpe. To make diversity cost something, lower the Correlation threshold as well. 0 does not switch deduplication off.
4.12Hall of Fame size
default 15range 1–100How many champions a round produces, the formulas written into your library when it finishes. Not a simple top-N: a new formula correlating above the threshold with a champion replaces it if it scores better and is dropped if not, so the list stays diverse. Raise it when rounds keep reporting "none kept"; lower it (5–8) when the library fills with entries you never open.
Watch out. Raising it does not get you more of your best work: the polish pass is hard-coded to the top 5, so a larger Hall of Fame mostly adds weaker entries.
4.13Robust blocks (0 = legacy)
default 0range 0–12An alternative scoring. At 0, fitness is min(TRAIN, VAL). At 2 or more, TRAIN and VAL are merged, cut into that many time slices, and the formula is scored on the near-worst slice. The app's own A/B on an 861-alpha library found no improvement over legacy; min(TRAIN, VAL) already is a two-block worst-regime rule. Treat it as an opt-in experiment; if you try it, use 3.
Watch out. Turning it on changes what "fitness" means everywhere and nothing in the interface says so: block fitness runs deep in the negative, so block-scored champions sort under every legacy row and never seed a refine round. It also retires VAL start from the score (5.02).
★ Part of the session contract (5.07): frozen once this timeframe's library holds a row.
4.14Two file-only knobs: the one-sided book guard, and the turnover objective
default config.ini only · guard on, 0.5 past 75/25 · metric = sharpeThe guard docks the fitness of formulas whose book leans hard to one side on TRAIN and VAL: nothing until the tilt passes 75/25, then up to 0.5 at a fully one-sided book. In crypto a long-only basket is the market with extra steps, and a rising TRAIN and VAL would reward it. It lives under [fitness] in evolution/config.ini, or as ALPHANODE_FIT_NET_PENALTY and ALPHANODE_FIT_MAX_NET; 0 turns it off. The objective metric = turnover (or ALPHANODE_FIT_METRIC=turnover) scores Sharpe × √(annual return ÷ daily turnover), so of two formulas with the same Sharpe the one that trades less wins; the number stays on the Sharpe scale.
Watch out. Both change what gets mined, not how anything is displayed: rows already in the library keep the fitness they were mined under. The L/S % column (6.11) shows the tilt on TEST while the guard measures TRAIN and VAL.
4.15Robustness penalty
default 0.5The search's own perturbation test. A candidate about to join the Hall of Fame is re-scored four times on TRAIN plus VAL, never TEST: on each half of the universe split by dollar volume, and with every window scaled by 0.8 and by 1.2. The worst of the four is its robust fitness, and this coefficient decides how much of the gap to the plain fitness is charged: 1 makes a formula worth its worst perturbation, 0 switches the test off. The charged number is what the library stores as fitness; the row also keeps the raw fitness and the four probes.
Watch out. The in-search twin of the robust column (6.15), which runs the same probes on TEST. Under six pairs the halves are too small to mean much.
4.16Library floor
default 0.5 × top-10Not every round's champion deserves a place in the library: an exploring round fills its Hall of Fame whatever the quality. The floor is the fitness a champion must reach to be written, this share of the mean fitness of the library's top ten. Rows under it are counted in the round's log line and dropped. 0 accepts every champion. The floor also feeds early stopping: only a champion above it counts as a new family.
Watch out. A library under ten rows has no floor, so the first rounds admit everything. If it feels harsh, lower the share before switching it off: 0.3 keeps the pure noise out and little else.
4.17Neutral book (neutralize)
default offrange off | dollarWhether the book may hold a view on the market at all. At off a formula that says "up" about every coin goes long everything. At dollar the mean forecast is subtracted on every bar, so long dollars equal short dollars and the market's direction cannot enter the P&L: the search can only score which coin beats which. Why it exists: on a rising TRAIN and VAL the search learns to time the market, the fastest score on offer, and that part does not age. In the 2026-09 study the timing part of the champions fell from a Sharpe of 3.2 in-sample to 0.3 on TEST while the neutral part held, 2.1 to 1.8. That is also why a high MKT ρ (6.12) is read as a warning. The mode travels with the row: everything that re-simulates a row (the computed columns, the chart, the exports, the portfolio, a served signal, a forward entry) uses the book it was mined on. Headless it is run --neutralize dollar or ALPHANODE_NEUTRALIZE=dollar.
Watch out. The traded book is only approximately neutral, and a bar with a single tradable coin goes flat, so on two or three pairs the mode has little to trade. Zero net dollars is not zero market beta: long the wild coins and short the sleepy ones still rides the market. off stays the honest choice when a market view is the strategy you mean to mine.
★ Part of the session contract (5.07): a library holds one mode, so switching means a new session.
Part 05Date segments, and the honesty discipline
Four dates define the three stretches, and by default all four follow today. The search may stare at TRAIN and VAL as long as it likes; TEST is walled off and only reported, never used to pick, rank, seed or tune. The session contract at the end of this part keeps a library measured on one rule.
5.01★ TRAIN start
default follows today: the whole window back — 2,400 days on 1drange YYYY-MM-DD · checked as you type and again at StartThe first bar of the window the app builds. Earlier means more market moods to prove a formula across, at the price of speed: every candidate is simulated over the whole span, so doubling it roughly doubles a round. Leave a couple of hundred bars of runway before the part of TRAIN you care about: lookbacks start half-filled and the volatility estimate needs 30 bars. This field decides the window's length, so it is the one the ceiling argues with: 3,000 bars on 1d, 16,000 on 4h, 40,000 on 1h, 96,000 on 15m. Exceed it and a red line says how many days to move it.
Watch out. The download never asks for your TRAIN start; it fetches from the timeframe's own history start. Pin TRAIN start earlier than that and the missing stretch is filled with a frozen price: every formula sits flat through it and every Sharpe is dragged down, silently.
5.02★ VAL start
default follows today: 50% of the window back — 1,200 days on 1drange strictly between TRAIN start and TEST start — enforcedThe wall between TRAIN and VAL, and the most powerful anti-overfitting lever in the app. A score is the lower of the TRAIN and VAL Sharpe, so a formula that made all its money in one kind of market is judged by the kind where it did not. The default puts it halfway through the window; pin it where the market's character genuinely changes if you know better. Keep VAL long enough to mean something: about ±1.2 of error around a one-year VAL at Sharpe 1.0, ±0.6 at four years.
Watch out. Robust blocks at 2 or more silently retires this date from the score, while the VAL row still shows on the champion card.
5.03★ TEST start
default follows today: 30% of the window back — 720 days on 1drange strictly between VAL start and TEST end — enforcedThe wall. Everything from here to TEST end is held out: never in the score, the shortlist, the warm start or the window polish. Its length is a budget: later gives the search more data and you a noisier verdict; earlier buys a trustworthy TEST at the cost of a thinner search. Keep at least 1.5–2 years on daily bars. Pin it when you want the wall to stay put while the rest of the window slides.
Watch out. A TEST under 30 bars is refused outright. Above that the degrading is quiet: under 5 traded bars the TEST cell shows "—" and the direction columns need 30 bars each. Re-cutting it on a non-empty library is a contract change.
5.04★ TEST end
default todayrange strictly after TEST start — enforced; not clamped to the data you holdThe last bar the app loads, for everything. By default it is today and moves with the calendar. Pin it only to reproduce an older run.
Watch out. Pinned past the end of your data it costs Sharpe silently: the last close is carried forward, every strategy returns zero across those bars, and TEST Sharpe shrinks accordingly.
5.05The window at each bar size
Every bar size takes the same shape: 80% of its ceiling, ending today, cut TRAIN 50% / VAL 20% / TEST 30%. 1d: 2,400 days, about 1,200 / 480 / 720 bars. 4h: 2,133 days, 6,400 / 2,560 / 3,840 bars. 1h: 1,333 days, 16,000 / 6,400 / 9,600 bars. 15m: 800 days, 38,400 / 15,360 / 23,040 bars. Finer bars trade calendar span for bar count. Switching the timeframe refills all four dates from this rule.
Watch out. The extra bars do not buy a more believable verdict: the error bar on a Sharpe depends on calendar years. At Sharpe 1.0 the TEST windows carry roughly ±0.7 (1d), ±0.9 (4h), ±1.2 (1h) and ±1.6 (15m). Read intraday TEST as a sanity check and lean on the forward track there.
5.06by — how portfolio members are picked
default TEST on the dashboard · combo, auto size, under Autopilotrange TEST | fitness | comboCombining alphas is a selection step like any other, and the easiest place to break the discipline by accident. "fitness" picks members by the worse of TRAIN and VAL, so the combined TEST curve is genuinely out-of-sample. "combo" is better still: from a pool of the top alphas by fitness (4×N, between 12 and 30) it searches for the best combination of N by the mix's Sharpe on TRAIN+VAL only, which naturally hunts members that do not move together. Autopilot always builds this way and lets the search choose the size as well.
Watch out. The dashboard selector opens on TEST, the one option that breaks the discipline. What stays real in a TEST-picked portfolio is the diversification gain; the level of the curve is not.
5.07★ The session contract
default recorded at the first Start that mines into an empty library · per timeframeA library is comparable with itself only if every row was scored under the same rules. Ten settings decide what a score means (the pairs, the four dates, target vol, fee, the win-rate objective, robust blocks and the neutral book) and they are marked ★. The first Start into an empty library records them (state/session_params.json, one per timeframe). Every later Start compares the panel against that snapshot: a difference opens a dialog listing each changed field as was → now, with "Revert to session settings" and "Clear node & start fresh". Everything not ★ is free to change between runs. A window that follows today is the same contract tomorrow; pinning a sliding date is a change.
Working with a re-cut: mine under one cut, read TEST once, enrol what you liked into the forward track, save a named session, then clear and re-mine on the new cut. A sliding window is not a re-cut: a library on the default dates keeps accepting rows as the calendar advances, each scored on the window of its own day. Pin the four dates when that matters, before the first row is mined.
Watch out. A library from before 3.1 has no snapshot; the first Start after the upgrade records whatever the panel holds. If you changed settings since those rows were mined, clear first.
5.08Batch report — the whole library judged at once
default written by the node when a search converges or runs out of roundsThe whole library judged at once, never by picking rows. The line under the leaderboard title, the Batch report button and report in the CLI answer four questions: is the batch better than noise (the TEST median, the share of rows above zero); is it the market in disguise (how the rows correlate with the basket on TEST); does anything hold across the two halves of TEST; and how many families is it really (rows whose TEST returns correlate at 0.6 or more are one bet). A fixed rule turns the numbers into a verdict: noise, the batch is the basket, mixed, or too few rows under twenty. No rule names a row as a pick; the forward track is the only judge of a formula.
Watch out. The verdict is about the search, not about any row: quoting it is honest where quoting a picked row's TEST is not. Stop does not write a report, only a natural end does.
Part 06The leaderboard, column by column
Four columns (fitness, TEST OOS, maxDD, CAGR) are stored numbers written when the formula was found. The rest are recomputed on demand by a background helper that re-simulates the formula on TEST with your pairs, target vol, fee and dates as they stand, and cached under the formula text until a restart, a timeframe switch or a fresh download. A dot (·) means still computing; an em dash (—) means no honest number here.
6.01★
default always shownA star means the formula is in your Favorites; clicking the cell toggles it. Your shortlist while scrolling a library of hundreds.
Watch out. The star set is keyed by the 6-char ID without the timeframe, so the same formula starred on 1d shows starred on 4h. Sealed rows cannot be starred.
6.02# · ID
default always shown · ID shown by default# is the row's position in the current sort: a place-marker, never a quality score. ID is a stable 6-character fingerprint of the formula, the handle used by the forward track, favourites, the search box and both CSV exports.
Watch out. "Export table" writes the 6 characters you see, "Export full library" writes 12, so a plain text match between the two files fails unless you trim.
6.03fitness
default always shown · the default sortThe score the search ranked by: the worse of the TRAIN and VAL Sharpe. The only column that is honest for picking, because TEST never touched it. On daily bars above roughly +1.5 is worth opening; well above +2.5 is usually too good and worth suspecting rather than celebrating.
Watch out. A row mined under "Optimize by win rate" shows a percentage here, and clicking this header sorts rows mined under your active objective to the top as a block.
6.04TEST OOS
default always shownThe Sharpe on the held-out slice, the honest out-of-sample verdict on a single formula. A dash means fewer than 5 TEST bars where the strategy made or lost anything. Read it, do not select on it. Expect it well below fitness; a TEST close to its fitness is the rare good sign, a wide gap the classic overfitting tell.
Watch out. Clicking this header re-reads the whole library ranked by TEST and changes the heading to "cherry-picked ⚠". That is peeking by construction. Click "fitness" to get the honest population back.
6.05maxDD · CAGR
default shown by defaultmaxDD is the worst peak-to-trough fall of the TEST equity curve, the pain metric that decides whether you could hold the thing. CAGR is the compound annual growth rate on TEST; a dash means the equity ended at or below zero. Read them together: CAGR ÷ |maxDD| is return per unit of pain. Both move with your target vol.
Watch out. Both prefer the value stored when the alpha was mined, so after a change of target vol, fee, pairs or dates they describe the old settings. The recomputed cells go stale too, until a restart, a download or a timeframe switch. Restart the app to re-measure the whole table.
6.06sortino
default hidden — right-click a header to switch it onLike Sharpe, but only losing bars count toward the wobble. Look at it when a Sharpe seems unfairly low: a big sortino-to-Sharpe gap means the volatility Sharpe punished was mostly good volatility.
Watch out. A dash can mean no losing bars at all, which almost always means an alpha that traded a handful of bars; cross-check tr/yr·a.
6.07T ↑ · T ↓ · T ~
default shown by default · each header carries its bucket's bar countTEST Sharpe measured only on the bars where the market as a whole was trending up, down, or neither. The regime is the market's, not the formula's: the equal-weight basket's drift over the trailing ~30 days, lagged one bar. T↑ and T↓ both positive is genuinely direction-neutral. T↓ is the most informative in crypto: most formulas quietly make their money long, and a positive T↓ is the evidence that the alpha survives a bear leg. T~ is where mean-reversion earns its keep and trend-followers bleed.
Watch out. Two causes of a dash: under 30 TEST bars in the bucket (hits every row at once) or the formula sat flat through the bucket (per row).
6.08L/S /yr·a · tr/yr·a
default hidden — right-click a header to switch them onLong and short entries per asset per year on TEST: "3.2/1.8" is roughly three new longs and two new shorts per coin per year. The alpha's directional personality: 4.0/0.1 is a long-only formula in a long/short costume; near 2.5/2.5 is two-sided. tr/yr·a is the two added together, the activity dial: low single digits means fees barely matter; a few hundred means an alpha whose profitability lives on your fee setting.
Watch out. Both count intended entries, not fills: the simulator leaves a position alone whenever the required change is under 10% of the target.
6.09win ↑ · win ↓
default shown by defaultThe share of the formula's up calls that came true, and of its down calls. Every (bar, asset) cell where it held a long position is a call that the asset rises over the next bar: right when the price rose, wrong when it fell. Unlike T ↑, which slices by what the market did, this judges what the formula said, asset by asset. Read the pair together: win↑ 56% against win↓ 48% says the short book is guesswork riding along with a real long edge. A formula that never shorts shows a dash in win↓.
Watch out. Two evidence floors, 30 calls on TEST and at least 5 where the price moved, so a high number from a barely-trading formula is the coin flip it is. A healthy win↑ can still lose money when the rare misses are large.
6.10formula
default always shownThe alpha itself, in full. Length is information: the search charges per node, so a short formula that still made the library beat that handicap and is usually the more robust one. Click a cell to make the text selectable, or use Copy formula.
Watch out. Absolute scale is meaningless, so do not read big constants as "aggressive". A locked row shows "locked" here and dashes in every recomputed cell.
6.11L/S %
default shown by defaultHow the book sits, as the long/short split of its exposure on TEST: 50/50 is market neutral, 100/0 never shorts. Inverse-vol weighted, so it reflects money at risk rather than a count of positions. The honesty check on the rest of the row: the further a row drifts from 50/50, the more of its result is simply the market, which in a rising market flatters TEST OOS, CAGR and win% all at once.
Watch out. A wrapper is often the culprit: ts_max(ts_roc(close)) sits around 84/16 however sound the signal, and wrapping it in cs_demean pulls it back to 50/50. The search charges for this past 75/25 (4.14), but on TRAIN and VAL, while this column shows TEST.
6.12MKT ρ
default shown by defaultThe correlation between the formula's TEST returns and the equal-weight basket of its universe. Where L/S % shows how the book sits, this shows what the equity curve did: a 50/50 book still rides the market if its longs are the high-beta coins and its shorts the sleepy ones. A cross-sectional alpha lives near zero; a row above +0.7 earned its TEST from the market and will hand it back when the market turns.
Watch out. A strongly negative value is no virtue: a row at −0.8 is a short-the-market machine whose TEST is the story of one bear leg. What you want is small |ρ| with a positive alpha, the next column.
6.13alpha
default shown by defaultThe annualised TEST return left after the market's share is taken out (Jensen's alpha against the equal-weight basket). Every row is simulated at the same target vol, so alphas compare down the column and against CAGR: a row with CAGR +30% and alpha +2% earned its growth by being exposed to the market; CAGR +12% and alpha +11% earned it itself.
Watch out. A residual inherits every weakness of its inputs: a short TEST or a rarely trading formula makes it noisy. Analysis, not selection: picking rows by alpha is one more way of peeking at TEST.
6.14turn/yr · SR @2×fee · fee₀
default turn/yr and SR @2×fee shown by default · fee₀ optionalThe cost trio. turn/yr is how many times a year the whole book is traded on TEST: 6 is a slow book, 200 turns over most days. SR @2×fee is the TEST Sharpe if every trade cost twice what the search assumed: a row that keeps most of its Sharpe is trading an idea, one that collapses is trading the fee assumption. fee₀ is the break-even fee in basis points at which TEST Sharpe reaches zero: compare it with what your venue charges plus slippage. Zero means already under water at the mined fee.
Watch out. tr/yr·a counts positions opened, turn/yr counts money moved. A formula can open few positions yet move a lot of money resizing them.
6.15robust
default shown by defaultThe worst TEST Sharpe of four re-runs of the formula: on each half of the universe split by dollar volume, and with every window scaled by 0.8 and by 1.2. Read it against TEST OOS: close means the edge survived its own perturbation; far below means the row was fitted to this exact universe and horizon. The alpha card lists the four probes.
Watch out. Half a universe is noisier than the whole, so some drop is normal, and under six pairs the halves mean little. Evidence about fragility, not a licence to pick rows by it.
6.16DSR
default optional columnThe Deflated Sharpe ratio of Bailey and López de Prado: the probability that the row's selection-span Sharpe genuinely beats what this many search trials reach by luck alone. The node counts every formula it evaluates; the row's Sharpe is tested against the expected best-of-N, corrected for track length, skew and fat tails. The per-row form of "out of how many attempts?".
Watch out. Expect small numbers: a champion is the maximum of many trials, which is why the evidence for a formula lives in TEST and the forward track, never in fitness. A dash means the node has not logged its trials yet.
Part 07What you can do with a formula
Everything reachable from a leaderboard row: the equity window and its buttons, the table's menus and exports, and the two buttons that can destroy work.
7.01Double-click a row → the equity window
Growth of $1 on a log scale, shaded into TRAIN | VAL | TEST, with the equal-weight buy-and-hold basket alongside; all curves net of fees. A lower panel tracks the unrealised profit of open positions. You are looking for a curve that keeps its shape across the boundaries rather than one lucky stretch. Wheel to zoom, drag to pan.
Watch out. A double-click landing in the ★ cell toggles the star twice and opens nothing. If a double-click does nothing, you hit the first column.
7.02Passport
An explanation of the formula rather than a measurement: the expression as a labelled tree, plain-English reading steps, the signal against one asset's price, an ablation of which inputs it depends on, its holding period and long/short balance, and the classic archetype its returns most resemble. No network, no AI. Use it when a formula looks good and you want to know why before trusting it.
Watch out. An explanation is not evidence. The order is always TEST first, forward track second, story third.
7.03PDF report
A four-page analytics dashboard written where you choose: headline numbers with equity and drawdown; exposure, long/short balance and turnover over time; the weights and a monthly-return calendar; a TRAIN/VAL/TEST breakdown with written conclusions. Every page is stamped with the date, the time and the 6-char ID. The artefact to keep or hand to someone else. The Portfolio card has the same button for a combined book.
7.04Serve signal (API)
Starts a small local web service that keeps this formula's live target positions available as JSON: it fetches fresh closed candles, recomputes the weights and serves the latest bar at /signal, with /health reporting its age. It claims the next free port from 8799 and appears in the SIGNAL API card; at most 10 services run at once. Point your execution code at http://127.0.0.1:<port>/signal. Refreshed every 15 minutes on 1d and 4h, every 5 on 1h and 15m.
Watch out. On daily bars the response carries "leverage" separately and the weights are the relative book; on intraday the weight already includes leverage and the served leverage is 1.0. Weight × leverage × equity is what stays identical between the two.
7.05Download signals (CSV)
The full position history: one row per asset per bar where it held a position, with its segment, the ticker, LONG or SHORT, the signed weight and that asset's OHLCV. A dialog then shows what the strategy would hold on the very last bar, the quick "what do I buy right now" answer.
Watch out. These weights are the normalised target book before volatility targeting: relative allocations, not position sizes.
7.06Forward track ➕, and the forward chart
Enrols this alpha: frozen exactly as it stands and paper-traded once per closed bar from a clean $10,000. Do it the moment a formula survives TEST and looks explainable; this is the only clock that runs forward. The entry also freezes the row's TEST segment (Sharpe, return, CAGR, max drawdown, win rate, bars, turnover and dates) as its promise: the SEALED column is that Sharpe, and a book hosted on AlphaHub shows the whole block as "promised by AlphaNode" (9.03). Double-click a row of the FORWARD TRACK panel for its forward chart, one point per live step, never fitted to anything. Give it weeks before reading anything into it.
Watch out. Enrolling the same formula twice is refused. Steps happen only while something runs: the open app, or a mining node on the same state folder. Nothing is backfilled: the frozen book rides through a gap, which costs most on intraday bars.
7.07★ Favorites
The button in the leaderboard heading opens your starred list: date added, ID, timeframe, fitness, TEST OOS and the formula; double-click for the chart. Stars live in their own file outside the library, so they survive "Clear all history". They belong to the session: saving a session saves its stars, loading one replaces them.
Watch out. A favourite is a snapshot, never refreshed: change target vol, fees or dates and the leaderboard's numbers move while the Favorites window's do not.
7.08Right-click a row → Copy formula / Copy formula + metrics
The plain copy (also Ctrl+C) puts the bare expression on the clipboard, for pasting into code. The +metrics version adds one line with the fitness, a note if it was mined by win rate, and the TRAIN, VAL and TEST Sharpe, for notes that stay readable months later.
7.09Right-click a header → the Columns menu
default on: ID, maxDD, CAGR, T↑, T↓, T~, L/S %, win↑, win↓ · off: sortino, L/S /yr·a, tr/yr·aA checklist of the optional columns; your choice is saved and reused next launch. ★, #, fitness, TEST OOS and formula are always present. Turn L/S /yr·a and tr/yr·a on the moment you care whether an alpha is two-sided or how much its fee assumption matters.
Watch out. Column order is fixed and follows the menu. Hiding a column only hides it: sorting still uses the hidden value, and "Export table" writes every column whatever is on screen.
7.10Sorting
default opens on fitness, descending — not remembered between launchesClicking a header sorts by it, best first; clicking again flips. Only fitness and TEST OOS change which formulas the table contains; every other column reorders what is already there.
Watch out. Sorting by a recomputed column computes that statistic for every row, a long job on a large library. Rows with no value sort as minus infinity, so ascending puts the dashes at the top.
7.11The two CSV exports
"Export table (CSV)…" (right-click) writes exactly the rows in the table, in the current order, with every leaderboard metric plus the TRAIN and VAL Sharpe and the objective. Filter and sort first, then export. "Export full library (CSV)…" (the CSV button in the heading) writes every alpha ever mined into this timeframe's library, with the round, the timestamp and the stored Sharpe / drawdown / CAGR / active bars per segment. It reads the file directly, so it works while the node mines.
Watch out. The table export's recomputed cells come from a cache filled a screenful at a time: sort by one of them first, or the rows you never scrolled to come out blank there. The library export carries none of the recomputed columns.
7.12▶ Build portfolio
default top 6, by TEST · neither is saved — both reset every launchRuns N alphas together as one book and shows the combined curve against buy-and-hold. When a build finishes the member list fills in and four buttons unlock: CSV (combined signals), Serve (one API for the whole book), PDF and Track (enrol the whole portfolio). Prefer "fitness" or "combo" over the default (5.06). The fourth choice, selected, builds from the rows you Ctrl- or Shift-clicked in the leaderboard; TEST was on screen while you picked, so read the result as a shortlist for the forward track. Every successful build is kept under SAVED PORTFOLIOS: double-click a row to put it back on the card as the last build, Delete to forget it. Headless it is portfolio list, portfolio forget ID… and portfolio open ID.
Watch out. Because neither setting persists, a habit of building by fitness has to be re-established every session. On a sealed library the build is a preview (7.15) and no button unlocks. "Clear all history" deletes the built portfolio and every saved one.
7.13"families only" switch
default off — every alpha shownCollapses the table to the best representative per family, where two formulas are the same family when their text is 80% or more similar. Turn it on when the top of your table is fifty cosmetic rewrites of one expression. Remembered across restarts.
Watch out. Capped twice: at most 20 families, collected from the top 500 rows only. A novel formula at rank 600 is invisible here.
7.14Clear all history / Clear node
The red button in the settings panel. It deletes the mined libraries, the round history, the status file, the built and saved portfolios, the session contract and the cached return series, after showing a count. Settings, favourites and the forward track survive. It starts a new session id, refuses while the node mines, and is the way out of a contract conflict: with the library gone, the ★ fields may be set to anything.
Watch out. It clears every timeframe while the counts in the dialog come from the current one, so "40 found alphas" can be about to delete thousands. Save a session first, because nothing else offers a way back.
7.15The sealed preview (no activation key)
Without a key the node cannot hand the builder a formula, so it hands it the next best thing: for every champion it also caches that champion's realised return series (state/series/, the top 100 by fitness). A return series carries no forward signal, so nothing tradeable leaves the vault, yet it is exactly what the combination search needs. The card runs the same search over the cached series, says "sealed preview", and Signal API, Report PDF and Forward track stay disabled. Activate, and the next build uses the real engine on the revealed formulas; the numbers move a little.
Watch out. Rows mined before 3.1.2 have no cached series and do not enter the preview. A preview is not a book: it is what the search optimises, not what Serve would trade.
Part 08The server — the dashboard in Docker
AlphaNode on a machine with no screen: one compose file builds the node from the same .deb the download page serves, and the dashboard of Parts 01–07 is served as a web page on the server's loopback. This part covers only what differs from the desktop. A grey block is something to type as it stands.
8.01Install — one file, one command
default Docker Compose v2.17 or newer · the image is built on your boxDownload the compose file from the download page into an empty folder of its own and start it:
# a folder of its own mkdir alphanode-node && cd alphanode-node curl -fsSLO https://alphanode.tech/dl/docker-compose.yml # builds the image from the .deb, starts the dashboard docker compose up -d --build # the login line (the next item) docker compose logs alphanode
The file carries its own Dockerfile: it fetches the .deb (about 130 MB), installs it into a small Debian image and runs the dashboard. No registry, no account. Everything the node writes goes into a named volume (8.11), so the container itself is disposable.
Watch out. curl -fsSLO overwrites a docker-compose.yml already in the folder. Compose v1 (docker-compose with a hyphen) does not understand the inline Dockerfile. The build needs alphanode.tech; the running node needs Binance and api.alphanode.tech.
8.02Reaching the dashboard, and the login
default 127.0.0.1:8787 on the server · user alphanode · password generated on the first startThe dashboard listens on the server's own loopback on purpose: it controls the node, takes your key and shows your formulas, over plain HTTP. From your desk, open an SSH tunnel; for a permanent address put a certificate in front of it, which Caddy does in one line:
# keep this terminal open, then browse http://127.0.0.1:8787 on your own machine ssh -L 8787:127.0.0.1:8787 user@your-server # or, with ports 80 and 443 open and a DNS name pointing at the server caddy reverse-proxy --from node.your-domain.com --to 127.0.0.1:8787
The login is HTTP Basic auth, user alphanode. The password is the one you set as ALPHANODE_WEB_PASSWORD in the compose file (never printed), or one generated on the first start, printed once and kept in the volume:
docker compose logs alphanode | grep password
Ten wrong passwords within a minute block that address for the minute. ALPHANODE_WEB_PASSWORD=none switches the login off, meant for a page reachable only through a tunnel.
Watch out. Changing the ports line to "8787:8787" publishes the page on every interface over plain HTTP, password and formulas included. The login also guards the signal endpoints (8.08). The node's own status page (3.06) is off inside the container.
8.03The first Start, and restarts
default ALPHANODE_AUTOSTART=auto — nothing mines until you press StartA fresh container does what a fresh desktop install does: nothing. The dashboard comes up with the node stopped; look through the settings, then press Start, which runs the desktop's gates (1.05) and downloads the market data into the volume. From then on the node is remembered: after a reboot or a container restart it comes back by itself if it was running, and stays stopped if you stopped it. ALPHANODE_AUTOSTART=1 starts the node at every boot without anyone opening a browser; ALPHANODE_AUTOSTART=0 never starts it from the boot.
Watch out. Stop on the dashboard, docker compose stop, a reboot and docker compose restart all abandon the round in flight, and Compose waits only ten seconds before killing the container. Use docker compose stop -t 120 if the round matters.
8.04What the browser dashboard is — and is not
default the dashboard of Parts 01–07, served as a web pageSearch settings with the desktop's rules, Start and Stop, the progress chart and tiles, the live log, the leaderboard (sorted by TEST by default here), the alpha card with Forward track +, Download signals, Serve signal, PDF report and Passport, the portfolio builder, the forward track with its "host on AlphaHub" button per row (Part 9), the Signals tab and the Licence tab. Every heavy step runs as a job with its own log; a failed job is one red line, never a dead dashboard.
Watch out. Not on the page: Sessions, Favorites, the two CSV exports, a portfolio's selector, deleting a forward-track entry. The volume holds the same files the desktop uses (8.11), so anything the page cannot do, the desktop can, on a copy of its state/ folder.
8.05Settings from the compose file
default the form opens on the compose file's ALPHANODE_* values; a saved form winsThe commented lines under environment: (ALPHANODE_TF, ALPHANODE_CPU_PERCENT, ALPHANODE_UNIVERSE and every other ALPHANODE_* key) are the values the settings form opens with on a fresh volume. Once you save the form (Start saves it), its values live in the volume and win; editing the compose file afterwards changes nothing until the matching field is changed on the page.
# docker-compose.yml, under environment: — uncomment what you want to change
- ALPHANODE_TF=4h
- ALPHANODE_CPU_PERCENT=80
- ALPHANODE_UNIVERSE=BTCUSDT,ETHUSDT,SOLUSDT
Watch out. The ★ contract fields are contract fields here too: a different bar size or basket in the compose file does not move a library that already exists. Start answers with the differences and offers Revert or Clear.
8.06Activating on a server
default the key lives in the volume; re-checked at every startThree ways to the same state. The Licence tab: paste the key, press Activate; with the node running the activation is queued until the round ends. The terminal, or the compose file:
docker compose run --rm alphanode alphanode --role cli activate YOUR-KEY # a node that was running reads the key at its next start docker compose restart alphanode # or, in docker-compose.yml under environment: the node activates itself at every start - ALPHANODE_VAULT_LICENSE=YOUR-KEY
The key is stored in the volume and the seat this server claims is one of your plan's. At every start the node asks the licence server for a fresh grant; if the server is unreachable it keeps mining in the open for up to three days, then mines sealed until the next successful check. Every sealed row opens at the next activation.
Watch out. A key already on as many machines as the plan allows is refused with the seat count. The device identity is in the volume: read 8.11 before deleting it.
8.07The terminal — the CLI inside the container
default docker compose run --rm alphanode alphanode --role cli …alphanode --role cli is the same program in the terminal, and docker compose run --rm alphanode … runs it in a throwaway container on the same volume:
# the leaderboard; --stats, --sort test, --all docker compose run --rm alphanode alphanode --role cli top -n 20 # that bar size's library docker compose run --rm alphanode alphanode --role cli top --tf 4h docker compose run --rm alphanode alphanode --role cli status # also: forward step docker compose run --rm alphanode alphanode --role cli forward list # or --rank 1 docker compose run --rm alphanode alphanode --role cli forward enrol --id 3f9a1c docker compose run --rm alphanode alphanode --role cli portfolio --top 6 # Part 9: hand a forward entry to AlphaHub; "network unhost ID" takes it back docker compose run --rm alphanode alphanode --role cli network host 3f9a1c --yes # every hosted book with the hub's numbers docker compose run --rm alphanode alphanode --role cli network hosted # the Autopilot's tail on a stopped node (--host hands the books to AlphaHub) docker compose run --rm alphanode alphanode --role cli autopilot docker compose run --rm alphanode alphanode --role cli activate YOUR-KEY
--tf 4h picks that bar size's library; the default is ALPHANODE_TF from the compose file, else 1d. --id takes the id the leaderboard shows. A sealed row prints as locked · id.
Watch out. Never run the run command this way: it starts a second miner on the same library. The CLI reads its dates, target vol and fee from the shipped defaults plus the compose environment, not from the form you saved on the page, so enrol from the page when the two differ.
8.08Signals from outside
default through the dashboard, with its login · up to 10 servicesServe from the alpha card, the portfolio card or a forward-track row, as on the desktop; each service takes the next free port from 8799 inside the container and gets a row on the Signals tab. From outside they are read through the dashboard's one published port, under its login:
# what is being served curl -u alphanode:PASSWORD http://127.0.0.1:8787/signal # target positions of the service on 8799 curl -u alphanode:PASSWORD http://127.0.0.1:8787/signal/8799/signal # its heartbeat curl -u alphanode:PASSWORD http://127.0.0.1:8787/signal/8799/health
The Copy URL button on a row gives exactly that address. Positions are recomputed every 15 minutes (5 on 1h and 15m bars). Services survive a restart of the container.
Watch out. A signal URL carries the dashboard password, so it is a secret in its own right. Serving stops when the container stops: a bot must treat a failed read as "hold", never as "flat". Advisory target positions only: no orders, no keys.
8.09Resources
default cpus: 4.0 · mem_limit: 6g in the compose file · CPU share 50% insideTwo ceilings stacked. The compose file caps the container (cpus on cores, mem_limit on memory); inside it the CPU share (3.01) picks how many workers the node runs out of the cores it sees. The search scales linearly with cores, so the compose line is the real throttle. 6 GB covers daily and 4h searches; on 15m bars with many pairs watch docker stats.
Watch out. A memory limit hit is a silent kill: the node restarts, the round is lost, and only docker inspect shows OOMKilled.
8.10Updating
default docker compose build --no-cache && docker compose up -dThe image is built from whatever .deb the download page serves at build time, so an update is a rebuild: --no-cache fetches the file again, up -d swaps the container. The volume is untouched, and a node that was running comes back by itself.
docker compose build --no-cache && docker compose up -d
Watch out. The rebuild restarts the node like a reboot: the round in flight is lost. The compose file does not update itself: curl -fsSLO it again when the release notes say it changed.
8.11The volume — what lives there, and backing it up
default alphanode_state, mounted at /root/.local/share/AlphaNodeCompose prefixes the volume with the folder's name (alphanode-node_alphanode_state for a folder called alphanode-node), and that full name is what the commands take. Inside: the container's copy of the folder of 2.04, config/ with the licence store, the dashboard's own settings, password and served-signal list, and the node log.
# the full name docker volume ls | grep alphanode_state # back up the whole volume into the current folder docker run --rm -v alphanode-node_alphanode_state:/s -v "$PWD":/b debian tar czf /b/alphanode-state.tgz -C /s . # restore into a fresh volume docker run --rm -v alphanode-node_alphanode_state:/s -v "$PWD":/b debian tar xzf /b/alphanode-state.tgz -C /s
A copy of state/ dropped into a desktop install's folder opens the same library in the desktop app.
Watch out. docker compose down -v deletes the volume: the library, the key and the node identity. A new volume is a new machine to the licence server and claims another seat of your plan. Stop with docker compose down (no -v) or docker compose stop.
Part 09The AlphaHub Network — your forward, stepped by the hub
AlphaHub is the vendor's server, the one that activates nodes, and the Network is its public page: strategies that nodes handed to the hub, stepped by the hub itself after every closed bar and shown with the hub's own numbers. Hosting is free and optional; a hosted strategy can be put on sale, and a buyer pays its author directly from a wallet. Everything here needs an activated node: a sealed formula cannot be hosted.
9.01What hosting is
default nothing is hosted until you press AlphaHub · 10 books per nodeHosting hands the hub a copy of a forward-track entry: its bar size, pairs, fee, target vol, book mode and formulas, sealed to the hub's key and bound to your node. From the next closed bar the hub steps the book itself with the same engine, the same trading cost and the perpetual funding, whether your app runs or not. There is no backfill: the hub's numbers begin at the first bar after hosting, and your own track keeps stepping from its own enrolment. The hub shows numbers and never the formula, and says "simulated on market data — not a live account" under every strategy.
Watch out. Ten books per node. The hub never misses a bar and your app does when it is closed, so the two tracks drift apart after a gap. A book whose formula fails on the hub reads "halted"; one not stepped for two closed bars reads "behind".
9.02AlphaHub (Forward Track panel) — host, see the hub's numbers, stop hosting
Select a forward-track row and press AlphaHub: a dialog says what leaves and asks once; hosted, the row's kind reads "· hub". Tick several rows and the button hosts every ticked one after a single confirmation. Press it on a hosted row and you get the hub's own numbers for that book and "Stop hosting", which deletes the hub's track and its sealed formulas; your own track stays. The browser dashboard has the same button per row; the terminal has network host ID --yes, network unhost ID and network hosted (8.07); the Autopilot (3.13) hosts what it enrols when asked.
Watch out. A sealed row answers "activate the node to host it". Stop hosting is final for the hub's track: hosting again starts the hub's count from zero bars. The promise block of the next item travels only with entries enrolled by this version or a newer one.
9.03The Network page — what everyone sees
default alphanode.tech/network.html · free to browse, no accountThe list: a strategy's public id (not your entry id) and its node's tag, its kind and bar, its pairs, hosted since, the bars run, the return since hosting, the Sharpe (from thirty bars on), the confidence, the max drawdown, the status (live, behind, halted) and the last bar. Confidence is the chance that the true Sharpe is above zero given how long the strategy has run; it sits near 50% until the track is long enough to mean something. Open a row: the return bar by bar and the drawdown, the facts, the Sharpe beside "promised X by AlphaNode", and "Backtest · promised by AlphaNode": the TEST numbers the author's node measured before hosting (7.06). The page says it plainly: measured by the node, which the hub cannot verify, and a strategy picked among many reads better on its test than it will live. The track above it is the test that counts. A star adds the strategy to your favourites; "follow node" follows every strategy of that node.
Watch out. Nothing on the page leads back to your machine, your name or your entry id. Your own tag and your strategies' public ids are shown where you host: the AlphaHub button on a hosted row, the dashboard's hosted lines and network hosted print them; the app's "node" id is a different number and never leaves the machine. A strategy stopped by its author leaves the list; what it earned stays on record for the people who bought it.
9.04Selling the signals — the market
default not on sale · a price in USDT per 30 days · the author gets 80%, on the spotWhat a hosted strategy holds after every bar is the author's until they put it on sale from the account page: link a wallet, pick a hosted book and a price in USDT for 30 days. A book can be listed only after its bar's minimum on the hub: 15 days at 1d, a week at 4h, four days at 1h, two days at 15m. A buyer needs no account: their wallet signs them in at Subscribe, and the payment goes through the splitter contract on the chain, 80% to the author's wallet and 20% to the hub in one transaction. The hub holds no money and no key. The buyer then sees the SIGNALS box under the strategy after every bar and can read the same answer with a bot through the account API. A purchase runs 30 days; paying again in its last days adds 30 more.
Watch out. A paid period is never cut short: stop selling or stop hosting and the buyers' days keep running. The author was paid directly, so there is nothing to refund from. The node licence plans are a separate thing, bought from a wallet with a mailed code.
9.05Your account on the site
default alphanode.tech/account.html · the key from your plan, or a wallet · a mailed code for a lost keyLog in with the key that came with your plan, or with the wallet you buy strategies with: the wallet signs a free message and AlphaHub keeps the account behind it, no e-mail needed. A lost key comes back by a code mailed to the account's address. The page has five parts. Signals: what each strategy you follow or bought holds after its last closed bar, as shares of capital, long to the right and short to the left; refreshed every minute. My subscriptions: the strategies you bought, each payment 30 days paid from your wallet straight to the author; nothing is charged by itself, and in the last 7 days you can pay again on the Network page to add 30 more. My strategies: your hosted books, named as the Network names them (the public id and your node's tag, both shown by the app on a hosted row), with a price box and "sell" once a book has run on the hub long enough for its bar, "stop selling", and "delete", which is Stop hosting; the wallet you link here is where 80% of each sale lands. Favourites: the strategies you starred and the nodes you follow. Connect a bot: the same signals as JSON for your own code, the next item. The header holds "New key" and "Log out".
Watch out. A new key stops the old one everywhere at once, so every node you run must be re-activated. Deleting a hosted strategy here is Stop hosting with no second dialog in the app. A new price reaches the next payments only; stopping a sale takes no days from anyone.
9.06Connect a bot — the signals API
default POST api.alphanode.tech/account/signals · the account key in the body · ask once a barThe same signals the account page shows come as JSON to anything holding your key: your own bot, a script, a webhook relay. One POST with the key in the body. Without ids the answer holds every strategy you bought and your favourites; with "ids": ["…"] just those strategies, by the public ids the Network page shows. Ask once per bar, a few seconds after it closes: the hub steps a book right after the close, and closed and next in the answer say which bar you are looking at and when the next one ends. Your exchange keys never leave your machine: the hub hands out target shares, never orders.
# the signals of your bought strategies and favourites, as JSON curl -s -X POST https://api.alphanode.tech/account/signals \ -H "Content-Type: application/json" \ -d '{"token": "YOUR_KEY"}' # just these strategies curl -s -X POST https://api.alphanode.tech/account/signals \ -H "Content-Type: application/json" \ -d '{"token": "YOUR_KEY", "ids": ["3f9a1b2c4d5e"]}'
The answer is signals, one object per strategy: its public numbers (id, node, kind, tf, status, steps, ret, sharpe, conf, dd, last), its price and your bought_until; and, for a strategy you bought, bar (the last closed bar it was stepped on), prev_bar, closed, next, and positions: one entry per pair with t the ticker, w the signed share of capital to hold (0.25 = long a quarter of your capital, −0.1 = short a tenth) and prev the share before this bar, with gross and net summing them. A strategy you have not bought carries positions: null and locked: "buy" when it is on sale, "author" when its author has not opened it. gone lists the ids you asked for that are no longer hosted. Without a single purchase, and without ids, the hub answers 402.
Watch out. The key in that body is your account key: it also activates your nodes, so keep it out of logs and shared machines; if it leaks, issue a new one on the account page and the old one stops everywhere at once. Positions are target shares after a closed bar, not orders: a bot sizes them on its own capital and treats a failed read as "hold", never as "flat". Simulated on market data, not a live account.
9.07What the hub knows about your node
default a technical snapshot with every host · formulas sealed · no names, paths or addressesWith every host the node sends a technical snapshot of itself: the version and build, the operating system, the CPU model and its cores, the memory, and how it runs (desktop, browser dashboard, terminal, Docker); never a user name, a path, an address or a formula. It is kept only while you host something. Your formulas reach the hub sealed to its key; the hub stores them sealed and shows them to nobody.
Watch out. Sealed to the hub's key means the hub can open them; it has to, to step the book. The vault protects your formula from the public and from other users, not from the vendor; that is the trade for a track nobody can backdate. If you do not want that trade, keep the strategy on your own forward track and off the Network.