语法指南
在 TradingGoose 中编写指标的 PineTS 语法规则
PineTS 使用 JavaScript/TypeScript 语法,与 Pine Script 的运行时行为保持一致。如果你用过 TradingView 的 Pine Script,迁移会很顺畅——主要区别在于变量声明和标准 JS 语法约定。
变量声明
PineTS 区分 let 和 var,以匹配 Pine Script 的执行模型。这是最需要理解的核心概念。
let — 每根 K 线重新计算
使用 let 声明的变量(以及使用 const 声明的不可变值)会在每根 K 线上重新求值,与标准 Pine Script 变量完全一致:
// Recalculated on every bar
const sma20 = ta.sma(close, 20);
let direction = close > open ? 1 : -1;var — 跨 K 线持久状态
使用 var 声明的变量仅在第一次(第一根 K 线)初始化,并在后续 K 线中保留其值——与 Pine Script 的 var 关键字一致:
// Initialized once, persists across bars
var cumulativeVolume = 0;
cumulativeVolume = cumulativeVolume + volume;在 PineTS 中,var 不等同于标准 JavaScript 的 var。它采用 Pine Script 的语义:变量只设置一次并持续保留。如果你需要一个每根 K 线都重置的值,请使用 let。
并排对比
| 行为 | Pine Script | PineTS |
|---|---|---|
| 每根 K 线重新计算 | float x = close | let x = close 或 const x = close |
| 跨 K 线持久保留 | var float x = 0.0 | var x = 0.0 |
| 重新赋值 | x := x + 1 | x = x + 1 |
历史数据访问
使用中括号表示法访问前一根 K 线的值,与 Pine Script 完全一致:
const prevClose = close[1]; // 1 bar ago
const tenBarsAgo = close[10]; // 10 bars ago
const momentum = close - close[10];循环
标准 JavaScript 循环语法:
// Pine Script: for i = 0 to 9
let sum = 0;
for (let i = 0; i < 10; i++) {
sum += close[i];
}let i = 0;
let sum = 0;
while (i < 10) {
sum += close[i];
i++;
}控制流
// If/else
if (close > open) {
direction = 1;
} else {
direction = -1;
}
// Ternary
const color = close > open ? '#00FF00' : '#FF0000';
// Switch
switch (maType) {
case 'ema': return ta.ema(close, length);
case 'sma': return ta.sma(close, length);
default: return ta.rma(close, length);
}函数
使用标准 JavaScript 语法定义可复用函数:
// Pine Script: f_ma(source, length) => ta.sma(source, length)
function f_ma(source, length) {
return ta.sma(source, length);
}
const ma = f_ma(close, 20);
plot(ma, 'Custom MA');元组(多个返回值)
有些函数(如 ta.macd() 和 ta.bb())会返回多个值。使用数组解构:
// Pine Script: [macdLine, signalLine, hist] = ta.macd(close, 12, 26, 9)
const [macdLine, signalLine, hist] = ta.macd(close, 12, 26, 9);
// Pine Script: [middle, upper, lower] = ta.bb(close, 20, 2)
const [middle, upper, lower] = ta.bb(close, 20, 2);特殊值
| 值 | 描述 |
|---|---|
na | 不可用 —— 等同于 Pine Script 中的 null/undefined |
nz(value) | 将 na 替换为零(或指定的默认值) |
color | 图表颜色命名空间 |
const prev = close[1];
const change = na(prev) ? 0 : close - prev; // Handle na values
const safeValue = nz(someCalculation, 0); // Default to 0 if na完整示例:抛物线 SAR
此示例演示了 var 用于持久状态、if/else 逻辑、历史数据访问以及自定义函数:
indicator('Custom SAR', { overlay: true });
const start = input.float(0.02, 'Start');
const increment = input.float(0.02, 'Increment');
const maximum = input.float(0.2, 'Maximum');
function pine_sar(start, inc, max) {
var result = na;
var maxMin = na;
var acceleration = na;
var isBelow = false;
let isFirstTrendBar = false;
if (bar_index == 1) {
if (close > close[1]) {
isBelow = true;
maxMin = high;
result = low[1];
} else {
isBelow = false;
maxMin = low;
result = high[1];
}
isFirstTrendBar = true;
acceleration = start;
}
// ... calculation logic ...
return result;
}
const sar = pine_sar(start, increment, maximum);
plot(sar, 'SAR', { style: plot.style_cross });