How we choose and measure our picks
Returns, algorithmic selection, and re-buys — all public and verifiable on blockchain.
Last updated: 2026-04-10
1. Introduction
This page documents the exact method we use to compute portfolio returns and select the positions that appear on pages like /lecciones. The goal is to let anyone (human or AI agent) audit our track record without having to take our word for it.
2. Position size
Every position is modelled as a $50 USD investment. We buy fractional shares, so the share count is $50 / buy_price. This does NOT represent real investment amounts — it is a fixed hypothetical position size so we can compare picks consistently without position size skewing returns.
3. Return calculation
The return of a single position is: return_pct = ((current_price − weighted_avg_price) / weighted_avg_price) × 100. Current prices come from the latest daily snapshot in our database, which in turn fetches Yahoo Finance on every market day.
4. Weighted-average price (re-buys)
When we have multiple buys of the same ticker, the effective price is the weighted average. In our model each transaction invests the same hypothetical $50, so share-weighted average is equivalent to: avg_price = sum($50) / sum($50/price_i). A re-buy at a lower price improves the average and reduces the loss; a higher one worsens it.
Example: If we buy XYZ at $100 and then at $50, each $50 tranche buys 0.5 + 1 = 1.5 shares. The average price is $100 / 1.5 ≈ $66.67. If the current price is $60, the return is (60 − 66.67) / 66.67 ≈ −10%, not −40%.
5. Losing pick selection (lessons)
The list on /lecciones is generated by a pure algorithm that operates on the same return calculation. The algorithm CANNOT be edited by hand — any change requires modifying the public source code.
- 1. Group all transactions by ticker and compute weighted-average price
- 2. Compute return % using the current price from the most recent snapshot
- 3. Filter positions with at least 30 days since the FIRST buy (to avoid short-term noise)
- 4. Filter positions with return < 0
- 5. Sort ASC by return_pct (worst first). Tiebreak: oldest first buy date
- 6. Take the first 5. If fewer than 5 are negative, only the existing ones are shown
6. Stock splits
We pull real corporate-action split events directly from Yahoo Finance for every ticker. When a split occurs after a buy, we adjust the cost basis by the exact ratio (numerator/denominator) so shares and returns reflect post-split reality. The handler lives in `src/lib/split-detection.ts`.
7. Update frequency
Prices are updated on every open market day (Mon-Fri except holidays) at 4:30 PM ET via a cron job that fetches quotes from Yahoo Finance and writes a snapshot to Supabase. Public pages that depend on this data are cached for ~5 minutes with stale-while-revalidate.
8. What is NOT included
Our calculations are GROSS. They exclude: taxes on dividends and capital gains, broker commissions, execution slippage, and FX differences for non-USD stocks. Real-world returns for an individual investor will always be lower than the ones shown.
9. Known limitations
Our model assumes instant execution at closing price, perfect reinvestment of dividends (not currently modelled), and availability of fractional shares (not always possible at all brokers). These simplifications are standard in most backtests but matter when comparing with real account performance.
10. How to audit all of this
All code is public. The calculations live in `src/lib/position-utils.ts` (aggregatePositions) and `src/lib/lessons.ts` (selectLessons). Transactions live in `src/data/stocks.ts` and each one has an on-chain attestation UID. If you find a bug in the calculation or methodology, open an issue on GitHub or email Hello@vectorialdata.com.
Looking for how to start investing little by little? That's the method →