Skip to main content
Guidelines8 min read
Guidelines and recommendations for writing efficient, maintainable, and error-free kScript code.

Code Structure

Variable Declarations

Use the appropriate variable type for your data: Static variables for constants: Use for constants and values that never change across bars (e.g., periods, thresholds, multipliers).
var period = 14;
var threshold = 70;
var multiplier = 2.0;
Regular variables for dynamic values: Use for dynamic values that change per bar but don’t need historical access.
var signal = close > open;
var colorIndex = rsiValue > 70 ? 0 : 1;
Timeseries for historical data: Use only when absolutely necessary as they consume more memory. Declare as timeseries when you need to:
  • Store data source outputs: timeseries price_data = ohlcv(...)
  • Access past values at previous candle indices: sma_values[5]
// Only use timeseries when you need historical access
timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Indicator results should be var unless you need history
var currentRSI = rsi(source=ohlcvData.close, period=14);

Technical Indicators

Explicit Parameters

Always specify parameters explicitly for clarity. This makes your code more readable and maintainable.
// Good - explicit parameters
var rsiValue = rsi(source=ohlcvData.close, period=14);

// Avoid - positional only (harder to read)
var rsiValue = rsi(ohlcvData.close, 14);

Historical Data Access

Use bracket notation to access historical values safely:
var currentClose = ohlcvData.close[0];   // Current bar
var previousClose = ohlcvData.close[1];  // Previous bar
var change = currentClose - previousClose;

Plotting & Visualization

Descriptive Plots

Use meaningful colors and widths to make your plots easy to distinguish:
// Good - clear visual hierarchy
plotLine(value=fastMA, width=2, colors=["green"], label=["Fast MA"], desc=["10-period EMA"]);
plotLine(value=slowMA, width=3, colors=["red"], label=["Slow MA"], desc=["50-period EMA"]);

Choose Appropriate Plot Types

Select the right plot function for your data type:
FunctionUse Case
plotLine()Continuous lines (MAs, RSI)
plotBar()Histogram data (volume, MACD)
plotCandle()OHLC data
plotShape()Discrete signals

Debugging

Use printTimeSeries for Timeseries Objects

Always use printTimeSeries() for timeseries objects instead of print(). The print() function only outputs the first value, while printTimeSeries() displays the complete structure.
timeseries ohlcvData = ohlcv(symbol=currentSymbol, exchange=currentExchange);

// Good - shows full structure
printTimeSeries(ohlcvData);

// Limited - only shows first value
print(ohlcvData);

Error Prevention

Null Checking

Always check for invalid data before performing calculations:
var safeValue = isNaN(calculation) ? 0 : calculation;

Division by Zero

Protect against division by zero errors:
var result = denominator != 0 ? numerator / denominator : 0;

Array Bounds

Be careful when accessing historical data to avoid index errors:
// Check if enough history exists
if (barIndex >= lookbackPeriod) {
  var historicalValue = data[lookbackPeriod];
}

Performance Optimization

Avoid Redundant Calculations

Store frequently used calculations in variables instead of recalculating:
// Good - calculate once
var closePrice = ohlcvData.close[0];
var signal1 = closePrice > threshold1;
var signal2 = closePrice > threshold2;

// Avoid - redundant access
var signal1 = ohlcvData.close[0] > threshold1;
var signal2 = ohlcvData.close[0] > threshold2;

Use Static Variables

For values that don’t change between bars, declare them once at the start:
// Constants declared at start
var period = 14;
var overbought = 70;
var oversold = 30;

// Used throughout script
var rsiValue = rsi(source=ohlcvData.close, period=period);

Limit Timeseries Creation

Only create timeseries when you actually need historical access. Regular variables are more memory-efficient:
// Good - use var for current bar values
var currentRSI = rsi(source=ohlcvData.close, period=14);

// Only use timeseries if you need history
timeseries rsiHistory = rsi(source=ohlcvData.close, period=14);
var previousRSI = rsiHistory[1];  // Now you can access history