Quant agents that evolve under audit.
An oracle that keeps a ledger.
Factor timing Β Β·Β Multi-perspective research Β Β·Β Factor lab Β Β·Β Risk engine Β Β·Β Strategy evolution Β Β·Β Machine-approved orders Β Β·Β Omikuji
English Β |Β δΈζ
Every factor proposed, every strategy mutated, every order routed β logged, versioned, reviewable. Agents pick the currently-effective factors to time entries, write the strategies, and evolve them; the LLM writes the code, and the engineering harness signs every decision.
Inalpha is a professional quant agent framework β an open-source system where LLM agents research (with a panel of investing legends), pick the factors that work now, write and evolve strategy code, and route every order through machine approval, all under an audit-grade engineering harness. A unified kernel (one strategy codebase β swap only the Clock and Gateway), multi-market routing (crypto, US equities, A-shares, global indices, macro), and a Claude Code-style hooks/permissions/plan-exec layer back it β built for teams that demand every decision be provable and every order path be unreachable by the LLM directly.
Inalpha is a professional quant agent framework, governed by engineering discipline. It treats LLM agents not as black-box signal generators, but as code-writing collaborators bounded by hooks, permissions, plan-then-execute approval, and a one-shot signature on every order path.
Agents pick the factors that work now. Instead of a hard-coded indicator set, they rank factors by time-series Rank IC and surface the ones currently effective (factor.timing), then use that to back research and timing. Data itself is source-attributed by default β as_of-stamped and freshness-checked β so agents don't quietly reason on stale data.
Several capability lines sit on top of that harness:
- Factor lab + factor timing β agents formalize, compute, IC-test, multiple-testing-check, and register factors, and rank them by time-series Rank IC to time entries; every hypothesis is logged with author, timestamp, and the economic-story gate decision.
- Multi-perspective research β a deep dive convenes technical / fundamental / sentiment analysts, plus an optional panel of investing legends (Buffett / Lynch / Wood / Burry / Druckenmiller / Marks) for opposing views that feed a synthesis.
- Risk engine β declarative rules (notional caps, price deviation, drawdown veto) enforced at the HTTP boundary, not in prompts.
- Strategy evolution β LLMs mutate full Python source through auditable unified diffs; AST audit, restricted loading, subprocess execution, and the
Strategyprotocol contract precede evaluation; multi-objective fitness (Sharpe + Calmar β turnover β drawdown) keeps one metric from dominating. - Machine-approved orders (no direct LLM path) β order intents go
trade.create_plan β approve β execute_planwith a single-use, TTL-boundapproval_token; the LLM has no direct path to placing an order, and every step is logged into the audit trail. - Inari Omikuji β a shrine fortune draw (playful easter egg) β undecided on direction? Cast a hexagram or draw a tarot card for a vantage outside the data; hard-walled from decisions, it can't touch risk, orders, or factors (see Core Capabilities Β§7).
The name combines Inari (the Japanese fox deity of prosperity) with alpha (the quant term for excess return) β a companion that reads your direction and keeps every step on the record.
Status: Inalpha is in alpha β 79 factors with lineage & decay watch, restricted-DSL factor discovery, a three-party research debate, multi-market paper trading, and an E1 strategy-evolution service. Each evolution run requires explicit approval, freezes its dataset and non-secret LLM/pricing snapshot, and never auto-promotes or starts a candidate. Read the code, weigh in on design β do not run this against real money (real-money trading is out of scope).
The Operator Console (apps/dashboard) is the home base β a runtime dashboard that surfaces everything you'd otherwise have to ask the agent for, with a docked agent chat on the right. The shots below are the live console, running locally.
Portfolio Overview β accounts, positions, live runners, recent orders, and the strategy pool at a glance, with a KPI strip (return Β· max drawdown Β· Sharpe Β· win rate).
See Quick Start to bring the console up locally (
pnpm devβ http://localhost:3001).
| Principle | Substance |
|---|---|
| Discipline over vibes | Hooks, permissions, plan-exec separation, and a one-shot approval token are declared in config β not in prompts. A failing guardrail has a single point of debug. |
| Structured roles, not a chat wrapper | Research convenes a panel of analysts and an opposing-stance bull / bear / risk debate; every decision routes through hooks, permissions, and plan-exec. The structure lives in code, not in one mega-prompt. |
| Transparency over precision | Prefer an agent that says "I don't know" over one that sounds certain but cannot show its evidence. |
| Unified kernel | One strategy codebase across backtest and paper β swap the Clock and Gateway, not the logic. When behavior diverges, the cause is physical (slippage, latency, data precision), not two code paths. (Real-money live is intentionally out of scope.) |
| Long-horizon compounding | Solid infrastructure before flashy features. Surviving long matters more than running fast. |
Three software layers over one data layer. A request flows down; results flow back up.
L1 Β· User entry. The Operator Console (apps/dashboard) is the home base, with a docked agent chat. The mastra dev playground is there for live trace; direct CLI tool calls still work.
L2 Β· Orchestration β packages/orchestration (Mastra Β· TypeScript). The one layer LLMs run in: a single orchestrator agent wrapped in tools, hook/permission middleware, DB-backed plan/approval state, conversation memory, and telemetry.
L3 Β· Kernel services β Python Β· FastAPI. Five independent services, each owning one job:
| Service | Owns |
|---|---|
services/data |
Market data, web search, and financial fundamentals (A-shares / HK / US / global). |
services/paper |
The event-driven kernel β backtest + paper on the same code β plus the LLM-authored-strategy sandbox and the live runner. |
services/research |
Multi-agent deep dive: 6 analysts in parallel, then a bull / bear / risk debate (triggered only when they disagree, with a soft early-stop and the decision chain persisted for replay). |
services/factor |
The factor library (pandas-ta / Alpha101 / qlib + FRED macro): IC screening, current-effective factor timing, lineage & decay watch, DSL factor discovery. Signals only β never places an order. |
services/evolver |
Owner-scoped E1 strategy evolution: unified-diff mutation, frozen-data evaluation, candidate/run lineage, cost accounting, and an explicit approval boundary. Never auto-promotes, starts, or trades a candidate. |
L4 Β· Persistence & external. Postgres + TimescaleDB holds all time-series and business state. External venues span crypto, US / A-share / HK and other Asian & European single-name equities, global indices, and FRED macro β the orchestrator routes each venue automatically by market type.
The strategy-evolution loop runs asynchronously alongside the runtime. It persists and ranks candidates inside services/evolver; moving a selected candidate into the Paper strategy lifecycle remains a separate, explicitly approved action β there is no automatic promotion (sandbox gates, fitness function, and the E1 β E4 ramp are in Core Capabilities Β§3). See docs/04-current-state.md for the live module inventory and what's still in flight.
Each capability below is built so the work it produces is auditable from day one β not retrofitted later.
An alpha hypothesis is a guess about what predicts returns ("stocks with low volatility outperform"; "options skew steepens before drawdowns"). Traditional factor research is bottlenecked by the manual loop β a single researcher can usually validate 5β10 such guesses a day. Inalpha lets agents do that work without taking shortcuts.
- Talk it through. Drop a hypothesis in plain language; agents formalize it, compute the values, and run the standard statistical checks in seconds.
- Not just a registry β timing too. Rather than a hard-coded indicator set, agents rank factors by time-series Rank IC to surface the ones effective right now (
factor.timing), backing research and entry timing β when the market rotates, the chosen factors rotate with it. - Cross-section, not only timing. The same factors also rank across a basket β
factor.panel_scorescores a universe by cross-sectional Rank IC each period (who's strongest now, who to rotate into), orthogonal to single-name timing. Alpha101 cross-sectional factors are computed natively on the panel. - An economic story gate. A factor without a "why" never enters the library. The gate is a required step, not a recommendation.
- Guardrails for the classic mistakes. Looking ahead in time, surviving-only universes, over-parameterized search, too few samples, normalization leaks β five middleware checks intercept each one before it pollutes a result.
- No silent promotion. Registering a factor to the library is permanently human-only. Rejected factors are kept on file for postmortems, not silently dropped.
Shipped today: conversational tools (L0), a fixed validation workflow (L1), and factor discovery β a restricted-DSL candidate pool with multiple-testing correction and a null-IC benchmark, plus lineage & decay watch on the factors a strategy depends on. A multi-agent factor crew (L2) and weekly automated scans (L3) are planned. Design notes in
docs/03-kernel-design.md.
Letting an LLM call submit_order directly is how you lose money fast. Telling it "don't exceed 10% of capital" in a prompt is a suggestion, not a constraint β a sufficiently confident model will override it. So Inalpha moves risk out of prompts and into the middleware.
- Three-step orders. Every trade idea travels propose β approve β execute. Approval (by a risk agent, by a human, or by an automated rule) mints a single-use, short-lived signing token. Execution consumes the token; the token is revoked the moment it is spent.
- Hard rules at the service boundary. Notional caps, price-deviation guards, drawdown veto, per-instrument-class limits β enforced before any state change. A violating order is rejected with its reason logged against the originating proposal.
- A complete audit trail. Every proposal, approval, and execution is persisted with who, why, when, and the token's full lifecycle. The same record drives postmortems and feeds back into the strategy-evolution loop.
- A framework-level disaster stop. Independent of any strategy, a Position Guard enforces a catastrophe stop-loss (default β20% hard stop) across both backtest and live β it doesn't ask the LLM, and a prompt can't talk it out of firing.
Human-written strategies hit a velocity ceiling, and parameter tuning can only adjust dials β it cannot discover a structural change like "add an RSI filter to the SMA cross." Inalpha lets an LLM rewrite the strategy's Python source, then puts every candidate through hard gates before it ever touches a backtest.
- Full source with auditable mutations. The run starts from a vetted built-in or owner-owned promoted strategy, asks the LLM for a unified diff, applies it with bounded fuzz, and persists both the parent snapshot and diff.
- Layered execution gates. A static AST audit, restricted loader, subprocess evaluation, and final
Strategycontract check reject malformed candidates. The subprocess boundary keeps CPU work away from the API loop; it is not presented as a hardened container or VM sandbox. - Balanced fitness, baseline-checked. Candidates are scored on a balanced fitness (return + risk-adjusted return β turnover β drawdown veto), and each is auto-raced against a buy-and-hold baseline β a high score has to beat just holding, not a single Sharpe number. MAP-Elites-style diversity control is deferred until after the narrower E2 loop and only if real runs justify it.
- Cross-validated, not a single lucky split. A candidate can run time-series cross-validation β WalkForward / Purged K-Fold / Combinatorial Purged CV with a Deflated Sharpe β so an edge has to hold across many out-of-sample paths instead of one window, with the test fold always reaching the latest bar.
- Reproducible end to end. One run freezes
as_of, the closed-bar dataset manifest/hash, seed source, baseline, candidate source/diff, evaluation snapshots, and non-secret LLM/provider/pricing metadata. The user's encrypted API key is resolved only for that owner and never stored in the run. - Explicitly authorized and non-promoting. Starting a run requires a trusted approval bound to the owner, operation ID, request, estimated cost, and frozen LLM snapshot. Completion never promotes, starts, or routes a candidate into the order path.
E1 now runs as the separate
services/evolverservice on port 8005. E2 is intentionally narrower than the original research plan: best-parent multi-generation selection plus early stopping first; MAP-Elites and Island Model wait for real run data to justify the complexity.
Real quant research is concurrent by nature: 5 symbols Γ 3 factor families Γ 4 time windows = 60 backtests. Running them one at a time inside the agent runtime is a dead end.
Inalpha splits scheduling from compute. The agent runtime fans out the grid and aggregates results; a Python worker pool inside services/paper actually runs the backtests in parallel processes with resource limits. "Run momentum / mean-reversion / breakout across BTC, ETH, SOL, BNB, AVAX for 2024" becomes one workflow call that returns a Pareto frontier.
Current implementation (S1): single-host process pool, concurrency 4, grid capped at 20 backtests per call.
A deep dive doesn't hand you one "correct answer." Beyond the usual technical, fundamental, and sentiment analysts, you can convene a panel of master personas β Buffett (value / moats), Lynch (GARP growth), Wood (disruptive innovation), Burry (contrarian / bubbles), Druckenmiller (macro trends), Marks (cycles / risk): each argues in their own style, naturally forming opposing views that feed a synthesized judgment.
- Opt-in, cost-controlled. A plain deep dive costs the same as before; you only pay for the masters you actually convene.
- Views grounded in data. Each persona reads technicals / fundamentals / web intel with
as_ofpinned to now β no passing a stale forecast off as the present. Fundamentals are read point-in-time, filtered by report period and release lag so a backtest never sees a number before it was public (Baostock today; yfinance v1 not yet PIT, flagged in place). - Structured bull / bear / risk debate β now live. Beyond the parallel analysts, opposing-stance bull and bear researchers argue across rounds while a risk researcher stress-tests both β triggered only when the analysts genuinely disagree, with a soft early-stop when arguments stop changing and the full decision chain (why it debated, why it stopped, how it was synthesized) persisted for replay.
A good investing method is often a procedure, not a model β "trace a hot theme down its supply chain to the bottleneck," say. Inalpha can load those as skills: auto-discovered markdown playbooks the orchestrator pulls into context on demand.
- Progressive disclosure. On startup it scans the skills folder and surfaces a one-line menu; a skill's full text loads only when a task actually needs it β no prompt bloat, zero cost when none apply.
- Fail-open and trust-bounded. A broken skill is skipped with a warning, never blocking the agent. Skills are read-only markdown (no bundled scripts are vendored or executed), and every "look up data" step is mapped onto the existing
web.* / data.* / factor.* / research.*tools under the same freshness discipline. - Bundled today.
cn-equity-research(A-share systematic research),serenity(supply-chain-bottleneck investing),earnings-analysis(earnings recap),thesis-tracker(falsifiable-thesis tracking) β each rewritten to be market-agnostic and source-grounded, with any trade action routed back through the approval chain.
Real money invites real hesitation. When you're stuck, let the Inari priestess β Ξ± kit on her shoulder β draw you an omikuji (a shrine fortune slip): cast an I Ching hexagram or pull a tarot card for a vantage outside the data. A different angle, a breath, maybe a small unexpected nudge from Inari.
- A whisper, not an order. The hexagram or card never touches risk, approval, order placement, or factor scoring β it can't read or sway a single real decision. Which quietly makes the point: if even Inari's omen can't reach the decision path, the machine-approval boundary is real.
- The trade still answers to data. Once the slip is drawn, the call still belongs to research, factors, and backtests; the omikuji only helps unknot your brow.
The hardest adversary in quant research isn't the market β it's multiple-testing bias. Pick the best of many trials and you'll find a Sharpe of 2.0 in pure noise. So Inalpha never leans on one clever backtest; every stage where a "best" gets selected carries its own statistical correction.
| Stage | Defenses | What it prevents |
|---|---|---|
| Backtest validation | Combinatorial Purged CV (purge + embargo) Β· Deflated Sharpe (corrects for N trials) Β· bootstrap Sharpe 95% CI Β· parameter-neighborhood sensitivity β POST /backtest/cv, POST /backtest/sensitivity |
A lucky window, or a fragile parameter peak, passing as a real edge |
| Factor screening | null-IC selection benchmark Β· BenjaminiβHochberg FDR correction Β· economic-story gate Β· Ο < 0.85 de-correlation | A data-mined ghost factor reaching the library |
| Strategy evolution | multi-objective fitness (return β turnover β drawdown veto) Β· buy-and-hold baseline race | A candidate gaming a single metric to look good |
| Look-ahead defense | point-in-time fundamentals Β· FRED release-lag table Β· bars truncated to as_of Β· CV test fold ends on the latest bar |
A backtest seeing data that wasn't public yet |
DSR and the bootstrap Sharpe CI are surfaced in the CV / backtest reports today; PBO (Probability of Backtest Overfitting, CSCV) lives in
services/paper/.../engine/robustness.py, ready for swarm-grid comparison.
Where each capability stands today. Live module inventory and the end-to-end decision sequence diagram live in docs/04-current-state.md.
| Status | Capability | Phase | Highlight |
|---|---|---|---|
| β Shipped | Plan/Exec audit trail + Hooks + Permission Engine | D-8a | three-step orders Β· one-shot signing token Β· 5 lifecycle hook events Β· allow / ask / deny tri-state |
| β Shipped | Research β strategy β backtest lineage | D-8c | deep_dive β compose_strategy β run_backtest with research_id / backtest_id threaded through |
| β Shipped | LLM-authored strategies β E1 MVP | D-9 | three sandbox gates (AST Β· subprocess Β· Strategy contract) + multi-objective fitness + baseline auto-run |
| β Shipped | Strategy evolution β E1 production loop | E1 | services/evolver:8005 Β· explicit cost-bearing approval Β· unified-diff mutation Β· frozen dataset/hash Β· seed/baseline/candidates evaluated on the same bars Β· owner-scoped async run/slot state |
| β Shipped | Frozen LLM approval snapshot | E1 closure | Dashboard approve/deny Β· owner/operation/model/pricing binding Β· Ed25519 replay-safe credential grant Β· per-slot token/cost accounting, including rejected mutations |
| β Shipped | Risk engine at the HTTP boundary | D-9 | declarative risk_rules.toml Β· pre-trade enforce Β· risk_locks table with independent commit |
| β Shipped | Bull / bear researcher debate | D-9 | opposing-stance researchers under services/research |
| β Shipped | Scheduler / cron agent mode | D-9 | scheduler_jobs + advisory lock + /api/scheduler/* management plane |
| β Shipped | RiskGuard per-account isolation | D-9.1a | RiskGuardFactory removes cross-account state bleed |
| β Shipped | Multi-market data sources β web search + financial fundamentals | D-10 | zero-key DDGS web search Β· baostock is the logical A-share venue: Tencent HTTPS bars/ticker + Baostock fundamentals/calendar/constituents; yfinance covers global markets including HK Β· analyst integration + fallback Β· per-market lookbackDays |
| β Shipped | Unified multi-market financial news | D-12 | GET /news + data.get_news Β· Eastmoney / SEC / HKEX / Crypto feeds Β· current-snapshot as_of filtering with explicit incomplete-history coverage Β· observable provider failures Β· explicit index/ETF proxy labels for market-level stock news |
| β Shipped | Risk engine β all 5 rules live in HTTP path | D-9 closed | closed_trades writes from HTTP order flow; RoutingCalendar for US equity + crypto; all trade-based rules trigger on real data |
| β Shipped | askUserChoice β ask permission path |
D-11 (issue #2) | pending-permission flow resolves the ask state (no longer a workaround) |
| β Shipped | permissions.yaml configuration |
D-11 (issue #4) | config/permissions.default.yaml + yaml_loader.ts replace the hard-coded defaults.ts |
| β Shipped | Multi-market paper trading β live runner + multi-currency cash | D-11 | closed-bar on_bar β guarded plan/exec Β· per-currency cash buckets + FX-converted equity Β· D-11.1 trust-boundary hardening (candidate ownership check Β· per-account run cap Β· retryable-error split) |
| β Shipped | Factor library + IC effectiveness | D-11 | services/factor (pandas-ta / Alpha101 / qlib) Β· factor.timing / .score / .catalog Β· signals only, no execution |
| β Shipped | Live runner ops hardening | D-11.2 | net PnL (fees deducted) Β· runtime TTL auto-stop Β· build-phase backoff + error classification |
| β Shipped | Skills as procedural memory | D-11 | auto-discovered markdown skills (progressive disclosure Β· fail-open Β· read-only trust boundary) |
| β Shipped | Research debate β three-party + contested trigger | D-12 | 6 analysts + bull / bear / risk researcher Β· contested-only trigger Β· Jaccard soft early-stop Β· decision chain persisted |
| β Shipped | Factor lineage & decay watch | D-12 | factor_snapshot + factor_baseline Β· independent decay patrol Β· factor_decay warning (alert-only, no auto-trim) |
| β Shipped | Monthly FRED macro factors | D-12 | CPI / core CPI / unemployment / payrolls / M2 (62 β 70 factors) Β· per-series release-lag table |
| β Shipped | FRED macro factors β Phase 3 | D-12 | credit spreads (HY / IG OAS) Β· curve front-end (10Yβ3M) Β· real economy (PPI / industrial production / retail) Β· sentiment (70 β 79 factors) |
| β Shipped | Factor discovery β L1 | D-12 | restricted qlib-style DSL (zero eval/exec) Β· factor_candidates pool Β· multiple-testing correction + null-IC benchmark Β· discovery workflow β propose; register is dashboard-only |
| β Shipped | Cross-sectional factor scoring | D-12 | factor.panel_score Β· POST /panel/score Β· cross-sectional Rank IC (rank the pool each period vs forward cross-sectional return) Β· native Alpha101 a1/a3 Β· orthogonal to single-name timing |
| β Shipped | Time-series cross-validation β anti-overfitting | D-12 | WalkForward / PurgedKFold / Combinatorial Purged CV + Deflated Sharpe Β· POST /backtest/cv Β· test fold always includes the latest bar Β· auto-fallback to walk-forward when samples are short |
| β Shipped | Point-in-time fundamentals | D-12 | Baostock financials filtered by actual publication date Β· GET /fundamentals?as_of= Β· prevents look-ahead (yfinance v1 not yet PIT, explicitly flagged) |
| ποΈ Planned | Strategy evolution β E2 | E2 | best-parent multi-generation loop + early stopping; MAP-Elites / Island Model deferred until real run data shows a diversity problem |
| ποΈ Planned | Factor discovery β L2 / L3 | L2 / L3 | multi-agent factor crew (L2) + weekly automated scans (L3), on top of the L1 DSL pipeline already shipped |
| ποΈ Planned | Automated decay handling | TBD | reflection-driven backtest + auto-trim of decaying factors β today the decay patrol only alerts, never moves the book |
| π¬ Exploring | Alpha Zoo cold start | E1+ | seed factor library with public alphas (Qlib / Kakushadze / GTJA) |
| π¬ Exploring | E4 evolve_strategy MCP tool |
E4 | evolution loop exposed to the orchestrator as one MCP tool |
| π¬ Exploring | Point-in-time fundamentals β deeper coverage | TBD | bars-table PIT metadata + adjustment handling, beyond the report-lag filter shipped today |
| π¬ Exploring | Analog backtesting | TBD | similarity-window-driven backtest range selection (STUMPY) |
Legend β β Shipped: behavior already lives in
mainΒ· βοΈ In Flight: actively in this phase Β· ποΈ Planned: scoped for an upcoming phase, not started Β· π¬ Exploring: research recorded, no commit date.
| Audience | Value |
|---|---|
| Quant researchers and students | LLM agents accelerate research; one tech stack for backtest and live |
| Trading system engineers | A reference integration of modern agents with traditional kernels, cross-referenced against Nautilus / qlib / vnpy |
| AI agent developers | Real-world financial deployment of multi-agent + hooks + permissions |
| Individual traders (research-oriented) | A research companion you can talk to, plus an engineered home for your strategies |
This is the supported Docker path for a personal server or local machine. It builds the complete stack locally: PostgreSQL/TimescaleDB, Redis, migrations, data, paper, research, factor, evolver, Mastra, and the Operator Console.
Prerequisites: Docker Engine with Docker Compose v2, Git, and OpenSSL. Clone the repository, then initialize the local-only environment file and start the stack:
git clone https://github.com/mirror29/inalpha.git
cd inalpha
bash scripts/selfhost.sh init
bash scripts/selfhost.sh upThe console is available only on the host at http://127.0.0.1:3001. Wait until bash scripts/selfhost.sh status shows the application services healthy, then create the first login account. The prompt reads the password without echoing it or placing it in shell history:
bash scripts/selfhost.sh create-user --email you@example.comFor a public deployment, create the review account with the admin role (use your
existing owner subject if it must keep the current account data):
bash scripts/selfhost.sh create-user --email admin@inalpha.dev --roles admin --subject console:devVisitors can then choose Request a trial on the sign-in page. Registration creates a
pending account without accepting a password. Approval in Trial Waitlist generates a
one-time activation link: send it to the applicant's stated email address to verify mailbox
ownership. The applicant sets a password from the link and only then becomes active. Links
expire after 48 hours and can be regenerated; rejected applications remain blocked.
Because the application endpoint is public, keep a persistent per-IP rate limit or challenge
enabled at the reverse proxy / CDN layer; the in-process limits are only a second line of defence.
Sign in at http://127.0.0.1:3001, open LLM Settings, and add your provider, model, and personal API key. The Dashboard encrypts it with LLM_CONFIG_ENCRYPTION_KEY; the orchestrator and Evolver resolve that owner-scoped credential. The standalone Research service still uses the deployment-level LLM_PROVIDER / LLM_MODEL and matching provider key in infra/.env.selfhost, so configure that block if you need deep dives and treat it as a shared-credential boundary until per-owner propagation lands.
Useful operations:
bash scripts/selfhost.sh logs [service]
bash scripts/selfhost.sh status
bash scripts/selfhost.sh downThe self-host Compose file intentionally exposes only 127.0.0.1:3001. For remote access, place your own TLS-terminating Caddy, Nginx, or Cloudflare Tunnel in front of the Dashboard and proxy only that address. Never publish PostgreSQL, Redis, Mastra, or the Python service ports, and do not expose the login or API-key settings page over bare HTTP.
cd packages/orchestration && pnpm i && cd ../..
for service in data paper research factor evolver; do
(cd "services/$service" && uv sync)
doneA single .env at the repo root is read by Mastra (TS) and all Python services. Copy the template and fill in the LLM provider you want to use:
cp .env.example .envInside .env, set LLM_PROVIDER to one of deepseek | anthropic | openai | gemini | kimi | zhipu | ollama and fill in the matching key.
Defaults pick each vendor's current flagship as of 2026-05. Override with LLM_MODEL=... if you want a reasoning / cheaper variant.
| Provider | env var | Default model (2026-05) | Get a key |
|---|---|---|---|
deepseek |
DEEPSEEK_API_KEY |
deepseek-v4-pro |
platform.deepseek.com |
anthropic |
ANTHROPIC_API_KEY |
claude-opus-4-8 |
console.anthropic.com |
openai |
OPENAI_API_KEY |
gpt-5.5 |
platform.openai.com |
gemini |
GEMINI_API_KEY |
gemini-3-pro |
aistudio.google.com |
kimi |
KIMI_API_KEY |
kimi-k2.6 |
platform.moonshot.ai |
zhipu |
ZHIPU_API_KEY |
glm-5.2 |
open.bigmodel.cn |
ollama |
β (local) | llama4 |
ollama pull llama4 |
Override the default model by setting LLM_MODEL=... in the same file. Mastra and services/research both read this one file β no per-service config to juggle.
If you want to run Evolver, also generate its Ed25519 credential-grant keypair and place the DER
base64 values in EVOLUTION_CREDENTIAL_PRIVATE_KEY_B64 / EVOLUTION_CREDENTIAL_PUBLIC_KEY_B64.
The exact commands are in services/evolver/README.md. Evolution is
fail-closed without these keys and currently accepts only the priced default model for each of
DeepSeek, OpenAI, Kimi, and Zhipu; ordinary chat can still use other models or custom proxies.
Already have keys in
services/*/.envorpackages/orchestration/.envfrom earlier? Those still work as cwd-level overrides while you migrate. Once you copy them up into the root.env, the per-service files can be deleted.
Optional Β· FRED key for macro factors. The factor library's macro factors (macro.* β rates, term & credit spreads, CPI, payrolls, real-economy, sentiment) read FRED data via venue=fred. Set FRED_API_KEY in .env to enable them β it's free and instant. Without a key the connector simply isn't registered and macro factors degrade gracefully (price/volume factors are unaffected). Note: macro factors are computed only at timeframe=1d/1wk β they're filtered out on intraday bars (monthly series would be a step function), so request 1d to see them.
cp infra/.env.example infra/.env
(cd infra && docker compose up -d)
(cd infra/migrations && uv sync && uv run alembic upgrade head)The local defaults in infra/.env.example and the repository-root .env.example are intentionally
identical. If you change the database password or port, update both files before starting services.
bash scripts/dev.sh # one shot β data (8001) + paper (8002) + research (8003) + factor (8004) + evolver (8005) + mastra (4111)
bash scripts/dev.sh logs # follow service logs
bash scripts/dev.sh stop # stop everythingThe Operator Console is the recommended way to use Inalpha β your home base. A runtime dashboard surfaces everything you'd otherwise have to ask the agent for, at a glance: portfolio & positions, live runners with bar-by-bar decisions, the cross-module agent activity timeline, the strategy lab, the system factor library, the risk panel, and the Inari Omikuji. A docked agent chat sits on the right β talk to the orchestrator directly: pull quotes, run backtests, tune factors, draw a hexagram, all in one place.
cd apps/dashboard
pnpm i # first time only
pnpm dev # β http://localhost:3001No per-app config β the console reads the repo-root .env directly (backend URLs + JWT_SECRET
are inherited), so as long as the services from step 4 are up, it just connects. It ships with
dark / light themes (a terminal "Vermilion" aesthetic β see apps/dashboard/design.md)
and an en / δΈ switcher in the sidebar.
The console is the single front door: data, research, backtests, live runners, and the conversation with the orchestrator now all live in one place.
The orchestrator and an explicitly approved
services/evolverrun can consume your owner-scoped LLM key;services/researchcurrently uses the deployment-level provider/key, andservices/papernever calls an LLM directly. Evolver resolves the encrypted credential just in time through an owner/operation-bound credential grant. A lost response permits one exact-scope retry within two minutes; the queued grant is cleared after a successful exchange, and only the frozen non-secret config/pricing snapshot remains. Prefer the manual multi-terminal flow, or want the low-level live trace (themastra devplayground at http://127.0.0.1:4111)? SeeAGENTS.md Β§4.
With the console up, talk to the orchestrator in the docked chat on the right β it replies in the language of your message. Each prompt below shows off a different part of the system:
Which factors are working for NVDA right now, and how strong is each?β factor timing: ranks the currently-effective factors by time-series Rank IC, with decay state.Research NVDA: latest price + fundamentals, run a bull / bear / risk debate, and synthesize a rating.β multi-perspective research: six analysts in parallel plus a three-party debate, triggered only when they disagree, with the decision chain persisted.Research TSLA with a Buffett and a Cathie Wood take.β investing-legends panel: opt-in master personas argue in their own styles.Trace the AI-compute supply chain to its tightest bottleneck and surface the names worth researching first.β research-methodology skills: auto-loads an external playbook (e.g.serenitysupply-chain bottleneck, orcn-equity-researchfor A-shares).Design a mean-reversion strategy for ETH, backtest the last 6 months, and show its fitness vs buy-and-hold.β LLM-authored strategy: the model writes the full source, it clears three sandbox gates, then auto-races a baseline.Evolve my promoted BTC strategy with one candidate and stop after this run.β E1 evolution: shows the frozen model and estimated cost for approval, evaluates seed/baseline/candidate on one dataset hash, and leaves promotion as a separate human decision.Backtest momentum / mean-reversion / breakout across BTC, ETH, SOL for the last year and give me the Pareto frontier.β swarm: dozens of backtests fanned out in parallel.Open a small NVDA position.β machine-approved orders: watch it route through propose β approve β execute; the LLM has no direct path to placing an order.
Examples only, not a fixed menu β ask about any ticker or market (crypto Β· US Β· A-shares Β· HK Β· global indices Β· commodities Β· FRED macro) in any language; the orchestrator picks the venue and answers in kind.
Inalpha is tool-neutral and local-first. Strategies, data, and decision records live in your repository β LLM calls go to external providers, but structured outputs and cache control are owned by the codebase, so the harness is observable, auditable, and provider-swappable. The hard constraints (naming, untouchable directories, commit conventions, three-part tool-description style) are declared once and read by every AI coding tool:
CLAUDE.mdβ Claude Code project-level memoryAGENTS.mdβ common entry point for Cursor / OpenAI Codex / Aider / Continue / Clinescripts/check-consistency.shβ mechanical cross-file consistency checks
Inalpha is built on top of other people's good ideas. What we borrowed is named here so it's clear we're standing on their shoulders, not starting from zero.
Trading system designs
- Nautilus Trader β the same-code invariant across backtest / paper / live, and the event-driven kernel
- vnpy β the Gateway abstraction and multi-market access mindset
- Microsoft qlib β factor expression DSL and point-in-time universe handling
- Hummingbot Β· Freqtrade β what open-source crypto tooling can be
Agent and LLM engineering
- TradingAgents β multi-agent opposing-stance debate for research
- Anthropic and the Claude Code team β hooks, permissions, plan/exec, MCP, and subagents as borrowable engineering primitives
- Mastra β the TypeScript agent orchestration scaffolding
- Model Context Protocol β the open protocol that lets tools plug in without hand-rolled glue
Infrastructure
- PostgreSQL Β· TimescaleDB Β· FastAPI Β· CCXT Β· Next.js Β· CopilotKit Β· uv Β· pnpm
And to every quant researcher who refuses to accept opaque "AI signals" β this project is written for you. We hope to give back, in time.
GNU AGPL-3.0 β free software with a strong network copyleft.
- Allowed: any use (personal research, academic, commercial in-house, integration into AGPL-compatible projects)
- Required: if you modify Inalpha and offer it as a network service, you must release the complete corresponding source under AGPL-3.0
- Commercial licensing (proprietary / closed-source / hosted SaaS without source release): please open an issue to discuss a dual license






