Skip to content

變量與限定符

變數聲明

變數可以使用顯式或推斷類型聲明:

navi
// 類型推斷
let a = 10;                // 推斷為 int
let name = "AAPL";         // 推斷為 string

// 顯式類型
let b: float = 3.14;
let label: string = "Buy";
let flag: bool = true;

如果無法推斷類型,則需要顯式註解:

navi
let a = na;                // 錯誤:無法推斷變數類型
let a: float = na;         // OK

重新賦值

使用 = 重新賦值變數。也支援複合賦值運算子:

navi
let a = 10;
a = 20;    // 重新賦值
a += 5;    // a = a + 5
a -= 1;    // a = a - 1
a *= 2;    // a = a * 2
a /= 3;    // a = a / 3
a %= 4;    // a = a % 4

類型限定符

Navi 有四個類型限定符,描述值何時已知,從最嚴格到最寬鬆:

限定符含義
const編譯時已知,永不改變
input腳本啟動時已知(如用戶輸入)
simple在第 0 根 K 線時已知,每根 K 線相同
series每根 K 線都可能變化
navi
let a: const int = 2;
let b: input int = 10;
let c: simple int = a + b;
let d: series float = close;

限定符層級為:const -> input -> simple -> series。值可以沿此層級自動提升,但不能降級。

var — 初始化一次,跨 K 線保持

沒有聲明模式的變數在每次腳本執行時(每根 K 線、每個 tick)都會重新初始化。var 關鍵字改變了這一點 — 變數僅在第一根 K 線時初始化一次,並在後續所有 K 線上保留其最後賦值:

navi
indicator("Green Bars Count");
var count = 0;
let isGreen = close >= open;
if isGreen {
    count = count + 1;
}
plot(count);

沒有 varcount 會在每根 K 線上重置為 0,所以繪圖只會顯示 01。有了 var,值會在各 K 線之間累積。

varif 塊中

var 可以在 if 塊中使用。變數在首次進入該塊的執行時初始化:

navi
var a = close;
var b = 0.0;
if close > open {
    var x = close; // 當此分支首次執行時初始化一次
    b = x;
}

var 與集合

var 適用於所有類型,包括陣列和物件。var 陣列會在各 K 線之間持續存在並增長:

navi
var a = Array.new<float>(0);
a.push(close);       // 每根 K 線陣列增長 1 個元素

var 的即時行為

在歷史 K 線上,var 和非 var 行為相同,因為腳本每根 K 線只執行一次。差異在即時 K 線上可見:沒有 var,變數在每個 tick 時重置;有 var,變數在 tick 之間保留值,但會受到回滾的影響(當 K 線確認時,值恢復到上一根已確認 K 線的狀態,然後為新的已確認 K 線重新執行一次)。

varip — 無回滾持久化

varip(var intrabar persist)類似於 var — 僅初始化一次。關鍵區別是 varip 變數在即時 K 線上不受回滾影響。它們在所有執行中保留值,包括同一未確認 K 線內的多個 tick:

navi
indicator("varip demo");
varip updateCount: int = na;
if barstate.is_new {
    updateCount = 1;
} else {
    updateCount = updateCount + 1;
}
plot(updateCount, style: PlotStyle.Circles);

這對追蹤 tick 級別的數據很有用。在歷史 K 線上,varip 的行為與 var 相同。

varip 用於類型欄位

varip 可以用於單個類型欄位,使其在 K 線內更新間持久化,而其他欄位仍然會回滾:

navi
struct Counter {
    int bars = 0,
    varip int ticks = 0,
}

var counter: Counter = Counter.new();
counter.bars += 1; // 在未確認 K 線上會回滾
counter.ticks += 1; // 不會回滾

對比表

行為無關鍵字varvarip
初始化每次執行一次(第一根 K 線)一次(第一根 K 線)
歷史 K 線每根 K 線重新初始化持久化持久化
即時 tick每個 tick 重新初始化持久化(有回滾)持久化(無回滾)

元組解構

返回元組的函數可以使用 (...) 語法解構:

navi
let (median, upperBand, lowerBand) = ta.bb(close, 20, 2.0);
plot(median);
plot(upperBand);
plot(lowerBand);

丟棄(_

使用 _ 丟棄不需要的值。它可以多次使用:

navi
let (_, upper, _) = ta.bb(close, 20, 2.0);

let _ = someFunction();      // 丟棄返回值
let _ = anotherFunction();

na — 缺失值

na 表示缺失或未定義的值。當數據不足時,許多函數會返回 na

navi
let sma5 = ta.sma(close, 5); // 前 4 根 K 線為 na

// 使用 na() 檢測 na
if not na(sma5) {
    label.new(bar_index, sma5, str.tostring(sma5));
}

使用 nz()na 替換為預設值:

navi
let value = nz(ta.sma(close, 5), 0.0);  // 將 na 替換為 0

使用 fixnan()na 替換為最後一個非 na 值:

navi
let value = fixnan(ta.sma(close, 5));

下一步

基於 MIT 許可證發佈。