What is this?
st-ox is a web app for tracking a multi-currency stock portfolio. Your data is stored in a secure cloud database tied to your account — sign in from any device and your portfolio is there.
Navigation
The app is organised into seven pages accessible from the left sidebar:
- Dashboard — summary cards, portfolio value chart, allocation donut, and a market sentiment gauge.
- Holdings — holdings table, cash panel, search, add lot, and CSV import.
- Watchlist — a saved list of tickers with live price and daily change.
- Analyse — TradingView Advanced Chart, Technical Analysis, and Fundamental Data for any symbol.
- Screener — Smart Screen: a multi-factor screen across 12 markets with Quality Compounder, Emerging Growth, and Capital Preservation presets, plus opt-in US day-trading scans (momentum / gappers / low-float).
- Models — a library of example model portfolios (Wealth Preservation, Growth, Ivy Portfolio, All-Weather, Income, Permanent Portfolio, EUR-Hedged Global) you can load into the Rebalance tool, plus a 🎲 What-if tab for hypothetical projections.
- Valuation — long-horizon market-valuation gauges (price-vs-trend across regions, plus the US Buffett Indicator and Q Ratio) with an overall verdict.
The bottom of the sidebar holds a market open/closed indicator (US hours), a Theme toggle (light / dark), Settings, Feedback (or Admin for admin accounts), User Guide, and Sign Out. On desktop, Collapse shrinks the sidebar to an icon-only rail (click again to expand); on mobile the sidebar becomes a hamburger overlay.
Account & sign-in
- Register with an email and password. No third-party login required.
- Your session is remembered securely via a cookie — you stay signed in across page reloads.
- Use Sign Out at the bottom of the sidebar to end your session. Signing out clears this device's locally cached portfolio data; signing in as a different account also clears the previous account's cache, so nothing leaks between accounts on a shared browser.
- When signing in for the first time on a new browser, the app offers to import data previously saved in that browser's local storage (if any).
- To change your email address or password, open Settings → Account. Both changes require your current password.
Dashboard
- Summary cards — Invested, Current Value, Total Return, Daily Change — all converted to your display currency. Invested is the cost basis of your current holdings plus any cash held; Current Value is their market value plus cash. Total Return is the price-based capital gain/loss on the holdings (cash nets out) plus dividends received since each lot's buy date; the card's sub-text breaks out the capital-only figure and the dividend portion, and per-ticker dividends also appear in the Holdings table.
- Status strip — Data Quality, Quotes freshness, FX status, Display Currency.
- Portfolio Value chart — range buttons 1M / 3M / 6M / 1Y. Each lot is valued from its buy date forward (forward-filled across non-trading days), and the latest point uses live quotes so the chart's right edge matches the Current Value card. Cash is included at its current balance and undated lots span the full range — both estimated as constant, since no per-day cash history is stored. The vs benchmark… selector overlays a comparison line rebased to your portfolio's starting value: a cash / deposit baseline — a EUR or USD money-market line (tracking the euro overnight rate or short-dated US T-bills), i.e. roughly what the money would have earned in a bank deposit at the risk-free rate or an equity index (S&P 500, Nasdaq 100, MSCI World). The overlay is total-return (dividends reinvested), so it's a fair "what if I'd parked it instead" comparison.
- Allocation donut — current weight of each holding including cash positions. Use the By holding / By type toggle to switch between per-ticker weights and a breakdown by asset class (Stocks, Fixed income, Real estate, Commodities, Crypto, Cash). Types are detected automatically from market data; you can override a holding's class in its Edit Lot form (or when adding it) if it lands in the wrong bucket.
- Market Sentiment — a VIX-based gauge (below the allocation donut) showing the broad market mood. See Market Sentiment below.
- Journal (top right of the page) opens your Trading Journal — ledger, realised P&L and analytics. See Trading Journal below.
- Use Refresh (top right of the page) to force an immediate quote update.
Holdings page
- Cost — total invested, converted to display currency.
- Daily — change since previous close.
- Return — total gain/loss since purchase.
- Ann. — annualised return (requires a buy date on each lot).
- Div. — dividends received since your buy date (Yahoo Finance data).
- Analyse button — opens the Analyse page with that ticker pre-loaded (chart, technicals and fundamentals).
- Signal dots — two coloured dots next to each ticker name. The first dot is the technical signal (green = Buy, yellow = Hold, red = Caution) computed from 7 indicators; it loads automatically on page load, after adding a lot, and after Refresh. The second dot is the analyst consensus (requires a Finnhub API key in Settings); it loads in the background after the technical dot — if it hasn't appeared yet, opening the ticker detail modal forces it immediately. Hover either dot for a tooltip.
- Red left border — price is below the 15% trailing stop (rolling high × 0.85 from your buy date).
- Click ▶ on a multi-lot row to expand and see individual lots.
- Journal — opens your Trading Journal (ledger, realised P&L and analytics). See Trading Journal below.
- Rebalance — set a target % per ticker; the app calculates whole shares to buy or sell.
- Analyse with AI — copies a structured portfolio summary prompt to your clipboard for pasting into any AI assistant.
- Cash panel (above the table) — track cash balances per currency; deposit with + Add Cash, or withdraw / clear per row. See Selling & cash below.
Adding holdings
- Use the Add Holding form on the Holdings page (a new ticker creates a holding, an existing one adds another lot). Enter a ticker (e.g.
AAPL, BMW.DE, EFT1T.TL), shares, and optionally a buy date.
- Leave buy price empty — the app auto-fetches the historical price from Yahoo Finance for that date. Clearing the ticker field also clears the prefilled price and date.
- Each purchase is stored as a separate lot so the portfolio chart reflects your actual entry dates.
- Cost Currency — records what currency you paid in. Defaults to the quote currency (e.g. USD for US stocks). Change it only if you actually paid in a different currency.
- Automatic cash deduction — if your cash balances cover the purchase cost, the amount is deducted when you click Add Lot. Same-currency cash is used first; if that's insufficient the remainder is converted from your other currency balances using live FX rates. A green hint shows exactly what will be deducted; if cash is insufficient the hint turns red and no cash is touched. Untick Deduct cost from cash balance to record the purchase without touching cash (e.g. bought with money not tracked in the app).
Selling & cash
- Click Sell on a holdings row, enter shares, sell price, and proceeds currency. The proceeds are added to your cash balance automatically. Lots are reduced FIFO (oldest first).
- Cash lives in its own Cash panel above the holdings table — one row per currency, showing the native amount (e.g. $900.00) with the display-currency equivalent as a small hint, and a running total in the panel header.
- Click + Add Cash in the Cash panel header to deposit without a sale. Pick any currency (including one you don't hold yet); each deposit adds to the existing balance rather than overwriting it.
- On each currency row, use − Withdraw to take an amount out, or ✕ to clear that balance entirely.
- Cash is included in total portfolio value and the allocation donut. Deposited cash is tracked separately so it does not inflate Total Return; withdrawing realised gains correctly reduces it.
Trading Journal
Open the Journal from the button in the Dashboard page header or the top of the Holdings panel. It's a full record of your trading, in three tabs (all amounts in your display currency at current FX):
- Ledger — a dated blotter of every buy and sell, newest first: date, action, ticker, shares, native price, and the display-currency amount. Purchases carry a Held / Partly sold / Sold tag; sells show the realised profit or loss, the holding period, and the % return. A strip at the top totals how much you've Invested, Sold for, and your overall Realised P&L. A position you bought once and sold in pieces still shows as a single purchase row at its full original size.
- Realized — the detailed closed-trade log, one row per lot consumed on each sell (FIFO cost basis), with native buy/sell prices, cost, proceeds, realised P&L, holding period, and a per-year breakdown.
- Analytics — how your trading is doing overall: win rate, total and average realised (expectancy), profit factor, average holding period, average win/loss, your best and worst trades, and realised P&L by year.
Entries appear automatically — a purchase is logged when you add a lot, and its outcome when you sell. Use Export CSV to download the current tab (the Ledger or the Realized log) as a spreadsheet.
The Journal reflects your current holdings and sell history — editing a lot updates its ledger entry, and Clear All Data (in Settings) erases it along with everything else.
CSV import
On the Holdings page, paste or drop a CSV: ticker, shares[, avgPrice, buyDate, currency, note]. Only ticker and shares are required; rows with no resolvable price are skipped. The note is the last field, so it may contain commas. Example:
AAPL,10,145.50,2023-06-01,USD,Initial purchase
Ticker detail chart
Click any ticker name in the holdings or watchlist table to open its detail modal. Shows price history (3M / 6M / 1Y / 2Y), 200-day MA, and (for holdings only) a 15% trailing stop line. Indicators:
- RSI (14) — below 30 = oversold, above 70 = overbought.
- RVI (10) — bullish when RVI line is above its signal line.
- Rel. Volatility (14) — Dorsey Relative Volatility Index; above 50 = volatility concentrated in up moves.
- OBV — rising = buying pressure dominates.
- HV — 30-day annualised historical volatility.
- vs 200 MA — price position relative to the 200-day moving average, coloured for dip-buy entry quality: green inside the entry band (−10% to +5% of the MA), amber just outside (moderately extended above, or a deeper dip), red when far extended (>+20%) or in falling-knife territory (<−20%).
- 52-Week — price within its 52-week high/low range. Bar is green when in the lower 40% of its range (potential value), amber in the middle, red near the top (extended).
The 15% trailing stop is only shown when the ticker is in your holdings — it is anchored to your earliest buy date and has no meaning for watchlist-only tickers.
The Buy / Hold / Caution verdict is a mean-reversion ("buy the dip") checklist in two parts. First it looks for a genuine pullback (RSI < 40, price within 0.90–1.05 × 200 MA, and in the lower 40% of the 52-week range); then it requires early stabilization (RVI bullish, relative volatility ≥ 50, OBV rising, or 30-day volatility contracting below its 90-day baseline). A Buy needs both a real dip (at least two pullback signals) and at least one stabilization signal — a falling stock with no sign of steadying is never labeled Buy, and if stabilization can't be measured at all (e.g. a non-US ticker with no volume data) the verdict is capped at Hold. A regime gate caps the verdict at Hold when the 200-day MA is falling, so dips in broken downtrends are never labeled Buy. On a Buy or Hold the panel also shows suggested invalidation levels — a suggested stop set a volatility buffer (½·ATR) below the recent 20-day swing low, kept at least 3% and at most your trailing-stop % away from price so a shallow dip doesn't produce a hair-trigger stop, plus the deeper 0.90 × 200 MA hard floor below which the setup breaks down — reference points for where the dip-buy thesis would be wrong.
Watchlist
- Navigate to Watchlist in the sidebar.
- Multiple watchlists — the tab bar above the table shows your lists (up to 10). Click a tab to switch, + to create a new list, and on the active tab use ✎ to rename or ✕ to delete it (the last remaining list can't be deleted). The same ticker may appear in several lists.
- Type a ticker directly and click + Add, or use the Search panel on the right to find stocks by name and add them with one click — tickers are added to the currently active list.
- Lists are stored per user in the cloud and persist across devices; your last active list is remembered on each device.
- Each row shows live price, daily change, and a technical signal dot (green/yellow/red) that loads automatically when you open the Watchlist page — no manual step needed.
- Click any ticker name to open its detail chart (indicators, 200 MA). The analyst consensus dot also appears in the row after opening the modal.
- Click Buy to jump to the Holdings page with the Add Holding form pre-filled for that ticker, so you can turn a watched stock into a position in a couple of clicks.
- Click Analyse to open the ticker in the Analyse page with the Advanced Chart, Technical Analysis, and Fundamental Data widgets loaded.
- Click ✕ to remove a ticker from the watchlist.
Analyse page
- Enter a symbol in TradingView format (e.g.
NASDAQ:AAPL, XETR:BMW) and click Load.
- The Analyse button in Holdings and Watchlist navigates here automatically with the correct symbol pre-filled.
- Chart — for US stocks, the full interactive TradingView candlestick chart. For other markets (London, Paris, Xetra, Tokyo, Hong Kong, …), where TradingView's embedded chart has no data, st-ox shows its own price chart with a 200-day moving average and 3M–2Y range buttons instead.
- Technical Analysis — buy/sell/neutral gauge across multiple timeframes.
- Fundamental Data — key financials (valuation, income statement, margins).
Models page — Model Portfolios
The Models page (in the sidebar, below Screener) is a small library of example allocations. An EU / US investor toggle in the top-right switches every model between euro-listed UCITS (for a EUR investor) and the equivalent US-listed ETFs (for a US investor) — the same strategy, expressed with whichever instruments you can actually buy. In US mode the EUR-hedging language is dropped and the hedged model is renamed Global Balanced; your choice is remembered per device. (The Ivy Portfolio always uses its original US ETFs in both modes.) Pick a model from the tabs:
- Wealth Preservation — a capital-preservation mix (short & intermediate govt bonds, inflation-linked, quality & min-vol equity, gold, and a cash/money-market sleeve). Built for low drawdown and protecting real purchasing power, not maximum return.
- Growth — a more aggressive, equity-led mix with a small gold and short-bond ballast. The developed-market equity sleeves are EUR-hedged; emerging markets stays unhedged.
- Ivy Portfolio — Mebane Faber's five-asset-class mix held in equal 20% weight using the original US ETFs (VTI, VEU, IEF, VNQ, DBC); quotes are in USD and carry currency risk, and EUR retail investors generally can't buy US-domiciled ETFs directly. The original adds a 10-month moving-average timing rule (hold a sleeve only while it's above its 10-month average); the app loads the buy-and-hold equal-weight version, so check the monthly AdvisorPerspectives update if you want to apply the timing overlay yourself.
- All-Weather — Ray Dalio's risk-balanced mix (30% equity, 55% government bonds split long/intermediate, 7.5% gold, 7.5% commodities), adapted to euro-listed UCITS. Designed to hold up across all economic regimes with shallow drawdowns rather than chase maximum return.
- Income — a yield-oriented UCITS mix: global high-dividend and dividend-growth equity, listed real estate, and investment-grade euro bonds. Built for cash flow and relative stability rather than growth; the distributing sleeves feed regular income into your Total Return.
- Permanent Portfolio — Harry Browne's four-way split, 25% each in stocks, long-term government bonds, gold and cash, adapted to euro-listed UCITS. Extremely simple and robust — each sleeve is built to shine in one economic environment.
- EUR-Hedged Global (Global Balanced in US mode) — a globally diversified ~60/40 balanced mix where every sleeve is EUR-hedged or natively euro-denominated, so USD/EUR swings don't drive returns: EUR-hedged developed-world equity, euro bonds, and a gold-and-commodities allocation split between gold (crisis hedge) and a EUR-hedged broad commodity ETF (inflation hedge). Being fully hedged means no emerging-markets sleeve (EM can't be practically hedged); real estate is euro-denominated European property for the same reason. Note hedging carries an ongoing cost (roughly the EUR–USD rate differential).
Each sleeve shows its target %, your current weight, and the drift between them (current − target, in percentage points) — shown green when you're close to target and amber when it's worth rebalancing. Where a model groups sleeves (e.g. a combined equity allocation), a subtotal line shows the group's target, current and drift. Click any ticker to open its detail chart (price history, indicators). A Phasing note suggests how to deploy. Load into Rebalance copies the model's targets into the Rebalance tool — which then tells you the exact whole shares to buy at live prices, even for instruments you don't own yet. Add all to watchlist seeds a watchlist named after the model.
Switch to the 🎲 What-if tab (after the model tabs) to project how an investment might grow under each model. Enter a lump sum, an optional monthly top-up, and a time horizon; the table then shows every model's pessimistic, expected and optimistic ending value side by side, with a Risk rating (Low / Medium / High) that explains how wide that range is — higher risk means a bigger gap between the pessimistic and optimistic outcomes (hover the rating for the exact figures). Tick Show in today's money to adjust the results for inflation at a rate you set. The outcomes come from simulating thousands of return paths from each model's long-run return and volatility assumptions, so they are hypothetical illustrations — not forecasts or guarantees.
These are example allocations, not personalised investment advice. If a ticker doesn't resolve on your venue, use the same fund's ISIN on another exchange.
Screener page — Smart Screen
A multi-factor screen that finds stocks and ranks them with a single 0–100 score. Use the market dropdown to screen any of 12 exchanges — US, London, Paris, Frankfurt (Xetra), Amsterdam, Milan, Switzerland, Stockholm, Copenhagen, Helsinki, Tokyo, or Hong Kong. Then pick a preset: Quality Compounder (profitable, cash-generative businesses growing at a reasonable price), Emerging Growth (faster mid & small caps with durable margins), or Capital Preservation (defensive, low-volatility dividend payers ranked on Quality, Stability, Value and Income — not growth).
Smaller markets (e.g. Helsinki) naturally return short lists — there are simply fewer companies that clear every gate.
Each stock must pass a set of hard gates (e.g. ROIC/margins, free cash flow, an uptrend filter; the defensive preset adds low beta, low volatility and a dividend), then the survivors are scored on the four factors shown — the four bars in each row show the breakdown, and the labels change per preset. No more than four stocks per sector are shown, so one hot industry can't dominate the list. Click How this screen works for the full criteria.
Use 📈 to open a stock on the Analyse page, or + to add it to your watchlist. Open the full TradingView screener at the bottom to build your own custom filters.
Data freshness: results are cached for 30 minutes per market and preset (the line above the table shows "as of HH:MM"). The underlying numbers are fundamentals that update only when companies report (roughly quarterly), so a 30-minute cache is plenty — the list is effectively current as of the latest earnings.
This is an idea generator, not investment advice — a screen is the start of research, not a buy list. Always verify the numbers and the story before buying.
⚡ Day trading scans (high risk)
At the bottom of the Screener page, expand ⚡ Day trading scans for a separate set of US-only, intraday screens that surface today's unusual-volume movers — for building a short-term watchlist, not for long-term investing:
- Momentum — up on the day with heavy relative volume and enough dollar-volume to trade.
- Gap & Go — names that gapped from the prior close on strong volume (the pre-open / opening-range setup).
- Low-Float Runners — small-float stocks running hard on huge relative volume; the fastest movers and by far the riskiest.
Each row shows the score, factor bars, and the day-trading metrics that matter: Chg (today's move), Gap, RVol (relative volume), $ Vol (liquidity), Float, and daily Volatility. 📈 and + work the same as above. The line above the table shows when the scan was pulled ("as of HH:MM") — day scans use a short 3-minute cache.
Day trading is high risk and most participants lose money. These scans run on delayed (~15 min) data with no real-time tape, Level 2, VWAP or news — strictly an idea generator. Always confirm on a live broker platform before trading.
Valuation page — is the market expensive?
The Valuation page shows long-horizon gauges that answer "is the market expensive vs. its own history?" — useful for setting expectations (stretched valuations historically mean lower long-run returns and bigger drawdowns), not for market timing. At the top, an overall verdict blends the indicators into a single read (Undervalued → Significantly overvalued).
- Price vs. long-term trend — an index plotted (log scale) against an exponential regression of its own history, with ±1σ / ±2σ bands; the readout shows how far above/below trend prices sit. A region dropdown switches it between the US (S&P 500), Europe (Euro STOXX 50), Germany (DAX), France (CAC 40), UK (FTSE 100) and Japan (Nikkei 225). Non-US indices have shorter histories, so their trend is less robust.
- Buffett Indicator — total US corporate equities as a % of GDP; Buffett's "best single measure" of overall valuation. US-only.
- Q Ratio (Tobin's Q) — market value of US corporate equities ÷ their net worth at replacement cost; above ~1 means stocks cost more than the assets behind them. US-only.
Each gauge shows a σ (sigma = standard deviation) figure — how far the current reading is from its own historical average. Beyond ±2σ is genuinely extreme (≈95% of history sits inside that range). When the US is selected the verdict blends all three gauges; for other regions it uses the price-vs-trend gauge alone, because the Buffett Indicator and Q Ratio only exist for the US.
A contextual note ties the reading back to the Models page — e.g. when valuations look stretched it suggests phasing money in and leaning toward lower-risk models. The valuation data refreshes daily.
These are notoriously poor market-timing tools — valuations can stay stretched for years. Treat them as context for long-run expectations, not buy/sell signals. The macro gauges are US-equity metrics and don't map directly to euro-hedged or bond-heavy models. Not investment advice.
Market Sentiment
Found on the Dashboard (below the allocation donut). Derived from the VIX (CBOE Volatility Index) — shows the raw VIX reading, a status label (Calm → Neutral → Fear → Extreme Fear), and the change vs the previous VIX reading. The VIX is an inverse gauge: a low value (under 15) signals market calm; a high value (35+) signals fear/panic.
Rebalancing
Click Rebalance in the Holdings panel header. Set a target % per ticker — the app shows how many whole shares to buy or sell to reach those weights. Buy counts are floored, sell counts are ceiled. Targets persist between sessions. Tickers you've targeted but don't yet hold (e.g. loaded from a Model Portfolio on the Models page) appear too, so you can see the buys needed to build the position from scratch.
Currencies & FX
Each lot stores its own cost currency. Live FX rates are fetched and cached for 12 hours. Set your display currency in Settings.
Analyst consensus
Register free at finnhub.io, copy your API key, and paste it into Settings → Finnhub API Key. Once set, analyst ratings are fetched automatically on page load, after adding a new lot, and after Refresh — appearing as a second coloured dot in the holdings table and a consensus bar in the ticker detail modal. Ratings are re-fetched fresh each time you open the site (and reused for the rest of that session). Only US-listed tickers are covered by Finnhub's free tier; tickers with exchange suffixes (e.g. .DE, .L) are skipped automatically.
Data freshness
Quotes auto-refresh when stale. Use Refresh on the Dashboard to force an immediate update. Quote Freshness Window in Settings controls cache duration (5 min / 15 min / 1 h / 6 h).
Settings
Display
- Display Currency — all values converted to this currency.
- Default Cost Currency — pre-filled in the Add Lot form.
- Quote Freshness Window — cache duration before a quote is re-fetched.
- Appearance — switch between Dark (default) and Light theme; also toggleable from the sidebar. Saved on this device.
- Finnhub API Key — enables analyst consensus (free at finnhub.io).
- Import from this browser — migrate old localStorage data into your account.
- Clear All Data — permanently deletes all holdings, cash, and history.
Account
- Change email — requires current password.
- Change password — minimum 8 characters, requires current password.
Supported exchanges & tickers
Use Yahoo Finance ticker format for adding holdings. Common formats:
AAPL — US (Nasdaq/NYSE)
BMW.DE — Germany (Xetra)
BARC.L — UK (London, GBp)
EFT1T.TL — Estonia (Nasdaq Tallinn)
GRD1R.RI — Latvia (Nasdaq Riga)
TEO1L.VS — Lithuania (Nasdaq Vilnius)
NOKIA.HE — Finland (OMX Helsinki)
ERIC-B.ST — Sweden (OMX Stockholm)
The Analyse button converts Yahoo Finance tickers to TradingView exchange format automatically. Note that some European tickers use different symbols on TradingView — if the chart shows "symbol not found", search within the TradingView chart widget directly.