LootX

Стратегии и тестер

новое Обновлено 30 сентября 2026 г. Эта страница в PDF

Как написать стратегию на LootScript и проверить её на истории в тестере: объявление strategy(), заявки, модель исполнения, издержки, вкладки отчёта и ограничения бэктеста.

Стратегия — это скрипт, который кроме линий на графике подаёт заявки. Заявки исполняет не биржа, а симулятор внутри терминала: он прогоняет стратегию по истории графика с комиссиями, проскальзыванием и фандингом и показывает результат в окне Тестер стратегии.

Объявление strategy()

Стратегию отличает от индикатора первая строка: strategy(...) вместо indicator(...). Всё остальное — настройки, отрисовка, данные рынка — работает так же. Функции strategy.* в индикаторе не компилируются: «strategy.* доступно только в strategy(…)».

Параметр По умолчанию Что задаёт
initialCapital 10000 Стартовый капитал
defaultQtyType, defaultQtyValue strategy.qty.fixed, 1 Размер заявки, если в ней не указан qty
commissionType, commissionValue процент, не задана Комиссия: strategy.commission.percent — процент от оборота (0.05 = 0,05 %), strategy.commission.cash_per_contract — сумма за единицу количества, strategy.commission.cash_per_order — сумма за исполнение
slippageTicks 0 Проскальзывание в тиках
pyramiding 0 Сколько входов в одну сторону может быть открыто; 0 — один
positionModel strategy.model.netting Одна общая позиция или раздельные длинные и короткие (strategy.model.hedging)
processOrdersOnClose false Исполнять рыночные заявки по закрытию текущего бара
calcOnEveryTick false Разрешить заявки на формирующемся баре
marginLong, marginShort, leverage 0, 0, 1 Маржа в процентах или плечо; при 0 ликвидация не моделируется
applyFunding true Учитывать фандинг
fillModel strategy.fill.conservative Предположение о пути цены внутри бара

Значения параметров — только числа и константы прямо в тексте. Выражение или input.* в объявлении — ошибка компиляции. Параметр calcOnOrderFills принимается, но в этой версии не действует: на вкладке «Свойства» тестера он помечен «не действует в этой сборке».

Размер заявки при qty = na задаёт defaultQtyType:

Тип defaultQtyValue означает
strategy.qty.fixed Количество в монетах (базовой валюте)
strategy.qty.cash Сумму в валюте котировки
strategy.qty.percent_of_equity Процент текущего капитала
strategy.qty.risk_percent Процент капитала, которым рискуете до защитного стопа

Для strategy.qty.risk_percent нужен strategy.exit со стопом (loss или stop), иначе компилятор остановит: «требует стоп, от которого считать размер». Количество округляется вниз до шага количества инструмента. Если после округления остаётся ноль, заявка отклоняется и попадает в счётчик тестера «Отвергнуто заявок (размер)».

Заявки

Функция Что делает
strategy.entry(id, direction, qty, limit, stop, …) Открывает позицию или разворачивает её. Учитывает модель позиции и pyramiding
strategy.order(id, direction, qty, limit, stop, …) То же без учёта модели позиции и pyramiding
strategy.exit(id, from_entry, qty, qty_percent, profit, limit, loss, stop, trail_price, trail_points, trail_offset, …) Ставит выход — тейк, стоп или трейлинг — на открытый вход
strategy.close(id, comment, qty, qty_percent) Закрывает вход рыночной заявкой
strategy.close_all(comment) Закрывает всё
strategy.cancel(id), strategy.cancel_all() Снимает ещё не исполненные заявки

Направление — strategy.long или strategy.short. У всех функций есть необязательный when: when = false пропускает вызов. У входов, выходов и закрытий есть ещё comment — текстовая подпись к заявке.

  • Тип входа. Без limit и stop — рыночная заявка, с limit — лимитная, со stop — стоп-заявка, с обоими — стоп-лимит. Повторный strategy.entry с тем же id заменяет ещё не исполненную заявку.
  • Разворот. В модели netting вход в противоположную сторону закрывает текущую позицию и открывает новую одним действием.
  • Единицы выхода. profit и loss — в тиках от цены входа, limit и stop — абсолютные цены. Трейлинг задаётся парой: trail_offset плюс trail_price или trail_points.
  • Выход без уровней ничего не делает. Компилятор предупредит: «strategy.exit без единого уровня (profit/loss/stop/limit/trail) — пустая операция».
  • Перенос стопа. Повторный strategy.exit с тем же id заменяет выход — так двигают стоп.

Состояние стратегии читается рядами: strategy.position_size (со знаком, короткая позиция — отрицательная), strategy.position_avg_price, strategy.equity, strategy.netprofit, strategy.openprofit, strategy.opentrades, strategy.closedtrades, strategy.funding_paid и другими — полный список в справочнике.

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

Заявка, поданная на баре, исполняется не раньше следующего бара. Решение принимается по закрытию бара, и исполнять его по той же цене значило бы заглянуть вперёд.

Заявка Исполнение
Рыночная По открытию следующего бара плюс проскальзывание. С processOrdersOnClose = true — по закрытию текущего
Лимитная Когда цена проходит лимит, по цене лимита. Если бар открылся за лимитом — по открытию
Стоп Когда цена проходит стоп, по цене стопа плюс проскальзывание. При гэпе — по открытию плюс проскальзывание

Путь цены внутри бара. Настоящего пути внутри бара тестер не знает и предполагает его. Модель strategy.fill.conservative (по умолчанию) считает, что цена сначала сходила к худшему экстремуму: на растущем баре — открытие → минимум → максимум → закрытие, на падающем — наоборот. Если в одном баре оказались и стоп, и тейк, срабатывает стоп. Модель strategy.fill.optimistic предполагает обратное — годится только для сравнения. Проигрывания по младшему таймфрейму в этой версии нет: в колонке «Путь» каждая сделка отмечена как предположенная моделью.

Издержки.

  • Комиссия. Если commissionValue не задан, тестер берёт тариф по умолчанию: 0,02 % за лимитные исполнения и 0,05 % за рыночные и стоп. Тариф вашего счёта и рибейты терминалу неизвестны. Заданное число действует на все исполнения.
  • Проскальзывание — slippageTicks против вас на рыночных и стоп-исполнениях. Лимитные не проскальзывают.
  • Фандинг списывается на каждом реальном расчёте биржи — по фактической ставке и цене закрытия бара расчёта. Для этого нужны данные фандинга: фьючерсы на биржах из таблицы покрытия.
  • Маржа. С marginLong/marginShort или плечом больше 1 тестер моделирует упрощённую изолированную маржу. Длинная позиция ликвидируется при цене вход × (1 − m/2), короткая — при вход × (1 + m/2), где m — доля начальной маржи. Ликвидированная сделка теряет всю начальную маржу.

Сделки, не закрытые к концу истории, закрываются по закрытию последнего бара с причиной «конец данных».

Тестер стратегии

Добавьте стратегию на график

В редакторе скриптов нажмите Добавить на график (Ctrl+Enter). Скрипт с ошибками на график не попадёт.

Откройте тестер

В панели инструментов редактора нажмите Тестер стратегии… — кнопка активна только для скрипта с strategy(...). Второй путь — настройки стратегии из легенды графика (шестерёнка), кнопка Тестер стратегии….

Дождитесь прогона

Тестер считает по свечам, загруженным на графике. Пока их нет, окно пишет «Стратегия ещё не считалась: дождитесь загрузки свечей». Когда приходят новые свечи, результат пересчитывается сам; кнопка Пересчитать запускает полный прогон вручную.

Если на графиках несколько стратегий, нужную можно выбрать прямо в окне тестера.

Вкладка Что на ней
Сводка Плитки «Чистая прибыль», «Профит-фактор», «Макс. просадка (по закрытиям)», «Доля прибыльных», «SQN»; полоса «Чего этот бэктест не знает»; кривые капитала, «купил-и-держи», капитала без фандинга и двух просадок
Показатели Результат, риск (просадка по закрытиям и внутри бара отдельно, Шарп, Сортино, Калмар), сделки (доля прибыльных, средние и крупнейшие, серии), издержки (комиссия и фандинг)
Сделки Таблица сделок: вход, выход, причина, объём, P&L, ран-ап, просадка, комиссия, фандинг. Клик по строке прокручивает график к бару входа, Ctrl+C копирует выделенные строки
Свойства Параметры объявления, диапазон баров, шаг цены, шаг количества, минимальный лот, комиссия, счётчики прогона: отклонённые заявки, пропущенные по pyramiding, ликвидации, расчёты фандинга

В заголовке окна — метки режима: conservative или optimistic по модели исполнения и close-fill при processOrdersOnClose = true. Метки optimistic и close-fill значат, что вживую результат, скорее всего, будет хуже.

Чего стратегия читать не может

Живой стакан и лента. Стратегия, которая читает book.* или tape.*, не компилируется: «Стратегия читает … у стакана и ленты нет истории, бэктест был бы вымыслом». Для истории стакана есть depth.*, для сделок — delta.* и cluster.*.

Скринер. screener.* тоже есть только на последнем баре, но компилятор такую стратегию пропускает. На истории значения скринера — na, поэтому условия на них там не выполняются, и сделок по ним в отчёте не будет.

Заглядывание вперёд. request.security(..., lookahead = true) в стратегии даёт в редакторе предупреждение «Стратегия заглядывает вперёд … отчёт помечен как недостижимый в реальном времени». Относитесь к такому отчёту как к завышенному: на истории стратегия видит значения, которых вживую ещё не было. Подробнее — в разделе Данные рынка.

Пример

Пробой канала с подтверждением дельтой. Вход — на закрытии за границей канала за последние len баров, если дельта бара в ту же сторону. Стоп — в ATR, тейк — вдвое дальше.

Loot
strategy("Пробой канала с дельтой", overlay = true,
         initialCapital = 10000,
         defaultQtyType = strategy.qty.percent_of_equity, defaultQtyValue = 20,
         commissionValue = 0.05, slippageTicks = 2)

len      = input.int(20, "Канал, баров", minval = 5, maxval = 200)
stopAtr  = input.float(1.5, "Стоп, ATR", minval = 0.5, maxval = 10, step = 0.1)
needFlow = input.bool(true, "Подтверждать дельтой")

upper = ta.highest(high, len)[1]
lower = ta.lowest(low, len)[1]
atr   = ta.atr(14)

flowLong  = not needFlow or (delta.available and delta.value > 0)
flowShort = not needFlow or (delta.available and delta.value < 0)

if close > upper and flowLong and strategy.position_size <= 0 {
    strategy.entry("L", strategy.long, comment = "пробой вверх")
}
if close < lower and flowShort and strategy.position_size >= 0 {
    strategy.entry("S", strategy.short, comment = "пробой вниз")
}

stopTicks = math.round(atr * stopAtr / sym.tick_size)
strategy.exit("L-x", from_entry = "L", loss = stopTicks, profit = stopTicks * 2)
strategy.exit("S-x", from_entry = "S", loss = stopTicks, profit = stopTicks * 2)

plot(upper, "Верх канала", color = color.teal)
plot(lower, "Низ канала", color = color.red)

На бирже без дельты (например, Binance Alpha) при включённой настройке «Подтверждать дельтой» стратегия не сделает ни одной сделки: delta.available там ложно. Это правило na в действии, а не ошибка.

Ограничения

  • Только симуляция: реальных заявок нет.
  • Лимитные заявки исполняются так, будто вы стояли первым в очереди. Для мейкерских стратегий это главный источник завышенного результата.
  • Ваши сделки не двигают цену, частичных исполнений нет: заявка исполняется целиком или никак.
  • Путь цены внутри бара предполагается моделью, а не берётся из младшего таймфрейма.
  • Ликвидация упрощена: движок ликвидаций биржи, ADL и страховой фонд не моделируются.
  • Комиссия — тариф по умолчанию, а не тариф вашего счёта.
  • Отсутствие данных — не отсутствие движения: бар без кластеров всё равно двигался.
  • Результат зависит от того, сколько истории загружено на графике.

Дальше

FAQ

Может ли стратегия на LootScript торговать на бирже?
Нет. Заявки стратегии исполняет симулятор внутри терминала, реальных заявок на бирже она не выставляет. У скриптов нет доступа к сети и к вашим API-ключам.
Как открыть тестер стратегии?
Добавьте стратегию на график и нажмите «Тестер стратегии…» в панели редактора скриптов или в настройках стратегии из легенды графика.
Какую комиссию берёт тестер, если её не задать?
Тариф по умолчанию: 0,02 % за лимитные исполнения и 0,05 % за рыночные и стоп. Тариф вашего счёта терминалу неизвестен — задайте commissionValue сами.
Почему стратегия со стаканом не компилируется?
У живого стакана и ленты нет истории, и бэктест по ним был бы вымыслом. Для истории стакана используйте depth.*, для сделок — delta.* и cluster.*.