← Դեպի փաստաթղթեր
LootX

Սինտաքսիս և տիպերը

Կազմվել է: 2026-10-01 docs.lootx.trade
Основы

1Սինտաքսիս և տիպերը

Ինչպես կառուցված է LootScript-ը՝ հաշվարկը ըստ բարերի, script-ի հայտարարում, հնգակողմ ձևեր վերագրելու, տիպեր և որակագրիչներ, na, x[n]‑ի պատմությունը, օպերատորներ, պայմաններ, switch, ցիկլեր, ֆունկցիաներ և սեփական տիպեր։

Այս էջը — լեզվի կարճ նկարագիրը. ինչպես կամ չափով հաշվարկվում է script‑ը բարերով, ինչպես հայտարարել փոփոխականներ, ինչպիսի տիպեր կան, ինչ է na, ինչպես կարդալ անցյալ բարերը, ինչպես գրել պայմաններ, ցիկլեր և ֆունկցիաներ։ Բոլոր օրինակները ամբողջական աշխատանքային script‑ներ են․ դրանք կարելի է քպել խմբագրում և ավելացնել գրաֆիկին.

Как выполняется скрипт

Բ ملف‑ի վերին մակարդակում գտնվող ամեն ինչ կատարվում է մի անգամ յուրաքանչյուր բարի համար — ամենադրանից հնագույնից մինչեւ ներկա, տող առ տող։ Ուստի LootScript‑ում փոփոխականը չպահպանում է մեկ թիվ, այլ ունի արժեք յուրաքանչյուր բարի համար, և կարելի է փորձել անցյալ արժեքներին։

Loot
indicator("Тело свечи")

body = close - open          // считается заново на каждом баре
plot(body, "Тело", style = plot.style_columns)

Ներկա, դեռ չփակված բարի վրա script‑ը վերագնահատվում է յուրաքանչյուր նոր tick‑ի հետ, սկսելով նույն состояния‑ից, որը գոյություն ուներ նախորդ բարի փակման պահին։ Փակված բարերը այդ դեպքում չեն վերագնահատվում։

Объявление

Script‑ի առաջին հրամանը — ճիշտ մեկ հայտարարություն՝ indicator(...), strategy(...) կամ library(...)։ Նրա վերևում կարող են լինել միայն մեկնաբանություններ և միայնակ #version 1 տողի ընտրովի գրությունը։ Եթե հայտարարություն չկա, script‑ը չի կոմպիլացվի և կտպի սխալ՝ «Нет объявления скрипта — начните с indicator(“Название”)»։

Loot
#version 1
// Комментарии и строка версии могут стоять выше объявления.
indicator("Размах бара", shortTitle = "Размах", overlay = false)

plot(high - low, "Размах", style = plot.style_histogram)

Ինդիկատորի գլխավոր պարամետրերը՝ title — անունը script‑ների ցանկում, shortTitle — կարճ անունը լեգենդայի համար, overlay — նկարել գնի վրայի՞ (true) թե առանձին վահանակում (false, ըստ էության)։ Ստրատեգիայի պարամետրերը նկարագրված են Стратегии и тестер էջում։

Переменные и присваивание

Форма Что делает
x = выражение Հայտարարում է փոփոխական։ Յուրաքանչյուր բարում այն հաշվվում է նորից։
x := выражение Վերագրում է արդեն հայտարարված փոփոխականի նոր արժեքը։ Տիպը պետք է հապատառվի։
var x = выражение Հայտարարում է փոփոխականը մեկ անգամ՝ առաջին բարում։ Արժեքը փոխանցվում է հաջորդ բարերին։
varip x = выражение Ինչպես var, բայց արժեքը պահպանվում է նաև ներկա բարի ներսում tick‑երի միջով։
[a, b, c] = функция(...) Բազմաթիվ վերադարձների դեպքում տեղավորում է արդյունքները փոփոխականների մեջ։

Կարճ ձևեր արդեն հայտարարված փոփոխականի փոփոխման համար՝ +=, -=, *=, /=, %=. Տիպը կարելի է նշեl բացահայտ՝ float level = 0։ Վстроенные շարքերի և տարածությունների անունները (close, volume, ta և այլն) զբաղված են — տո Ձեր փոփոխականը այդ անունով կոչել нельзя։

Գլխավոր տարբերությունը սովորական լեզուներից՝ սովորական փոփոխականը չի կուտակում արժեքը բարերի միջև։ Ընդհանրական հաշիչների և գումարների համար պահանջվում է var:

Loot
indicator("Счётчик зелёных свечей")

var greens = 0          // объявляется один раз и переживает переход к следующему бару
if close > open {
    greens += 1
}

today = 0               // а эта переменная равна 0 на каждом новом баре
today := today + 1      // поэтому здесь всегда 1

plot(greens, "Зелёных с начала истории")

varip‑ը հազվադեպ է պետք — օրինակ՝ բարում tick‑երը հաշելու համար։ Tick‑երի պատմություն չկա, այնպես որ նման արժեքը անցյալ բարերում կարող է տարբեր լինել այն արժեքից, որը եղել է կենդան ժամանակında։ Եթե varip արժեքը գծապատկերին արտասերվի, խմբագիրը կհուշի հնարավոր վերագր绘։

Типы

Тип Что хранит Пример
int ամբողջ թիվ 14, 1_000_000, 0xFF
float հորիզոնական թիվ 2.5, .5, 1e-9
bool ճշմարիտ կամ կեղծ true, false
string տեքստ "BTC", 'BTC'
color գույն թափանցիկությամբ #FF9800, #FF980080, color.teal

Կան նաև բաղադրյալ տիպեր՝ զանգվածներ array<float>, բառարաններ map<string, float>, մատրիցներ matrix<float>, ինչպես նաև ձեր սեփական տիպերը և enum‑ները (տես հետին՝), և գրաֆիկական օբյեկտներ line, box, label, table։

Հաճախ հայտնվող կանոնները՝

  • Տիպը ֆիքսվում է հայտարարման պահին. Եթե x = 1 եք գրել, ապա x := 2.5 գրել չեք կարող — x ամբողջ է։ Գրեք x = 1.0 կամ float x = 1։
  • Ամբողջը ինքնից չի դառնում բուծային, իսկ դառնալը՝ միայն ուղղակիորեն. Օգտագործեք math.round, math.floor, math.ceil, math.trunc։
  • Ամբողջների բաժանումը՝ ամբողջ է. 7 / 2 = 3. Սպասարկման համար մեկ թիվը դարձրեք բութ՝ 7.0 / 2։
  • Թեքում ^ միշտ տալիս է բութ թիվ. 2 ^ 3 = 8.0։
  • Տողը нельзя գումարել թվի հետ. "Цена: " + close չի կոմպիլացվի — օգտագործեք "Цена: " + str.tostring(close)։
  • Պայմանը միայն bool կարող է լինել. if volume { … } — սխալ, վերջացրեք if volume > 0 { … }։

Կвалификատորներ՝ որքան հաստատուն է արժեքը

Տիպից բացի յուրաքանչյուր արժեք ունի որակագրիչ՝ որքանով է այն փոփոխական թեր ժամանակի ընթացքում։ Սխալից դեպի ուժեղը՝

Квалификатор Когда известно значение Пример
const արդեն կոմպիլացիայի ընթացքում 14, "EMA"
input կարգավորումների ընթերցումից հետո, ավելի չի փոխվում input.int(14, "Период")
simple պրոցեսի մեկնարկի պահին, հետո չի փոխվում գործիքի արժեքի քայլը
series կարող է փոխվել յուրաքանչյուր բարի վրա close, bar_index

Նախնական կիրառման մեջ կարևոր է մեկ տեղ՝ ta.* ֆունկցիաների հաշվարկային տևողությունները պետք է լինեն հաստատուն — լիտերալ կամ input։ Ոչ այդպիսկ՝ ֆունկցիաները ստիպված կլինեին վերակառուցել իրենց վիճակը յուրաքանչյուր բարի վրա։

Loot
indicator("Период из настроек")

len = input.int(14, "Период", minval = 2)
plot(ta.rsi(close, len), "RSI")

// ta.rsi(close, bar_index) не скомпилируется:
// «length» в «ta.rsi» требует значение не слабее input, а передано series

na — չկա արժեք

na նշանակում է «արժեք չկա»՝ ոչ բավական հին պատմություն հաշվարկի համար, բորսան չի վերադարձնում ցուցանիշը, տվյալներում բաց է։ na կարող է լինել ցանկացած տիպում։

  • Арифметика с na дает na: na + 1 → na.
  • Любое сравнение с na ложно, այնպես որ if x > 0 при x = na չի կատարվի։
  • Միակապես բացակայությունը ստուգեք na(x)-ով. Գրությունը x == na կոմպիլյատորը մերժում է սխալով՝ «Сравнение с na всегда ложно — используйте na(x)»։
  • nz(x) վերադարձնում է 0‑ը na‑ի փոխարեն, nz(x, v) վերաճում է v։ Հարմար կարճ ձևը՝ x ?? v.
  • Ցանկացած na գծապատկերին կդիմացնի գծի կտրուկ դադար, ոչ զրո։
Loot
indicator("Средняя без пустого начала", overlay = true)

avg = ta.sma(close, 50)             // на первых 49 барах — na

line1 = na(avg) ? close : avg       // проверка через na(x)
line2 = avg ?? close                // то же короче

plot(line2, "Средняя или цена", color = color.orange)

История: x[n]

x[n] — արժեքը x‑ի այն բարի վրա, որը եղել է n բարեր առաջ; x[0] — ներկա բարը։ Աշխատում է ցանկացած շարքի հետ, այդ թվում ձեր փոփոխականների։

Loot
indicator("Наклон средней")

ma    = ta.ema(close, 20)
slope = ma - ma[1]                  // изменение за один бар

plot(slope, "Наклон", style = plot.style_histogram,
     color = slope >= 0 ? color.teal : color.red)
  • Եթե n‑ը մեծ է պատմության սկզբից մինչեւ ընթացիկ բարի քանակից, արդյունքը na է, ոչ սխալ։
  • n կարող է փոխվել բարից բար. close[len] при переменном len թույլատված է։
  • Սխալ է օգտագործել բացասական ինդեքս՝ անցնել ապագա բարերը։
  • Պատմության խորությունը կարգավորելու կարիք չկա․ script‑ին հասանելի է ամբողջ պատմությունը, որը լեցված է գրաֆիկում։

Операторы

Տարանջատման կարգը՝ բարձրից դեպի ցածր․

Приоритет Операторы
1 x[n], вызов f(…), доступ через точку a.b
2 ^ — степень, вычисляется справа налево
3 унарные -, +, not
4 *, /, %
5 +, -
6 <, >, <=, >=
7 ==, !=
8 and
9 or
10 ?? — замена na
11 ? : — условное выражение
  • Сравнения не сцепляются: вместо a < b < c գրեք a < b and b < c.
  • and և or אינם հաշվարկում աջ կողմը, եթե լուծումը արդեն հայտնի է ձախից։
  • Դասավորություն՝ степень ավելի բարձր է унарного минуса से։ -2 ^ 2 = -4. Եթե պետք է 4՝ գրեք (-2) ^ 2։
  • Բութ թվեր համեմատեք թույլատրելիությամբ՝ math.approx(a, b), որովհետև 0.1 + 0.2 == 0.3 կարող է կեղծ լինել։

Պայմաններ

Բլոկները միշտ ուղված են ծալքավոր բրակետներով {}։ if կարող է լինել և՛ հրահանգ, և՛ արտահայտություն; երկուսի դեպքում արագ ընտրությունն անում է ? :։

Loot
indicator("Направление бара")

dir = 0
if close > open {
    dir := 1
} else if close < open {
    dir := -1
}

// if как выражение: обе ветки обязательны
bodySize = if close >= open { close - open } else { open - close }

// условный оператор для простых случаев
barColor = dir > 0 ? color.teal : color.red

plot(bodySize, "Тело", style = plot.style_columns, color = barColor)

switch

switch‑ը ընտրում է առաջին համընկնող շերտը։ Օբյեկտով ձևը համեմատում է այն շերտերի արժեքների հետ, առանց օբյեկտի ձևը հերթով ստուգում է պայմանները։ => առանց պայմանի — ստանդարտ (default) ճյուղն է։ Ցածրացման (fallthrough) механիզմ չկա. Եթե switch արժեք է վերադարձնում՝ default ճյուղը պարտադիր է։

Loot
indicator("Средняя на выбор", overlay = true)

kind = input.string("EMA", "Тип средней", options = ["EMA", "SMA", "WMA"])

ma = switch kind {
    "EMA" => ta.ema(close, 20)
    "SMA" => ta.sma(close, 20)
    =>       ta.wma(close, 20)
}

zone = switch {
    close > ma * 1.02 => 1
    close < ma * 0.98 => -1
    =>                   0
}

plot(ma, "Средняя", color = zone == 1 ? color.teal : zone == -1 ? color.red : color.gray)

Циклы

for i in a .. b անցնում է թվերի միջոցով՝ սկսելով {a}‑ից ներառյալ մինչև {b} անընդմեջ չմասնակցելով։ Քայլը задаётся словом by, կարող է լինել բացասական։ Ցիկլի փոփոխականը գոյություն ունի միայն ցիկլի ներսում և չի փոփոխվում մարմնում։

Loot
indicator("Зелёные свечи за N баров")

n = input.int(10, "Сколько баров", minval = 1, maxval = 200)

greens = 0
for i in 0 .. n {               // i = 0, 1, …, n − 1
    if close[i] > open[i] {
        greens += 1
    }
}

plot(greens, "Зелёных", style = plot.style_columns)
Loot
indicator("Виды циклов")

total = 0
for i in 0 .. 10 by 2 {         // 0, 2, 4, 6, 8
    total += i
}
for i in 10 .. 0 by -1 {        // 10, 9, …, 1
    if i % 3 == 0 {
        continue                // сразу к следующему шагу
    }
    total += i
}

var closes = array.new<float>(0)
closes.push(close)
if closes.size() > 20 {
    closes.shift()
}
sum = 0.0
for v in closes {               // по элементам массива; for [i, v] in … — с индексом
    sum += v
}

k = 0
while k < 100 {
    k += 7
    if k > 50 {
        break                   // выход из цикла
    }
}

plot(sum / closes.size(), "Средняя из массива")

Անվերջ ցիկլը սրա համար հանգեցուցիչ չի լինի, տերմինալը չի կախվի՝ script‑ին հատկացված է օպերացիաների բյուջե յուրաքանչյուր բարի համար և ժամանակի սահմանակ։ Դրանք հն تجاوزելու դեպքում script‑ը կանգ կտա և ցույց կտա հաղորդագրություն՝ «Скрипт исчерпал бюджет операций на бар — упростите цикл» կամ «Скрипт превысил лимит времени на проход»։

Функции

Ֆունկցիան հայտարարում են func‑ով։ Կարճ ձեւը՝ արտահայտություն =>‑ից հետո, երկար ձեւը՝ մարմինով {} և return‑ով։ Փարամետրերի տիպերը կարելի է չնշել — դրանք ինքնաբերաբար ենթադրվում են կանչերից; պարամետրերը կարող են ունենալ նախնական արժեքներ։ Պարգևները փոխանցվում են ըստ կարգի կամ ըստ անունի։

Loot
indicator("Z-оценка объёма")

func barRange(h, l) => h - l

func zscore(series float src, input int len) => float {
    m = ta.sma(src, len)
    s = ta.stdev(src, len)
    return s == 0 ? na : (src - m) / s
}

func scaled(x, k = 2.0) => x * k

z = zscore(volume, 50)
plot(z, "Z объёма", style = plot.style_columns, color = z > 2 ? color.orange : color.gray)
plot(scaled(barRange(high, low), k = 0.5), "Полразмаха")
  • Ռեկուրսիա չկա. Ֆունկցիան չի կարող կանչել ինքն իրեն, ուղղակի կամ միջանկյալ միջոցով։ Վերադարձից կրկնությունը սրվում է ցիկլով։
  • Վիճակը յուրաքանչյուր կանչի համար առանձին է. Եթե ֆունկցիայի մեջ կան ta.* կամ var, երկու կանչերը նույն ֆունկցիայի տարբեր անկախ հաշվարկներ կիրականացնեն։
Loot
indicator("Два вызова одной функции", overlay = true)

func smooth(src, len) => ta.ema(src, len)

fast = smooth(close, 10)        // своя средняя
slow = smooth(close, 30)        // другая, независимая средняя

plot(fast, "Быстрая", color = color.teal)
plot(slow, "Медленная", color = color.orange)

Նույն ֆունկցիաները, որոնց պետք է մի քանի script‑երում, կարելի է տեղափոխել գրադարան՝ հայտարարությամբ library("Имя", 1), ֆունկցիաների առաջ տեղադրել export, այլ script‑ում օգտագործել import Имя/1 as имя։ Գրադարանն առնվում է ձեր script‑ների فولդերից։

Несколько результатов

Որոշ ֆունկցիաներ վերադարձնում են միանգամից մի քանի շարքեր՝ ta.bb, ta.macd, ta.kc, ta.dmi, ta.supertrend և այլն։ Արդյունքը բաշխվում է փակագծերով ցուցադրված փոփոխականների մեջ; անունների թիվը պետք է համընկնի վերադարձվող արդյունքների թվի հետ։

Loot
indicator("Полосы Боллинджера", overlay = true)

[basis, upper, lower] = ta.bb(close, 20, 2.0)

plot(basis, "Середина", color = color.gray)
plot(upper, "Верх", color = color.teal)
plot(lower, "Низ", color = color.teal)

Свои типы и перечисления

type‑ը հավաքում է մի քանի դաշտ մեկ կառուցվածքի մեջ։ Օբյեկտը ստեղծվում է Имя.new(...) միջոցով, դաշտերը ընթերցվում և վերագրվում են կետով։

Loot
indicator("Последний локальный максимум", overlay = true)

type Swing {
    int   barIndex
    float price
}

var Swing last = Swing.new(barIndex = 0, price = high)

ph = ta.pivothigh(high, 5, 5)
if not na(ph) {
    last.barIndex := bar_index - 5
    last.price := ph
}

plot(last.price, "Максимум", style = plot.style_stepline, color = color.orange)

enum — փակ տարբերակների ցուցակլեյբլներով։ Սխալներ տարբերակների անուններում ավելի լավ է դարձնել կոմպիլյացիոն սխալ, քան լռելյայն սխալով անցնել։ Միասինinput.enum`‑ի հետ enum‑ը կդառնա dropdown կարգավորումներում — տես Настройки и отрисовка։

Loot
indicator("Режим рынка")

enum Regime {
    trend = "Тренд"
    flat  = "Флэт"
}

regime = math.abs(close - close[20]) > ta.atr(14) * 3 ? Regime.trend : Regime.flat

plot(regime == Regime.trend ? 1 : 0, "Тренд", style = plot.style_stepline)

Функции ta.* внутри условий

Ֆունկցիաներ՝ ինչպիսիք են ta.ema, ta.rsi կամ ta.atr, հիշում են իրենց վիճակը նախորդ բարի մակարդակից։ Եթե այդպիսի կանչ կատարեր միայն որոշ բարերի վրա՝ օրինակ if‑ի ներսում կամ ? :-ի մի ճյուղում, հաշվարկը կսակավեցնի բարերը և կտա թերարժեքներ։

LootScript‑ը դա չէր թույլատրում՝ կոմպիլյատորը ինքն է դուրս բերում յուրաքանչյուր ta.* կանչը պայմաններից և կատարում այն յուրաքանչյուր բարի վրա, իսկ պայմանը միայն ընտրում է՝ օգտագործել արդյո՞ք արդյունքը։ Ուստի նման օրինակը ճիշտ կպատգամի RSI‑ը։

Loot
indicator("RSI только на зелёных барах")

r = close > open ? ta.rsi(close, 14) : na

plot(r, "RSI", style = plot.style_circles)

Կհեռացվի միայն այն դեպքում, եթե նրա սննխահարկի (argument) ինքնը ծնվում է ճյուղի ներսում։ Այդ դեպքում կոմպիլյատորը չի կարող կանխատեսել և կտա սխալ՝ «Аргумент «len» нельзя вычислить вне ветки — вынесите вызов ta.* на верхний уровень». Իրականացումը՝ հաշվարկել արգումենտը նախ պայմանից դուրս։

Loot
indicator("Аргумент до условия")

// Так нельзя — len объявлена внутри ветки:
// if close > open {
//     len = 10
//     e = ta.ema(close, len)
// }

len = 10
e = ta.ema(close, len)

plot(close > open ? e : na, "EMA на зелёных барах", style = plot.style_circles)

Комментарии и перенос строк

  • // — մեկնաբանություն մինչև տողի վերջը, /* … */ — բլոկային մեկնաբանություն, բլոկները կարելի է ներարկել։
  • Հրամանն ավարտվում է տողի վերջում, կետակի պարզապես չի պահանջվում։
  • Երկար արտահայտությունը շարունակվում է հաջորդ տողում, եթե տողը կտրվել է փակագծում, ավարտվում է օպերատորով կամ հաջորդ տողը սկսվում է օպերատորով, ? կամ :։
Loot
indicator("Перенос строк")

typical = high
        + low
        + close

signal = close > open
    ? typical / 3
    : na

plot(signal, "Типичная цена на зелёных барах", style = plot.style_circles)

Дальше

https://docs.lootx.trade/hy/loot/syntax