← К документации
LootX

Примеры скриптов

Собрано: 2026-10-01 docs.lootx.trade
Справочник

1Примеры скриптов

Восемь готовых скриптов на LootScript: скользящие, RSI, VWAP с полосами, кумдельта с расхождениями, открытый интерес, фандинг, дисбалансы кластеров и стратегия для тестера.

Восемь готовых скриптов на LootScript: от скользящих и RSI до кумдельты, открытого интереса, фандинга и кластеров. Каждый — рабочий индикатор, который можно сразу положить на график и подстроить под себя. Все примеры собираются компилятором текущей версии без ошибок и предупреждений.

Как запустить пример

  1. Нажмите ƒ на панели графика, в окне Индикаторы — Редактор….
  2. В редакторе нажмите Новый (Ctrl+N), замените шаблон кодом примера и нажмите Сохранить.
  3. Нажмите Добавить на график (Ctrl+Enter). Настройки из input.* появятся в окне настроек индикатора.

1. Три скользящие с выбором типа

Быстрая, средняя и медленная средние одного типа на выбор. Фон подсвечивается, когда все три выстроились по тренду.

Loot
indicator("Три скользящие", shortTitle = "MA×3", overlay = true)
maType = input.string("EMA", "Тип средней", options = ["EMA", "SMA", "WMA", "HMA"])
src    = input.source(close, "Источник")
len1   = input.int(20, "Быстрая", minval = 1)
len2   = input.int(50, "Средняя", minval = 1)
len3   = input.int(200, "Медленная", minval = 1)

func ma(s, len) => switch maType {
    "SMA" => ta.sma(s, len)
    "WMA" => ta.wma(s, len)
    "HMA" => ta.hma(s, len)
    => ta.ema(s, len)
}

m1 = ma(src, len1)
m2 = ma(src, len2)
m3 = ma(src, len3)

plot(m1, "Быстрая", color = m1 >= m1[1] ? color.teal : color.red, linewidth = 2)
plot(m2, "Средняя", color = color.orange)
plot(m3, "Медленная", color = color.gray, linewidth = 2)
bgcolor(m1 > m2 and m2 > m3 ? color.new(color.teal, 20) : m1 < m2 and m2 < m3 ? color.new(color.red, 20) : na)

Как устроено

  • input.string с options превращается в выпадающий список в настройках.
  • Функция ma выбирает среднюю через switch. Состояние ta.* живёт у каждого места вызова, поэтому три вызова ma — три независимые средние.
  • Цвет быстрой линии — выражение: растёт по сравнению с прошлым баром (m1[1]) — бирюзовая, падает — красная.
  • Панель рисует до трёх линий plot на скрипт — поэтому средних три.

2. RSI с зонами и оповещениями

RSI с закрашенной полосой между уровнями. Линия и фон окрашиваются, когда RSI в зоне перекупленности или перепроданности.

Loot
indicator("RSI с зонами", shortTitle = "RSI", overlay = false)
len = input.int(14, "Период", minval = 2)
src = input.source(close, "Источник")
ob  = input.float(70, "Перекупленность", minval = 50, maxval = 100)
os  = input.float(30, "Перепроданность", minval = 0, maxval = 50)

r = ta.rsi(src, len)

hOb = hline(ob, "Перекупленность", color = color.red)
hOs = hline(os, "Перепроданность", color = color.teal)
fill(hOb, hOs, color = color.new(color.purple, 20))
plot(r, "RSI", color = r > ob ? color.red : r < os ? color.teal : color.purple, linewidth = 2)
bgcolor(r > ob ? color.new(color.red, 35) : r < os ? color.new(color.teal, 35) : na)

alertcondition(ta.crossunder(r, ob), "RSI вышел из перекупленности", "RSI опустился ниже верхнего уровня")
alertcondition(ta.crossover(r, os), "RSI вышел из перепроданности", "RSI поднялся выше нижнего уровня")

Как устроено

  • hline возвращает ручку уровня, а fill закрашивает полосу между двумя ручками.
  • Уровни — настройки input.float, поэтому линии и заливка двигаются вместе с ними.
  • alertcondition объявляет два оповещения. Сами по себе они не звенят — как их включить, рассказано на странице Алерты из скриптов.
  • Альфа в color.new — от 0 (прозрачно) до 255 (непрозрачно).

3. VWAP дня с полосами отклонения

Средневзвешенная по объёму цена с начала суток по UTC и полоса ±σ вокруг неё.

Loot
indicator("VWAP дня с полосами", shortTitle = "VWAP", overlay = true)
src  = input.source(hlc3, "Цена")
mult = input.float(1.0, "Ширина полосы, σ", minval = 0.1, step = 0.1)

anchor = session.isfirstbar
vw = ta.vwap(src, anchor)

// Сумма объёма и сумма объёма на квадрат цены с начала дня — для разброса вокруг VWAP.
var float sumV  = 0.0
var float sumV2 = 0.0
if anchor {
    sumV  := 0.0
    sumV2 := 0.0
}
if not na(volume) and not na(src) {
    sumV  := sumV + volume
    sumV2 := sumV2 + volume * src * src
}
sigma = sumV > 0 and not na(vw) ? math.sqrt(math.max(sumV2 / sumV - vw * vw, 0)) : na

pUp = plot(vw + mult * sigma, "Верх", color = color.new(color.blue, 150))
plot(vw, "VWAP", color = color.blue, linewidth = 2)
pDn = plot(vw - mult * sigma, "Низ", color = color.new(color.blue, 150))
fill(pUp, pDn, color = color.new(color.blue, 25))

Как устроено

  • ta.vwap начинает счёт заново на баре, где якорь истинен. У криптовалют session.isfirstbar — первый бар после 00:00 UTC.
  • Переменные var переживают переход между барами. Их обнуляет тот же якорь, поэтому полоса считается за тот же период, что и VWAP.
  • Разброс — корень из средневзвешенного квадрата цены минус квадрат VWAP. math.max(…, 0) страхует от крошечного минуса из-за округления.
  • Смысл есть на внутридневных таймфреймах. Хотите VWAP от последней выплаты фандинга — поставьте anchor = funding.settled.

4. Дневная кумдельта с расхождениями

Кумулятивная дельта, которая обнуляется каждые сутки, и отметки на барах, где цена обновила экстремум, а дельта — нет.

Loot
indicator("Дневная кумдельта с расхождениями", shortTitle = "CVD", overlay = false)
len = input.int(20, "Окно поиска максимумов", minval = 3)

var float cvd = 0.0
if session.isfirstbar {
    cvd := 0.0
}
if delta.available {
    cvd := cvd + delta.value
}
cvdLine = delta.available ? cvd : na

// Цена обновила максимум окна, а кумдельта — нет: покупатели не подтверждают рост.
bearish = high >= ta.highest(high, len) and cvdLine < ta.highest(cvdLine, len)
bullish = low <= ta.lowest(low, len) and cvdLine > ta.lowest(cvdLine, len)

plot(cvdLine, "Кумдельта", color = cvdLine >= 0 ? color.teal : color.red, linewidth = 2)
hline(0, "Ноль", color = color.gray)
plotshape(bearish, "Медвежье расхождение", style = shape.triangledown, location = location.top, color = color.red, size = size.tiny)
plotshape(bullish, "Бычье расхождение", style = shape.triangleup, location = location.bottom, color = color.teal, size = size.tiny)

Как устроено

  • delta.value — агрессивные покупки минус агрессивные продажи за бар. Где покрытия нет, delta.available ложно, и линия прерывается, а не рисует ноль.
  • Накопитель var обнуляется в начале суток. Нужна кумдельта по всей загруженной истории без сброса — возьмите готовый ряд delta.cum.
  • Расхождение: цена на максимуме окна, а кумдельта ниже своего максимума за то же окно. Для минимумов — зеркально.
  • location.top и location.bottom ставят отметки у краёв подокна, а не у цены.

5. Всплески открытого интереса

Изменение открытого интереса от бара к бару в процентах и отметки там, где оно выбивается из обычного разброса.

Loot
indicator("Изменение открытого интереса", shortTitle = "ΔOI %", overlay = false)
len = input.int(50, "Окно для всплесков", minval = 5)
k   = input.float(3.0, "Порог всплеска, σ", minval = 0.5, step = 0.5)

pct = oi.available and oi.close[1] > 0 ? 100 * (oi.close - oi.close[1]) / oi.close[1] : na
sd  = ta.stdev(pct, len)
spike = not na(sd) and math.abs(pct) > k * sd

plot(pct, "ΔOI, %", style = plot.style_columns, color = pct >= 0 ? color.teal : color.red)
hline(0, "Ноль", color = color.gray)
plotshape(spike, "Всплеск", style = shape.circle, location = location.top, color = color.orange, size = size.tiny)

Как устроено

  • oi.close — открытый интерес на закрытии бара, oi.close[1] — на прошлом баре. Проверка oi.available не даёт посчитать изменение из пустоты.
  • Всплеск — бар, где изменение по модулю больше k стандартных отклонений за окно len.
  • Открытый интерес приходит поминутно. На таймфреймах меньше минуты соседние бары повторяют одно значение, и изменение там нулевое — это данные, а не ошибка.

6. Ставка финансирования

Фандинг бессрочного фьючерса в процентах за период или в пересчёте на год, с отметками выплат и подсветкой высокой ставки.

Loot
indicator("Ставка финансирования", shortTitle = "Funding", overlay = false)
mode = input.string("За период", "Показывать", options = ["За период", "Годовых"])
thr  = input.float(0.05, "Порог, %", minval = 0.0, step = 0.01)

perPeriod = funding.rate * 100
periodsPerYear = funding.interval_hours > 0 ? 24.0 / funding.interval_hours * 365 : na
value = mode == "Годовых" ? perPeriod * periodsPerYear : perPeriod
level = mode == "Годовых" ? thr * periodsPerYear : thr

plot(value, "Ставка, %", style = plot.style_columns, color = value >= 0 ? color.teal : color.red)
hline(0, "Ноль", color = color.gray)
plotshape(funding.settled, "Выплата", style = shape.circle, location = location.bottom, color = color.gray, size = size.tiny)
bgcolor(math.abs(value) > level ? color.new(color.orange, 30) : na)

Как устроено

  • funding.rate — доля, а не проценты: 0.0001 — это 0,01 %. Поэтому ставка умножается на 100.
  • Для годовых ставка умножается на число выплат в год. 24.0 записано дробью намеренно: деление двух целых в LootScript отбрасывает остаток.
  • funding.settled истинно на баре, где прошла выплата, — там внизу ставится точка.
  • Порог задаётся за период и для годовых пересчитывается тем же множителем.

7. Дисбалансы в кластерах

Отметки на графике цены там, где в кластерах бара стоит «лесенка» дисбалансов или их просто много, плюс уровень максимального объёма (POC) каждого бара.

Loot
indicator("Дисбалансы кластеров", shortTitle = "Imbalance", overlay = true)
minSteps = input.int(3, "Уровней подряд", minval = 2)
minCount = input.int(5, "Дисбалансов в баре", minval = 1)

levels = cluster.available ? cluster.levels : 0
buys  = 0
sells = 0
for i in 0 .. levels {
    side = cluster.imbalance(i)
    if side == 1 {
        buys := buys + 1
    } else if side == -1 {
        sells := sells + 1
    }
}

plot(cluster.poc, "POC", style = plot.style_circles, color = color.orange)
plotshape(cluster.stacked_buy_steps >= minSteps, "Лесенка покупок", style = shape.triangleup, location = location.belowbar, color = color.teal, size = size.small)
plotshape(cluster.stacked_sell_steps >= minSteps, "Лесенка продаж", style = shape.triangledown, location = location.abovebar, color = color.red, size = size.small)
plotshape(buys >= minCount, "Много дисбалансов покупок", style = shape.circle, location = location.belowbar, color = color.new(color.teal, 120), size = size.tiny)
plotshape(sells >= minCount, "Много дисбалансов продаж", style = shape.circle, location = location.abovebar, color = color.new(color.red, 120), size = size.tiny)

Как устроено

  • cluster.imbalance(i) возвращает +1, −1 или 0 для ценового уровня i. Порог дисбаланса берётся из настроек кластеров графика, поэтому скрипт видит то же, что вы.
  • cluster.stacked_buy_steps — сколько уровней подряд идёт дисбаланс покупок. Цикл for i in 0 .. levels считает все дисбалансы бара, не только подряд.
  • Скрипт сам подписывается на кластеры и работает на обычном свечном графике. На бирже без покрытия и на таймфреймах меньше 30 секунд или больше суток кластеров нет — тогда levels равно 0 и отметок не будет.

8. Стратегия: пересечение EMA со стопом по ATR

Вход в лонг на пересечении средних, стоп и цель — в долях ATR, выход и по обратному пересечению.

Loot
strategy("EMA-кросс со стопом по ATR", overlay = true, initialCapital = 10000,
         defaultQtyType = strategy.qty.percent_of_equity, defaultQtyValue = 10,
         slippageTicks = 2)
fastLen = input.int(12, "Быстрая EMA", minval = 1)
slowLen = input.int(26, "Медленная EMA", minval = 2)
atrLen  = input.int(14, "Период ATR", minval = 1)
stopK   = input.float(1.5, "Стоп, в ATR", minval = 0.1, step = 0.1)
takeK   = input.float(3.0, "Цель, в ATR", minval = 0.1, step = 0.1)

fast = ta.ema(close, fastLen)
slow = ta.ema(close, slowLen)
atr  = ta.atr(atrLen)

// ATR запоминается в момент сигнала, чтобы стоп и цель не ползли вслед за волатильностью.
var float riskAtr = na
if ta.crossover(fast, slow) and strategy.position_size == 0 {
    riskAtr := atr
    strategy.entry("Long", strategy.long)
}
if ta.crossunder(fast, slow) {
    strategy.close("Long", comment = "Обратный кросс")
}
if strategy.position_size > 0 {
    entry = strategy.position_avg_price
    strategy.exit("Стоп/цель", from_entry = "Long", stop = entry - stopK * riskAtr, limit = entry + takeK * riskAtr)
}

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

Как устроено

  • Параметры strategy(…) — литералы: капитал 10 000, размер позиции 10 % капитала, проскальзывание 2 тика. Комиссия не задана, поэтому тестер берёт тариф по умолчанию: 0,02 % за лимитное исполнение и 0,05 % за рыночное и стоп. Свой тариф в процентах задаёт commissionValue.
  • Рыночный вход исполняется по открытию следующего бара, а не по закрытию сигнального: так тестер не заглядывает в будущее.
  • strategy.exit ставит стоп и цель от средней цены входа. Если за один бар задеты оба, тестер по умолчанию считает, что сработал стоп.
  • Результаты — сделки, кривая капитала, просадки — в окне Тестер стратегии… редактора. Подробнее — на странице Стратегии и тестер.

Дальше

https://docs.lootx.trade/ru/loot/examples