Скрипты на C++: инструментарий Clang в WebAssembly и ABI v1

Senzoukria умеет компилировать скрипт на C++17 в WebAssembly внутри своей песочницы настоящим Clang, а затем выполнять его на барах графика. Инструментарий скачивается один раз по запросу, проверяется по размеру и SHA-256 и открывает небольшой ABI: of_compute строит одно значение на бар, of_strategy возвращает намерения на покупку и продажу для симулированного счёта.

Senzoukria · Документация · Обновлено: сентябрь 2026


Где найти

Где
Страница «Скрипты» → выбор языка → C++ (над редактором кода появляется полоса «Инструментарий C++»)
Инструментарий
Clang 8.0.1 + LLD + libc++, скомпилированные в WebAssembly и зафиксированные на коммите 648c4a89 проекта Binji wasm-clang; около 60,4 МБ (в интерфейсе — «60.4 Mo»), скачиваются один раз
Ёмкость
256 последних баров на вызов; исходник до 64 КиБ; 2 с на запуск; таймаут компиляции 45 с
Область стратегии
Только симулированный счёт; приложение никогда не превращает намерение из C++ в ордер брокеру

Что это даёт

Движок C++ — третий язык скриптов рядом с JavaScript и Python. Выбор C++ в переключателе языка на странице «Скрипты» открывает полосу «Инструментарий C++». Её первое состояние — «Не установлен» с кнопкой «Установить инструментарий C++» и примечанием «Около 60.4 Mo к загрузке, один раз (Clang 8.0.1 + LLD + libc++, Apache-2.0).». Пять файлов (clang, lld, memfs, sysroot.tar, shared.js) скачиваются с зафиксированного коммита GitHub, каждый отклоняется, если его размер в байтах или SHA-256 расходится со значением, записанным в приложении, и складываются в IndexedDB, так что загрузка происходит лишь однажды.

Старт движка компилирует около 50 МБ WebAssembly — поэтому «Запуск движка…» является видимым состоянием, отличным от запуска скрипта. Когда всё готово, полоса выводит «Версия wasm-clang-648c4a89, старт за {ms} мс» и далее строку ограничений. Каждый скрипт компилируется один раз, ключом служит SHA-256 составленного исходника (заголовок хоста плюс ваш код); повторные запуски того же скрипта в ритме графика ничего не перекомпилируют. Хост держит до 8 скомпилированных модулей, воркер — тоже 8.

ABI, который видит ваш скрипт

Объявления, добавляемые хостом перед вашим кодом (не объявляйте их повторно)
СимволСмыслПримечания
struct OfBarbucket_ts_ns (int64), open, high, low, close, volume, delta (double), trades (uint32)64 байта, сначала самый старый бар, n ≤ 256
int of_compute(const OfBar* bars, uint32_t n, double* out, uint32_t out_len)Записать одно значение на бар в out[i]; NaN означает отсутствие значения; вернуть nРисуется одной зелёной линией (#7ed321, толщина 1) на графике
int of_strategy(const OfBar* bars, uint32_t n, int32_t* out, uint32_t out_len)Записать одно намерение на бар: −1 продажа, 0 ничего, +1 покупкаЧитается только намерение последнего бара; qty, stopTicks и targetTicks берутся из параметров скрипта
OF_CAPACITY256Бары старше ёмкости не передаются; строка предупреждения сообщает, сколько пропущено
#line 1 "script.cpp"Номера строк в диагностике совпадают с вашим редакторомПервая запись «script.cpp:N:M: error» задаёт подсвеченную строку

Состояния движка и элементы управления

Состояния полосы инструментария C++ и кнопки, доступные в каждом
СостояниеПоказывается какДоступное действие
absentНе установлен + примечание о размереУстановить инструментарий C++
downloadingЗагрузка движка… {percent} %Отменить загрузку
startingЗапуск движка…нет (таймаут старта 120 с)
readyДвижок готов, версия и время старта, ограниченияУдалить движок (очищает модули воркера и кэш IndexedDB)
errorДвижок недоступен + сообщениеПовторить

Как этим пользоваться

Создайте новый скрипт, выберите C++ и начните с шаблона по умолчанию: простая скользящая средняя за 20 периодов на бегущей сумме, NaN на прогреве, возврат n. Запускайте той же кнопкой, что и скрипты на JavaScript. Предупреждения и ошибки компилятора приходят в консоль строками журнала; запуск, вышедший за двухсекундный бюджет, падает так же, как любой другой скрипт. Сегодня поставляется единственный шаблон на C++ — та самая скользящая средняя; готовой стратегии на C++ нет. Достаточно самому написать of_strategy: её намерения идут тем же путём принятия решений, что и стратегии на JavaScript, и только к симулированному оценочному счёту.

Если на графике больше 256 баров, консоль печатает «ABI v1 C++ считает 256 последних баров: у N более старого бара (баров) значения нет.» Старые бары просто рисуются без значения, а не заполняются догадкой.

Ограничения и подводные камни

  • Поддерживается C++17; C++20 явно не обещан. Заголовки вроде <cmath>, <vector> и <numeric> доступны из libc++.
  • Исходник ограничен 64 КиБ вместе с заголовком хоста; скомпилированный модуль может использовать до 64 МиБ памяти.
  • Движок скачивается только с raw.githubusercontent.com; перенаправление отклоняется, а файл с иным размером или хешем отбрасывается ещё до попадания в песочницу.
  • Если песочница перезапустилась или инструментарий удалили во время компиляции, запуск сообщает «песочница перезапущена или инструментарий удалён во время компиляции — запустите снова».
  • Запуск скрипта на C++ до установки инструментария возвращает «инструментарий C++ не запущен — установите его на странице «Скрипты»»; после готовности движка запуск проходит сам собой.

Эта страница на других языках

Частые вопросы

Нужен ли инструментарию C++ интернет при каждом запуске?
Нет. Пять файлов скачиваются один раз, проверяются и остаются в IndexedDB. Последующие старты читают кэш и работают полностью офлайн; «Удалить движок» очищает этот кэш.
Может ли стратегия на C++ отправлять ордера моему брокеру?
Нет. of_strategy выдаёт намерения −1/0/+1, которые превращаются в решения для симулированного счёта тем же путём, что и у стратегий на JavaScript. Ни один скрипт в Senzoukria не размещает ордер у брокера.
Почему мой индикатор обрывается после 256 баров?
ABI v1 передаёт 256 последних баров на вызов. У более старых баров значения нет, и консоль сообщает, сколько их пропущено.