Navi Stream Language Skill
Navi Stream (.nvs) is a domain-specific language (DSL) designed specifically for quantitative trading and technical analysis. It is optimized for real-time streaming data processing and technical indicator calculations.
Core Features
-
Real-time Stream Processing - Designed for processing market data tick by tick
-
Technical Indicator Library - Rich built-in technical analysis functions (ta module)
-
Market Data Access - Direct access to OHLC data (quote module)
-
Visualization Support - Built-in plotting functions for indicator display
-
Parameterized Configuration - Support for dynamic parameters and metadata declarations
-
Internationalization - Native support for multi-language labels
-
Navi Integration - Can be imported and called by Navi programs
Quick Reference
Basic Structure
// 1. Metadata declaration meta { title = "MACD", overlay = false, }
// 2. Module imports use quote, ta;
// 3. Parameter definition param { Length1 = 12, Length2 = 26, Length3 = 9, }
// 4. Indicator calculation let fast_ma = ema(close, Length1); let slow_ma = ema(close, Length2);
// 5. Export variables export let hist = fast_ma - slow_ma; export let signal = ema(hist, Length3); export let macd = (hist - signal) * 2;
Key Syntax Rules
-
File extension: .nvs
-
Use 4 spaces for indentation
-
Single-line comments: //
-
String interpolation:
value: ${x} -
Variable declaration: let (immutable), var (mutable)
Metadata System
Meta Block
meta { title = "Indicator Name", overlay = false, // false: separate window, true: overlay on price chart hideparams = true, // Hide parameter panel }
Parameter Declaration
param { // Simple parameter Period = 14,
// Parameter with metadata
@meta(title = "MA Period", range = 1..250)
MA_Period = 20,
// Multiple parameters
Short = 12,
Long = 26,
Signal = 9,
}
// Use parameters in code let ma = ema(close, Period);
Internationalization Labels
@title_period { "en" = "Period", "zh-CN" = "周期", "zh-HK" = "週期", }
// Use label param { @meta(title = @title_period) period = 14, }
Market Data Access (quote module)
Built-in Data Fields
use quote;
// Access current period data let current_price = close; let high_price = high; let low_price = low; let open_price = open; let vol = volume; let amt = turnover;
// Access historical data (time series) let prev_close = close[1]; // Previous period let prev_high = high[2]; // 2 periods ago
Available data fields:
-
close
-
Close price
-
open
-
Open price
-
high
-
High price
-
low
-
Low price
-
volume
-
Volume
-
turnover
-
Turnover
-
time
-
Timestamp
Time Series Pattern
// Access past data if (close > close[1]) { // Current close is higher than previous period }
// Multi-period comparison if (close > high[5]) { // Current price breaks above high from 5 periods ago }
Technical Indicator Functions (ta module)
Moving Averages
use ta;
// Simple moving average let sma20 = ma(close, 20);
// Exponential moving average let ema12 = ema(close, 12); let ema26 = ema(close, 26);
// Apply to different data sources let high_ma = ema(high, 10); let low_ma = ema(low, 10);
Common Technical Indicators
// MACD let diff = ema(close, 12) - ema(close, 26); let dea = ema(diff, 9); let macd = (diff - dea) * 2;
// Bollinger Bands logic let mid = ma(close, 20); let upper = mid * 1.02; let lower = mid * 0.98;
Helper Functions
// Min and max values let min_val = min(a, b); let max_val = max(a, b);
// Absolute value let abs_val = abs(diff);
// Conditional count let count_up = count(close > open, 10); // Number of up days in last 10 periods
// Bars since condition met let bars = barslast(close > ma);
Plotting System
Plot Function
// Basic plotting plot(value, title: "Title", color: #ff0000);
// Multiple series plot(ma5, title: "MA5", color: #ddff53, key: "ma5"); plot(ma10, title: "MA10", color: #4781ff, key: "ma10"); plot(ma20, title: "MA20", color: #fc6ebc, key: "ma20");
Shape Drawing
// Draw candlestick shapes stick(top, bottom, color, hollow: true);
// Example: Price range if (close > open) { stick(high, low, #red, hollow: false); }
// Fill area fill(upper, lower, #blue);
// Polyline polyline(value, #green);
Text Annotation
// Draw text at specified position if (buy_signal) { drawtext(close * 0.95, "Buy", #red); }
if (sell_signal) { drawtext(close * 1.05, "Sell", #green); }
Variables and Types
Variable Declaration
// Immutable variable let price = close; let ma = ema(close, 20);
// Mutable variable var counter = 0; var sum: number = 0.0;
// Export variable (becomes indicator output) export let signal = cross_signal; export let macd = macd_value;
Basic Types
// Number type (floating point) let price: number = 100.5; let volume: number = 1000000;
// Boolean let is_up = close > open; let crossed = cross_over(fast, slow);
// String
let message = "Hello";
let label = Price: ${close};
// nil (null value) let optional_value: number = nil;
// Color let red = #ff0000; let blue = #0000ff; let green = #00ff00;
Array Operations
// Create array var values = array.new::<number>();
// Array operations if (barstate.is_confirmed) { values.unshift(close); // Insert at beginning }
let first = values.get(0); // Get element let length = values.len(); // Get length
// Iterate array for (let i in 0..values.len()) { let val = values.get(i); }
Control Flow
Conditional Statements
// if-else if (close > open) { stick(high, low, #red); } else if (close < open) { stick(high, low, #green); } else { stick(high, low, #gray); }
// Conditional plotting if (close > ma20) { plot(close, color: #red); }
Loops
// Range loop for (let i in 1..10) { sum += values.get(i); }
// Calculate minimum let min_val: number = values.get(0); for (let i in 1..min(n, values.len())) { min_val = min(min_val, values.get(i)); }
Function Definition
// Custom function fn calc_average(x: number, y: number): number { return (x + y) / 2; }
// Function with state fn dllv(x: number, n: number): number { var values = array.new::<number>(); if (barstate.is_confirmed) { values.unshift(x); }
let result: number = values.get(0);
for (let i in 1..min(n, values.len())) {
result = min(result, values.get(i));
}
return result;
}
// Use function let low_val = dllv(close, 10);
Common Patterns
Trend Detection
// Golden cross and death cross let golden_cross = fast_ma > slow_ma && fast_ma[1] <= slow_ma[1]; let death_cross = fast_ma < slow_ma && fast_ma[1] >= slow_ma[1];
// Breakout let breakout = close > high[20]; // Break above 20-period high let breakdown = close < low[20]; // Break below 20-period low
Divergence Detection
// Bullish divergence: price makes new low but indicator doesn't let price_low = dllv(close, n); let indicator_low = dllv(diff, n);
let bullish_divergence = close < price_low[period] && // Price makes new low diff > indicator_low[period]; // But indicator doesn't
Multi-Period Analysis
// Short, mid, long-term trends let short_trend = ema(close, 5); let mid_trend = ema(close, 20); let long_trend = ema(close, 60);
// Trend alignment let all_up = short_trend > mid_trend && mid_trend > long_trend; let all_down = short_trend < mid_trend && mid_trend < long_trend;
Channel System
// Price channel let mid = ema(close, 20); let upper = mid * 1.02; let lower = mid * 0.98;
// Draw channel plot(upper, color: #red); plot(mid, color: #yellow); plot(lower, color: #green);
// Breakout signal if (close > upper) { drawtext(close, "Breakout", #red); }
Integration with Navi
Calling NVS from Navi
// Navi code (call_macd.nv) use nvs.macd; // Import macd.nvs
struct Candlestick { time: int, open: float, high: float, low: float, close: float, volume: float, turnover: float, }
fn main() throws { let indicator = macd.new(); // Create instance
// Feed data tick by tick
for (let candle in candlesticks) {
indicator.execute(
time: candle.time,
open: candle.open,
high: candle.high,
low: candle.low,
close: candle.close,
volume: candle.volume,
turnover: candle.turnover
);
// Access exported variables
println(`hist=${indicator.hist:?}`);
println(`signal=${indicator.signal:?}`);
println(`macd=${indicator.macd:?}`);
}
}
Best Practices
Naming Conventions
// Parameters: CamelCase or snake_case param { ShortPeriod = 12, long_period = 26, }
// Variables: snake_case let fast_ma = ema(close, ShortPeriod); let slow_ma = ema(close, long_period);
// Export variables: lowercase export let signal = buy_signal;
Parameter Ranges
// Set reasonable ranges for parameters param { @meta(range = 1..100) Period = 14, // Limited to 1-100
@meta(range = 1..250)
MA_Period = 20,
}
Performance Considerations
// Good: Avoid repeated calculations let ma20 = ema(close, 20); let signal1 = close > ma20; let signal2 = ma20 > ma20[1];
// Bad: Repeated calculations let signal1 = close > ema(close, 20); let signal2 = ema(close, 20) > ema(close, 20)[1];
Conditional Optimization
// Good: Combine conditions let uptrend = close > ma20 && ma20 > ma60; if (uptrend) { plot(close, color: #red); }
// Use intermediate variables for readability let price_above_ma = close > ma20; let ma_trending_up = ma20 > ma20[1]; let strong_signal = price_above_ma && ma_trending_up;
CLI Commands
Navi Stream runs through Navi
navi run script.nv # Run Navi script that calls .nvs navi build # Build project (including nvs modules)
When to Load References
Load reference files from references/ directory when you need detailed information:
-
syntax.md - Complete syntax reference
-
indicators.md - Technical indicator functions in detail
-
plotting.md - Plotting system detailed guide
-
patterns.md - Common indicator patterns and strategies
Use Read tool to load these files from ~/.claude/skills/navi-stream/references/ .
Examples Directory
The examples/ directory contains runnable code samples:
-
macd.nvs
-
MACD indicator example
-
ma_cross.nvs
-
Moving average crossover example
-
bollinger.nvs
-
Bollinger Bands example
-
rsi.nvs
-
RSI indicator example
Resources
-
Navi Official Website: https://navi-lang.org
-
Standard Library: https://navi-lang.org/stdlib/
-
File Extension: .nvs
Important Notes
-
Navi Stream focuses on indicator calculation, not general-purpose programming
-
All calculations are streaming - process one data point at a time
-
Exported variables become indicator outputs, displayable on charts
-
When called from Navi programs, each execute() call processes one new data point