ChartnautDocs

Declarations

The top of a study declares everything it reads and publishes: its settings, the definitions whose events it measures, any indicators, the dimensions that split events into groups, and each result. Declarations run once, at module scope, before any event.

meta

meta({
  name: "OR break first hit",
  kind: "study",
  category: "Opening range",
  params: {
    horizonMin: { type: "number", def: 60, min: 1, max: 1440, step: 1 },
    markColor: { type: "color", def: "#26a69a", allowAlpha: false },
  },
  runOn: ["1m", "5m", "15m"],
  runOnReason: "Needs several bars inside each opening range.",
});

Field

Notes

name

Shown in the study list and on the run card.

kind

"study" for an event study. Trade studies use "trade_study" and a different anchor.

category

Optional grouping label.

params

Settings the trader can change before a run. Read them as ctx.params.<key>.

runOn

Optional list of timeframes the study may run on. Leave it out to allow all.

runOnReason

Shown when someone picks a timeframe outside runOn.

Each param takes type ("number", "string", "boolean" or "color"), def, and optionally min, max, step and options. Colour params also take allowAlpha and presetColors. Use type: "color" for any colour so the run dialog shows a picker.

flows.declare

flows.declare({ slug: "or-break", as: "orb", version: 3 });

Field

Notes

slug

The definition's slug, not its display name.

as

Alias. ctx.event.flow holds this alias, and ctx.flows.<as> reads this definition.

version

Required. Lint fails with flows/missing-version without it.

settings

Optional setting overrides for the definition.

A study reads only the events recorded under the exact version you pin. When a definition is created and then written, its code lands on version 2, and version 1 is the empty row created with it. Pin version 1 and the study lints clean, then every run comes back with no events. Pin the version you ran over history.

A study that ships inside an app can name a definition from the same app by path: flows.declare({ from: "definitions/ib-structure", as: "ib" }). A from declaration takes no version. It resolves to whatever version is installed for the person running it.

indicators.declare

indicators.declare({ slug: "atr", as: "atr14", version: 1, settings: { period: 14 } });

Same shape as in indicators and definitions, described in Declaring indicator dependencies. version is required here too (indicators/missing-version). Reading the values is covered in Dependencies.

dimensions.declare

A dimension is a way to split events into groups, such as break direction or session. Results indexed by a dimension report one row per group, and a Forward Insight uses scope dimensions to pick the reading for the event you click.

dimensions.declare({
  id: "direction",
  role: "scope",
  title: "Break direction",
  description: "Which side of the opening range the close broke.",
  values: ["up", "down"],
});

dimensions.declare({
  id: "next_regime",
  role: "report",
  title: "Next-day regime",
  description: "Measured from the following session.",
  values: ["rotational", "trending", "ranging"],
});

id, title and description are required (study/dimension-declare-fields). Ids must be unique.

role

Meaning

Returned by scope()

Indexes a Forward Insight

"scope" (default)

Known when the event fires: direction, weekday, a volatility bucket at the event

Required, on every path

Yes

"report"

Measured later in onEvent: next-day regime, forward return bucket, which barrier hit

Forbidden

No

Declare an outcome axis as role: "report". Left without a role it defaults to "scope", and lint then asks scope() to return an outcome it cannot know when the event fires. scope covers both roles.

values lists the canonical values. When it is set, scope() and published cells must use exactly those strings. Put display labels such as "Strong trending" in result text, never in a dimension value. Without values the dimension is open and takes any value.

results.declare

results.declare({
  id: "hit_rate",
  kind: "metric",
  title: "Target hit rate",
  description: "Share of breaks where the target hit before the stop.",
  size: "xs",
});

results.declare({
  id: "by_direction",
  kind: "table",
  title: "By break direction",
  description: "Hit rate and sample for up and down breaks.",
  indexedBy: ["direction"],
  columns: [
    { id: "target_rate", format: "percent" },
    { id: "events_in_group", format: "count" },
  ],
});

Field

Notes

id

What you pass to ctx.publish. Publishing an undeclared id is a lint error.

kind

One of the kinds in Results and stats.

title

Heading on the result.

description

One to three plain sentences on what it measures and in what unit. It also appears in Forward Insight popovers. Lint warns when it is missing.

indexedBy

Dimension ids whose values key the published rows. Each row must carry every listed id as a field.

columns

Table columns: id, format ("percent", "number", "integer", "count", "text") and optional bind.

size

"xs", "sm", "md" or "lg". Defaults: metric xs, table, heatmap and prose lg, everything else md.

role

For kind: "prose" only: "question", "answer", "caveat", "note" or "section".

hints

Renderer options, such as orientation and sort for bar charts.

Results render in the order you declare them. Consecutive xs metrics share a row of up to four tiles, consecutive md results sit side by side, and each lg takes a full row. Declare a prose answer first, then the headline metrics, then the main chart.

Declare every id you publish. Lint warns about a declared id you never publish (study/declare-without-publish).

A report table may be indexed by more dimensions than a Forward Insight uses, including report-role ones. ["direction", "next_regime"] is fine for a contingency table.

Common mistakes

  • Writing the definition's display name instead of its slug in flows.declare.

  • Pinning version: 1 on a definition that has moved on.

  • Leaving role off an outcome dimension.

  • Using a display label as a dimension value when values is declared.

  • Writing a pin_cell result by hand. Attach to chart writes it. See Forward Insights.