Method rule, pre-registered

Method portfolio · v0b.15

Method version: v0b.15 · dated as of go-live

Changes in v0b.15, 8 October 2026: every day after the portfolio is valued we record the class of every ticker analysed on the site, with its reason, axis scores and the session's closing price, and the SPY price at the same session. A ticker without a class is recorded too, with its reason. A recorded day never changes, and the record's hash goes into the daily hash. The check of whether the classes predict returns was pre-registered before any data existed, and the document's sha256 is in the first version 5 daily hash. The class rule did not change: no class, trade or portfolio value changes because of this.

Changes in v0b.14, 7 October 2026: corporate actions are now recorded automatically, each as its own ledger row. Splits are looked up every night in one request for every position and SPY, so a split the run did not see on its night is applied on the night it is found; records already written on the old share count stay and are flagged, the fix is forward only. A split changes the share count from the first session on the new basis, and the value record always multiplies the count by the raw close of that same session, never by a price adjusted after the fact. A SPY split is counted in the benchmark. Spun-off shares are converted to cash at their value on the first session after the spin-off, unless SEC shows a charter amendment for a split; when the new company's price gives a different amount (up to 30 %), the lower one is credited and the gap is flagged. A merger, a take-private, a delisting and a bankruptcy are read from SEC filings: the position is closed at the last traded session's close (or at the deal's cash when it is within 2 % of that close), 4 or more identical closes the provider repeats after trading ended are not a price, and a bankrupt position with no session after the filing for 10 days is written off to zero with the dispute open. A ticker change is not a trade: prices are read by the new ticker. A special dividend (10 % of the price or more, or the second in a quarter) is credited as a dividend, and the provider's split on the same day that the dividend itself explains is not applied. An unclear action is never guessed: for the first 3 nights no record is written, then the position is frozen at its last close before the action, and after 30 days it is closed at that close with the dispute open; if nothing has confirmed the action in that time (no SEC date, no end of trading, no price move by the split factor) and the position still trades normally, the suspicion is dropped with no trade and valuation resumes. From v0b.14 the daily hash also covers these ledger rows. Past records, events and hashes are kept as they were recorded.

Changes in v0b.13, 7 October 2026: brokers (SCHW, HOOD) get a descriptive model instead of "model in preparation", like investment banks from v0b.7. Broker metrics are shown descriptively: there are too few comparable companies for a class. They are compared with one group of 7 brokers (SCHW, HOOD, IBKR, LPLA, RJF, SF, OPY): return on common equity, revenue and earnings per share over the year, assets to equity, P/B and P/E stand next to the values of the other companies in the group, without a rank, a median or a class. With no class there are no new buys of these tickers, and the freeze rule with the deadline of 31 December 2026 still applies to them. The portfolio holds no SCHW or HOOD position, so no position changes.

Changes in v0b.12, 7 October 2026: a trade that opens or closes a position now fills at the close of the same session at which the whole value record of that day is valued. The run first picks the session, then makes the trades. Before, a trade took the provider's latest price before the session was picked, so on a trade night the cash and the positions in the record could stand on different sessions. The fill session is recorded with the trade, and the dividend entitlement and the split check count from it. If no session can be set, that day has neither a record nor trades. A candidate to buy with no close at that session waits for a later run that has its close and does not move the record's session. If the signal behind a trade already saw a close newer than that session, the trade also waits for the next run, so a fill is never older than its signal. A record's session is never older than the previous record's: otherwise that day has neither a record nor trades. Past trades are kept as they were made. Separately: for 14 companies with an off-calendar fiscal year the quarter check between AlphaVantage and Finnhub now works, so for 7 companies (ADBE, AVGO, COST, CSCO, HD, INTU, WMT) the shown quarter count changed and disputed quarters appeared; no class changed.

Changes in v0b.11, 6 October 2026: each daily value record now values every open position and SPY at the closing prices of one and the same trading session, the latest one for which every price has a close. A price that is already newer than that session is read again for that session, and the session is stored with the record. The fallback source for the SPY price (Finnhub) is used only when its price belongs to that session, and such a record is flagged. If any price for the session is missing, there is no record for that day. A position without a fresh price is still valued at its last known price, and the record says so; the other prices are then taken at that price's session, unless it is more than 10 days old. Correction: on weekdays from 11 September to 5 October 2026 the records valued SPY and some positions at different sessions, mostly one session apart, which moved the daily alpha by up to 1.4 percentage points. Those records are kept as they were made.

Changes in v0b.10, 5 October 2026: the portfolio and its benchmark now count dividends, so the return and the alpha are shown with dividends. A dividend belongs to a position held at the close of the session before the ex-date: the share count times the amount per share, in US dollars, with no tax withheld. From the ex-date to the pay date the amount counts in the value as a dividend receivable; from the pay date it is cash. Nothing is reinvested, in the portfolio or in SPY. Dividends from the portfolio's start up to this change are credited in one entry on the same day, listing every dividend; earlier value and hash records were not changed, so the chart shows a step that day. A dividend whose amount or entitlement could not be confirmed is not credited and is listed among the known gaps; while an SPY dividend is missing, the comparison is marked incomplete. Separately: a split is now checked from the session whose closing price filled the position, not from the date the event was recorded.

Changes in v0b.9, 5 October 2026: for deposit banks and property and casualty insurers, the consensus versus reality check is now computed within their own group, not across the whole financial sector, where payment networks, brokers and insurers sit next to banks. The company's forward P/E (the analysts' estimate for next year) is ranked among the companies of its group, and realized growth is taken from the sector model itself: net revenue (net premiums written for insurers) and earnings per share over the year. If the company is dearer than most of its group and grows more slowly than most (both scores at 40 or below), the "Passes the quality and price filter" class is lowered to "Partly passes". If fewer than 8 other companies in the group have a forward P/E, there is no check: no downgrade and no upgrade. The check can only lower a class and never adds one; the model's business and price lines still apply. Investment banks (GS, JEF) get no forward P/E rank. On the day of the change none of JPM, BAC and PGR had the "Passes the quality and price filter" class, so their classes did not change. Separately, for every company: the beat score in the outlook axis is now computed from the same record of quarters the page shows, that is up to the 8 latest quarters from AlphaVantage, each checked against Finnhub, and a quarter where the sources disagree is not counted. Before, the score took only 4 quarters from Finnhub, and the page and the score could call the same quarter differently. On the data of the day of the change, AMZN and VZ move from "Does not pass the filter" to "Partly passes", and no company's "Passes the quality and price filter" class changed.

Changes in v0b.8, 5 October 2026: the age of the data is now measured from the day the rule is applied, not from the date of the calculation itself. If the company's calculation is more than 15 days old, or a sector model's comparison with its group more than 16 days old, there is no class. Nothing new is bought in such a ticker, and a held position is kept with no exit and no top-up until the data is refreshed. The exit at the sector-model deadline of 31 December 2026 still applies: it depends on the type of business, not on the data.

Changes in v0b.7, 4 October 2026: deposit banks and property and casualty insurers get their class from their own sector models instead of "model in preparation". They are compared with a group of companies in the same business (13 banks, 11 insurers) on profitability, risk, growth and price, with the same price lines of 40 and 30; there is no composite of 70 for them. A bank's risk is measured by net charge-offs as a share of net revenue, not of loans. At its first classification by the model, a position opened before the model is kept only if the model confirms the "Passes the quality and price filter" class; otherwise it is closed in one event with the reason "assessed by the sector model: class not confirmed". After that such a position follows the shared rule. Transitions: JPM: "Partly passes"; BAC: "Partly passes"; PGR: "Partly passes".

Changes in v0b.6, 27 September 2026: when data the rule needs is missing, there is no class, and it no longer reads as Does not pass the filter; a held position is carried and nothing new is bought. Banks, brokers and property and casualty insurers get no class until they have their own sector model; their positions are frozen until 31 December 2026. Price is now a separate condition: a new "Passes the quality and price filter" class needs a valuation against the sector of at least 40 out of 100, and a position the portfolio already holds is closed on price only below 30. A class needs a broad enough sector comparison: at least 8 peers, 8 of 12 metrics ranked among them, and all four metric groups; otherwise there is no class, as with missing data. The number of analysts no longer moves the outlook axis, and forward P/E is compared with sector peers. The positive class is now called "Passes the quality and price filter" (formerly "Shortlist"); the new name does not change the rule's conditions.

Changes in v0b.5, 26 September 2026: a position with no fresh price is no longer force-closed but valued at its last price; new positions open from free cash only.

This document is published in advance, before the portfolio has any track record. Anyone can compare the actual trades against this rule and check that the terms were not changed after the fact.

01

Selection

The portfolio tracks positions only for tickers that carry the public "Passes the quality and price filter" classification, the same one shown on the /en/[ticker] page.

The classification's conditions (all must hold at once):

  • Quality passed: the business shows steady profitability and financial strength on the method's quality axis.
  • Growth passed: EPS and revenue from SEC filings are rising on the method's growth axis.
  • Composite ≥ 70: the method's weighted composite (quality 25 · valuation 25 · growth 20 · outlook 15 · health 15) is at least 70 out of 100.
  • Price ≥ 40: the valuation against the sector (percentile of the valuation multiples, 0 to 100; higher means cheaper than the sector) is at least 40. For a position the portfolio already holds the line is lower, 30; see "Price exit line".

No narrower filter, no arbitrary top-N. Entry and exit follow this classification alone, with no manual selection.

Clarification: the composite weights above are generated from the code that computes the composite, so this text follows the formula that actually runs. If a company has no outlook score, its share is spread across the other axes in proportion to their weights. Earlier versions of this page listed different weights; the ones above are current.

02

Entry and exit: mechanics

  • Equal weight, fixed slot. Each position takes exactly $1250 of starting capital. 8 slots in total.
  • Limit: no more than 8 positions open at once. When candidates outnumber free slots, priority goes by composite (descending); ties break by ticker (alphabetical); the rest wait in a queue.
  • Free cash only. A new position opens only if the portfolio's free cash covers a full $1250 slot: no borrowing, no partial positions. If cash falls short, the candidate stays in the queue until a session when it is enough, and the reason is recorded in the operations log. Exits in the same session are filled first, so the cash they free up can fund new positions right away.
  • Entry and exit price. A trade fills in the daily run that first sees the signal, at the close of the session at which that run values the whole value record. No look-ahead: the price is fixed after the signal, not before.
  • No discretion. No manual departures from the rule: when the classification changes, the position closes; when it appears, the position opens. A price between 30 and 40 does not close a position already held, and no class because data is missing, or because the method does not apply, closes none; see the points below.
  • Swings, no delay. A change between the "Passes the quality and price filter" classification and any other is acted on at once, with no holding period. The one difference between entry and exit is price; see the next point. Frequent swings show up in the log as they are.
  • Price exit line. A new position opens only at a price of at least 40. A position the portfolio already holds is closed on price only when it drops below 30; between 30 and 40 it is kept if the other conditions hold. That way a ticker sitting near 40 is not bought and sold each time its valuation moves a little. Both lines are the same for every ticker and fixed in advance. The ticker page shows the class under the entry rule.
  • No price or delisting. If the provider has no fresh price, the position is not closed and no cash is released: it is valued at the last close the provider does have, and that day's NAV record is flagged as carried. If there is no such price at all, no NAV is recorded for that day. A position is closed only when there has been no fresh price for 5 daily runs in a row and the last trading session was more than 30 days ago. Trading is then treated as ended, the position is closed at that last price, and the reason is recorded. We don't know the actual delisting or buyout payout, and the record does not guess it. From v0b.14 a merger, a take-private, a delisting and a bankruptcy are first read from SEC filings, see "Corporate actions"; this rule stays as the fallback when SEC is silent, and 4 or more identical closes in a row that the provider repeats after trading ended are not a fresh price.
  • Data missing for the classification. If a figure the rule needs is missing, there is no class. A held position is not closed: it is carried and marked "classification not updated". Nothing new is bought in that ticker until the data is back.
  • Stale data. A class is given on fresh data only: on the day of the daily run, the company's calculation must be no more than 15 days old, and a sector model's comparison with its group no more than 16 days old. Otherwise there is no class: the ticker stays among the analysed ones, nothing new is bought in it, and a held position is neither closed nor topped up until the data is refreshed. A first classification by a sector model also waits for fresh data. One exception: the exit at the sector-model deadline of 31 December 2026 applies even on stale data, because it depends on the type of business, not on the data.
  • Sector models for banks and insurers. Deposit banks and property and casualty insurers are classified not by the general method but by their own sector model, which compares the company with a group of companies in the same business. The "Passes the quality and price filter" class needs all of these at once: profitability of 50 or more out of 100 against the group; growth over the year in net revenue (for an insurer, net premiums written) and in earnings per share; risk of 30 or more; price of 40 or more (30 or more for a position the portfolio already holds). Two or three of the three business criteria failed give "Does not pass the filter", everything else "Partly passes". These models have no composite of 70, because their scale is different; candidates are ranked by the model's "Business" score. A missing metric means no class, not a fail.
  • Positions opened before the sector model. For a position the portfolio opened before the ticker's sector model started classifying it, the first classification applies once: on the first daily run where the model gives that position a result and that session's close can be fetched (if it cannot, nothing is recorded and the next run decides again). If the model confirms the "Passes the quality and price filter" class under the rule for a held position, the position is kept, and the journal gets one no-trade record with the reason "assessed by the sector model: class confirmed, position kept". Otherwise the position is closed in one event at that session's close with the reason "assessed by the sector model: class not confirmed". Before 31 December 2026, no class because the company's own data is missing also counts as such a result; from 31 December 2026 missing data carries the position and the first classification waits. After a confirmation the position follows the shared rule: an exit on price below 30 or on another criterion carries the ordinary reason, and missing data carries the position. An outage on our side (the group not recomputed in time) is not a result: the position is carried and the first classification waits.
  • Move to the sector models. JPM, BAC and PGR had no class before: their sector model was in preparation. In the dry run before the rule took effect, the classes are: JPM: "Partly passes"; BAC: "Partly passes"; PGR: "Partly passes". The table is published together with the rule change and is not changed afterwards. The classes of every bank and insurer in both groups under other thresholds are on the methodology page.
  • Investment banks and brokers. The general method does not apply to investment banks, bank-brokers or retail brokers, so they get no class until a separate sector model exists. A held position is frozen: it is carried with no top-up, and its share count does not change. The deadline is 31 December 2026. By then either the sector model classifies the ticker (the "Passes the quality and price filter" class unfreezes the position, any other gives one exit), or the position closes on the first daily run on or after 31 December 2026 (if the ticker has no data that day, on the first later run that has it) at that session's close, with the reason "change in the method's applicability". There is one exit event. From v0b.7 investment bank metrics (GS, JEF) and from v0b.13 broker metrics (SCHW, HOOD) are shown descriptively, without a class: there are too few comparable companies, so this rule still applies to them.
  • Corporate actions. Each corporate action is recorded as its own ledger row, and nothing is entered by hand. Split: a provider row is a split only when its factor is a clean ratio of whole numbers up to 20 and the raw closes before and after confirm it; the share count changes from the first session on the new basis, the entry price is divided by the factor, and cash does not change. Spin-off: the spun-off shares become cash, the close of the first session after the spin-off times (factor minus 1), and the share count does not change; if SEC shows an 8-K with a charter amendment for a split within 45 days before the ex-date, the action is not guessed; the new company's price is a second source, and when the two differ by 3 to 30 % the lower amount is credited and flagged, while a gap beyond 30 % is treated as a parsing error and only recorded. Merger, take-private, delisting: when SEC no longer lists any ticker for the company, the position is closed at the close of the last session before the 8-K date; the deal's cash from exhibit 99.1 replaces that close when it differs by no more than 2 %, and between 2 and 10 % the lower amount is credited and flagged. Bankruptcy (8-K, item 1.03): the position is closed at the first session after the filing, and if there is none for 10 days it is written off to zero. A ticker change (the same CIK, the new ticker's prices continuing the old one's) is not a trade. A special dividend of 10 % of the price or more, or the second in a quarter, is credited like any dividend; the provider's split row on the same day is not applied when the dividend explains it (a size of 10 % of the price or more, or a factor equal to the dividend's adjustment, with the raw closes agreeing); a dividend of 25 % or more of the price may go ex after it is paid, and the cash then counts from the ex-date. An action the rule does not recognise: for 3 nights no record is written, then the position is frozen at its last close before the action and not traded, and after 30 days it is closed at that close with the dispute open. The exception: when the suspicion can come from the data (SEC lists no ticker without a dated filing, an 8-K with 2.01 and 3.01 while the ticker still trades, a split row the prices do not fit, an unexplained price jump), nothing has confirmed it, and the position still trades normally, after 30 days the suspicion is dropped: no trade, valuation resumes, and the frozen nights stay as recorded. A position whose entry is not known relative to a split date is treated as an unclear action too.
  • Dividends. A dividend belongs to a position the portfolio held at the close of the session before the ex-date. What counts is the session whose closing price filled the opening or closing trade, not the date the event was recorded. The amount is the portfolio's share count on that date, adjusted for splits, times the amount per share, in US dollars. No tax is withheld, since this is a paper portfolio in US dollars; for foreign issuers the provider's gross US dollar amount per US-listed share is used. A position closed between the ex-date and the pay date still receives its dividend. From the ex-date to the pay date the amount counts in the value as a dividend receivable; from the pay date it is free cash. If the pay date is not published, the amount is credited on the ex-date and flagged. Nothing is reinvested: cash is spent only by the rule on a new slot. SPY with the same starting capital receives its dividends under the same rule and buys no new shares. The dividend source is Marketstack, checked against a second source where one exists. If the sources differ by more than 2%, or the entitlement cannot be established, the dividend is not credited and is listed among the known gaps. A difference of up to 2% is settled against us: the portfolio gets the lower amount and SPY the higher. While an SPY dividend for a quarter is not confirmed, the comparison with it is marked incomplete. The dividend record is never rewritten: new data adds a new entry dated on the day it arrived.
03

What we attest

Each day's record is sealed with a public SHA-256 hash, so it cannot be changed later. The hash is computed from that day's full private record: the classification set, the open positions, the day's signal events, and from v0b.10 the dividends recorded that day, and from v0b.14 the corporate-action ledger rows recorded since the previous day, and from v0b.15 the hash of the daily class record of every analysed ticker, and it chains in the previous day's hash, so changing any earlier day breaks the chain from that day forward. The public commit itself carries only the date, the hash, the schema version, and the open-position and event counts, published in the list on: the public hash list (append-only). The positions and the signal history behind the hash are not published there. This site shows them to Pro subscribers.

This hash proves one thing: 'we recorded this snapshot on this date and have not changed it since.'

How the hash is computed

The steps below are documented so anyone can independently recompute the same hash from the same data and check it against the published value.

  1. Every amount is first written as a number with a fixed number of decimal places (prices and share counts), so the same real value always produces the same text.
  2. Tickers, positions, and events are put in one fixed order, not the order they happened to be read from the database.
  3. Every field name in the record is sorted alphabetically, and the whole record is written with no extra spaces, so formatting can never change the hash.
  4. That text is hashed with SHA-256, and the result is combined with the previous day's hash before hashing again, so each day of the chain depends on the one before it.

The hash does not prove that the selection can be reproduced independently: selection depends on our own SEC-data extraction, sector medians, and signal logic, which are proprietary. The hash is also not proof of an edge over the market.

'Recomputation from public prices' applies only to the NAV curve for the recorded positions. It is there for transparency, not as a claim of an edge.

Daily class record

From v0b.15 we record the classes of every analysed ticker in the hash chain every day: each ticker's class with its reason, axis scores and closing price. The check of whether the classes predict anything is pre-registered, that is, the analysis rules were fixed before any data existed: the pre-registration document (its sha256 is in the first version 5 daily hash, from 8 October 2026). The first conclusions come no earlier than 13 months later. Until the check passes its preset threshold, we do not say that the class predicts returns.

04

What this is not

This record is about transparency and discipline, not performance.

  • Not a price forecast. The method classifies fundamentals against the sector; it does not predict future price moves.
  • Not investment advice. A paper portfolio to check the method, not a recommendation to take any specific action on securities.
  • Not proof of alpha. A backtest over 2016 to 2026 found no statistically stable out-of-period edge for any of the method's signals. The portfolio keeps its record honestly, losing positions included.

Method version: v0b.15 · rule pre-registered · hash log: the public hash list · Not investment advice