OpenWhale
Health Warn
- No license — Repository has no license file
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 140 GitHub stars
Code Fail
- rm -rf — Recursive force deletion command in packages/assistant/package.json
- rm -rf — Recursive force deletion command in packages/aster/package.json
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
The programmable layer for composable, AI-native economic strategies
OpenWhale
The programmable layer for composable, AI-native economic strategies
OpenWhale is a TypeScript framework for building automated economic strategies. Monitors, Strategies, and Executors are fully decoupled — the same strategy code runs on any venue, plugs into any data source, and can be written, audited, and evolved by an AI.
Why OpenWhale
- Fully decoupled layers — Monitors collect, Strategies decide, Executors act. Replace any layer without touching the others.
- Venue-agnostic by construction — a strategy never names an exchange. It declares account slots; the venue derives from whichever account you bind at activation. One strategy, any platform.
- The adapter matrix — venues plug in as cells of a (kind × venue) matrix (
exchange/perp × binance,exchange/spot × hyperliquid, …). Domain packages define the vocabulary, venue packages fill the cells, and a data-driven ccxt roster ships twelve venues out of the box. - AI as a programmer — LLM inference with structured output is built into the strategy layer, and the repo ships a
skills/openwhale-devskill that teaches any Claude the full framework contract so it can produce installable plugins with tests. - Deep observability — every strategy run leaves a persistent decision trace: what it saw, which gate said no, what it emitted. Deactivate an instance or restart the gateway and the audit trail survives.
- PnL attribution built in — executors auto-claim the orders they place; a background collector joins venue fills (ground-truth realized PnL and fees) and funding income back to the claiming instance. Two instances trading the same symbol on the same account stay separable.
- Type-safe plugin architecture — every component implements a strict TypeScript interface. IDE support, safe refactoring, and AI-generated code the compiler validates.
Core concepts
| Concept | What it is |
|---|---|
| Monitor | Collects data and emits keyed records (venue:symbol, …). Declared as a contract with one or more implementations; users create per-key instances, optionally credential-bound. Emits persist as JSONL and drive triggers. |
| Strategy | Pure decision logic. Declares monitor/executor/account dependencies by label, receives triggers, returns ExecutionInstruction[]. Params split into base (required) and tunable (defaulted, AI-optimizable) zod schemas. |
| Executor | Turns instructions into venue actions through adapter sessions: retry discipline, idempotent client order ids, per-order latency and slippage capture. Strategies stay pure. |
| Instance | A strategy + params + account bindings, activated as a unit. Everything observable hangs off the instance: live events, executions, run traces, logs. |
| Account | A named entity binding a credential to an account implementation (generic or venue-specialized). Strategies read balances and positions only through their bound account's Reader. |
| Trigger | Cron schedules and monitor conditions (multi-source AND within a time window). Subscriptions keep monitors collecting without waking the strategy. |
Monitor (data collection)
↓ emit(key, data)
TriggerManager (cron + monitor conditions)
↓ StrategyContext
Strategy (rules / AI inference) → run trace persisted
↓ ExecutionInstruction[]
ExecutionQueue
↓
Executor (venue actions via adapter sessions)
The dashboard
- Instances — cards with folders, drag-drop ordering, emoji icons, and a live net-PnL badge per card; four live tabs per instance (Live Events scoped to the instance's own monitors, Executions, Runs, Logs). A full-page Board per instance adds click-to-rename, account rebinding, an editable parameter panel, and a PnL panel.
- Per-instance PnL — realized / fees / funding / net / unrealized cards backed by the attribution ledger, with drill-down tabs for by-symbol totals, raw venue fills, and fill-derived open positions priced at the venue mark. Funding events split across instances by the position each held at the settlement boundary.
- Run tracing — every run records its steps: gates, skips, sizing, emitted instructions, captured log lines. Runs with instructions or errors persist to disk; idle runs are heartbeat-sampled. Filter by outcome, search by content.
- Monitor boards — monitors declare dashboard panels via the
plots()convention: line/bar/candles plus a sortabletablekind, single- and multi-select pickers, record-window control. - Params as forms — zod
.meta()drives the UI: sections, sliders, unit suffixes, conditional visibility, searchable market pickers (single and multi), per-value availability verdicts against the bound venue, editable row-table list params for ladders, and sandboxed interactive illustrations that redraw live as you edit values. - Scripts — plugins ship operator utilities (
scripts: [...]) that run on demand against the live runtime and return a monospace report: plan previews, fit inspectors, one-off audits. Params render as a small form, with live-resolved dropdowns for runtime values such as instance ids. - Compiler & Assistant — an experimental natural-language strategy compiler, plus the recommended path: point Claude at
skills/openwhale-devand have it write the plugin.
Code examples
A minimal strategy
const decls = {
monitors: [{ name: 'exchange/ticker', label: 'price' }],
executors: [{ name: 'exchange/perp-trading', label: 'perp' }],
accounts: [{ account: PerpAccount, label: 'main' }],
} as const satisfies StrategyDeclarations
class MomentumStrategy extends BaseStrategy<typeof decls> {
readonly strategyId = 'momentum'
override readonly monitors = decls.monitors
override readonly executors = decls.executors
override readonly accounts = decls.accounts
readonly baseParamsSchema = z.object({
symbol: z.string().meta({ displayName: 'Symbol' }),
threshold: z.number().meta({ displayName: 'Entry price' }),
})
async evaluate(context: StrategyContext) {
const { symbol, threshold } = this.baseParamsSchema.parse(this.params.base)
const tick = context.getData('price', `${this.accountVenue('main')}:${symbol}`)
this.trace('tick:read', { tick }) // lands in the run trace
if (!tick || tick.price < threshold) return []
return [
this.instruction('perp', 'placeOrder', {
symbol, side: 'buy', type: 'market', amount: 0.01,
}),
]
}
}
Assembling the runtime
const runtime = new OpenWhaleRuntime({ database, credentialStore })
runtime.loadPlugin(binancePlugin, {})
runtime.loadPlugin(hyperliquidPlugin, {})
await runtime.start()
await runtime.activate({
strategyId: 'my-plugin/momentum',
credentials: { main: 'My Binance' }, // the account binding decides the venue
params: { base: { symbol: 'BTC/USDT:USDT', threshold: 60000 } },
})
AI-driven strategy with structured output
async evaluate(context: StrategyContext) {
const data = await this.monitorData('market')?.readLatest(this.accountVenue('main'))
const { action, confidence } = await this.llm({
messages: [{ role: 'user', content: JSON.stringify(data) }],
schema: z.object({
action: z.enum(['buy', 'sell', 'hold']),
confidence: z.number(),
}),
})
if (action === 'hold' || confidence < 0.7) return []
return [
this.instruction('perp', 'placeOrder', {
symbol: 'BTC/USDC:USDC', side: action, type: 'market', amount: 0.01,
}),
]
}
An operator script
export const planPreview: ScriptDefinition = {
id: 'plan-preview',
name: 'Plan preview',
paramsSchema: z.object({ instance: z.string().default('') }),
paramOptions: async (runtime) => ({ instance: await listMyInstances(runtime) }),
run: async ({ params, runtime }) => ({ text: await renderPlan(runtime, params) }),
}
Plugins
A plugin is a package with a default-exported factory returning its registrations:
export default definePlugin((ctx) => ({
name: 'my-plugin',
version: '1.0.0',
monitorImplementations: [ /* contract / implementation / instance model */ ],
executors: [ /* … */ ],
strategies: [ /* … */ ],
scripts: [ /* operator utilities for the Scripts page */ ],
credentialTypes: [ /* venue credential recipes: schema, raw opt-in, connectivity test */ ],
adapters: [ /* (kind × venue) matrix cells */ ],
accounts: [ /* account implementations */ ],
}))
Install from the dashboard's Plugins page (npm name or local path) or runtime.loadPlugin() in code. Components register namespaced (my-plugin/momentum); hot reload is supported.
Writing plugins with Claude
Copy skills/openwhale-dev/ into your plugin project's .claude/skills/ (or reference this repo's path in Claude Code), describe the strategy you want, and Claude produces a complete plugin package — monitors, executors, strategies, tests — that installs from the Plugins page.
Use cases
| Scenario | Description |
|---|---|
| Funding / basis capture | Cron-triggered cycles around settlement instants, sized by order-book depth, timed against fitted market microstructure |
| Pair / spread reversion | Two-leg hedged ladders driven by a z-scored spread monitor, with dwell confirmation and stop discipline |
| Copy trading | Monitor a target wallet, mirror its trades proportionally with position caps |
| AI market analysis | LLM inference with structured output directly inside evaluate() |
| Multi-condition signals | Combine price, volume, and rate monitors — fire only when all conditions align within a time window |
Quick start
Prerequisites
- Node.js ≥ 20, pnpm ≥ 9
Gateway + Dashboard
The backend (gateway) owns the runtime and all secrets; the dashboard is a pure frontend.
pnpm install
pnpm build
cp .env.example .env # fill in OPENWHALE_MASTER_KEY + OPENWHALE_ADMIN_USER/PASSWORD
pnpm dev # gateway on :3001 + dashboard on :3000
The gateway fails closed: with no user account and noOPENWHALE_ADMIN_USER/OPENWHALE_ADMIN_PASSWORD it refuses to start rather
than serve an unauthenticated trading API. Set them once, sign in, then remove
them from the environment.
Open http://localhost:3000 to manage strategy instances, accounts, monitors, credentials, scripts, and the AI compiler. The dashboard's only setting is OPENWHALE_GATEWAY_URL (defaults to http://localhost:3001).
Authentication
Auth is enforced by the gateway, not the dashboard: that process holds the
decrypted venue credentials, can place orders, and can install plugins
(arbitrary code), so a frontend-only login would be bypassed by anyone who can
reach port 3001. Every /api/* route requires a session; the dashboard just
carries the cookie, and its route guard is a redirect for humans rather than a
security boundary.
Sessions are opaque tokens in SQLite (revocable, 7-day expiry) and passwords are
scrypt-hashed. Manage accounts on the Users page — there are no roles: anyone
who can sign in can move real money.
Before exposing the gateway to a network:
- terminate TLS in front of it (the session cookie is marked
Secureonly when
the request arrives over https) - keep port 3001 off the public internet if the dashboard proxies for you; set
OPENWHALE_ALLOWED_ORIGINonly for genuinely cross-origin frontends
Packages
| Package | Description |
|---|---|
@openwhaleorg/core |
Domain-agnostic engine: credential materialization, adapter matrix, first-class Accounts, monitor contract/implementation/instance model, Strategy/Executor/Trigger, run-trace persistence, PnL attribution (order claims + fill/funding collector), Scripts, definePlugin + @Ow* decorators, CompiledLoader |
@openwhaleorg/exchange |
Exchange domain package: kinds exchange/perp + exchange/spot, Perp/SpotAccount read views, shared trading executors, public market monitors (ticker/orderbook/volume/kline/funding-rates) with dashboard plots |
@openwhaleorg/ccxt-adapter |
Generic ccxt implementation of the exchange adapter interfaces + the data-driven venue roster |
@openwhaleorg/hyperliquid / binance / aster |
Venue plugins: credential types + adapter cells (+ venue-specialized accounts, Portfolio Margin support on Binance) |
@openwhaleorg/gateway |
Resident backend: runtime singleton, auth, REST + SSE API, compiler service, plugin install — all secrets live here |
@openwhaleorg/dashboard |
Next.js frontend: instances (folders/boards), accounts (equity curves), monitor boards, executors, credentials, plugins, scripts, AI compiler |
@openwhaleorg/compiler |
AI strategy compiler: NL → analyze → codegen → L1–L4 validation ladder → human review → hot load |
@openwhaleorg/assistant |
Personal assistant layer (planned) |
@openwhaleorg/mcp-server |
Expose the strategy engine as an MCP server (planned) |
Roadmap
M1 — Compiler (shipped)
A conversational compiler that guides users step by step to define strategy logic, then compiles Monitor / Strategy / Executor components into type-safe TypeScript. Runs a deterministic validation ladder (build → typecheck → registration probe → mock dry-run) automatically. After human review, hot-loads the result into the runtime.
M2 — Optimizer
Dual-agent optimization loop: an analysis agent reads runtime performance and historical monitor data to generate an optimization plan; an execution agent adjusts parameters or rewrites strategy code and validates the result through backtesting.
M3 — Assistant
A unified conversational interface for the full strategy lifecycle: create and manage instances, trigger the Compiler and Optimizer, receive proactive alerts and performance reports.
M4 — MCP Server
Expose the core engine capabilities as standard MCP tools, enabling external AI agents to drive strategy creation, activation, and optimization directly.
Contributing
OpenWhale is in active early development. The core engine is working, and we're building the rest in the open.
- Open an issue to discuss ideas or report bugs
- Submit a PR for fixes, new venue plugins, or strategy examples
- Star the repo if you find it useful — it helps others discover the project
License
MIT
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found