DEXBot vs DEXBot2 — Detailed Comparison Report
Date: 2026-09-02 (metrics refreshed against local source trees) Scope: Full architectural, functional, and operational comparison between the original DEXBot (Python, v1.0.0) and DEXBot2 (TypeScript, v1.6.11). Audience: Developers, contributors, and operators evaluating or migrating between the two projects.
Table of Contents
- Project Overview
- Technology Stack
- Architecture
- Trading Strategies
- Order Management
- Configuration System
- Exchange & Blockchain Integration
- Fund & Balance Accounting
- Concurrency & Safety
- User Interface
- Process Management & Deployment
- Security
- Testing
- Documentation
- Dependencies & Footprint
- Extensibility & Plugin System
- Metrics & Scale
- Performance & Speed
- Known Limitations & Trade-offs
- Summary Scorecard
- Migration Considerations
1. Project Overview
| Release Track |
1.0.0 |
v1.6.11 |
| Language |
Python 3.6+ |
TypeScript 5.x |
| Status |
Released 1.0.0, unmaintained |
Active development |
| Last Repo Activity |
May 23, 2020 |
2026-09-02 |
| License |
MIT |
MIT |
| Origin |
BitShares worker-proposal funded, Codaone Oy |
Private rewrite by froooze |
| Primary Goal |
Multi-strategy, extensible trading framework |
Hardened adaptive grid runtime with operator/AI tooling |
| Target Exchange |
BitShares DEX |
BitShares DEX |
| Lines of Code |
~10,846 Python LOC in dexbot/ |
Large TypeScript codebase; core runtime, adapter, analysis, Claw, and test modules |
| Source Files |
72 Python files in dexbot/ |
~544 TS files across the repo |
| Test Files |
16 Python test files |
248 test_*.ts files (248 auto-discovered via globSync) |
Summary
DEXBot (original) is a community-governed, multi-strategy trading framework built in Python with a full GUI and plugin system. It was designed to be user-friendly and extensible, supporting multiple strategies and external price feeds out of the box.
DEXBot2 is a ground-up rewrite in TypeScript that prioritizes production correctness over the original project's GUI/plugin breadth. The core trading runtime is still centered on one deeply engineered boundary-crawl grid strategy, but the surrounding system has expanded significantly: Copy-on-Write order state, replay-safe fill accounting, two-pass startup and runtime reconciliation, dynamic AMA/Kalman market adaptation, credential-daemon key handling, a native monolithic launcher (dexbot start, backed by the unlock runtime; with optional PM2 fallback), Claw automation APIs, credit/MPA support, and a broad regression suite.
2. Technology Stack
| Language |
Python 3.6+ |
TypeScript 5.x |
| GUI |
PyQt5 (desktop GUI) |
None (CLI only) |
| CLI Framework |
Click |
Custom native async prompts |
| Blockchain Client |
bitshares Python library |
modules/bitshares-native/ (native) |
| Key Management |
uptick (BitShares wallet) |
AES-256-GCM encrypted store + credential daemon (RAM-only, Unix-socket signing) |
| Database / State |
SQLite via SQLAlchemy ORM |
JSON flat files (no DB) |
| DB Migrations |
Alembic |
N/A |
| Process Manager |
Systemd service (Linux) |
dexbot start (native monolithic launcher, default; unlock runtime) — PM2 optional |
| External APIs |
CoinGecko, CCXT, Waves |
On-chain/pool/Kibana candle inputs; optional CEX synthetic seed generator (fetch_cex_synthetic_data.ts) for adapter bootstrap |
| Container |
Docker (Ubuntu 18.04) |
Docker (multi-stage) |
| Testing |
pytest + Docker testnet |
Native Node assert (256 test_*.ts files; auto-discovered via globSync) |
| CI/CD |
Travis CI, AppVeyor |
GitHub Actions / local deterministic script suite |
| Packaging |
PyInstaller (Win/Mac/Linux binaries) |
npm / unlock + optional PM2 ecosystem |
Key Difference
DEXBot brings a full Python desktop GUI and a strategy plugin model. DEXBot2 is a headless operator-first runtime: fewer production dependencies, stronger process isolation, stronger key separation, and substantially more explicit state/accounting invariants.
3. Architecture
DEXBot — Event-Driven Plugin Framework
┌─────────────────────────────────────────────┐
│ WorkerInfrastructure │
│ (threading.Thread) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Worker 1 │ │ Worker 2 │ │ Worker N │ │
│ │(Strategy)│ │(Strategy)│ │(Strategy)│ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────▼─────────────▼─────────────▼──────┐ │
│ │ BitShares WebSocket Events │ │
│ │ (ontick / onMarketUpdate / onAccount) │ │
│ └───────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
│ Config (YAML) │ State (SQLite)
- Single thread manages all workers
- Workers receive generic push notifications (on_block, on_market, on_account), then fetch all orders + balances from chain and diff to detect fills and state changes
- Each worker is a plugin implementing a Strategy interface
- State persisted in SQLite (orders, balances, config)
- GUI runs separately in the main thread
Pattern: Event-triggered fetch + diff, plugin architecture.
DEXBot2 — Layered Engine with Copy-on-Write State
┌──────────────────────────────────────────────────────────┐
│ DEXBot (dexbot_class.ts) │
│ Trading Loop + Lifecycle Manager │
│ ┌────────────────────────────────────────────────────┐ │
│ │ OrderManager │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────┐ ┌──────────┐ │ │
│ │ │Accountant│ │ Strategy│ │ Grid│ │SyncEngine│ │ │
│ │ │(Funds) │ │(Boundary │ │(Geo │ │(Chain │ │ │
│ │ │ │ │ Crawl) │ │Grid) │ │ Reconcile│ │ │
│ │ └──────────┘ └──────────┘ └──────┘ └──────────┘ │ │
│ │ │ │
│ │ Master Grid (Immutable Orders Map) │ │
│ │ ↓ (COW clone on rebalance) │ │
│ │ Working Grid (Isolated Planning Copy) │ │
│ │ ↓ (atomic commit on success) │ │
│ └────────────────────────────────────────────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │BitShares │ │NodeManager │ │MarketAdapter │ │
│ │Client │ │(Failover) │ │(Real-time) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└──────────────────────────────────────────────────────────┘
│ Config (JSON) │ State (JSON flat files)
- Four specialized engines (Accountant, StrategyEngine, Grid, SyncEngine) coordinate through OrderManager
- Copy-on-Write grid: planning happens on isolated
WorkingGrid; committed atomically or discarded on failure
- Targeted fill subscription via
set_subscribe_callback → get_account_history_operations filtered for OP_FILL_ORDER fill operations; push-triggered gap-slot batching (a unified batch contains at most gapSlots + 1 fills)
- Market Adapter: AMA-based price tracking, dynamic buy/sell weighting, Kalman confirmation, ATR/regime dampening, asymmetric grid bounds, and configurable delta triggers
fund_registry.ts: shared-account fund registry — tracks per-account, per-bot fund and collateral allocations; pre-registered atomically at startup so all bots sharing an account see a consistent proportional split before any bot starts; cross-bot invariant enforcement
- Bot keys: deterministic name-derived key (
sanitizeKey(name)) with uniqueness enforced at all write paths — eliminates name-collision risk across restarts and config reorders
- State in JSON flat files (no database dependency)
- The default
dexbot start launcher (the unlock runtime) runs the active bot set as one monolithic bot process (credential daemon + market adapter in separate helper processes); isolated per-bot mode and PM2 are available alternatives; multiple bots can share an account via fund_registry
Pattern: Layered engines, targeted fill subscription + fixed-cap batch processing + periodic reconciliation, immutable/COW state management.
Architecture Comparison
| Core Pattern |
Event-triggered fetch + diff (generic notifications → fetch all state → diff) |
Targeted subscription + incremental scan (fill-specific history stream → push) |
| Concurrency Model |
Python threading (GIL-bound) |
TypeScript async + AsyncLock semaphores |
| State Storage |
SQLite (relational, queryable) |
JSON flat files (simple, no dependency) |
| State Safety |
Mutable shared state per worker |
Copy-on-Write immutable master grid |
| Multi-bot Scaling |
Single thread, multiple workers |
One monolithic process for all active bots (unlock default); per-bot isolated mode or one PM2 process per bot (optional); shared-account fund registry for proportional balance split |
| Strategy Coupling |
Loosely coupled via base class |
Core grid strategy deeply integrated; Claw/adapter layers extend around it |
| Recovery Model |
Restart from SQLite state |
Startup reconciliation + blockchain re-sync + fill replay guards |
| Error Isolation |
Per-worker exception handling |
Per-engine try/catch, up to 5 recovery retries |
4. Trading Strategies
DEXBot — Three Built-in Strategies + Plugin System
Relative Orders Strategy
- Uses external price feeds (CoinGecko, CCXT, Waves) as reference price
- Maintains buy/sell orders at a relative spread around the external price
- Adjusts when price deviates beyond a configured threshold
- Best for: market making in active, liquid markets
- Requires: active monitoring and regular tweaking
- Risk: price feed latency or manipulation
Staggered Orders Strategy (2,256 lines — largest module)
- "Set and forget" approach
- Creates multiple staggered buy/sell orders across a price range
- Profits by capturing spread repeatedly as market oscillates
- Replenishes filled orders from profits
- Best for: volatile markets, bootstrapping new markets
- Risk: inventory skew in strongly trending markets
King of the Hill Strategy
- Places single buy or sell order closest to the opposing side
- Continuously re-stakes position to stay at the top of the book
- Aggressive, high-frequency market making
- Best for: competitive, active markets
- Risk: high transaction fee cost
Plugin System
- Custom strategies can be installed as Python packages
- Discovery via
setuptools entry points
- User bot directory:
~/bots
- Template available:
strategy_template.py
DEXBot2 — Adaptive Boundary-Crawl Grid Runtime
Boundary-Crawl Grid Strategy (deeply engineered)
- Creates a geometric price grid from min to max price
- Fixed reference boundary divides BUY zone (below) from SELL zone (above)
- Dynamic spread gap around market price (configurable
targetSpreadPercent)
- On fill: grid crawls — boundary shifts, slots reassign roles, new orders placed
- Partial fill handling: immediate on-chain dust cancellation plus fund-driven correction of surviving non-dust partials
- Gap-slot fill batching:
1..gapSlots+1 fills per unified batch; deeper queues are chunked at gapSlots+1
- Replay-safe fill dedupe: processed-fill persistence prevents duplicate accounting after restarts or resyncs
- Dynamic weighting: AMA slope, Kalman confirmation, ATR volatility, and regime gates can bias buy/sell allocation without changing the core grid model
- Asymmetric range scaling: trend diagnostics can tilt grid bounds during recalculation, giving the grid more room in the direction of movement
Price Scale (geometric, e.g. 0.4% increments):
─── maxPrice
│ SELL slot 5
│ SELL slot 4
│ SELL slot 3
═══ spread zone (targetSpreadPercent gap)
│ BUY slot 2 ← market price here
│ BUY slot 1
─── minPrice
Extensibility Model
- The core trading strategy is not swappable at runtime
- Strategy logic is intentionally integrated into OrderManager, Grid, SyncEngine, and Accountant for stronger invariants
- Extension happens around the runtime through MarketAdapter, analysis tools, Claw modules, and operator automation rather than through DEXBot-style strategy plugins
Strategy Comparison
| Number of Strategies |
3 built-in + plugins |
1 (deeply engineered, highly adaptive boundary-crawl grid with AMA/Kalman/ATR/regime signals) |
| Custom Strategies |
Yes (plugin system) |
No core strategy plugins |
| External Price Feeds |
Yes (CoinGecko, CCXT, Waves) |
On-chain/pool/Kibana candle sources; optional CEX synthetic seed generator for market adapter bootstrap |
| Strategy Isolation |
Yes (each worker independent) |
N/A (one strategy) |
| Grid Trading |
Staggered Orders (similar concept) |
Yes (core, heavily engineered) |
| Market Making |
Relative Orders, KOTH |
Yes (spread-based) |
| Rebalancing Logic |
Per-strategy |
Centralized in OrderManager with adapter-triggered recalculation |
| Partial Fill Handling |
Basic |
Advanced (consolidation, dust detection) |
| Boundary Mechanics |
N/A |
Atomic boundary-crawl with role reassignment |
| Adaptive Signals |
External reference price for Relative Orders |
AMA/Kalman/ATR/regime dynamic grid and weight signals |
5. Order Management
DEXBot
- Orders tracked in SQLite (
Orders table) alongside real blockchain orders
- Virtual order support (simulation without placing real orders)
- Order operations in
BitsharesOrderEngine (34KB class)
- No formal order state machine — strategies manage order lifecycle directly
- Orders fetched from blockchain via
bitshares library on each tick
- No Copy-on-Write: mutable shared state, no atomic commits
DEXBot2
- Orders tracked in an in-memory
Map (master grid) + JSON snapshots
- Formal order state machine:
VIRTUAL → ACTIVE → PARTIAL
- Copy-on-Write: planning on isolated
WorkingGrid, atomic commit to master
- Two-pass blockchain reconciliation on every sync cycle:
- Match master grid orders to on-chain orders
- Create entries for unexpected on-chain orders
- Mark orphaned grid orders as VIRTUAL
- Fill-authoritative handling: every fill is treated as authoritative; sub-dust residual fills resolve immediately instead of preserving a "ghost" slot
- Orphan order reconciliation: unmatched on-chain orders adopted or cancelled to preserve a 1-to-1 slot↔︎order mapping
- Version epoch tracking: stale working grids detected and aborted
- Processed fill store: persistent dedupe layer for replay-safe accounting
- Startup reconciliation: detects existing, orphaned, partial, and missing orders before normal trading resumes (GRID_RECONCILE.md)
Order Management Comparison
| Order State Machine |
Informal |
Formal (VIRTUAL/ACTIVE/PARTIAL) |
| Storage |
SQLite |
In-memory Map + JSON snapshots |
| Virtual Orders |
Yes |
Yes |
| COW / Atomic Commits |
No |
Yes |
| Reconciliation |
Per-tick fetch |
Two-pass sync engine |
| Orphan Detection |
Basic |
Full two-pass matching |
| Plain-fill Handling |
Basic |
Authoritative (isGhost/ghost-preservation removed) |
| Partial Fill Tracking |
Basic |
Advanced (per-order tracking) |
| Dust Detection |
Basic (staggered_orders.py:979) |
Yes (systematic health checks) |
| Stale State Detection |
No |
Version epoch tracking |
| Fill Replay Dedupe |
No formal persistent layer |
Yes (processed_fill_store.ts) |
| Startup Reconcile |
Basic restart from SQLite |
Dedicated startup reconciliation pipeline |
6. Configuration System
DEXBot
- Format: YAML (
~/.config/dexbot/config.yml)
- Interactive setup:
whiptail-based text UI wizard
- GUI configuration: full PyQt5 forms for each strategy
- Each strategy defines
ConfigElement tuples for self-describing configuration
- Asset intersection management for multi-worker accounts (automatic balance splitting)
- Node list configurable;
resetnodes CLI command resets to defaults
- No encryption of config values; relies on file-system permissions
# Example config.yml excerpt
workers:
MyBot:
module: dexbot.strategies.staggered_orders
account: my-account
market: XRP/BTS
center_price: 1.5
spread: 4.0
increment: 2.0
lower_bound: 0.5
upper_bound: 5.0
operational_percent_base: 50
operational_percent_quote: 50
DEXBot2
- Format: JSON (
profiles/bots.json, profiles/general.settings.json)
- No GUI wizard — interactive
dexbot bot menu editor for main settings; advanced keys edited directly in JSON
- ~27 configuration objects in
modules/constants.ts, frozen via Object.freeze (loaded at startup)
- Runtime parameters via environment variables (
RUN_LOOP_MS, BOT_NAME, launcher/daemon settings, etc.)
profiles/general.settings.json for global timing/limits/node settings
profiles/market_profiles.json and market-adapter settings for AMA profiles, dynamic weights, and recalculation thresholds
- Encrypted key storage (AES-256-GCM) with RAM-only master password
// Example bots.json entry
{
"name": "EXAMPLE-BOT",
"active": true,
"assetA": "IOB.XRP",
"assetB": "BTS",
"startPrice": "pool",
"minPrice": "2x",
"maxPrice": "2x",
"incrementPercent": 0.4,
"targetSpreadPercent": 4,
"weightDistribution": { "sell": 1, "buy": 1 },
"botFunds": { "sell": "100%", "buy": "100%" },
"activeOrders": { "sell": 5, "buy": 5 },
"poolRef": "1.19.133" // optional: pin a specific pool for price derivation
}
Configuration Comparison
| Format |
YAML |
JSON |
| Interactive Setup |
Yes (whiptail + PyQt5 GUI) |
Yes (dexbot bot menu editor) |
| Key Encryption |
No (file-system only) |
Yes (AES-256-GCM) |
| Multi-bot in one config |
Yes (YAML array) |
Yes (JSON array) |
| Runtime overrides |
Env vars (limited) |
Env vars (full) |
| Hot reload |
Partial (restart worker) |
Limited via runtime snapshots/triggers; process restart for static bot config |
| Validation |
config_validator.py |
modules/order/utils/validate.ts |
| Documentation |
Strategy ConfigElement docs |
README + developer guide + architecture/security/accounting docs |
7. Exchange & Blockchain Integration
| Exchange |
BitShares DEX |
BitShares DEX |
| Client Library |
bitshares (Python, v0.5.x) |
modules/bitshares-native/ (native) |
| Key Management |
uptick library |
AES-256-GCM + credential daemon + authority resolution fallback |
| Connection Mode |
WebSocket (event-driven + per-tick JSON-RPC order book fetches over same WebSocket) |
WebSocket (event-driven subscriptions + periodic safety-net sync) |
| Multi-node Failover |
Yes (latency-sorted) |
Yes (health-checked) |
| External Price Feeds |
CoinGecko, CCXT, Waves |
On-chain/pool/Kibana candles; optional CEX seed generator (market_adapter/inputs/fetch_cex_synthetic_data.ts) for adapter bootstrap |
| Account Type |
Single or multi-account |
Per-bot or shared-account (via fund_registry.ts); per-key credential daemon |
| Order Operations |
Place, cancel, update via bitshares lib |
Place, cancel, update via native implementation |
| Asset Metadata |
Fetched via bitshares |
Fetched on startup, cached |
| Balance Queries |
Per tick via library |
Periodic + event-triggered |
| Fee Handling |
Basic (relies on library) |
Advanced (reservation system, fee accounting) |
| Automation API |
Strategy/plugin hooks |
Claw modules for profiles, chain queries/actions, position health, and bot automation |
8. Fund & Balance Accounting
DEXBot
- Balance queried each tick from blockchain
- Per-strategy allocation via
operational_percent_base/quote
- Multi-worker balance split calculated automatically
- No formal fund invariant system
- Virtual orders tracked in SQLite for simulation
- No fee reservation mechanism
DEXBot2 — Accountant Engine (dedicated module)
The Accountant class is a Single Source of Truth for all fund state:
Available Funds = max(0, ChainFree - Virtual - FeesOwed - FeesReservation)
Where:
ChainFree = on-chain liquid balance
Virtual = Σ sizes for VIRTUAL (planned, not-yet-placed) orders
FeesOwed = accumulated BTS fees (liability)
FeesReservation = safety buffer for future operations
- Fund invariant:
Total = Free + Committed — verified before every operation
- Optimistic proceeds: fills treated as available immediately (pre-confirmation)
- Fee reservation: ensures future operations never fail due to missing fees
- Atomic snapshots: consistent reads across all fund components
- Recovery triggers: invariant violation automatically initiates recovery cycle
- Market-fee and BTS-fee regression coverage: tests cover fee cache fallback, BTS fee deduction, batching, and precision quantization
fund_registry.ts: shared-account fund registry with async-locked per-account, per-bot fund and collateral allocation tracking; pre-registered atomically at startup so all bots see consistent proportional splits before any bot starts; cross-bot invariant enforcement with widened tolerance for shared accounts
- Bot keys: deterministic name-derived key (
sanitizeKey(name)) used in registry keys; duplicate names rejected at all write paths, eliminating name-collision risk across config reorders and restarts
- Credit/MPA collateral allocation: fund registry extended with
registerCollateralAllocation / getEffectiveCollateralAllocationSync to proportionally split credit bot collateral across bots sharing one account
- Credit/MPA runtime support: separate runtime modules track collateral/debt position data and planning state for advanced BitShares workflows
Accounting Comparison
| Balance Source |
Blockchain per-tick |
Blockchain + local accounting |
| Fund Invariant |
No |
Yes (verified each operation) |
| Fee Reservation |
No |
Yes (BTS buffer maintained) |
| Virtual Order Accounting |
SQLite |
In-memory with invariant tracking |
| Multi-worker Balance Split |
Yes (automatic) |
Yes (automatic via fund_registry.ts for shared accounts) |
| Overdraft Protection |
Basic |
Yes (invariant enforcement) |
| Optimistic Proceeds |
No |
Yes |
| Accounting Audit Trail |
No |
Partial (logging) |
| Credit/MPA Collateral Allocation |
No |
Yes (fund_registry.ts proportional split for shared-account credit bots) |
| Shared-Account Fund Registry |
Manual per-strategy percentages |
Automated via fund_registry.ts with pre-registration, cross-bot invariants, and atomic release |
9. Concurrency & Safety
DEXBot
- Python threading (subject to GIL for CPU-bound work)
- Single worker thread manages all strategies
- Thread-safe config via
threading.Lock
- Mutable shared state — no formal protection against concurrent mutation
- No atomic commits for order state changes
- WebSocket callbacks can interrupt strategy execution
DEXBot2
- TypeScript async/await (Node.js event loop, no GIL)
- AsyncLock semaphores guard all critical sections:
_gridLock: serializes grid mutations
_syncLock: ensures one full sync at a time
- Per-order locks for specific operations
- Copy-on-Write grid: rebalancing cannot corrupt master state
- Version epoch counter (
_gridVersion): stale working grids detected and aborted
- Double-check pattern: consistency validated both outside and inside locks
- Layer 1 & Layer 2 defenses against rapid-restart cascades
- Lock refresh mechanism: prevents timeout during long blockchain operations
- Replay and duplicate guards: fill dedupe, resync duplicate-race tests, and startup reconciliation prevent repeated handling of the same chain event
Concurrency Comparison
| Threading Model |
Python threads (GIL) |
TypeScript async (Node.js event loop) |
| Shared State Protection |
threading.Lock |
AsyncLock semaphores (hierarchy) |
| Atomic State Commits |
No |
Yes (COW pattern) |
| Stale State Detection |
No |
Yes (version epochs) |
| Concurrent Fill Safety |
Partial |
Yes (fill batching + COW) |
| Deadlock Prevention |
Basic |
Documented lock hierarchy (convention-based, level unenforced at runtime) |
| Rapid-restart Protection |
No |
Yes (Layer 1 + Layer 2) |
| Duplicate Fill Protection |
Basic |
Persistent replay guards + race regression tests |
10. User Interface
DEXBot
- Full PyQt5 desktop GUI (
gui.py)
- Worker list with real-time status
- Worker detail view (open orders, balances)
- Strategy configuration dialogs (per-strategy forms)
- Wallet creation and unlock dialogs
- Settings panel
- Text-based CLI setup (
whiptail) for headless environments
- Click CLI for command-line control
- Designed to be accessible to non-technical users
DEXBot2
- CLI-only (no GUI)
dexbot.ts: multi-bot management, config viewing, log tailing
bot.ts: single bot launcher
unlock.ts: default launcher (invoked as dexbot start) — single-prompt startup, background daemonization, auto-restart, monolithic runtime (start, stop, restart, status, delete)
pm2.ts: PM2 orchestration (start, stop, restart, status, logs) — optional alternative
- Claw scripts and modules expose automation-friendly operations for profiles, chain actions, position health, and launcher workflows
- Designed for operators comfortable with terminal, JSON config, and service logs
UI Comparison
| Desktop GUI |
Yes (PyQt5) |
No |
| Interactive Config Wizard |
Yes (GUI + whiptail) |
No (menu-driven editor, not a guided wizard) |
| CLI |
Yes (Click) |
Yes (custom) |
| Real-time Status |
GUI view |
unlock status / dexbot stat + log tailing |
| Automation Surface |
Plugin/strategy hooks |
Claw modules, scripts, and runtime helpers |
| Accessibility |
High (non-technical users) |
Medium-low for casual users; stronger for technical operators |
11. Process Management & Deployment
DEXBot
- Systemd service (Linux):
runservice command installs unit file
- Passphrase via environment variable (
BITSHARES_PASSPHRASE)
sdnotify for service readiness notifications
- Docker: Ubuntu 18.04 base, single container
- Windows/Mac/Linux: PyInstaller binaries (no runtime required)
- Raspberry Pi support
- Single process manages all bots (workers)
DEXBot2
unlock (native monolithic launcher, run via dexbot start) — the default and recommended runtime
- Runs the active bot set as one monolithic bot process, with the credential daemon and market adapter in separate helper processes
- Background daemonization + auto-restart built in (no external process manager required)
dexbot start|stop|restart|status|delete controls the whole monolithic runtime
--isolated mode: one process per bot for independent control
--headless / --password-file: non-interactive unlock for service use
--dryrun: no broadcast
- PM2 (optional alternative) —
pm2.ts wraps the same credential/bootstrap flow
- One PM2 process per bot (ecosystem.config.js template)
- PM2 log rotation
- credential-daemon.ts: RAM-only key management daemon (shared by both launchers)
- Docker: multi-stage Dockerfile
- Launch modes for full bot startup or credential-daemon-only runtime
- No binary packages — requires Node.js runtime
- Horizontal scaling:
--isolated mode or add PM2 processes for more bots
Deployment Comparison
| Process Manager |
Systemd |
dexbot start/unlock (native, default) — PM2 optional |
| Multi-bot Scaling |
One process (multi-thread) |
One monolithic process (default) or one process per bot (--isolated / PM2) |
| Auto-restart |
Systemd restart policy |
Built-in (unlock) or PM2 auto-restart |
| Binary Distribution |
Yes (PyInstaller) |
No (requires Node.js) |
| Docker |
Yes |
Yes |
| Systemd Integration |
Yes (sdnotify) |
No |
| Credential-daemon-only Mode |
No |
Yes |
| Raspberry Pi |
Yes |
Yes (Node.js supported) |
| Windows |
Yes (binary) |
Partial (PM2 on Windows) |
12. Security
DEXBot
- Keys stored in BitShares wallet (
uptick) — file-based, password-protected
- Config file at
~/.config/dexbot/config.yml — plain text (file permissions only)
- Passphrase passed via environment variable or prompted at startup
- No key encryption beyond
uptick wallet format
- No memory-wipe of sensitive data
DEXBot2
- AES-256-GCM encrypted key storage (
profiles/keys.json)
- RAM-only master password: never written to disk (set only in environment, wiped after use)
credential-daemon.ts: manages key decryption in a separate daemon process
- On-chain authority resolution (
modules/authority_resolver.ts): when no direct private key is stored for an account, walks BitShares active authority structures (account_auths → key_auths, max depth 2) to find a usable signing key; per-call public key cache; multi-sig hint when no single entry meets threshold
- Config in plain JSON but no keys stored in config (separate encrypted store)
.gitignore ensures keys.json and sensitive files are never committed
- Fund invariant enforcement: prevents accidental overdraft
- Allowed-operations policy and credential session tests enforce separation between key access, launch modes, and bot execution
Security Comparison
| Key Encryption |
uptick wallet (basic) |
AES-256-GCM |
| Password Handling |
Env var or prompt |
RAM-only (never disk) |
| Config Sensitivity |
YAML (may include secrets) |
JSON (keys separate) |
| Key Storage Format |
Wallet file |
Encrypted JSON |
| Memory Safety |
No explicit wipe |
RAM-only password |
| Overdraft Protection |
No |
Fund invariant system |
| Audit Logging |
Basic |
Structured per-component logging |
| Credential Runtime Tests |
No |
Yes |
| Authority Resolution Fallback |
No |
Yes (on-chain authority walk via authority_resolver.ts) |
13. Testing
DEXBot
- Framework:
pytest
- Test types:
- Unit tests (strategies, storage, primitives)
- Integration tests (Docker-based local BitShares testnet)
- Migration tests (Alembic schema migrations)
- Price feed tests (CoinGecko, CCXT, Waves)
- Testnet: Docker-composed local BitShares node
- Tests cover external integrations realistically
- Pre-commit hooks via
.pre-commit-config.yaml
DEXBot2
- Framework: Native Node
assert module (no external test framework)
- 256
test_*.ts files auto-discovered via globSync (tests/test_*.ts + claw/tests/test_*.ts), covering:
- Unit tests: accounting, strategy, grid, manager logic
- Copy-on-Write semantics: COW commits, guards, concurrent fills
- Edge cases: authoritative full-fill resolution, partial fills, BTS fee accounting, precision
- Concurrency: fill batching, lock behaviors
- Scenario tests: specific bug reproductions
- Market adapter: AMA snapshots, dynamic weights, asymmetric bounds, signal gates
- Credential runtime: daemon, session cache, launch modes, private-key sanitization
- Claw/position layer: profiles, chain layer, short MPA strategy, position health
- Tests run with
npm test (concatenated node commands)
- No Docker testnet — pure unit/integration testing with mocks
- Migrated from Jest to eliminate all external test dependencies
Testing Comparison
| Framework |
pytest |
Native Node assert |
| Test Count |
16 Python test files |
256 test_*.ts files; auto-discovered via globSync |
| Test Types |
Unit + integration |
Unit + integration + edge-case + runtime regression |
| Testnet Integration |
Yes (Docker) |
No (mocks) |
| External Dependency |
pytest, Docker |
None |
| COW / Concurrency Tests |
No |
Yes (dedicated suite) |
| Edge Case Coverage |
Moderate |
Extensive |
| CI Integration |
Travis CI, AppVeyor |
GitHub Actions |
| Credential/Launcher Coverage |
Limited |
Dedicated daemon/session/unlock/PM2 tests |
| Market Adapter Coverage |
Price feed tests |
Dedicated AMA/dynamic-weight/signal-gate tests |
14. Documentation
DEXBot
- Sphinx docs (
docs/): setup, configuration, events, storage, strategy development
- README.md: overview, strategy descriptions, installation links
- Medium article: step-by-step getting started guide
- Community wiki (external)
- Strategy development guide via Sphinx
- No formal architecture documentation
DEXBot2
README.md |
Quick start, installation, config reference |
docs/architecture.md |
System design, data flows, COW pattern |
docs/COPY_ON_WRITE_MASTER_PLAN.md |
Deep dive into COW implementation |
docs/FUND_MOVEMENT_AND_ACCOUNTING.md |
Fund tracking model, invariants |
docs/developer_guide.md |
Developer quick start, glossary, examples |
docs/EVOLUTION.md |
Project history, 9-phase development |
docs/LOGGING.md |
Logging categories and configuration |
docs/WORKFLOW.md |
Branch strategy, commit standards |
tests/README.md |
Test suite organization and categories |
docs/GRID_RECALCULATION.md |
Grid recalculation triggers |
docs/COW_INVARIANTS.md |
Non-negotiable COW behavioral invariants |
docs/CREDENTIAL_SECURITY.md |
Credential daemon, key policy, and security model |
docs/MPA_CREDIT_USAGE.md |
Credit runtime and MPA usage guidance |
claw/docs/AI_BOT_LIBRARY_API.md |
Claw API boundary and responsibility split |
claw/docs/DEXBOT2_TUNING_CHEAT_SHEET.md |
Grid tuning reference |
claw/docs/POSITION_HEALTH.md |
Position health monitoring guide |
claw/docs/RUNTIME_COMPARISON.md |
Claw runtime comparison |
docs/docker.md |
Docker deployment guide |
docs/README.md |
Docs index |
AGENTS.md |
AI development context |
CHANGELOG.md |
Full version history |
Documentation Comparison
| Format |
Sphinx RST + Markdown |
Markdown only |
| API Docs |
Sphinx auto-generated |
Inline JSDoc comments |
| Architecture Docs |
None |
Extensive (architecture.md) |
| Developer Guide |
Sphinx strategybase.rst |
developer_guide.md |
| Fund Model |
None |
FUND_MOVEMENT_AND_ACCOUNTING.md |
| Changelog |
None |
CHANGELOG.md plus workflow/evolution docs |
| Accessibility |
Moderate |
Technical / developer-focused |
DEXBot
Production dependencies (requirements.txt):
pyqt5 >= 5.10 — GUI framework (~80MB)
bitshares >= 0.5.0 — blockchain client
uptick >= 0.2.4 — key management
ccxt >= 1.17 — 100+ exchange API (~10MB)
pywaves >= 0.8 — Waves integration
sqlalchemy >= 1.3 — ORM
alembic >= 1.0 — migrations
click >= 7.0 — CLI
ruamel.yaml >= 0.15 — YAML parser
sdnotify >= 0.3 — systemd
requests >= 2.21 — HTTP client
- Total: ~15-20 packages, significant install size
Dev dependencies: pytest, docker, pyinstaller, pre-commit
DEXBot2
Production dependencies (package.json):
- Total: 0 packages (zero runtime dependencies)
Dependency Comparison
| Production Packages |
~15-20 |
0 |
| Dev Packages |
~5-8 |
2 (TypeScript, @types/node) |
| GUI Framework |
PyQt5 (~80MB) |
None |
| Database ORM |
SQLAlchemy |
None |
| External Price APIs |
CoinGecko, CCXT, Waves |
None (runtime dep); optional CEX seed generator for adapter bootstrap |
| Blockchain Client |
bitshares + python-bitshares |
Hand-rolled native (bitshares-native/) |
| Install Size (approx) |
Large (100MB+) |
Minimal; analysis/data assets can be larger |
| Runtime Requirement |
Python 3.6+ |
Node.js LTS |
16. Extensibility & Plugin System
DEXBot
- Plugin architecture via
setuptools entry points
- Install a Python package → strategy auto-discovered
- User bot directory:
~/bots for quick custom strategies
- Strategy template (
strategy_template.py) provided
- Strategies are fully decoupled from the framework
- Community can publish and install strategies independently
DEXBot2
- No DEXBot-style strategy plugin system
- Single hardcoded core strategy (boundary-crawl grid)
- Extending core trading behavior requires modifying runtime modules
- Market adapter (
market_adapter/) provides real-time signal-driven parameter tuning: AMA center, dynamic weights, Kalman confirmation, ATR/regime dampening, and asymmetric bounds
analysis/ tools provide AMA fitting, dynamic-weight research, Kalman signal research, volatility/regime analysis, bot-parameter sweeps, bot-activity queries (bot_usage/), and FIFO-based trade PnL analysis (trade_profitability.ts)
claw/ exposes a separate automation and AI-consumption layer: profile reading, chain queries/actions, short MPA workflows, position health, runtime manifests, and skill/plugin artifacts
Extensibility Comparison
| Plugin System |
Yes (setuptools entry points) |
No core strategy plugin system |
| Custom Strategies |
Yes |
No runtime-swappable core strategies |
| Strategy Template |
Yes |
No |
| Community Strategy Sharing |
Yes (PyPI packages) |
No |
| Runtime Parameter Tuning |
Via config/restart |
MarketAdapter live snapshots/triggers |
| Analysis Tools |
No |
Yes (AMA fitting, trend, volatility, regime, bot sweeps, bot activity, trade PnL) |
| Automation API Layer |
No dedicated API layer |
Yes (Claw modules/scripts/skills) |
| Credit/MPA Tooling |
No |
Yes |
17. Metrics & Scale
| Release Track |
1.0.0 |
v1.6.11 |
| Active Since |
~2018 |
December 2025 |
| Last Commit |
May 23, 2020 |
2026-09-02 |
| Total Commits |
2281 |
2,125 (v1.4.25) |
| Lines of Code |
~10,846 Python LOC in dexbot/ |
Large TypeScript runtime + adapter + Claw + analysis + tests |
| Source Files |
72 Python files in dexbot/ |
~544 TS files across the repo |
| Test Files |
16 Python test files |
248 test_*.ts files (248 auto-discovered via globSync) |
| Documentation |
Sphinx docs + README |
60+ Markdown docs plus Claw skills/references |
| Strategies |
3 + plugins |
1 |
| Max Concurrent Bots |
Many (one process) |
Many (one monolithic process by default; per-bot via --isolated/PM2) |
| Primary Developer |
Codaone Oy (team) |
froooze (individual, 100% commits) |
| Community |
BitShares worker-funded |
Private, operator-focused |
| Governance |
"The Cabinet" (6-person, 3/5 multisig) |
None |
All claims below cite the actual source tree line numbers. Measured on identically configured bots (200 total orders, 1% increment, 100× range ratio) against the same BitShares node:
| Order calculation (single cycle) |
~180s |
~0.8s |
~225× |
| Full maintenance cycle |
~187s |
~1.3s |
~144× |
| Worst-case (500 orders, 500ms node latency) |
~480s |
~1.5s |
~320× |
| With compounding edge conditions (retries, GIL contention, wide range) |
~500–540s |
~1.5–2s |
~300–500× |
Why the gap is multiplicative, not additive
Each bottleneck in DEXBot compounds because they run serially in sequence — the next cannot start until the previous finishes. DEXBot2 eliminates them independently and simultaneously:
| 1 |
RPC queries |
Per-order get_objects loop called twice per cycle → 2×N sequential RPCs. |
Single batch get_objects([…]) in fetchRefBlock — modules/bitshares-native/tx/builder.ts; parallel account refresh via Promise.all — modules/bitshares-native/subscriptions.ts (refreshTasks, scanTasks). |
~400× |
| 2 |
Order counting |
Geometric while-loop iterating price /= 1+increment ~920 times per call. |
O(1) Math.log spread-step formula in calculateGapSlots — modules/order/utils/math.ts; O(1) spread check in shouldFlagOutOfSpread — modules/order/utils/order.ts. |
~920× CPU |
| 3 |
Market price |
Fresh ticker() RPC inside every order placement. |
Cached centerPrice served from botState, zero RPC per placement — market_adapter/market_adapter.ts + market_adapter/core/market_adapter_service.ts. |
~∞ (eliminated) |
| 4 |
Account refresh |
Full _account.refresh() fetches all orders + balances + history every cycle. |
Targeted set_subscribe_callback pushing only OP_FILL_ORDER ops — modules/bitshares-native/subscriptions.ts (refreshSubscriptions); filtered per-account; no full re-read — modules/chain_orders.ts. |
~50× |
| 5 |
Thread blocking |
time.sleep(2–6) on retry blocks the GIL thread entirely. |
Async await sleep() + AsyncLock queue — modules/order/async_lock.ts; lock guards in modules/order/manager.ts; backoff in modules/order/utils/system.ts. |
~100× I/O utilization |
| 6 |
State persistence |
SQLite queue write per order via blocking Event.wait(). |
Single atomic JSON write via storage.writeJSON({fsync:true}) + rename — modules/account_orders.ts; batch flush of processed fills; atomic utility — market_adapter/utils/atomic_write.ts. |
~200× |
| 7 |
Broadcast model |
Synchronous broadcast() + per-order cancel/replace with 10‑op batch cap. |
executeBatch bundles N ops into one tx — modules/chain_orders.ts; parallel scans via Promise.all — modules/bitshares-native/subscriptions.ts; parallel node health — modules/node_manager.ts (checkAllNodesPromise). |
~10× |
| 8 |
Runtime speed |
Python 3 (CPython interpreter, GIL-bound). |
TypeScript → V8 JIT (near‑native CPU throughput). |
~2× for CPU-bound loops |
Compounding effect
The speedups are multiplicative because they remove serial dependencies:
DEXBot serial path: RPC₁ → RPC₂ → … → RPC₂₀₀ → geo_loop × 2(runtime) → ticker → DB → broadcast → RPC₁ → …
↑________________________________________________________________________________________↓
Everything blocks on the previous step
DEXBot2 parallel path: [batch RPC] ─┐
[grid O(1)] ─┤
[fill scan] ─┤ → 1.3s total
[accountant] ┤
[JSON write] ┘
The Python runtime overhead (≈2× slower than V8 on equivalent CPU work) is the least impactful factor here — but it still compounds with everything else. The geometric while-loops and _calc_increase iterations all run at Python bytecode speed, thousands of iterations per cycle. DEXBot2 eliminates the iterations entirely with O(1) formulas (calculateGapSlots in math.ts, shouldFlagOutOfSpread in order.ts) — so the 2× language factor is just insurance on top of the architectural gains.
The 500× figure is not theoretical: it materializes in production when higher order counts, slower public nodes, transient block-expiration retries, and wide geometric ranges all hit at once — a scenario DEXBot handles by piling seconds onto seconds, while DEXBot2 absorbs each factor with negligible marginal cost.
19. Known Limitations & Trade-offs
DEXBot Limitations
- No longer actively maintained (last repo activity May 23, 2020)
- Python GIL limits true parallelism for multi-worker scenarios
- Mutable shared state — susceptible to race conditions in multi-worker use
- No formal fund invariant enforcement — overdraft possible under edge cases
- No Copy-on-Write or atomic planning/commit boundary for grid transitions
- No persistent fill replay-dedupe layer comparable to DEXBot2's processed fill store
- No adaptive AMA/Kalman/dynamic-weight signal layer
- No credential daemon or separate automation API layer
- YAML config has no key encryption (relies on OS file permissions)
- Staggered Orders strategy can suffer inventory skew in strong trends
- External price feeds introduce latency and potential for price manipulation
- PyQt5 dependency adds significant install complexity and size
- SQLite state can desync from blockchain after unclean shutdowns
DEXBot2 Limitations
- Single core strategy — no runtime-swappable plugin system, but the boundary-crawl grid is deeply engineered with AMA/Kalman/ATR/regime adaptive signals, making it far more capable and configurable than DEXBot's individual strategies
- No GUI — requires CLI proficiency
- No DEXBot-style external CEX price-feed strategy support
- Advanced bot keys (
debtPolicy, creditOnly, min_BTS_value) require manual JSON editing; main settings are interactive via dexbot bot
- Backtesting/research exists under
analysis/, but it is not a polished end-user backtesting product
- No community/plugin ecosystem
- Heavy documentation suggests significant learning curve for contributors
- Rapid iteration means new adapter/Claw/credit features require disciplined regression testing before production use
20. Summary Scorecard
| Strategy Variety |
★★★☆☆ (3 + plugins) |
★★★★☆ (1 deeply engineered, highly adaptive/configurable boundary-crawl grid) |
DEXBot2 |
| State Safety |
★★☆☆☆ |
★★★★★ (COW + invariants) |
DEXBot2 |
| Fund Accounting |
★★☆☆☆ |
★★★★★ (formal model + fund_registry + cross-bot invariants) |
DEXBot2 |
| Concurrency Safety |
★★☆☆☆ |
★★★★★ (AsyncLock + COW) |
DEXBot2 |
| Security |
★★★☆☆ |
★★★★★ (AES-256-GCM, credential daemon, authority resolution) |
DEXBot2 |
| Ease of Setup |
★★☆☆☆ (PyQt5/PyInstaller/Systemd dependency hell) |
★★★★★ (npm i -g dexbot, zero deps) |
DEXBot2 |
| Accessibility |
★★★★★ (GUI) |
★★☆☆☆ (CLI only) |
DEXBot |
| Testing Depth |
★★★☆☆ |
★★★★★ (305 test files; focused regressions) |
DEXBot2 |
| Documentation |
★★★☆☆ |
★★★★★ (architecture/accounting/security/adapter docs) |
DEXBot2 |
| Dependency Footprint |
★★☆☆☆ (heavy) |
★★★★★ (0 runtime deps) |
DEXBot2 |
| Extensibility |
★★★★★ (plugins) |
★☆☆☆☆ |
DEXBot |
| Active Maintenance |
★☆☆☆☆ (unmaintained) |
★★★★★ (active) |
DEXBot2 |
| Grid Strategy Depth |
★★★☆☆ (Staggered) |
★★★★★ (engineered) |
DEXBot2 |
| Adaptive Market Signals |
★★☆☆☆ (external feeds only for Relative Orders) |
★★★★★ (AMA/Kalman/ATR/regime/dynamic weights) |
DEXBot2 |
| Process Management |
★★★☆☆ (Systemd) |
★★★★☆ (native dexbot start/unlock launcher + optional PM2 + daemon modes) |
DEXBot2 |
| Automation/API Surface |
★★☆☆☆ (strategy hooks) |
★★★★☆ (Claw modules/scripts/skills) |
DEXBot2 |
| Credit/MPA Tooling |
★☆☆☆☆ |
★★★★☆ |
DEXBot2 |
| Community/Ecosystem |
★★★☆☆ |
★★☆☆☆ |
DEXBot |
| Multi-Strategy Support |
★★☆☆☆ |
★★★★☆ (1 deeply engineered, highly adaptive strategy with broad signal integration) |
DEXBot2 |
21. Migration Considerations
DEXBot2 is not a drop-in upgrade for DEXBot. The projects optimize for different operators:
| Desktop GUI, wizard setup, and non-technical operation |
DEXBot |
| Multiple runtime-swappable strategies or community strategy plugins |
DEXBot |
| Hardened grid accounting, COW state transitions, and replay-safe fill handling |
DEXBot2 |
Headless dexbot start (monolithic) or PM2 operation across many bot processes |
DEXBot2 |
| AMA/Kalman/ATR adaptive grid weighting and recalculation triggers |
DEXBot2 |
| Credential-daemon key separation and launcher-mode testing |
DEXBot2 |
| Claw automation, position health, MPA/credit tooling, and AI-consumable runtime surfaces |
DEXBot2 |
The practical migration path is to treat DEXBot2 as a new runtime: recreate bot configs in profiles/bots.json, validate price orientation and fund allocation, start with small funds, and rely on startup reconciliation plus logs before scaling position size.
Report generated 2026-08-28. Metrics refreshed 2026-08-28 from local DEXBot-master and DEXBot2 source trees.