Real-time trading at AlgoNexus
Updated 2026-10-20
AlgoNexus is an AI investing and trading assistant for the United States, India, the United Kingdom and the euro area. It proposes ideas (Copilot), or trades inside a policy the user writes and consents to (Autopilot), through the user's own broker or a paper account. This report describes how the system is built and the rules it follows.
What AlgoNexus does not do. It never promises profits, a goal reached "in 10 days", or making anyone rich. Goals are answered with a probability and a P10–P90 range. Every signal shows its verified record after costs. The model cannot place an order on its own: every order passes the deterministic risk gate and is written to a tamper-evident audit log first. Most of what follows exists to enforce those three sentences.
Contents
- Architecture
- Data vendors and licensing
- Signal and backtest standards
- Goals across every horizon
- The Nexus agent and its memory
- Support desk
- Country framework
- Learning loop and privacy
- Model governance and the public report card
- Marketplace rules
- Risk controls
- Interfaces and platforms
- Operations
- Status and open items
1. Architecture
| Layer | What it is | Where |
|---|---|---|
| Engine | Python 3.12, FastAPI, SQLAlchemy. REST (OpenAPI 3.1), GraphQL (Strawberry) and an MCP server, all over one set of route handlers | apps/engine |
| Tick stream | Market-data fan-out: vendor and per-user broker websockets → normalised ticks → candles (1 s to 1 d) in Redis → server-sent events | apps/engine/.../marketdata/tickstream.py, bars.py |
| Web dashboard | Next.js 15, React 19, Tailwind (design system in docs/DESIGN_SYSTEM.md) — the signed-in app and the admin console | apps/dashboard |
| Website | Next.js public site: product pages, market pages, track record, report card, this report | apps/website |
| Mobile | Expo (React Native) for iOS and Android | apps/mobile |
| Desktop | Tauri 2 shell around the dashboard with a tray, notifications and a global "Pause Autopilot" shortcut | apps/desktop |
| Shared packages | api-client (typed client for every route), ui-web (components), chat-core, tokens | packages/* |
| Model pipeline | Daily ingest → datasets → training (quant models on CPU, Nexus LLM adapter on GPU) → eval gates → two-person promotion | model/, ml/, .github/workflows/daily-train.yml |
Request path for an order. Idea (model, signal, agent or user) → policy limits → risk gate (risk/__init__.py, deterministic, every check recorded) → audit log entry (hash chain) → orders/service.route → broker adapter (60+ adapters; paper by default) → reconciliation cron. In Copilot the order waits for the user's Approve. In Autopilot it is placed only inside the user's consented policy, and live money needs verified KYC and a per-broker live switch approved by two staff (4-eyes).
Real time. A tick carries source and delay from the exchange to the pixel. Candles are built deterministically from ticks, so the same ticks replayed give the same candles and the same signals — the test suite does exactly that. The browser batches a burst of ticks into one redraw per frame; the target is under 300 ms from trade to screen at p95 with 25 symbols on screen.
Storage. PostgreSQL (Neon in production, SQLite in tests) for accounts, policies, ideas, orders, the audit chain, signals and the learning tables; Redis for the hot candle window, rate limits and stream fan-out; an R2/S3 data lake for the model pipeline. Tables are created by db.init_db() and new columns are always nullable.
Deployment. Vercel (engine as serverless functions plus the two Next.js apps) or Kubernetes (Helm chart in deploy/helm/algonexus, which also runs the per-minute crons Vercel cannot). Docker Compose for local and single-VM installs. Every change that adds an environment variable, a service or a cron updates Compose, Helm and (for crons) the Vercel dispatcher's table apps/engine/src/algonexus_engine/cron_schedule.py in the same pull request.
2. Data vendors and licensing
Showing exchange data to many users needs a distribution licence; showing a user their own broker's data does not. So the rule is: the user's own broker feed when connected, otherwise an app-wide licensed feed, and every price says which one it is and how delayed.
| Need | Source | Licence status |
|---|---|---|
| India, app-wide real time | TrueData websocket (NSE cash and F&O, MCX) | redistribution agreement required; off until signed |
| India, per user | Zerodha Kite, Upstox, Dhan, Angel One, Fyers websockets | the user's own entitlement |
| US stocks and CME futures, app-wide | Databento live (distribution licensing); Polygon/Massive as a stocks-only alternative | off until licensed |
| US, per user | Schwab streamer, Alpaca, IBKR | the user's own entitlement |
| UK and EU, app-wide | Twelve Data (Pro/Enterprise with LSE, Euronext, Xetra licences) or EODHD real-time where licensed | TWELVEDATA_ENABLED=false until signed |
| UK and EU, per user | Saxo OpenAPI, IBKR | the user's own entitlement |
| Fundamentals, officers, news (IN/UK/EU) | EODHD All-In-One | licensed (paid key) |
| US fundamentals and filings | SEC EDGAR (public), Finnhub (free key) | public / free tier |
| Macro series, US release dates | FRED (St. Louis Fed) | public domain |
| Indian mutual-fund NAVs | AMFI daily NAV file; history via mfapi.in | official, free |
| Central-bank decision dates | Each bank's published schedule (Fed, RBI, ECB, BoE) | public; rows link to the official page |
| CPI / GDP / earnings dates, all markets | EODHD economic events and earnings calendar | licensed |
| Earnings-call transcripts | EODHD where the plan includes them (EARNINGS_TRANSCRIPTS_URL), or the company's own published transcript added by staff | licence or company publication; never scraped |
Free fallbacks (Stooq, Yahoo-style delayed quotes, Upstox public instruments) are labelled "delayed" and are never presented as real time. A vendor goes live only after its contract and API key are in place; until then the feature is behind a flag and the UI says what is missing.
3. Signal and backtest standards
Signals are data, not code. A signal is a declarative JSON spec (signals/spec.py): indicator conditions on a timeframe, plus stop and target rules. User-written code is never executed. Built-ins today: MACD/Bollinger breakout and breakdown, TTM Squeeze fire (long and short), DMI trend, ATR trend flip, TD Sequential setup 9 and countdown 13, EMA cross, RSI oversold reversal, VWAP reclaim, pivot R1 breakout, support bounce and resistance breakout. Ports of custom thinkorswim studies are tested bar for bar against exports before they ship.
Every emitted signal is fingerprinted before its outcome is known. Each firing is stored with the sha256 digest of the canonical event and an entry in the audit hash chain. A record cannot be edited or cherry-picked afterwards.
Backtest rules (signals/backtest.py), deliberately conservative:
- a hit on bar *i*'s close is entered at bar *i+1*'s open, so nothing the trade uses was unknown at the time;
- stop and target come from the spec, sized from information up to bar *i* and the actual entry;
- one position per symbol at a time;
- exits: stop, target, a maximum hold, or the last bar. When the stop and the target are both inside one bar, the stop is assumed hit first;
- costs: the market's fee schedule (
charges/) on both legs at a reference order size, plus slippage on both legs (US 2 bps, India 5 bps, UK/EU 3 bps); - the history is split by time: in-sample first, the last 30% out-of-sample.
Tradable or information only. A signal may create trade ideas only when its out-of-sample expectancy after costs is positive over at least 30 trades and its in-sample expectancy is positive too. Anything else is "information only": it still appears on charts, labelled, but never produces an idea. The verdict is re-computed every week, and the learning loop's live per-signal expectancy switches losers off automatically.
Public track record (/track-record, trackrecord.py). Every built-in signal's live firings are followed forward with the same rules as the backtest (entry at the next open; stop, target or 10 bars) and stored once by the track-record cron; they are never edited. The page shows live results next to the latest backtest, both net of costs, and publishes a digest over all records. Anyone can fetch the records (GET /v1/track-record/{signal}), recompute the statistics and check each audit hash.
4. Goals across every horizon
Feasibility first. policy/feasibility.py turns "grow X by Y% in N years" into the required annual return and an honest band (conservative → unrealistic) against long-run market history.
Probability and range. The goal planner (horizons/goal.py, POST /v1/goals/plan) answers "invest X, reach Y by this date" for a goal that can combine long-term investing, mutual funds, intraday and F&O, in any of the four markets, measured in the investor's home currency:
- monthly Monte Carlo with fat tails (Student-t, so crashes hit every sleeve together) and correlated sleeves;
- long-term sleeves use the market's capital-market assumptions (
allocation/cma_sets, illustrative until two approvers sign them off) for the chosen risk profile, less fund or trading costs; - intraday and F&O assume no edge: expected return is minus the market's round-trip costs times an assumed number of trades, with high volatility. The planner shows what short-term trading does to the odds and suggests the alternative;
- a sleeve in another currency carries FX volatility, an interest-parity drift and a conversion fee each way;
- tax by residence: capital-gains tax once at the goal for long-term sleeves, income-style tax every year for intraday and F&O (Indian speculative / non-speculative business income, US Section 1256 60/40, UK CGT, EU country rates); ISA, SIPP, IRA, Roth, 401(k), PEA and the Nordic wrappers pay none on the investing sleeves. Rates are estimates marked [verify];
- the answer: probability (shown as a ±10-point range, the model's calibration error), P10–P90 at the date, a yearly fan, each sleeve's assumptions, and the levers that would raise the odds (more time, a higher top-up, moving short-term money to long-term, or the typical outcome as the target).
Mutual fund pages (fundpages.py): India (AMFI) and UK/EU UCITS funds with a KID — NAV chart, trailing and rolling 1/3/5-year returns from every month-end, costs (OCF, Indian stamp duty, exit-load note), holdings where licensed, SEBI's risk-o-meter or the PRIIPs summary risk indicator with the KID link, and SIP / lump-sum calculators that also replay the plan on the fund's real NAVs (with XIRR).
5. The Nexus agent and its memory
POST /v1/agent/chat streams answers over SSE. The model order is configurable (AI_PROVIDER_ORDER): our own model once it passes its gates, then Claude, then the fallbacks. LLM output is analysis only; it never reaches a broker.
Tools — quotes, bars, signals and company detail; portfolio and orders; explain an order; goal feasibility and the goal planner; draft and backtest a signal spec; and propose a trade. A proposal becomes an idea with model_version starting agent:, which the order service always parks in "awaiting approval": the agent never places an order. While a staff member is impersonating, every agent tool refuses to act.
Memory — three tables: conversations, messages (personal identifiers such as PAN, card and Aadhaar numbers are masked before storage) and user memories (risk style, markets, signal preferences, goals, facts). Memories are retrieved each turn. Users see, edit and delete them in Settings → Nexus memory. Thumbs up/down on answers feed the learning loop (rating only — never the text).
Where it lives — a floating chat button on every page, a "Chats" section in the navigation (new, search, rename, delete, continue), the same on mobile, and ⌘/Ctrl+Shift+J on desktop. Website visitors get a help-only assistant.
6. Support desk
Chatwoot was removed (it leaked part of the login token as a contact id). The desk is built in.
- Talk to a human from Nexus chat (button or keywords): the conversation joins the support queue with its full transcript; the agent stops answering in it; staff replies stream back into the same chat (SSE, with typing and presence; polling on React Native) and stay in the user's chat history.
- Admin Support module: live queue, claim and assign, canned replies, internal notes, and create a ticket from a conversation.
- Tickets: status, priority, category, assignee; SLA timers (1 business day, and the SEBI grievance rule: acknowledge within 1 day, resolve within 21); email notifications; users see their tickets on the Support page. Guarded by the
tickets.managepermission. One support address everywhere. - Impersonation is view-only: no orders, approvals, settings, broker changes, chat messages or signal changes on a user's behalf; every page view is logged; a session can be started from a ticket and is linked to it.
7. Country framework
Countries are separate from markets. A person living in Germany can invest in the EU and US markets; a person in a country we do not serve is told so instead of silently becoming a US user.
- Registry (
countries/, ISO 3166): residence rules and age of majority, regulator, KYC requirements, currency, allowed products and markets, tax profile, disclosures, supported brokers, and an access tier: full, paper / education only, or blocked (sanctioned jurisdictions under OFAC, EU, UK and UN lists). - Gate checks:
country_access,product_allowed_for_country,kyc_verified(live only) andcountry_suitability. Live orders without a known country fail closed. - Product rules include: EU retail cannot buy US-domiciled ETFs (no KID), so UK/EU fund lists hold only UCITS funds, OEICs and ETCs that publish one; UK retail CFD and crypto-derivative restrictions; India's LRS limit for investing abroad; ESMA/FCA appropriateness questions and retail leverage caps for derivatives.
- KYC: a provider adapter (Onfido / Sumsub globally; DigiLocker / CKYC in India, or manual review), an admin review queue, and live trading only after a verified KYC.
- Tax: India (LTCG/STCG, ELSS 80C), US (short/long term, wash sales), UK (AEA, ISA/LISA/SIPP, s.104 pool, bed-and-breakfast rule), and EU profiles for DE, FR, NL, IT, ES, IE, BE, AT and the Nordics, each with official sources and marked [verify]. Not tax advice.
8. Learning loop and privacy
Details: docs/PRIVACY_LEARNING.md.
- Consent first.
User.training_consentis off by default. Only users who turned it on are captured, and only events at or after that moment. Turning it off stops collection at once and emits a tombstone so the pipeline drops that person's earlier events from future training sets. - Hourly capture (
learning-capture.yml→GET /v1/admin/export/events) of ideas and their signals, approvals, rejections and edits, manual trades, Autopilot actions, fills, outcomes at 1 h / 1 d / 5 d, gate blocks, model abstentions and errors, and thumbs on agent answers. - Pseudonymised: user ids become HMAC-SHA256 with a salt that never leaves the engine; no names, emails, account or broker ids; no free text written by the user; money only as a percentage of the account.
- Daily, the pipeline builds the mistakes report, supervised and preference training rows, and live per-signal expectancy (which switches losing signals off).
9. Model governance and the public report card
- Gates decide promotion. Every candidate model — the Nexus LLM adapter and the quant models (sentiment, regime, alpha) — is evaluated against baselines and the production model on held-out data: structured-output validity, refusal and regulation items per country, calibration, walk-forward metrics on real prices. A failed or unevaluated gate blocks promotion; a model reaches production only through a pull request approved by two people, and rollback is one command.
- Scores can never add risk on their own. Alpha scores become bounded, zero-sum tilts (±5% by default) that the risk gate still sizes; stale scores mean the engine abstains.
- Public report card (/models/report-card,
reportcard.py): daily, the pipeline publishes the mistakes report (losing trades and user rejections by signal kind, regime and market; risk-gate blocks by rule; abstentions; agent thumbs) and every model's gate results to the engine. The public view hides any group backed by fewer than 5 events; staff see everything in the admin console.
10. Marketplace rules
- Records are computed by us, never typed in by a creator. Every listing shows the same verified, net-of-cost record as the public track record, built from fingerprinted events.
- Free first. Sharing a signal (a public page with its rules, purpose, creator, verified record and risks, and "Apply to my account") ships before paid listings.
- Paid listings switch on per country only after the creator's KYC and a registration check: SEBI Research Analyst or Investment Adviser in India, a registered investment adviser (or a legal sign-off) in the US, FCA authorisation in the UK, MiFID / MAR compliance in the EU. Registration is shown on the listing.
- Payouts through Stripe Connect (Express), Razorpay Route and PayPal, minus a platform fee.
- A user-built signal is saved only after the user confirms it, is versioned and audited, and can drive Autopilot only after a passed backtest and two weeks of paper trading. Copy-trading follows the same rules, paper first, each follower with their own cap and risk gate.
11. Risk controls
The risk gate (risk/__init__.py) runs on every order from every source and records every check: kill switch, side and quantity valid, symbol allowed for the policy, quote available and data fresh, market open (per venue calendar), broker enabled and reachable, account state available, buying power and cash reserve, sufficient holdings for sells, no duplicate order, maximum position and per-fund caps, maximum orders per day, drawdown limit, asset classes allowed, lock-in (ELSS), crypto cap, intraday allowed / cut-off / capital and daily-loss limits, live trading allowed, and the country checks in section 7. F&O adds suitability (questionnaire per market), margin and hedge previews; speculative F&O always needs the user's approval.
Around the gate:
- policies are versioned and consented; Autopilot acts only inside the active version;
- the audit log is a SHA-256 hash chain (
/v1/admin/audit/verify, checked by a daily cron); - a platform kill switch (activated by operations or compliance; deactivation needs a second person);
- live trading per broker is enabled only through a 4-eyes approval;
- intraday positions are squared off before the broker's cut-off by a per-minute cron;
- staff use MFA, a stricter password policy, idle timeouts and RBAC permissions; impersonation is read-only;
- the MCP server and the agent are read / propose only — they never place, approve or cancel an order.
12. Interfaces and platforms
Every feature ships in REST, GraphQL, MCP (read and propose only), the TypeScript api-client and the generated docs together. A CI test fails if a REST route has no GraphQL field, MCP tool and client method, unless it is on a reviewed allow-list (admin-only routes, webhooks, crons, writes MCP must not perform). See docs/INTERFACE_PARITY.md and docs/API_ENDPOINTS.md.
Every customer feature ships on web, mobile and desktop together (docs/PARITY.md). End-to-end Playwright journeys run against a seeded paper environment, with accessibility checks on every website page.
13. Operations
- Crons: reconciliation, queued orders, equity snapshots, daily reports, trial lifecycle, broker re-auth reminders, backup verification (database plus audit chain), market movers, securities masters, intraday square-off, live snapshot, signal scans and backtests, and the track record. The list and schedules are in
deploy/README.md. - CI gates: unit, contract (OpenAPI fuzzing, GraphQL and MCP snapshots), mutation score, security (Semgrep, Trivy), typecheck and build, and the Playwright suite.
- Errors and traces across engine, web and mobile; a public status page; daily backups with a monthly restore drill.
14. Status and open items
Built and merged: the engine, brokers, allocation and goals, charges and tax, UK/EU markets, the data plane, the learning loop, interface parity, the design system, the goal planner across horizons, fund pages, the economic calendar and earnings-call summaries, the public report card and track record. In review: the signal engine, the Nexus agent, the support desk, countries and KYC, the admin panel, live dashboards. Under way: the marketplace, portfolios, tools and social features.
Things only the company can do, so the features stay off behind flags until they are done: vendor contracts and keys (TrueData, Databento, Twelve Data, EODHD transcripts), the KYC provider account, Stripe Connect / Razorpay Route / PayPal business accounts, legal sign-off for paid signals per country, and sign-off of the capital-market assumptions.
Past or simulated performance does not guarantee future results. AlgoNexus is not a registered investment adviser in every jurisdiction it serves; see the regulatory status page.