Skip to main content

Trading engine — gateway, task manager, and process SDK

Project description

Trading Engine

Run algorithmic trading strategies as managed tasks — with a live dashboard, per-task logs, restart policies, and a market SDK that abstracts across venues.


Quickstart

1 — Install

pip install tribulnation-engine

2 — Initialize

Initialize the engine in a new directory:

engine init
# creates engine.toml, .env, and strats/ directory

Edit engine.toml and .env to configure accounts and strategies.

3 — Write a strategy

# strats/my_strat.py
from tribulnation.engine import Process, RestartPolicy

class MyStrat(Process):
  name = 'my-strat'
  restart = RestartPolicy(on='error', delay=5.0)

  async def run(self, market: str):
    mkt  = await self.sdk.market(market)
    book = await mkt.depth()
    self.log.info('mark price: %s', book.mark_price)

run() parameters become the task's argument schema — they appear as a form in the dashboard and are coerced to the declared types when a task is started.

4 — Start the engine

engine start          # foreground, logs to stdout
engine start -d       # background — writes .engine.pid and engine.log

For longer-running deployments on a systemd host, you can also install it as a user service:

engine service install --cwd . --memory 2G -v
engine service status
engine service logs -f

The generated service runs engine start, restarts automatically, and uses systemd MemoryMax when --memory is provided. It also uses a bounded stop timeout so stuck shutdowns are force-killed by systemd:

engine service install --cwd . --memory 2G --timeout-stop-sec 20

Manage it with:

engine service restart
engine service stop
engine service uninstall

5 — Run a strategy

From the dashboard at http://localhost:3121 or via the CLI:

engine task start my-strat bitcoin -a market=mexc:spot:BTCUSDT
# engine task start <process_name> <run_id> -a <arg_name>=<arg_value> ...

6 — Stop a strategy

From the dashboard or:

engine task stop my-strat bitcoin
# engine task stop <process_name> <run_id>

Strategies

The Process base

from tribulnation.engine import Process, RestartPolicy

Implement async def run(self, ...). Anything run() needs is injected via self:

Attribute What it is
self.sdk Market SDK — call await self.sdk.market('venue::symbol')
self.log Logger scoped to this task
self.run_id The run ID this task was started with
self.set_state(s) Publish a named state ('connected', 'quoting', …)
self.require(cls, id) Declare a dependency on another running task
self.ipc Call methods on Service processes

Restart policy

class Hedger(Process):
  restart = RestartPolicy(on='error', delay=5.0)
on= Behaviour
'never' Stop on exit or error
'error' Restart after an unhandled exception, with delay seconds between attempts
'always' Restart after any exit

max_attempts=N caps the number of consecutive restarts.

Dependencies

Use require() to gate a task on another reaching a named state:

class DydxMaker(Process):
  async def run(self, maker: str, hedge: str) -> None:
    async with self.require(Hedger, self.run_id, state='connected')(
      listen=maker, hedge=hedge
    ):
      # runs only while Hedger/{self.run_id} is alive and in state 'connected'
      ...

require() also auto-starts the dependency if it isn't running, and cancels the dependent if the dependency stops or errors.

Logging

Standard logging calls are automatically captured and streamed to the dashboard. No setup needed:

log = logging.getLogger(__name__)

class Hedger(Process):
  async def run(self, ...):
    log.info('listener live: %s%s', listen, hedge)
    # or use the process logger:
    self.log.info('works the same way')

INFO and above are always captured. DEBUG records are captured only from loggers whose name starts with a prefix listed in [daemon] debug_loggers:

[daemon]
debug_loggers = ["strats"]

Config reference (engine.toml)

[engine]
processes = [
  "strats.hedger:Hedger",
  "strats.dydx_maker:DydxMaker",
]

[daemon]
host     = "localhost"
port     = 3121
db       = "engine.db"    # SQLite path; default "engine.db"
max_logs = 500            # in-memory log lines per task; default unlimited

[accounts.dydx-main]
venue    = "dydx"
mnemonic = "$DYDX_MNEMONIC"

[accounts.hyperliquid-main]
venue       = "hyperliquid"
address     = "$HYPERLIQUID_ADDRESS"
private_key = "$HYPERLIQUID_PRIVATE_KEY"

[[tasks]]
process = "hedger"
id      = "btc"
args    = { listen = "dydx:perp:BTC-USD", hedge = "hl::BTC" }

Account credentials are resolved from environment variables when the value starts with $. engine start automatically loads .env from the same directory as engine.toml.

[[tasks]] entries are started automatically when the engine starts. Each entry needs process (the registered process name), id (the run ID), and optionally args (a table of keyword arguments matching the process signature).


CLI

engine start                                          # launch gateway + manager (foreground)
engine start -d                                       # background — writes .engine.pid + engine.log
engine service install --cwd . --memory 2G -v          # install as a user systemd service
engine service logs -f                                 # follow service logs
engine stop                                           # stop a background engine
engine task start hedger btc -a listen=dydx:perp:BTC-USD -a hedge=hyperliquid::BTC
engine task stop  hedger btc
engine register strats.new_strat:NewStrat             # hot-load a process class

HTTP API

Method Path Description
GET /api/tasks Running tasks
GET /api/tasks/history Completed tasks (SQLite)
GET /api/task/{process}/{id} Single task
GET /api/task/{process}/{id}/logs Task logs
GET /api/task/{process}/{id}/attempts Restart attempts
POST /api/task/{process}/{id} Start a task — body: {"args": {...}}
DELETE /api/task/{process}/{id} Stop a task
DELETE /api/task/{process}/{id}?purge=true Stop and remove from history
DELETE /api/task/{process}/{id}/logs Clear logs and attempt history
GET /api/processes Registered process classes
POST /api/processes Register a process at runtime
GET /api/health Health check
GET /api/ws WebSocket event feed

Architecture

engine start
├── engine gateway    owns real venue SDK connections, serves the market RPC protocol
└── engine manager    task control plane
  ├── in-process runtime — strategies run as asyncio tasks
  ├── REST + WebSocket API (FastAPI / uvicorn)
  └── SQLite store — task history, logs, restart attempts

Strategies never hold venue connections directly. self.sdk inside a task is a ProxySDK that routes market calls to the gateway over a local Unix socket. The gateway owns the real credentials and connections; the manager owns task lifecycle and the dashboard.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tribulnation_engine-0.1.13.tar.gz (108.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tribulnation_engine-0.1.13-py3-none-any.whl (122.2 kB view details)

Uploaded Python 3

File details

Details for the file tribulnation_engine-0.1.13.tar.gz.

File metadata

  • Download URL: tribulnation_engine-0.1.13.tar.gz
  • Upload date:
  • Size: 108.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for tribulnation_engine-0.1.13.tar.gz
Algorithm Hash digest
SHA256 7f5d5b06749bbf4733014b5b925954dccc2eb3685800d1c9b46b828726faeade
MD5 98cc076364250f42fce0a28f90090818
BLAKE2b-256 5a61ad204276086874d87202bcbd04016cc5163e506b590ec687db284017fb65

See more details on using hashes here.

File details

Details for the file tribulnation_engine-0.1.13-py3-none-any.whl.

File metadata

File hashes

Hashes for tribulnation_engine-0.1.13-py3-none-any.whl
Algorithm Hash digest
SHA256 acf3c906a640972c84bcc269b9474c12d7f93a0dfd1bbbabab5eda4bc0c907b1
MD5 38284b77f2afacc4076575b7a7f08a55
BLAKE2b-256 a515b82f171f98a2f27de632d92fe7ba378d65d77caff9bee902204f7a58d8da

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page