Write valid Navi code for chart indicators, strategies, and reusable libraries. Keep every answer focused on Navi authoring: syntax, execution semantics, standard-library calls, and practical script patterns.
Source of Truth
Navi's standard library and, occasionally, its syntax evolve. This skill captures the stable authoring model — it deliberately does not reproduce the full API. Treat navi-lang.org as authoritative and verify concrete API details there instead of trusting memory or any list embedded in this skill.
Before using any concrete API — a function name, signature, enum variant, or method name — confirm it against the source above. When unsure, fetch llms-full.txt (or the specific page) rather than guessing.
Never construct a documentation URL from a symbol name. Fetch llms.txt first and copy an exact link from it. In particular:
- Guide pages live under
/docs/, not /ai/ or /guide/.
- Namespace/module pages use
/api/stdlib/<module>/index.md.
- Prelude types and enums use
/api/stdlib/prelude/<Type>.md, such as Table.md and PlotDisplay.md; they do not have nested index.md pages.
- Free prelude functions such as
plot, bg_color, na, and nz are sections of /api/stdlib/prelude/index.md; they do not have one page per function.
- If a guessed URL returns 404, stop guessing paths and return to
llms.txt.
Reference Map
Load only the reference needed for the task:
| Read this |
When you need to... |
| references/syntax.md |
Check Navi source syntax: statements, blocks, declarations, types, collections, functions, methods, structs, enums, imports, and exports. |
| references/execution-model.md |
Reason about bar-by-bar execution, series values, qualifiers, var/varip, rollback, na, history references, and repainting. |
| references/stdlib.md |
Learn the stdlib naming rules and how to look up exact API names, signatures, and enum variants on navi-lang.org. |
| references/patterns.md |
Start from complete indicator/strategy/library templates or reuse idioms for warmup guards, crosses, state, arrays, MTF data, divergence, debugging, and output polish. |
| references/cli.md |
Install the navi CLI, or run a script to see what it computes: navi check/fmt/run, the stdin NDJSON protocol, and driver patterns. |
Authoring Workflow
- Identify the script kind:
indicator() for visual studies, strategy() for orders/backtests, or library() for exported helpers.
- Put configuration first with
input.*() calls. Prefer typed inputs (input.int, input.float, input.source, input.string, input.bool) and use stable titles.
- Model time correctly. Treat
close, high, ta.* outputs, conditions, and plots as per-bar series values. Use x[1] for prior bars.
- Use
let for per-bar calculations, var for state that must persist across bars, and varip only for intentional intrabar state.
- Guard warmup and missing values with
na(), nz(), or fixnan(); never assume na is zero.
- Confirm standard-library API names and signatures against navi-lang.org (
llms.txt, then its exact page link) before using them; do not rely on remembered lists or synthesize URLs. As a rule, Navi built-in functions are snake_case (e.g. ta.cross_over, bg_color) and types/enums are PascalCase (e.g. Direction.Long).
- Make outputs deterministic and readable: stable plot order, clear titles, explicit colors, and
na or PlotDisplay.NONE when hiding output.
- When returning code, return complete
.nv source unless the user asked for only a fragment.
Naming Style
Follow these Navi naming conventions consistently:
- Use
snake_case for variables, parameters, functions, methods, and properties: fast_length, long_signal, ema_of.
- Use
PascalCase for structs, enums, newtypes, and enum variants: TradeState, Direction.Long.
- Use
SCREAMING_SNAKE_CASE for compile-time constants: MAX_LOOKBACK.
- Use
snake_case.nv for new filenames when repository conventions allow it.
CLI Validation
Validate every complete .nv file you create or modify with the navi CLI. Read
references/cli.md before the first CLI call in a session — installation,
every flag, and the navi run wire protocol are there.
navi check path/to/script.nv — the completion gate: syntax, types, compilation, imports.
navi fmt path/to/script.nv — canonical formatting. Independent of compilation, so run both.
navi run path/to/script.nv, with market data on stdin, when the task turns on
what the script computes rather than whether it compiles.
- Treat every non-zero exit status as a failed validation. Fix the script and repeat until
every command exits successfully; report the commands run and any validation that could not
be completed.
Pass several paths in one call rather than one call per file — check and fmt both accept
files, directories, and quoted glob patterns.
navi run executes the script against data you provide; the CLI bundles none and downloads
none. Its stdout is pure NDJSON (plot values, alerts, and the script's own log.*()) and its
stderr is human-readable diagnostics — capture them separately, never 2>&1, or the JSON
stream is corrupted.
Do not claim that a code fragment was CLI-validated unless it was placed in a complete .nv
script and the command succeeded.
Playground Preview Links
When a user wants an online preview, encode the complete UTF-8 source as unpadded Base64URL and append it as the code query parameter:
https://navi-lang.org/playground?code=<base64url-source>
Base64URL uses - and _ instead of + and /, with trailing = padding removed. Generate this link only after CLI validation, and keep the full script in the response because very large scripts may exceed browser or chat URL limits.
Navi Essentials
- Every script begins with
indicator(...), strategy(...), or library(...).
- Statements end with
;. Block declarations such as fn, if, for, while, switch, struct, and enum end with } when used standalone.
- Type annotations use
name: type, with qualifiers before the type: let ma: series float = close;.
- Collections are PascalCase:
Array<T>, Map<K, V>, Matrix<T>. Construct with Array.new<T>(), Map.new<K, V>(), and Matrix.new<T>().
- Tuples use parentheses and must be immediately destructured:
let (basis, upper, lower) = ta.bb(close, 20, 2.0);.
- Navi has no
return keyword. A function or expression block yields its last statement.
- Use PascalCase enums:
Shape.TriangleUp, Location.BelowBar, PlotStyle.Histogram, Direction.Long, BarmergeLookahead.Off.
Starter Templates
Minimal indicator:
indicator("My Indicator", overlay: true);
let len = input.int(14, "Length", minval: 1);
let src = input.source(close, "Source");
let ma = ta.sma(src, len);
plot(ma, "SMA", color: Color.ORANGE);
Minimal strategy:
strategy("MA Cross", overlay: true);
let fast_len = input.int(10, "Fast Length", minval: 1);
let slow_len = input.int(20, "Slow Length", minval: 1);
let fast = ta.ema(close, fast_len);
let slow = ta.ema(close, slow_len);
let long_signal = ta.cross_over(fast, slow);
let short_signal = ta.cross_under(fast, slow);
if long_signal {
strategy.entry("Long", Direction.Long);
}
if short_signal {
strategy.entry("Short", Direction.Short);
}
plot(fast, "Fast EMA", color: Color.GREEN);
plot(slow, "Slow EMA", color: Color.RED);
Reusable library:
// @description Shared moving-average helpers.
library("MaLib");
// @function Calculates an exponential moving average.
// @param src Source series.
// @param length EMA length.
// @returns EMA series.
// @see func:ta.sma
// @see func:ta.wma
export fn ema_of(src: series float, length: simple int): series float {
ta.ema(src, length);
}
1---2name: navi-23description: Write, refactor, debug, and review Navi `.nv` indicator, strategy, and library scripts. Use when working with Navi syntax, script declarations (`indicator`, `strategy`, `library`), bar-by-bar series logic, `const`/`input`/`simple`/`series` qualifiers, `var`/`varip`, `na`, history references (`x[1]`), non-repainting behavior, inputs, plots/drawings, `request.security`, collections (`Array`/`Map`/`Matrix`), or standard-library APIs such as `ta`, `math`, `String`, `input`, `strategy`, `Label`, `Line`, `Box`, and `Table`.4---56Write valid Navi code for chart indicators, strategies, and reusable libraries. Keep every answer focused on Navi authoring: syntax, execution semantics, standard-library calls, and practical script patterns.78## Source of Truth910Navi's standard library and, occasionally, its syntax evolve. This skill captures the stable authoring model — it deliberately does **not** reproduce the full API. Treat **navi-lang.org** as authoritative and verify concrete API details there instead of trusting memory or any list embedded in this skill.1112- Full documentation in one file (language guide + complete stdlib API): <https://navi-lang.org/llms-full.txt>13- Documentation index, per topic — fetch a single page on demand: <https://navi-lang.org/llms.txt>14- Any single doc page as raw markdown: use the exact URL listed in `llms.txt`, e.g. <https://navi-lang.org/api/stdlib/ta/index.md>1516Before using any concrete API — a function name, signature, enum variant, or method name — confirm it against the source above. When unsure, fetch `llms-full.txt` (or the specific page) rather than guessing.1718Never construct a documentation URL from a symbol name. Fetch `llms.txt` first and copy an exact link from it. In particular:1920- Guide pages live under `/docs/`, not `/ai/` or `/guide/`.21- Namespace/module pages use `/api/stdlib/<module>/index.md`.22- Prelude types and enums use `/api/stdlib/prelude/<Type>.md`, such as `Table.md` and `PlotDisplay.md`; they do not have nested `index.md` pages.23- Free prelude functions such as `plot`, `bg_color`, `na`, and `nz` are sections of `/api/stdlib/prelude/index.md`; they do not have one page per function.24- If a guessed URL returns 404, stop guessing paths and return to `llms.txt`.2526## Reference Map2728Load only the reference needed for the task:2930| Read this | When you need to... |31| --- | --- |32| [references/syntax.md](references/syntax.md) | Check Navi source syntax: statements, blocks, declarations, types, collections, functions, methods, structs, enums, imports, and exports. |33| [references/execution-model.md](references/execution-model.md) | Reason about bar-by-bar execution, series values, qualifiers, `var`/`varip`, rollback, `na`, history references, and repainting. |34| [references/stdlib.md](references/stdlib.md) | Learn the stdlib naming rules and how to look up exact API names, signatures, and enum variants on navi-lang.org. |35| [references/patterns.md](references/patterns.md) | Start from complete indicator/strategy/library templates or reuse idioms for warmup guards, crosses, state, arrays, MTF data, divergence, debugging, and output polish. |36| [references/cli.md](references/cli.md) | Install the `navi` CLI, or run a script to see what it computes: `navi check`/`fmt`/`run`, the stdin NDJSON protocol, and driver patterns. |3738## Authoring Workflow39401. Identify the script kind: `indicator()` for visual studies, `strategy()` for orders/backtests, or `library()` for exported helpers.412. Put configuration first with `input.*()` calls. Prefer typed inputs (`input.int`, `input.float`, `input.source`, `input.string`, `input.bool`) and use stable titles.423. Model time correctly. Treat `close`, `high`, `ta.*` outputs, conditions, and plots as per-bar `series` values. Use `x[1]` for prior bars.434. Use `let` for per-bar calculations, `var` for state that must persist across bars, and `varip` only for intentional intrabar state.445. Guard warmup and missing values with `na()`, `nz()`, or `fixnan()`; never assume `na` is zero.456. Confirm standard-library API names and signatures against navi-lang.org (`llms.txt`, then its exact page link) before using them; do not rely on remembered lists or synthesize URLs. As a rule, Navi built-in functions are snake_case (e.g. `ta.cross_over`, `bg_color`) and types/enums are PascalCase (e.g. `Direction.Long`).467. Make outputs deterministic and readable: stable plot order, clear titles, explicit colors, and `na` or `PlotDisplay.NONE` when hiding output.478. When returning code, return complete `.nv` source unless the user asked for only a fragment.4849## Naming Style5051Follow these Navi naming conventions consistently:5253- Use `snake_case` for variables, parameters, functions, methods, and properties: `fast_length`, `long_signal`, `ema_of`.54- Use `PascalCase` for structs, enums, newtypes, and enum variants: `TradeState`, `Direction.Long`.55- Use `SCREAMING_SNAKE_CASE` for compile-time constants: `MAX_LOOKBACK`.56- Use `snake_case.nv` for new filenames when repository conventions allow it.5758## CLI Validation5960Validate every complete `.nv` file you create or modify with the `navi` CLI. Read61[references/cli.md](references/cli.md) before the first CLI call in a session — installation,62every flag, and the `navi run` wire protocol are there.63641. `navi check path/to/script.nv` — the completion gate: syntax, types, compilation, imports.652. `navi fmt path/to/script.nv` — canonical formatting. Independent of compilation, so run both.663. `navi run path/to/script.nv`, with market data on stdin, when the task turns on67 what the script computes rather than whether it compiles.684. Treat every non-zero exit status as a failed validation. Fix the script and repeat until69 every command exits successfully; report the commands run and any validation that could not70 be completed.7172Pass several paths in one call rather than one call per file — `check` and `fmt` both accept73files, directories, and quoted glob patterns.7475`navi run` executes the script against data you provide; the CLI bundles none and downloads76none. Its stdout is pure NDJSON (plot values, alerts, and the script's own `log.*()`) and its77stderr is human-readable diagnostics — capture them separately, **never `2>&1`**, or the JSON78stream is corrupted.7980Do not claim that a code fragment was CLI-validated unless it was placed in a complete `.nv`81script and the command succeeded.8283## Playground Preview Links8485When a user wants an online preview, encode the complete UTF-8 source as unpadded Base64URL and append it as the `code` query parameter:8687```text88https://navi-lang.org/playground?code=<base64url-source>89```9091Base64URL uses `-` and `_` instead of `+` and `/`, with trailing `=` padding removed. Generate this link only after CLI validation, and keep the full script in the response because very large scripts may exceed browser or chat URL limits.9293## Navi Essentials9495- Every script begins with `indicator(...)`, `strategy(...)`, or `library(...)`.96- Statements end with `;`. Block declarations such as `fn`, `if`, `for`, `while`, `switch`, `struct`, and `enum` end with `}` when used standalone.97- Type annotations use `name: type`, with qualifiers before the type: `let ma: series float = close;`.98- Collections are PascalCase: `Array<T>`, `Map<K, V>`, `Matrix<T>`. Construct with `Array.new<T>()`, `Map.new<K, V>()`, and `Matrix.new<T>()`.99- Tuples use parentheses and must be immediately destructured: `let (basis, upper, lower) = ta.bb(close, 20, 2.0);`.100- Navi has no `return` keyword. A function or expression block yields its last statement.101- Use PascalCase enums: `Shape.TriangleUp`, `Location.BelowBar`, `PlotStyle.Histogram`, `Direction.Long`, `BarmergeLookahead.Off`.102103## Starter Templates104105Minimal indicator:106107```navi108indicator("My Indicator", overlay: true);109110let len = input.int(14, "Length", minval: 1);111let src = input.source(close, "Source");112113let ma = ta.sma(src, len);114plot(ma, "SMA", color: Color.ORANGE);115```116117Minimal strategy:118119```navi120strategy("MA Cross", overlay: true);121122let fast_len = input.int(10, "Fast Length", minval: 1);123let slow_len = input.int(20, "Slow Length", minval: 1);124125let fast = ta.ema(close, fast_len);126let slow = ta.ema(close, slow_len);127128let long_signal = ta.cross_over(fast, slow);129let short_signal = ta.cross_under(fast, slow);130131if long_signal {132 strategy.entry("Long", Direction.Long);133}134if short_signal {135 strategy.entry("Short", Direction.Short);136}137138plot(fast, "Fast EMA", color: Color.GREEN);139plot(slow, "Slow EMA", color: Color.RED);140```141142Reusable library:143144```navi145// @description Shared moving-average helpers.146library("MaLib");147148// @function Calculates an exponential moving average.149// @param src Source series.150// @param length EMA length.151// @returns EMA series.152// @see func:ta.sma153// @see func:ta.wma154export fn ema_of(src: series float, length: simple int): series float {155 ta.ema(src, length);156}157```