Introduction
kScript's type system is specifically designed for financial data analysis, featuring a hybrid approach that combines static analysis at compile time with dynamic execution at runtime. Unlike general-purpose programming languages, kScript optimizes for time-series data processing, which is reflected in its type architecture and constraints.
The compiler performs type checking with limited implicit conversions, helping catch type mismatches early during compilation rather than encountering them at runtime.
At its core, kScript distinguishes between two fundamental categories of values: primitive types (numbers, strings, booleans) and time-series types. The latter category represents kScript's domain-specific strength—the timeseries
type is the central data structure for handling historical market data, indicators, and any values that change across chart bars.
int
or float
as you would in languages like TypeScript or Java. Instead, types are inferred from the values and expressions you write. The distinction you do make is between regular variables (var
) and time-series data (timeseries
). This page covers everything from basic data types to advanced type conversion rules, data access patterns, and the extensive data sources available in kScript v2. By understanding the type system deeply, you'll be able to write more efficient, error-free trading algorithms and leverage kScript's full analytical capabilities.
Variable Declarations and Type Inference
In kScript, variable declarations use two keywords: var
and timeseries
. The choice between them is not merely stylistic—it fundamentally determines how the variable behaves throughout your script's execution.
The var
Keyword
Variables declared with var
hold scalar values: numbers, strings, booleans, or arrays of these types. These values can change from bar to bar as your script executes, but they represent single values at any given point in time. When you access a var
variable, you're getting its current value for the current bar being processed.
The type of a var
variable is inferred from its initialization expression. If you assign 100
, the type is number
. If you assign "BTCUSDT"
, the type is string
. Once inferred, the type remains consistent—you cannot assign a string to a variable that was initialized with a number.
In this example, price
is inferred to be of type number
, symbol
is type string
, and isActive
is type boolean
. The periods
variable has type number[]
(array of numbers), and the array must be homogeneous—all elements must be numbers.
The timeseries
Keyword
The timeseries
keyword declares variables that hold historical data—values that exist across multiple bars with temporal alignment. This is kScript's most distinctive feature and the foundation of all technical analysis. A timeseries variable doesn't just hold the current value; it maintains a complete history that can be indexed to access past values.
Timeseries variables are immutable in the sense that you cannot reassign them once declared. This constraint exists because timeseries data represents a continuous stream of market information, and reassigning it would break the temporal continuity. However, you can create new timeseries through operations on existing ones.
Here, ohlcvData
holds a complete time series of OHLCV (Open, High, Low, Close, Volume) data. When we extract closes
by accessing ohlcvData.close
, we get another timeseries containing only closing prices. The adjusted
variable demonstrates creating a new timeseries through arithmetic—adding 100 to every close price produces a new timeseries, not just a single number.
var
instead of timeseries
for data source functions will cause a compilation error: "cannot assign timeseries into 'var' variable"
. Always use timeseries
for functions like ohlcv()
, source()
, and technical indicators that return historical data. Primitive Data Types
Primitive types are the fundamental building blocks of kScript expressions. They represent single, indivisible values rather than collections or complex structures. kScript supports five primitive types: number
, string
, boolean
, null
, and the special na
value.
number
The number
type represents all numeric values in kScript, including both integers and floating-point numbers. Unlike many languages that distinguish between int
and float
, kScript uses a unified numeric type. You can write integer literals like 42
or 1000
, and floating-point literals like 3.14159
or 0.001
.
Numbers are used extensively throughout trading algorithms: for prices, volumes, periods for technical indicators, thresholds for signals, and mathematical calculations. All standard arithmetic operators (+
, -
, *
, /
, %
) work with numbers and return numeric results.
Many built-in functions expect number parameters. For instance, sma(source, period)
requires period
to be a number indicating how many bars to average. When you use technical indicators, they typically return numeric values representing the indicator's calculation at the current bar.
string
Strings represent textual data and are written using double quotes: "BTCUSDT"
, "binance"
. They're essential for identifying trading pairs, exchanges, and providing labels for plots and indicators. Strings in kScript are immutable—once created, their content cannot be modified.
String literals can contain special characters and must be properly quoted. kScript uses strings primarily for configuration and identification purposes rather than text processing. You'll use strings when calling data source functions like ohlcv(symbol=currentSymbol, exchange="BINANCE")
, where both the symbol and exchange are string values.
boolean
Boolean values are either true
or false
and are fundamental to conditional logic in trading algorithms. Comparison operators (<
, >
, ==
, !=
) return boolean values, as do logical operators (&&
, ||
, !
).
Booleans are crucial for implementing trading signals and conditions. For example, a crossover detection might use: var crossedAbove = (fastMA > slowMA) && (fastMA[1] <= slowMA[1])
. This boolean expression checks if the fast moving average just crossed above the slow one by comparing current and previous values.
na
- Not Available
The na
value is a special constant in kScript representing "not available" or missing data. It's distinct from null
and serves a specific purpose in time-series analysis: when data is unavailable for a particular bar or when a condition isn't met, na
is used instead of a numeric or string value.
One powerful use of na
is in conditional plotting. When you pass na
to a plot function, that data point is skipped, creating gaps in the visualization. This allows you to create indicators that only display under certain conditions without plotting misleading zero values.
In this example, the moving average is only plotted when volume exceeds a threshold. When volume is low, na
is plotted instead, creating gaps in the line. This technique is far superior to plotting zero or leaving the calculation running invisibly—it clearly shows when the condition is active.
TimeSeries: kScript's Core Type
If kScript has a single defining feature, it's the TimeSeries
type. This type represents time-aligned data that evolves as your script processes each bar of market history. Understanding timeseries is essential to writing effective kScript indicators and strategies.
What is a TimeSeries?
A timeseries is not just a single value—it's a complete history of values aligned to chart bars. When your script accesses a timeseries variable, it sees the value for the current bar being processed. But crucially, it can also look backward in time using the history reference operator []
.
Conceptually, you can think of a timeseries as a two-dimensional array where each row represents a bar (timestamped) and each column represents a data field. For OHLCV data, you have six fields: timestamp, open, high, low, close, and volume. Each field is itself a timeseries, which is why ohlcvData.close
returns a timeseries of closing prices.
The key insight is that timeseries variables automatically track history. You don't need to manually store arrays of past values or manage ring buffers. kScript's execution model handles this for you, making historical references both simple and efficient.
Historical Indexing
To access previous values in a timeseries, use square bracket notation with an integer offset. The index [0]
(or no index) refers to the current bar, [1]
refers to the previous bar, [2]
to two bars ago, and so on. This indexing is relative to the current bar being processed.
In this example, we calculate the difference between the current close and the close from 5 bars ago, then detect if the price has risen for three consecutive bars. Note how the comparison close > close[1]
creates a boolean expression that's evaluated at each bar—this is the power of series-aware operations.
Immutability and Global Scope
Timeseries variables have two important constraints. First, they are immutable in the sense that you cannot reassign a timeseries variable once declared. You cannot write ohlcvData = someOtherData
after the initial declaration. This prevents breaking the temporal continuity of the data.
Second, timeseries variables must be declared at the global scope (the top level of your script), not inside functions or conditional blocks. This requirement exists because the execution model needs to initialize and track these variables across all bars from the beginning of the chart data.
timeseries adjusted = original + offset;
OHLCV Data Structure
The most common timeseries you'll work with is OHLCV data, representing Open, High, Low, Close, and Volume for each bar. When you call ohlcv(symbol, exchange)
, you receive a timeseries with multiple fields accessible via dot notation.
Each field of OHLCV data is itself a complete timeseries. When you write ohlcvData.close
, you extract the closing price timeseries. You can then use this in calculations, pass it to indicators, or plot it. The field access is not just getting a single value—it's extracting an entire temporal sequence.
timestamp
open
high
low
close
volume
Understanding this structure is crucial because many technical indicators expect specific fields. For example, sma(source, period)
needs a single-dimensional timeseries, so you pass ohlcvData.close
rather than the entire OHLCV structure.
Arrays and Collections
Arrays in kScript provide a way to store multiple values of the same type in a single variable. While kScript's primary focus is on timeseries data, arrays serve important roles in configuration, storing multiple parameters, and managing sets of related values.
Array Type System
kScript supports typed arrays: number[]
, string[]
, and boolean[]
. Arrays are homogeneous, meaning all elements must be of the same type. You cannot create an array like [1, "hello", true]
that mixes types—this will cause a compilation error.
Array literals are created using square brackets with comma-separated values: [1, 2, 3, 4, 5]
creates a number[]
array. The type is inferred from the elements, so all elements must be compatible with the inferred type.
In this example, maPeriods
is a number[]
array used to configure multiple moving averages with different periods. The colors
array provides color strings for plotting each moving average. Arrays are particularly useful when you need to handle multiple similar configurations or iterate over a set of values.
input()
with type "select"
. Array Constraints
Arrays in kScript have several constraints that differ from general-purpose languages. First, array size is typically fixed at declaration—you cannot dynamically resize arrays or push/pop elements. Second, all elements must be of the same type, enforced at compile time.
Third, arrays are passed by reference, meaning if you pass an array to a function and the function modifies it, those changes affect the original array. This is different from primitive values, which are copied. Understanding this distinction is important to avoid unintended side effects.
Data Sources and Access Methods
kScript v2 provides extensive access to market data through data sources—functions that retrieve time-series information from exchanges and data providers. Understanding the available data sources and how to access them is fundamental to building sophisticated trading indicators.
Two Access Methods
kScript offers two ways to retrieve data from sources: direct functions and the universal source() function. Direct functions provide dedicated names for each data type, making code more readable and self-documenting. The source()
function offers a unified interface using a string identifier to specify which data to fetch.
Method 1: Direct Functions (Recommended)
Direct functions have names matching the data type: ohlcv()
, funding_rate()
, liquidations()
, etc. Each function returns a timeseries of the specified data type. This approach is recommended because it's clearer and provides better compile-time checking.
Method 2: Universal source() Function
The source()
function accepts a string identifier as its first parameter to specify what data to fetch. This method is more dynamic but less type-safe, as the string identifier is not checked until runtime.
Both methods produce identical results. The choice is primarily stylistic, though direct functions are generally preferred for their clarity and compile-time validation. Use source()
when you need dynamic data source selection based on user input or configuration.
symbol
and exchange
specify what asset and where to fetch data from. You can use currentSymbol
and currentExchange
to use whatever symbol the user has loaded on their chart. Available Data Sources
kScript v2 provides access to 18 different data sources spanning multiple categories of market data. These sources go far beyond basic price information, including derivatives metrics, options data, lending rates, and institutional flows. Understanding what's available allows you to build more sophisticated analytical tools.
Data sources are organized into six primary categories: Price & Volume (core OHLCV and orderbook data), Derivatives & Futures (funding rates, liquidations, open interest), Options & Volatility (options volume, implied volatility, skew), Lending & Margin (margin rates, credit sizes), Institutional & ETF (ETF flows, holdings, premiums), and Protocols & DeFi (protocol-specific metrics).
Price & Volume
Core market data including OHLCV, orderbook dynamics, and trading volume analysis
buy_sell_volume
ohlcv
orderbook
Derivatives & Futures
Funding rates, liquidations, open interest, and perpetual futures metrics
cme_oi
funding_rate
liquidations
long_short_ratio
open_interest
options_open_interest
Options & Volatility
Options trading data, implied volatility surfaces, and volatility indices
deribit_implied_volatility
deribit_volatility_index
options_volume
options_open_interest
skew
Lending & Margin
Margin borrowing rates, lending pool sizes, and credit market data
Institutional & ETF
ETF flows and holdings, institutional position data, and treasury balances
binance_treasury_balance
etf_flow
etf_holding
etf_premium_rate
Protocols & DeFi
Protocol-specific metrics, DeFi positions, and smart contract data
ethena_positions
na
values. Multi-Source Analysis Example
One of kScript's strengths is the ability to combine multiple data sources in a single indicator. By analyzing price action alongside derivatives metrics, liquidation data, and funding rates, you can build more comprehensive market views.
This example demonstrates accessing three different data sources and combining them in analysis. The spot price provides the baseline market price, funding rates indicate the perpetual futures premium/discount, and liquidation data shows forced position closures. Together, these create a multi-dimensional view of market conditions.
Type Conversion and Casting
kScript's type system features minimal automatic type conversion. Unlike languages like JavaScript that aggressively coerce types, kScript requires explicit type compatibility. This strictness prevents subtle bugs and makes code behavior more predictable.
Conversion Rules
TimeSeries to Number: When you call a technical indicator function like sma(source, period)
on a timeseries, it returns a number
—the indicator's value at the current bar. The function extracts the current value from the timeseries automatically. This conversion is implicit and happens whenever an indicator processes historical data to produce a current value.
Number to TimeSeries: Arithmetic operations between a timeseries and a number produce a new timeseries. For example, close + 100
creates a timeseries where every value is 100 more than the corresponding close price. The scalar value is broadcast across all bars. Similarly, close * 1.05
produces a timeseries with all values scaled by 5%.
No String Coercion: Strings are never automatically converted to numbers or vice versa. If a function expects a string parameter, you must provide a string. If it expects a number, you must provide a number. This prevents errors like accidentally passing a number where a symbol string was expected.
This example shows several type conversions. The sma()
function returns a number (the indicator value at the current bar), even though it operates on a timeseries. The subtraction close - sma20
produces a new timeseries because one operand is a timeseries. The multiplication volume * 1.5
also produces a timeseries.
rsi(source, period)
instead of a timeseries will fail with: "rsi.source must be a timeseries"
. Best Practices and Patterns
Writing effective kScript code requires understanding not just the type system rules, but also the patterns and practices that lead to clear, maintainable, and efficient indicators. These best practices emerge from the type system's design and kScript's execution model.
Descriptive Variable Names
Choose variable names that indicate both the data type and the purpose. For timeseries variables, names like closes
, volumes
, or prices
(plural) suggest they contain multiple values. For scalar variables, singular names like period
, threshold
, or crossover
indicate single values.
When extracting fields from OHLCV data, use names that reflect the field: var close = ohlcvData.close;
is clearer than var c = ohlcvData.close;
. The slight verbosity pays dividends in code readability, especially when multiple data sources are involved.
Cache Data References
When using data source fields in indicators, pass the field reference directly rather than creating intermediate timeseries variables. This avoids creating unnecessary timeseries objects and keeps your code more efficient. Simply pass trade.close
directly to indicator functions like sma(trade.close, period)
.
Be Explicit with Declarations
While kScript infers types, you still choose the declaration keyword: var
or timeseries
. Always use the correct keyword based on what you're storing. This explicitness serves as documentation—readers immediately know whether a variable holds a scalar or historical data without examining the initialization expression.
Group related declarations together and separate different types of declarations with blank lines. Put all timeseries declarations near the top of your script (as required), followed by configuration variables, then derived calculations. This organization makes the data flow clear.
Complete Example: Multi-Source Momentum Indicator
To demonstrate how the type system, data sources, and best practices come together, here's a complete indicator that analyzes momentum using multiple data sources. This example showcases proper type declarations, data source access, type conversions, and conditional plotting.
This indicator demonstrates several key concepts from the type system documentation:
- Data Sources: Accesses spot price (OHLCV), funding rate, and liquidation data from multiple sources
- Type Declarations: Uses
timeseries
for historical data andvar
for configuration and calculated values - Type Conversion: The
sma()
function converts timeseries to number; the RSI calculation demonstrates working with both - Arrays: Uses a color array for the plot, demonstrating array type
string[]
- Conditional Logic: Uses
na
to conditionally show the signal marker only during extreme conditions - Best Practices: Caches the
close
reference, uses descriptive names, and includes comments explaining the logic
Note how the types flow naturally through the script: timeseries data sources feed into indicators that return numbers, those numbers are used in comparisons that return booleans, and the booleans control conditional plotting with na
. Understanding this type flow is essential to writing effective kScript indicators.