Skip to content

Latest commit

 

History

1,280 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Profitmaker Story

Profitmaker v3 -- Open Source Crypto Trading Terminal

License Discord

Modular, widget-based trading terminal with support for 100+ crypto exchanges via CCXT. All user state is managed through a REST API backed by PostgreSQL -- every dashboard, widget, group, and setting is persisted per-user.

Launch Terminal | Docs | Discord | Telegram

The hosted terminal runs at terminal.marketmaker.cc (single sign-on via auth.marketmaker.cc). Self-host it anywhere with the steps below.


API-First Architecture

Profitmaker is an API-managed project. All functionality is exposed through a REST/WebSocket API on the backend, backed by PostgreSQL for persistent storage. This design enables:

  • LLM Integration -- AI agents (Claude Code, etc.) can manage the entire platform via API: register users, create dashboards, arrange widgets, place orders, manage exchange accounts
  • Headless Mode -- run the backend without the browser UI for automated trading, data collection, or bot integration
  • Multi-Client -- the same API serves the React frontend, CLI tools, mobile apps, or third-party integrations
  • Per-User Persistence -- every user gets their own dashboards, widgets, groups, exchange accounts, and settings stored in PostgreSQL
# Register a user and get a session token
curl -s -X POST http://localhost:3001/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email":"trader@example.com","password":"secret123","name":"Trader"}'

# Use the token to create a dashboard
curl -s -X POST http://localhost:3001/api/dashboards \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"My Dashboard"}'

See docs/server-api.md for the full API reference, and docs/remote-control.md for driving a live terminal from the backend — REST mutations stream to open browsers in real time, and UI verbs (switch tab, focus widget, read UI state) are executable over an API. Run bun scripts/control-demo.ts to see it end to end.

AI agents drive the terminal over MCP, and humans/scripts over a profitmaker CLI — both on one shared command registry (31 tools). See docs/mcp.md and docs/cli.md.


Tech Stack

Layer Technology
UI Framework React 18, TypeScript
Build Vite 5 + SWC
Components shadcn/ui (Radix UI + Tailwind CSS)
State Zustand 5 + Immer, synced to API
Data Fetching TanStack React Query
Charts Night Vision (OHLCV candlestick) + Recharts (pie, bar)
Exchange API CCXT 4.5 (100+ exchanges, REST + WebSocket)
Backend Bun + Elysia (HTTP API) + Socket.IO (WebSocket streaming)
Database PostgreSQL via Drizzle ORM
Auth Local sessions (bcrypt) or ecosystem SSO via auth.marketmaker.cc (RS256 JWT, verified through public JWKS)
Exchange keys SSO/central accounts: kept server-side in the auth.marketmaker.cc vault (AES-256-GCM) — the browser never holds secrets. Self-host: passed inline per request, held in memory for the call (not persisted)
Testing Vitest + JSDOM
Monorepo Bun workspaces (4 packages)

Features

Widget System

  • Drag & drop positioning with snap-to-grid alignment
  • Resize from all 8 directions (edges + corners)
  • Maximize, minimize, collapse -- collapsed widgets dock to bottom bar
  • Multiple dashboards with tab navigation, create/duplicate/rename/delete
  • Right-click context menu to add new widgets
  • Per-widget settings stored per-user in database
  • Editable titles -- double-click any widget header

Trading Widgets

Widget Description
Chart OHLCV candlestick (Night Vision), 13 timeframes, infinite scroll
Order Book Real-time bid/ask depth, spread display
Trades Live trade feed with filtering, aggregated mode
Order Form Market, limit, stop-loss, take-profit, trailing stop, iceberg; live ticker + real balance
Portfolio Cross-account allocation — total value, per-asset breakdown, allocation donut (USD-valued)
User Balances Detailed balances across all accounts with pie-chart breakdown
User Trading Data My trades, open orders, positions (futures)
Transaction History Deposits / withdrawals / transfers / fees from the exchange ledger
Deals Deal tracking with entry/exit analysis, built from real trade history

All widgets render live data — the demo/placeholder ("not ready") widgets were replaced with real exchange data wired through the data-provider layer.

Data Provider System

  • CCXT Server -- all market data + trading run through the Elysia backend (CORS-free, WebSocket via CCXT Pro); the browser has no CCXT
  • Pluggable server registry -- the built-in ccxt provider plus module-supplied providers (incl. native napi bindings); priority-based resolution, providerId override
  • Automatic fallback -- WebSocket to REST when an exchange lacks Pro support
  • Subscription deduplication -- one connection per data stream, shared across widgets
  • Authenticated calls -- balances, trades, orders, positions and the ledger resolve per account via { accountId } (central accounts) or inline credentials; the server attaches the keys before calling CCXT
  • KuCoin Broker Pro (hosted only) -- KuCoin trades routed through the hosted terminal are attributed to the MarketMaker broker for rebate; self-host installs are unaffected (no-op unless broker env vars are set)

Security & Accounts

  • Authentication -- local register/login (bcrypt, 30-day sessions in PostgreSQL), or ecosystem single sign-on via auth.marketmaker.cc (RS256 JWT verified through the public JWKS — no shared secret in this repo).
  • Central accounts (SSO mode) -- exchange API keys live server-side in the auth.marketmaker.cc vault (AES-256-GCM). The terminal sends only { accountId, want: 'read' | 'trade' } + the user's JWT; the backend fetches decrypted keys server-to-server. The browser never holds secrets.
  • Multiple simultaneous logins -- hold several ecosystem identities at once and quick-switch the active one.
  • Per-account access levels -- accounts can be shared read-only; trade operations on a read-grant are rejected server-side (403).
  • Self-host mode -- without SSO, exchange keys are passed inline per request and held in memory for the call only (never persisted). Legacy browser-stored keys are migrated into the vault and purged; a persistent encrypted self-host store is on the roadmap.
  • Dual server auth -- API_TOKEN for server-to-server + the user's JWT/session for browser calls (every /api/* requires a bearer token).

Quick Start

Prerequisites

Environment Variables

Variable Default Description
DATABASE_URL -- PostgreSQL connection string (required)
PORT 3001 API server port
API_TOKEN your-secret-token Server-to-server auth token

Install & Run

# Clone
git clone https://github.com/suenot/profitmaker.git
cd profitmaker

# Install dependencies
bun install

# Set up database
export DATABASE_URL="postgresql://user:password@localhost:5432/profitmaker"
cd packages/server && bun db:push && cd ../..

# Start the API server (port 3001)
bun server:dev

# Start the frontend (port 8080)
bun dev

Open http://localhost:8080 -- register an account to get a default dashboard with 6 widgets.

Scripts

Command Description
bun dev Start Vite dev server (port 8080)
bun run build Production build
bun server Start Elysia API server (port 3001)
bun server:dev Start API server with auto-reload
bun test Run tests (Vitest)
bun lint ESLint check
bun db:push Push schema to PostgreSQL (in packages/server)
bun db:generate Generate migration files
bun db:studio Open Drizzle Studio (database GUI)

Architecture

Monorepo Structure

profitmaker/
├── packages/
│   ├── client/             # @profitmaker/client -- React frontend
│   │   └── src/
│   │       ├── components/   # Widgets, UI, AuthPage, AuthGate
│   │       ├── store/        # Zustand stores (synced to API)
│   │       ├── services/     # API client, apiSync, storeSync
│   │       └── hooks/        # Custom React hooks
│   ├── server/             # @profitmaker/server -- Elysia API
│   │   └── src/
│   │       ├── db/schema/    # Drizzle ORM (9 tables)
│   │       ├── routes/       # auth, dashboards, widgets, groups,
│   │       │                 # accounts, settings, providers,
│   │       │                 # exchange, websocket, proxy, health
│   │       ├── services/     # auth, ccxtCache, wsSubscriptions,
│   │       │                 # defaultDashboard
│   │       └── middleware/    # requireUser (session validation)
│   ├── types/              # @profitmaker/types -- shared types (incl. provider contracts)
│   └── sdk/                # @profitmaker/module-sdk -- module SDK
├── package.json            # Bun workspace root
└── vite.config.ts          # Frontend build config

Database Schema

users
├── sessions              (auth tokens, 30-day expiry)
├── dashboards
│   └── widgets           (position, config, per-dashboard)
├── groups                (instrument linking)
├── exchange_accounts     (schema reserved; SSO keys live in the auth.marketmaker.cc vault)
├── data_providers        (ccxt-server provider configs)
├── user_settings         (key-value: theme, activeDashboardId, etc.)
└── widget_settings       (per-widget, per-user configs)

Data Flow

Browser                          Server                      Database
  │                                │                            │
  ├── Login ──────────────────────>│── Verify password ────────>│
  │<── Token + user ──────────────│<── Session created ────────│
  │                                │                            │
  ├── Load state ─────────────────>│── Query dashboards, ──────>│
  │<── Dashboards, widgets, ──────│<── widgets, groups, ───────│
  │    groups, settings            │    settings, providers     │
  │                                │                            │
  ├── Drag widget ─── Zustand ───>│── PUT /api/widgets/:id ──>│
  │    (local state)  (debounced)  │    (position update)       │
  │                                │                            │
  ├── Subscribe data ─────────────>│── CCXT/Socket.IO ────────>│ Exchange
  │<── Real-time stream ──────────│<── Market data ────────────│ API

API Endpoints

Group Endpoints Description
Auth POST /api/auth/register, login, logout GET /api/auth/me User authentication
Dashboards GET, POST, PUT, DELETE /api/dashboards CRUD per-user dashboards
Widgets GET, POST, PUT, DELETE /api/widgets PUT /api/widgets/batch CRUD + batch position update
Groups GET, POST, PUT, DELETE /api/groups Instrument linking groups
Accounts GET, POST, PATCH, DELETE /api/accounts Exchange API accounts
Settings GET, PUT, DELETE /api/settings/:key PUT /api/settings (bulk) Per-user key-value settings
Providers GET, POST, PUT, DELETE /api/providers Data provider configs
Exchange POST /api/exchange/fetch* POST /api/exchange/watch* CCXT market data
Proxy POST /api/proxy/request CORS bypass proxy
Health GET /health Server health (no auth)

Socket.IO (port 3002): public market-data events subscribe, unsubscribe, data, error; authenticated account-data events private:subscribe, private:unsubscribe, private:data, private:error.

For supported exchanges, the scalper and DOM use CCXT Pro private order, trade, and derivative-position streams as their live source of truth. REST provides the initial snapshot, reconnect backfill, final safety reconciliation, and fallback when a private channel is unavailable. Create and cancel responses are command acknowledgements only.

Supported Exchanges

100+ exchanges via CCXT including: Binance, Bybit, OKX, Coinbase, Kraken, Bitfinex, Gate.io, KuCoin, MEXC, Huobi, Bitget, and many more.

Related Projects

  • profitmaker.cc -- the open source crypto trading terminal and modular server in this repository
  • MarketMaker.cc -- the home of our quantitative research team, where we work on several projects, including Profitmaker

Team

StarMapper

StarMapper

Star History

Star History Chart

License

MIT License with Commons Clause.

Allowed: use for any purpose, modify, distribute, create products built with Profitmaker.

Not allowed: sell Profitmaker itself, offer it as a hosted service, create competing products based on it.

See LICENSE for full text. For commercial licensing -- Telegram or email.


MarketMaker.cc

MarketMaker.cc is the home of our quantitative research team. We work on several projects there, including the open source Profitmaker terminal.

Releases

Sponsor this project

Packages

Used by

Contributors

Languages