Skip to content

About

A trading platform for buying and selling stocks across exchanges worldwide, paired with Portfolio-Watcher for watching the same symbols.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

OpenTrading

A fast, secure, installable paper-trading experience for global stock exchanges.

Live site: https://charles2ke.github.io/OpenTrading/

Simulation only: OpenTrading does not execute real trades or provide investment advice. Market data is illustrative until a market-data provider is configured, and orders are never sent to a broker.

New to investing? Read the beginner's investor concepts guide for plain-language explanations and examples of stocks, short selling, calls, puts, and more. The same guide is available on the website on its own Learn page.

See the architecture documentation for the client, server, data, authentication, and deployment design.

Contents

Apps

  • Website: responsive desktop and mobile experience.
  • Windows: download the .exe installer (or portable .zip) for your chip from the latest release — both Intel/AMD x64 and arm64 (Snapdragon, Surface Pro) builds are published.
  • macOS: download the .dmg (or .zip) for Apple silicon arm64 or Intel x64 from the latest release, or build it yourself on a Mac with npm run desktop:pack:mac.
  • Android: open the website in Chrome and choose Install app.
  • iOS: open the website in Safari, choose Share, then Add to Home Screen.

The Progressive Web App uses one reviewed codebase across all platforms, works offline after first load, and stores the demo portfolio only on the device.

Features

  • Global market overview across US, UK, German, and Japanese exchanges
  • Search every listed market and index by name, ticker, exchange, country, or ISIN/CUSIP/SEDOL identifier
  • Validated buy and sell paper orders
  • Portfolio valuation, daily movement, cash, and returns
  • Responsive, accessible UI with offline caching
  • Connect any bank through Open Banking consent and review masked account details on a dedicated Banking page
  • Built-in support for ICICI Bank, HDFC Bank, and State Bank of India (India), AIB and Bank of Ireland (Ireland), and ABN AMRO (Netherlands)
  • Deposit and withdraw cash with ISO 20022 transfer instructions over SEPA, SWIFT, and the Indian IMPS and RTGS rails
  • Optional live exchange rates that convert foreign-currency bank transfers into the portfolio cash balance
  • Optional live market data: real quotes refresh the market movers, holdings, and order ticket when a provider is configured
  • Read-only Trading 212 brokerage integration showing live cash, positions, and account value
  • Institutional research workspace on a dedicated Research page: stock screener, DCF valuation, earnings intelligence, technical analysis, quantitative pattern research, competitive landscape, dividend analysis, portfolio construction, portfolio risk, macro impact, watchlists, and saved research reports
  • Every research figure is calculated by a deterministic analytics engine and tagged with its provider, source, and as-of timestamp; unavailable metrics are reported as missing instead of being estimated
  • Built-in beginner's guide to investing concepts on a dedicated Learn page
  • Setup page with installation steps for every platform and a first-run account checklist
  • Audit log page to review your recorded account activity and download it as CSV or JSON
  • Restrictive Content Security Policy and no analytics or remote scripts

Quick start

Requires Node.js 22 or newer.

npm ci
npm run dev

Open http://127.0.0.1:4173. npm run dev builds the site with Vite and serves it with the bundled Node server (scripts/server.js); set PORT to listen on another port.

No configuration is required for the paper-trading demo: without provider keys the app runs on bundled illustrative prices and stores the portfolio on the device. See Configuration to connect MongoDB, sign-in, banking, market data, exchange rates, news, or Trading 212.

Screenshots

Every image below is captured automatically by npx playwright test screenshots, so the documentation always matches the shipped UI.

Dashboard

Desktop Mobile
Desktop dashboard showing portfolio metrics, global markets, holdings, watchlist, and the news feed Mobile dashboard stacked into a single column

Navigation

Mobile navigation drawer open over the dashboard

Placing an order

Order ticket Confirmation
Order dialog with stock, side, share count, and estimated total Dashboard after a filled order showing the confirmation toast and the new position

Order validation

Order dialog rejecting a sell order for shares that are not owned

Searching markets

Market movers filtered to Tesla by the search field

Loading the news feed

Animated placeholders keep the news panel in place while headlines are being fetched.

News feed showing animated shimmer placeholders while data loads News feed showing animated shimmer placeholders while data loads on mobile

Research workspace

The Research page runs the whole research workflow — discover, research, value, analyse, allocate, and monitor — on one shared financial data and analytics foundation.

Desktop Mobile
Research workspace overview with the company header, dashboard widgets, and research shortcuts Research workspace overview on mobile
Stock screener DCF valuation
Stock screener filtering the investable universe on fundamentals and valuation metrics Discounted cash flow model with editable assumptions, a five-year forecast, and sensitivity matrices
Portfolio risk Macro impact
Portfolio risk dashboard with concentration, volatility, value at risk, stress scenarios, and a risk heat map Macro dashboard mapping economic factors to portfolio holdings and scenario impacts

Banking

Linked accounts Secure transfer
Banking panel listing a connected bank account with a masked IBAN and balance Transfer dialog with direction, currency, amount, IBAN, BIC, and the SEPA settlement scheme

Connect a bank dialog listing supported countries and the banks available in the selected country

Indian rupee transfers switch the dialog to account number and IFSC fields and settle over IMPS or RTGS.

Desktop Mobile
Transfer dialog with an Indian account number, IFSC code, and the IMPS settlement scheme Indian transfer dialog on mobile

Beginner's guide

Learn page explaining investing concepts for beginners

Setup

Desktop Mobile
Setup page listing installation guides for the web, Windows, macOS, Android, and iOS Setup page on mobile

Audit log

Desktop Mobile
Audit log page listing recorded account activity with filters and download buttons Audit log page on mobile

Configuration

Every integration is optional and disabled until its key is set. Keys stay server-side; the browser only calls the app's own origin. When a provider-dependent route is not configured, it returns 503 and the UI explains that the feature is unavailable.

Variable Feature Default
PORT Server port 4173
APP_BASE_URL Public base URL used for OAuth callbacks and URL parsing http://127.0.0.1:<PORT>
MONGODB_URI, MONGODB_DATABASE Server-side persistence and audit log on-device storage
DATA_PRIVACY_KEY, AUDIT_RETENTION_DAYS Audit pseudonymisation and retention development key, 365
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET Google sign-in disabled
MICROSOFT_CLIENT_ID, MICROSOFT_CLIENT_SECRET, MICROSOFT_TENANT_ID Microsoft sign-in disabled, tenant common
OPEN_BANKING_API_KEY, OPEN_BANKING_API_URL, OPEN_BANKING_REDIRECT_URI Bank connections and transfers disabled
MARKET_DATA_API_KEY, MARKET_DATA_PROVIDER, MARKET_DATA_API_URL Live quotes illustrative prices, finnhub
FX_RATES_API_KEY, FX_RATES_PROVIDER, FX_RATES_API_URL, FX_RATES_BASE Currency conversion 1:1 settlement, exchangerate, USD
NEWSAPI_KEY, TWITTER_BEARER_TOKEN News feed sources disabled
TRADING212_API_KEY, TRADING212_ENVIRONMENT, TRADING212_API_URL Read-only brokerage view disabled, live

MongoDB

OpenTrading uses MongoDB for server-side portfolio persistence and falls back safely to on-device storage when the database is unavailable. Create a least-privilege database user, keep its connection string server-side, and start with:

MONGODB_URI='mongodb://localhost:27017' MONGODB_DATABASE='opentrading' npm run dev

Never expose MONGODB_URI to browser code or commit it to the repository. The Audit page shows the signed-in user's own audit events and can export the filtered rows as CSV or JSON. MongoDB records use pseudonymous owner identifiers, scrub personally identifiable audit metadata, and apply retention for audit events (override with AUDIT_RETENTION_DAYS and DATA_PRIVACY_KEY). DATA_PRIVACY_KEY is required when NODE_ENV=production; the server refuses to start with the built-in development key.

Authentication

Google and Microsoft login use OpenID Connect Authorization Code Flow with PKCE. Identity credentials and sessions remain server-side in MongoDB. Register these callback URLs with each provider:

  • https://your-host/auth/google/callback
  • https://your-host/auth/microsoft/callback

Then configure:

APP_BASE_URL='https://your-host' \
GOOGLE_CLIENT_ID='...' GOOGLE_CLIENT_SECRET='...' \
MICROSOFT_CLIENT_ID='...' MICROSOFT_CLIENT_SECRET='...' \
MONGODB_URI='...' npm run dev

Optionally set MICROSOFT_TENANT_ID; it defaults to common.

Bank connections and transfers

Bank connections use an Open Banking (PSD2/FDX-style) provider. Consent is granted at your own bank, so OpenTrading never handles banking credentials, and only masked account details are shown. Transfers are prepared as ISO 20022 pain.001 instructions and settle over SEPA for euro payments inside the SEPA zone or over SWIFT otherwise.

OPEN_BANKING_API_URL='https://api.your-provider.com/v1' \
OPEN_BANKING_API_KEY='...' \
OPEN_BANKING_REDIRECT_URI='https://your-host/banking.html' npm run dev

Keep OPEN_BANKING_API_KEY server-side. Without this configuration the banking endpoints return 503 and the Banking page explains that the feature is not configured; GET /api/banking/institutions still lists the built-in banks.

ICICI Bank, HDFC Bank, State Bank of India, AIB, Bank of Ireland, and ABN AMRO are always offered in the bank picker. Irish and Dutch euro payments settle over SEPA. Indian rupee payments use an account number and IFSC code instead of an IBAN and BIC and settle over IMPS, or over RTGS from ₹200,000.

Market data

Market movers, holdings, and the order ticket use the bundled illustrative prices until a market-data provider is configured. With a key, the server fetches quotes over HTTPS, caches them for 30 seconds, and the dashboard refreshes them every minute and shows how fresh they are.

MARKET_DATA_API_KEY='...' MARKET_DATA_PROVIDER='finnhub' npm run dev

MARKET_DATA_PROVIDER accepts finnhub (default) or twelvedata, and MARKET_DATA_API_URL can override the base URL. Keep MARKET_DATA_API_KEY server-side; the browser only ever calls GET /api/quotes on the same origin. Without a key that route returns 503 and the dashboard keeps the cached, illustrative prices, so the app still works offline. Live prices only change the displayed valuations — orders remain simulated.

Exchange rates

Bank transfers can be sent in eight currencies while the portfolio's cash balance is held in US dollars. With an exchange-rate provider configured, the server converts each foreign-currency transfer with a live reference rate before it settles, and exposes those rates on GET /api/fx.

FX_RATES_API_KEY='...' FX_RATES_PROVIDER='exchangerate' npm run dev

FX_RATES_PROVIDER accepts exchangerate (exchangerate.host, the default) or openexchangerates, FX_RATES_API_URL can override the base URL, and FX_RATES_BASE changes the base currency (USD by default). Rates are cached for 10 minutes and the key stays server-side. Without a key, GET /api/fx returns 503 and transfer amounts settle one-to-one, exactly as before.

News feed

The dashboard news panel needs at least one source. Headlines are cached for five minutes and merged per watched symbol.

NEWSAPI_KEY='...' TWITTER_BEARER_TOKEN='...' npm run dev

Either variable is enough. Without both, GET /api/news returns 503 and the panel shows "News feed unavailable" while the rest of the dashboard keeps working.

Trading 212

The Banking page also shows a read-only view of a Trading 212 account (cash, open positions, and account value). Create an API key in the Trading 212 app and keep it server-side:

TRADING212_API_KEY='...' TRADING212_ENVIRONMENT='demo' npm run dev

TRADING212_ENVIRONMENT accepts live (default) or demo, and TRADING212_API_URL can override the base URL. Because the summary comes from the deployment's own server-side API key, GET /api/broker/summary requires a signed-in session and returns 401 otherwise. Without a key, it returns 503 and the page explains that Trading 212 is not configured. OpenTrading never places real orders through the API.

Desktop apps

The desktop app is an Electron shell (desktop/main.cjs) around the same reviewed build. It serves the build over a secure app:// scheme with context isolation, a sandboxed renderer, no Node integration, and navigation restricted to the packaged origin.

npm run desktop        # build the web assets and run the app locally
npm run desktop:pack   # build Windows x64 and arm64 installers into release/
npm run desktop:pack:mac  # build macOS x64 and arm64 packages into release/

Packaging must run on the target platform: Windows installers on a Windows machine or runner, macOS packages on a Mac.

Project structure

Path Contents
index.html, research.html, banking.html, learn.html, setup.html, audit.html Page entry points
src/core/ Framework-free trading, banking, FX, quotes, news, and audit logic shared by client and server
src/core/research/ Investment research foundation: reference dataset with provenance, statistics, and the screener, DCF, risk, technicals, earnings, dividend, competition, quant, macro, portfolio, watchlist, report, and orchestration engines
src/server/ Server-side services: authentication, MongoDB repositories, and provider integrations
src/*.js, src/styles.css Browser controllers and styling for each page
scripts/server.js Node HTTP server that serves the build and the /api/* routes
desktop/, electron-builder.yml Electron shell and desktop packaging configuration
public/ Static assets, web app manifest, and service worker
test/ Node test runner unit tests
e2e/ Playwright specs and generated screenshots
docs/ Architecture and investor-concepts documentation

Quality

npm run lint
npm run build
npm run test:unit
npx playwright install chromium
npm run test:e2e

Unit tests enforce 100% line, branch, and function coverage for trading, banking, persistence, MongoDB repositories, authentication, and every research analytics engine. Playwright exercises desktop, Android, and iOS experiences and captures screenshots. Each pull request receives a comment linking to its screenshot artifact.

Deployment

Every merge to main builds and publishes the website to GitHub Pages. The Build desktop apps workflow builds x64 and arm64 Windows installers and macOS .dmg/.zip packages on every push and pull request and uploads them as artifacts; pushing a v* tag attaches them to a GitHub release. macOS packages are unsigned, so Gatekeeper asks for confirmation on first launch; set the CSC_LINK and CSC_KEY_PASSWORD secrets and drop CSC_IDENTITY_AUTO_DISCOVERY: "false" from the workflow to sign them. Successful merged pull requests also update the release status below.

Latest merged pull request: #31

Security

Please report vulnerabilities privately through GitHub Security Advisories. Never include credentials or real financial information in issues.

Privacy and terms

Read the Privacy Policy for details on what data OpenTrading processes, where it is stored, and how long it is retained, and the Terms of Service for the rules governing use of the Service.

Licensed under the Apache License 2.0.

About

A trading platform for buying and selling stocks across exchanges worldwide, paired with Portfolio-Watcher for watching the same symbols.

Topics

Resources

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages