The Problem

Crypto‑trading frameworks often grow into large, entangled codebases where circular imports, deep nesting, and silent error swallowing make it hard to reason about changes or reproduce builds. Jesse provides a rich set of tools for strategy research, back‑testing, and live trading, but its internal structure contains several maintainability risks that can slow development and increase the chance of introduced bugs.

What This Does

Jesse is a Python‑based crypto‑trading bot that lets users define strategies with a simple syntax, choose from 300+ technical indicators, and run back‑tests, optimisations, or live sessions. Core entry points are jesse/cli.py:run (reaches 399 functions, called from one place) and jesse/cli.py:install_live (reaches 36 functions). A hub module jesse/strategies/__init__.py is imported by 138 other modules, giving it a broad blast radius; any change there ripples across many strategy files. The indicator library lives under jesse/indicators/, each file exposing a single ma, rsi, etc. Functionality that leaves the process includes 22 network calls (via requests.post), 6 model‑inference calls, 19 filesystem operations (e.g., os.makedirs in run → log_monte_carlo), 2 cryptographic operations, 9 database reads/writes, and 2 external‑command invocations.

How It Is Wired

Execution starts at jesse/cli.py:run, which fans out to slice_candles (168 callers), get_candle_source (109 callers), and other helper functions. The internal call graph contains 3 464 resolved call edges; notable cycles involve jesse/__init__.py, jesse/store/__init__.py, and jesse/routes/__init__.py. A deep‑nesting problem appears in jesse/routes/__init__.py (max indentation depth 6) and in several Nuxt‑Monaco files (jesse/static/_nuxt/nuxt-monaco-editor/vs/base/common/errors.js, platform.js). An empty catch {} in jesse/static/_nuxt/nuxt-monaco-editor/vs/base/common/platform.js silently discards errors; bare except in jesse/services/multiprocessing.py and jesse/models/Log.py swallows exceptions indiscriminately. The most‑connected modules also include jesse/__init__ (instability 0.22, in a cycle) and jese/indicators/__init__ (instability 0.98, in a cycle), indicating areas where refactoring would give the greatest stability benefit.

How To Use It

  • Setup: Install with pip install -e . (the repo uses setup.py and requirements.txt). Docker users can build via docker build -t jesse . using the provided Dockerfile.
  • Configuration: Edit jesse/config.py for default settings; environment variables for API keys are read from this file (no secrets are committed).
  • Running it: Invoke the CLI entry point jesse run to start a back‑test, or jesse install_live to initialise live‑trading mode. Example: jesse run --strategy GoldenCross --symbol BTC/USD.

Real‑World Use

A trader writes a short strategy class in jesse/strategies/ (e.g., class GoldenCross(Strategy): def should_long(self): short_ema = ta.ema(self.candles, 8); long_ema = ta.ema(self.candles, 21); return short_ema > long_ema). The strategy can be back‑tested with jesse run, optimised with jesse optimize, or deployed live after setting API credentials in jesse/config.py. The built‑in indicator library means the trader does not need to implement technical calculations from scratch.

Code Health & Issues

  • MEDIUM – Declare least‑privilege permissions for GITHUB_TOKEN in .github/workflows/python-package.yml (no permissions declared).
  • MEDIUM – Enable Dependabot or Renovate; only requirements.txt is present, no update bot configured.
  • MEDIUM – Pin the container base image by digest in Dockerfile (python:3.11-slim-bullseye uses a mutable tag).
  • MEDIUM – Gate pull requests on a dependency vulnerability scan; no dependency scan currently in CI.
  • MEDIUM – Move large binaries to Git LFS or out of the repository; jesse/static/_nuxt/nuxt-monaco-editor/vs/language/typescript/ts.worker.js is a 10.7 MB blob.
  • MEDIUM – Set persist-credentials: false on checkout in .github/workflows/codeql-analysis.yml.
  • MEDIUM – Add a non‑root USER to the Dockerfile; currently no USER directive.
  • LOW – Set timeout-minutes on workflow jobs in .github/workflows/codeql-analysis.yml (2 jobs have no timeout).
  • LOW – Add convention files this project lacks (.editorconfig, .gitattributes, formatter config).

All items above are drawn from the static‑analysis run; each carries its own recommended fix.

The Bottom Line

Jesse delivers a powerful, feature‑rich framework for crypto‑strategy development with a simple Python API and extensive indicator support, but its codebase suffers from circular imports, deep nesting, and missing build‑reproducibility safeguards. Teams that need rapid prototyping and are comfortable managing the outlined maintenance risks will find it valuable; organisations requiring strict CI‑gate security and reproducible containers may need to add the recommended fixes before production use.