Skip to contents

Construct a ledgr indicator

Usage

ledgr_indicator(
  id,
  fn,
  requires_bars,
  params = list(),
  stable_after = requires_bars,
  series_fn = NULL,
  source = "custom",
  gap_contract = NULL,
  history_class = NULL,
  required_fields = NULL,
  tolerance = NULL,
  input_carry = NULL
)

Arguments

id

Unique indicator identifier.

fn

Scalar indicator function evaluated on one bounded window of bars ending at the current bar, returning a numeric value or a list. Two forms are accepted: function(window), and function(window, params). When the function declares a second argument, ledgr also passes the indicator's params.

requires_bars

Minimum lookback period (integer).

params

Named list of deterministic parameters for fingerprinting.

stable_after

Number of bars after which the indicator output is stable.

series_fn

Optional vectorized indicator function: function(bars, params) -> numeric vector aligned to bars.

source

Indicator source label. Built-in ledgr indicators use "ledgr", TTR-backed indicators use "TTR", and user/adapted indicators use "custom".

gap_contract

Optional gap declaration. "strict_window" declares a bounded window and is equivalent to history_class = "bounded"; it contradicts history_class = "history_dependent".

history_class

Optional history class: "bounded" or "history_dependent". NULL with no gap_contract is disclosed as "history_dependent": ledgr never infers that a definition is bounded.

required_fields

Optional character vector of the bar fields the calculation requires, from "open", "high", "low", "close" and "volume". NULL requires the four price fields.

tolerance

Optional comparison tolerance for a bounded definition that supplies both fn and series_fn. NULL (the default) means exact. A nonzero tolerance is a scaled bound, abs(a - b) / max(1, abs(b)), and enters the definition's availability-aware identity.

input_carry

Optional input-carry declaration. "excluded" marks a return or volatility indicator: it never consumes a price carried by the experiment's history policy, so a gap leaves its inputs missing. NULL (disclosed as the default) and "eligible" consume the policy-treated input. Package built-ins and registered TTR forms take this from the package catalogue.

Value

A ledgr_indicator object.

Details

Indicator fingerprints bind deterministic direct captures of fn and series_fn. Atomic values and deterministic lists are supported; environments, connections, and other unsupported captures refuse as non-deterministic. A captured function contributes its function identity, but its own captures are not recursively included. Put explicitly varying research inputs in params.

On availability-aware experiments the history declarations decide how the indicator is calculated. A bounded definition depends only on its last requires_bars expected sessions: fn receives exactly that window and an incomplete window is missing. A history-dependent definition is calculated once per contiguous segment of available input and restarts after a gap. stable_after is the first-valid boundary after each start or restart; it does not promise convergence. A delisting ends bounded windows as well as carry: after every relisting a bounded definition restarts. The declarations enter the availability-aware feature identity; dense execution ignores them. An indicator whose id matches a built-in pattern (sma_<n>, return_1) still runs its own fn in both modes, in any session; running an experiment never writes the indicator registry.

Availability-aware preparation also checks every definition for look-ahead before any run, sweep candidate or precompute payload uses it: on the instrument with the most calculated values, at no more than four fixed sessions, the value recomputed from the history ending there must equal the prepared value, or preparation refuses with ledgr_feature_lookahead_detected. A custom bounded definition that supplies both fn and series_fn must also agree, at the same sessions, between fn on its window and series_fn within tolerance, or preparation refuses with ledgr_indicator_gap_parity. Both checks are samples, not proofs of causality.

Examples

last_close <- ledgr_indicator(
  id = "last_close",
  fn = function(window) tail(window$close, 1),
  requires_bars = 1
)
last_close$id
#> [1] "last_close"

mean_close <- ledgr_indicator(
  id = "mean_close_3",
  fn = function(window, params) mean(tail(window$close, params$n)),
  requires_bars = 3,
  params = list(n = 3)
)
mean_close$id
#> [1] "mean_close_3"