Omahub
← All plugins
S

Trading 212

by Simas Razinskas

Trading 212 portfolio in the Omarchy bar: invested amount and P/L at a glance, with a detail panel of positions.

Security review

No obvious issues detected

Deterministic scan — not a security guarantee

None
Risk level
None
Analyzed commit
2bd90cf
Scanned
1 month ago

No potentially dangerous behavior detected in the analyzed commit.

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
2bd90cf
Reviewed
1 month ago

This is a legitimate Trading 212 portfolio widget that fetches account data via the official API using a user-provided key stored in the system keyring. The code is well-structured, avoids exposing secrets in process arguments, and includes rate-limit and error handling. No malicious behavior or obfuscation was found.

  • The plugin executes shell scripts that interact with secret-tool and curl, but they are constructed with fixed strings and controlled parameters, and the credential is passed via stdin to avoid argv exposure.
  • The plugin writes state and cache files under ~/.local/state/omarchy-trading212, but the paths are derived from standard environment variables and the write operations are safe.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/simasrazinskas/omarchy-trading212-plugin --enable
Widgets #bar #quickshell #system

Omarchy Trading212 Plugin

Your Trading 212 portfolio in the Omarchy status bar: how much you have invested and your P/L at a glance, with a click-to-open panel showing the full account summary and every open position.

Built for the Omarchy 4.x shell (omarchy-shell / Quickshell) as a bar-widget plugin. It does not work on Omarchy ≤ 3.x (Waybar).

<p> <img src="preview-live.png" width="48%" alt="Detail panel with live account data, daily change, and positions"> <img src="preview.png" width="48%" alt="Detail panel in setup state with the API key input"> </p>

Features

  • Five bar display modes, cycled with a right-click:
    Mode Bar shows
    Value + P/L €12.8k +€322 — current worth of your investments and signed P/L
    Daily change +€12.40 +0.5% — today's move vs yesterday's closing snapshot (on install day: vs the day's first reading)
    P/L percent +2.6% / -4.0%
    Total value €12.9k (investments + cash)
    Privacy T212 ▲ — direction only, no amounts anywhere (including the tooltip)
  • Left-click opens the detail panel: invested / value / P/L / free cash, a portfolio graph built from the plugin's own daily snapshots (hover for per-day values; the Trading 212 API exposes no history, so the graph grows from install day), plus all open positions with per-position value and P/L. Middle-click (or R in the panel) forces a refresh.
  • The bar label always uses the theme's bar foreground (the +/− sign carries the direction), so it stays readable on every Omarchy theme; inside the panel, P/L is colored with the theme's accent (profit) and urgent (loss) colors.
  • The cycled mode is persisted to shell.json, so it survives shell restarts.
  • Records one daily portfolio snapshot to ~/.local/state/omarchy-trading212/history-<env>.jsonl — the dataset behind the graph and the daily-change mode. Each line keeps the day's opening and closing value; the graph also plots a live "now" point, so it moves intraday. (The Trading 212 API has no history endpoints, so everything is derived locally — daily change needs one prior day on record before it compares against a real close.)

Install

omarchy plugin add https://github.com/simasrazinskas/omarchy-trading212-plugin.git --enable

Then place it on the bar if it doesn't appear automatically:

omarchy bar put io.github.simasrazinskas.trading212 right

Uninstall

omarchy plugin remove io.github.simasrazinskas.trading212

The plugin leaves behind only two things, both yours to keep or delete:

secret-tool clear service trading212 account live    # the API key (and `account demo` if set)
rm -rf ~/.local/state/omarchy-trading212             # summary cache + daily snapshot history

Connect your Trading 212 account

The plugin talks directly to the official Trading 212 public API (Invest and Stocks ISA accounts; CFD is not supported by the API).

  1. In Trading 212 (app or web): Settings → API (Beta) → generate an API key.
    • Read-only permissions are enough — this plugin never places orders; granting it nothing else is safest.
    • Restricting the key to your IP is recommended by Trading 212.
    • The secret is shown only once at creation; copy it immediately.
  2. Left-click the widget and paste the key into the panel's input field as KEY:SECRET (a legacy single-token key also works — paste it as-is), pick LIVE or DEMO, and hit SAVE. Done.

Prefer the terminal? The equivalent manual command is:

secret-tool store --label="Trading 212 API (live)" service trading212 account live

or script it via IPC: omarchy-shell io.github.simasrazinskas.trading212 setKey "KEY:SECRET" — note that unlike the panel input, this puts the key in the command's argv and your shell history, so prefer the panel or secret-tool for interactive use.

Why the keyring?

The credential goes from the input field to your system keyring (gnome-keyring ships with Omarchy) over the storing process's stdin — it is never written to a config file, never passed on a process command line, and never appears in shell.json or this plugin's settings. At request time the widget runs secret-tool lookup, and the Authorization header is handed to curl via --config on stdin. Locked keyring = no requests.

Practice (demo) account

Keys are per-environment: a key generated while in Practice mode only works against the demo API. To point the widget at a practice account, store the demo key:

secret-tool store --label="Trading 212 API (demo)" service trading212 account demo

and set the environment in ~/.config/omarchy/shell.json on the widget's bar entry:

{ "id": "io.github.simasrazinskas.trading212", "environment": "demo" }

Settings

Key Default Meaning
refreshIntervalSec 60 Poll interval (15–3600 s). Also editable in the bar's widget settings UI.
environment live live or demo.
mode invested Current display mode; normally you just right-click instead of editing this.

The account-summary endpoint is rate-limited to 1 request / 5 s by Trading 212, so the 60 s default is conservative; the minimum of 15 s stays well clear of it. Manual refreshes (middle-click, IPC) are additionally floored at one summary fetch per 6 s, so you can't trip a 429 by mashing the widget. Mode switching never touches the API — it just re-renders cached data. Transient failures (rate limit, network blips, server errors) never replace data you already have: the widget keeps showing the cached numbers and silently retries after 15 s; errors are only shown when there is no data at all or the key itself is missing/rejected.

IPC

omarchy-shell io.github.simasrazinskas.trading212 toggle    # open/close the panel
omarchy-shell io.github.simasrazinskas.trading212 refresh
omarchy-shell io.github.simasrazinskas.trading212 cycle     # next display mode
omarchy-shell io.github.simasrazinskas.trading212 status    # JSON state

Development

tests/run                      # node unit tests + manifest validation
omarchy plugin validate .      # manifest only

Model.js is pure JavaScript (parsing + formatting) shared between the QML widget and the node test suite. Service.qml owns polling and keyring access; Panel.qml is the bar widget and popup panel.

License

MIT. Not affiliated with Trading 212 or Omarchy.