Skip to content

Authoring API

Public contracts imported by strategy.py. External I/O remains gateway-owned.

almanak.api

Public strategy authoring contracts. External I/O remains gateway-owned.

PoolPrice

Bases: PoolSource

The pool's price at the last block at or before each candle boundary: closes only.

PoolSwapCandles

Bases: PoolSource

OHLCV candles of the pool's trades between consecutive candle boundaries.

A candle opens at the previous boundary's pool price and closes at this one's; its high and low also cover every trade's price, and its volume sums the absolute quote-token amounts of those trades. A trade's price is the pool's resulting spot price (V3-style and V4 Swap events, Aerodrome Sync events) or, for Curve, its execution price including fees (TokenExchange events between the asset and quote). A candle without trades is flat with zero volume.

PriceBinding

Bases: Model

lookback_seconds property

lookback_seconds: int

History before a decision that its window needs, beyond the latest point.

AssetAmount

Bases: Model

Nonnegative base-unit amount with explicit asset identity.

PriceSeries

Bases: Model

values property

values: tuple[Decimal, ...]

The closes, for candles.

gaps property

gaps: tuple[tuple[UnixTime, UnixTime], ...]

Consecutive points further apart than the timeframe.

complete property

complete: bool

The full window, evenly spaced, with its latest point within the source age.

DecisionContext

Bases: Model

price

price(asset)

The declared series for one asset; a strategy declares at most one per asset.

InvalidConfig

Bases: ValueError

Raise from validate_config to refuse the configuration with this message.

The run reports it as a final invalid_config refusal, never as a crash, and from any function in strategy.py that validate_config calls.

StrategyState

Bases: Memory

Subclass as State inside strategy.py; typed fields are persisted by the worker.

TypedParameters

Bases: Model

Subclass once in parameters.py or strategy.py, as StrategyParams, to type strategy.parameters.

Declare it as a top-level class: the SDK reads its fields from the source, and loads the strategy to find a model defined any other way. Each YAML scalar converts to its field's type the way pydantic's lax JSON mode does: "1" or 1.0 to an int, 0.2 or "0.2" to a Decimal, 3 to a str; 1.5 for an int, infinities and NaN are refused. As without a model, a bool field takes only true or false, and a number field refuses a boolean and a _ in its digits; a tuple's elements convert laxly. Undeclared keys are refused, and a missing key takes its default or is refused when it has none. A list field is a tuple[...]: a mutable one is refused, since a hook could change it for the next.

parameter_base_units

parameter_base_units(
    parameters, name: str, decimals: int
) -> int

parameters.<name>, a quantity in an asset's units, in its base units.

A quantity finer than the asset's decimals is refused naming the field, never truncated: call it from validate_config so the refusal comes before any action.