Skip to content
All library documents

Stateless DAG Execution and Exchange Management for Trading Automations

Article OctoBot

Summary

This document explains the architecture of a serverless automation runner used to execute trading workflows. Each invocation receives an automation state, runs a directed acyclic graph of dependent actions, and returns the updated state. Ready actions are selected by dependency status, placeholders can use upstream results, and a DSL executor runs each action. Priority actions support initial account configuration before ordinary workflow execution.

The description also covers resuming workflows: a waiting operator can trigger a DAG reset that clears dependent actions for rerun while preserving their previous results. DSL scripts are parsed before exchange initialization so the runner can fetch only referenced OHLCV data. When credentials are absent, simulated exchange implementations use snapshots, although public OHLCV remains live; a ticker cache provides a fallback. Exchange managers are initialized and torn down per job, with explicit portfolio synchronization. These are implementation details rather than evidence of trading performance; the document does not describe a strategy or evaluate execution outcomes.

Key ideas

  • Each invocation runs from an explicit state object and returns its updated state.
  • Trading actions are organized as a dependency graph, with ready actions executed through a DSL interpreter.
  • Waiting actions can reset dependent steps while retaining prior results for resumable execution.
  • Scripts are inspected before exchange setup to limit OHLCV fetching to referenced data.
  • Simulated exchange behavior and per-job authentication isolate automations, but no strategy results are reported.

Tags

Full text
# Flow Package


---
title: Flow
description: Architecture and concepts of the octobot_flow package — OctoBot's serverless automation runner.
sidebar_position: 1
---

# Flow Package

`octobot_flow` is a stateless automation execution engine. An `AutomationState` object is passed in at the start of each invocation, the job runs, and the updated state is returned via `AutomationJob.dump()`. Nothing is held in memory between calls, which means the engine can run as a serverless function and multiple automations are naturally isolated from one another.

## Execution model

Each job runs a DAG of actions. The DAG identifies which actions are ready — not yet completed, with all dependencies satisfied — resolves any DSL placeholders by injecting upstream results, and executes them via `DSLExecutor`. After execution, exchange state is synced back into the automation state.

Priority actions stored in `AutomationState.priority_actions` run before the normal DAG cycle but use the main DAG as their resolution context. This is the mechanism for bootstrapping: on the very first invocation, when there is no previous execution and no exchange account, only `apply_configuration` actions are processed to set up the exchange account from config before the regular cycle runs.

A DAG reset can be triggered mid-run by a `ReCallingOperatorResult`, which the `wait()` operator returns when its condition is not yet met. A reset computes the transitive closure of dependents from the target action, saves their current results into `previous_execution_result`, and clears their execution timestamps so they re-run on the next invocation. The saved previous result lets re-running operators resume from where they left off rather than starting cold.

## DSL execution

`DSLExecutor` wraps the `octobot_commons` DSL interpreter with operator sets registered by tentacles. A fresh interpreter is created per action to prevent state leakage between actions in the same run. DSL scripts are parsed before the exchange is initialised so that required symbols and time frames can be extracted upfront — only the OHLCV data that scripts actually reference is fetched.

## Simulated and live modes

When no credentials are present, `ExchangeRepositoryFactory` returns simulated implementations that read from `FetchedExchangeData` snapshots instead of making live API calls. OHLCV data is still fetched live even in simulated mode because it is public. A portfolio can be forced onto the simulated exchange manager to test strategies against a specific account state.

The ticker cache, with a five-minute TTL and a fifty-entry cap, serves as a fallback when OHLCV data is unavailable during initialisation. Community repositories intentionally use non-singleton auth instances per job — no session is shared between automations, which prevents credential leakage.

## Exchange lifecycle

`ExchangeContextMixin` manages the full exchange lifecycle for each job: build config, initialise `ExchangeManager` with storage disabled, apply any forced portfolio for simulated runs, then tear down after the job completes. Portfolio sync is disabled during order creation because the flow package manages portfolio state explicitly through post-action sync calls rather than relying on automatic sync triggered by order events.

Shown in full with attribution under the source's licence. Licence: GPL-3.0

This summary was written by Stratmill's research agent from the original; it is not a copy of the source.