(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{Awda:function(e,t,n){"use strict";n.r(t),n.d(t,"_frontmatter",(function(){return i})),n.d(t,"default",(function(){return d}));var a=n("Fcif"),l=n("dV/x"),b=(n("mXGw"),n("/FXl")),r=n("TjRS");n("l1C2");const c=["components"],i={};void 0!==i&&i&&i===Object(i)&&Object.isExtensible(i)&&!Object.prototype.hasOwnProperty.call(i,"__filemeta")&&Object.defineProperty(i,"__filemeta",{configurable:!0,value:{name:"_frontmatter",filename:"src/components/ru/Scripting.mdx"}});const p={_frontmatter:i},o=r.a;function d(e){let{components:t}=e,n=Object(l.a)(e,c);return Object(b.b)(o,Object(a.a)({},p,n,{components:t,mdxType:"MDXLayout"}),Object(b.b)("h1",{id:"-api-для-пользовательских-индикаторов"},"📘 API для пользовательских индикаторов"),Object(b.b)("h2",{id:"-ии-для-генерации-пользовательских-индикаторов"},"🤖 ИИ для генерации пользовательских индикаторов"),Object(b.b)("p",null,"Используйте следующий документ с ChatGPT, Claude, Gemini или другими ИИ-моделями для генерации пользовательских индикаторов для MobChart."),Object(b.b)("p",null,"👉 ",Object(b.b)("a",{parentName:"p",href:"../../public/AI.txt"},"AI.txt")),Object(b.b)("p",null,"Пример запроса:"),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre"},"Прочитай приложенный файл AI.txt:\nhttps://mobchart.com/docs/public/AI.txt\n\nИспользуй его как единственный источник информации об API скриптинга MobChart.\n\nСоздай пользовательский индикатор, который отображает EMA с периодами 20 и 50 на графике. Окрась свечи в зелёный цвет, если EMA20 находится выше EMA50, и в красный — в противном случае.\n\nИспользуй только документированный API. Не придумывай функции. Верни полный код индикатора.\n")),Object(b.b)("h2",{id:"-принципы-безопасности-и-текущие-ограничения"},"🔒 Принципы безопасности и текущие ограничения"),Object(b.b)("ul",null,Object(b.b)("li",{parentName:"ul"},"Среда исполнения скриптов основана на безопасной JavaScript-песочнице. "),Object(b.b)("li",{parentName:"ul"},"На исполнение вашего скрипта выделяется ",Object(b.b)("inlineCode",{parentName:"li"},"1500ms"),"."),Object(b.b)("li",{parentName:"ul"},"Длина массива возвращаемых данных ",Object(b.b)("strong",{parentName:"li"},"не более 1500"),". Таким образом, индикатор не может распространяться глубже чем на ",Object(b.b)("strong",{parentName:"li"},"1500 свечей"),"."),Object(b.b)("li",{parentName:"ul"},"Доступно ",Object(b.b)("strong",{parentName:"li"},"8 обращения")," к источнику данных в рамках одного индикатора.")),Object(b.b)("hr",null),Object(b.b)("h2",{id:"️-разработка-индикатора"},"⚒️ Разработка индикатора"),Object(b.b)("p",null,"Разработка индикатора ведется внутри отдельного виджета, который может располагаться рядом с графиком, внутри которого будет включен данный индикатор."),Object(b.b)("img",{src:"../../public/code_chart_widgets.png"}),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-создание-индикатора"},"🧭 Создание индикатора"),Object(b.b)("h3",{id:"definetitle-description-type-ispublic-ispubliccode"},Object(b.b)("inlineCode",{parentName:"h3"},"define(title, description, type, isPublic, isPublicCode)")),Object(b.b)("p",null,"Регистрирует индикатор в системе."),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Параметр"),Object(b.b)("th",{parentName:"tr",align:null},"Тип"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"title")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"string")),Object(b.b)("td",{parentName:"tr",align:null},"Название индикатора")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"description")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"string")),Object(b.b)("td",{parentName:"tr",align:null},"Краткое описание")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"type")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"'onchart'")," ","|"," ",Object(b.b)("inlineCode",{parentName:"td"},"'offchart'")),Object(b.b)("td",{parentName:"tr",align:null},"Расположение индикатора (на графике или в отдельной панели)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"isPublic")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"true")," ","|"," ",Object(b.b)("inlineCode",{parentName:"td"},"false")),Object(b.b)("td",{parentName:"tr",align:null},"Индикатор доступен всем")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"isPublicCode")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"true")," ","|"," ",Object(b.b)("inlineCode",{parentName:"td"},"false")),Object(b.b)("td",{parentName:"tr",align:null},"Исходный код индикатора доступен всем")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'define("My Indicator", "Shows EMA line", "onchart", true, false);\n')),Object(b.b)("hr",null),Object(b.b)("p",null,"Расположение индикаторов при ",Object(b.b)("strong",{parentName:"p"},"onchart")," и ",Object(b.b)("strong",{parentName:"p"},"offchart"),":"),Object(b.b)("img",{src:"../../public/onchart_offchart.png"}),Object(b.b)("h2",{id:"️-ввод-параметров"},"⚙️ Ввод параметров"),Object(b.b)("p",null,"Классы ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"input"))," и ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"style"))," позволяют создавать настройки для пользователя (аналог ",Object(b.b)("inlineCode",{parentName:"p"},"input()")," в PineScript)."),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number(title, defaultValue, min, max, step)")),Object(b.b)("td",{parentName:"tr",align:null},"Числовой ввод")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"range(title, defaultValue, min, max, step)")),Object(b.b)("td",{parentName:"tr",align:null},"Ввод из диапазона")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"select(title, defaultValue, values)")),Object(b.b)("td",{parentName:"tr",align:null},"Выпадающий список")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"color(title, defaultValue)")),Object(b.b)("td",{parentName:"tr",align:null},"Выбор цвета")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"boolean(title, defaultValue)")),Object(b.b)("td",{parentName:"tr",align:null},"Двоичная переменная")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример (input) для основных параметров:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const length = input.number("Period", 14, 1, 100, 1);\nconst type = input.select("Type", \'sma\', [\'sma\', \'ema\']);\nconst color = input.color("Line Color", "#FF0000");\n')),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Или (style) для визуальных параметров:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const length = style.number("Size", 14, 1, 100, 1);\nconst color = style.select("Background Color", \'#FF0000\', ["#FF0000", "#AA0000", "#BB0000"]);\nconst color = style.color("Background Color", "#FF0000");\n')),Object(b.b)("p",null,"Параметры из ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"input"))," и ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"style"))," отображаются в отдельных вкладках в настройках индикатора:"),Object(b.b)("img",{src:"../../public/input_style.png"}),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-источники-данных"},"🧮 Источники данных"),Object(b.b)("p",null,"Класс ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"source"))," используется для получения рыночных данных с серверной стороны. "),Object(b.b)("p",null,"Мы ",Object(b.b)("strong",{parentName:"p"},"не всегда")," гарантируем полное соответствие возвращенных данных к видимым свечам на графике."),Object(b.b)("p",null,"Например, во время исполнения скрипта может быть возвращено 400 свечей от ",Object(b.b)("strong",{parentName:"p"},"ohlcv()")," метода, но только 300 лимитных заявок(для тепловаой карты) от ",Object(b.b)("strong",{parentName:"p"},"depths()")," метода.\nИспользуйте дополнительные проверки по параметрам ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"startTime"))," в своем коде."),Object(b.b)("p",null,"В данный момент длина массива возвращаемых данных ",Object(b.b)("strong",{parentName:"p"},"не более 1500"),".",Object(b.b)("br",{parentName:"p"}),"\n","Таким образом, индикатор не может распространяться глубже чем на ",Object(b.b)("strong",{parentName:"p"},"1500 свечей"),"."),Object(b.b)("p",null,"В данный момент доступно ",Object(b.b)("strong",{parentName:"p"},"8 обращения")," к источнику данных в рамках одного индикатора."),Object(b.b)("p",null,"Параметры ",Object(b.b)("inlineCode",{parentName:"p"},"exchange"),", ",Object(b.b)("inlineCode",{parentName:"p"},"ticker"),", ",Object(b.b)("inlineCode",{parentName:"p"},"timeframe")," по умолчанию привязаны к текущему графику, на котором был открыт индикатор.\nПараметр ",Object(b.b)("inlineCode",{parentName:"p"},"lookback"),"(выборка истории баров от текущей даты, но ",Object(b.b)("strong",{parentName:"p"},"не более 1500"),") устанавливается по усмотрению."),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},'Метод "ohlcv"'),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"ohlcv(exchange, ticker, timeframe, lookback?)")),Object(b.b)("td",{parentName:"tr",align:null},"Свечные данные")))),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'[\n {\n "open": 115886.17,\n "high": 115911.96,\n "low": 115764.27,\n "close": 115815.16,\n "volume": 228.41528,\n "startTime": 1757699100000\n },\n {...},\n ...\n] \n')),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},'Метод "depths"'),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"depths(exchange, ticker, timeframe, lookback?)")),Object(b.b)("td",{parentName:"tr",align:null},"Лимитные заявки")))),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'[\n {\n "data": {\n "asks": {\n "109425": 5.467,\n "109495": 3.564,\n ...\n },\n "bids": {\n "33000": 3.746,\n "35000": 16.49,\n ...\n }\n },\n "startTime": 1757699100000\n },\n {...},\n ...\n]\n\n')),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},'Метод "clusters"'),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"clusters(exchange, ticker, timeframe, lookback?)")),Object(b.b)("td",{parentName:"tr",align:null},"Кластерные данные")))),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'[\n {\n "data": {\n "totalBuy": 16053385,\n "totalSell": 20490989,\n "0.8654": { "buy": 286845, "sell": 336689 },\n "0.8653": { "buy": 271848, "sell": 259167 },\n "0.8652": { "buy": 318814, "sell": 373497 },\n ...\n },\n "startTime": 1757699100000\n },\n {...},\n ...\n]\n\n')),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},'Метод "liquidations"'),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"liquidations(exchange, ticker, timeframe, lookback?)")),Object(b.b)("td",{parentName:"tr",align:null},"Ликвидации")))),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'[\n {\n "data": {\n "totalBuy": 16053385,\n "totalSell": 20490989,\n "0.8654": { "buy": 286845, "sell": 336689 },\n "0.8653": { "buy": 271848, "sell": 259167 },\n "0.8652": { "buy": 318814, "sell": 373497 },\n ...\n },\n "startTime": 1757699100000\n },\n {...},\n ...\n]\n\n')),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},'Метод "moreData"'),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"moreData(exchange, ticker, timeframe, lookback?)")),Object(b.b)("td",{parentName:"tr",align:null},"Дополнительные данные")))),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'[\n { \n "data": {\n "FR": 0.00003777, // Funding Rate\n "OI": { // Open Interest Candle\n "open": 85645.708,\n "close": 83496.225,\n "high": 85801.04,\n "low": 83397.918\n },\n "LS": { "l": 0.5426, "s": 0.4574 }, // Long/Short Ratio\n "taLS": { "l": 0.552, "s": 0.448 }, // Top Traders Account Ratio\n "tpLS": { "l": 0.5996, "s": 0.4004 } // Top Traders Position Ratio\n },\n "startTime": 1757699100000\n },\n {...},\n ...\n]\n\n')),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},"const candles = source.ohlcv(); //Параметры exchange, ticker, timeframe по умолчанию привязаны к текущему графику.\nconst closes = candles.map(c => c.close);\n")),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-глобальные-переменные"},"🌐 Глобальные переменные"),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Переменная"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"),Object(b.b)("th",{parentName:"tr",align:null},"Пример"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"currentExchange")),Object(b.b)("td",{parentName:"tr",align:null},"Текущая биржа на графике"),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"binance"),", ",Object(b.b)("inlineCode",{parentName:"td"},"binanceFutures"),", ",Object(b.b)("inlineCode",{parentName:"td"},"coinbase"),", ...")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"currentTicker")),Object(b.b)("td",{parentName:"tr",align:null},"Текущий тикер на графике(формат зависит от бижри)"),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"BTCUSDT"),", ",Object(b.b)("inlineCode",{parentName:"td"},"ADA-USD"),", ",Object(b.b)("inlineCode",{parentName:"td"},"BTC/USDC"),", ...")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"currentTimeframe")),Object(b.b)("td",{parentName:"tr",align:null},"Текущий таймфрейм на графике"),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"1m"),", ",Object(b.b)("inlineCode",{parentName:"td"},"5m"),", ",Object(b.b)("inlineCode",{parentName:"td"},"15m"),", ...")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},"const candles = source.ohlcv(currentExchange, currentTicker, currentTimeframe);\nconst closes = candles.map(c => c.close);\n")),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-логирование"},"🧾 Логирование"),Object(b.b)("p",null,"Класс ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"logger"))," используется для вывода информации и отладки."),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"log(...args)")),Object(b.b)("td",{parentName:"tr",align:null},"Добавляет запись в лог (с ограничением длины и количества)")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const candles = source.ohlcv();\nlogger.log("First candle:", candles?.[0]);\n')),Object(b.b)("img",{src:"../../public/code_editor_log.png"}),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-визуализация"},"📈 Визуализация"),Object(b.b)("p",null,"Класс ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"plot"))," отвечает за отрисовку графических элементов и серий данных."),Object(b.b)("h3",{id:"-геометрические-фигуры"},"🔹 Геометрические фигуры"),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"box(title, date1, price1, date2, price2, fill, opacity, stroke, strokeOpacity, strokeWidth)")),Object(b.b)("td",{parentName:"tr",align:null},"Прямоугольник")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"square(title, date1, price1, size, fill, opacity, stroke, strokeOpacity, strokeWidth)")),Object(b.b)("td",{parentName:"tr",align:null},"Квадрат")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"diamond(title, date1, price1, size, fill, opacity, stroke, strokeOpacity, strokeWidth)")),Object(b.b)("td",{parentName:"tr",align:null},"Ромб")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"triangle(title, date1, price1, size, fill, opacity, stroke, strokeOpacity, strokeWidth)")),Object(b.b)("td",{parentName:"tr",align:null},"Треугольник")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"circle(title, date1, price1, radius = 10, fill, opacity, stroke, strokeOpacity, strokeWidth)")),Object(b.b)("td",{parentName:"tr",align:null},"Круг")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"text(title, value, date1, price1, fontSize, fill, opacity)")),Object(b.b)("td",{parentName:"tr",align:null},"Текст на графике")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"straightLine(title, date1, price1, date2, price2, stroke, strokeOpacity, strokeWidth, strokeDasharray)")),Object(b.b)("td",{parentName:"tr",align:null},"Прямая линия")))),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Параметр"),Object(b.b)("th",{parentName:"tr",align:null},"Тип данных"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"title")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"string")),Object(b.b)("td",{parentName:"tr",align:null},"Название элемента (уникальный идентификатор на графике)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"date1")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")," (timestamp, ms)"),Object(b.b)("td",{parentName:"tr",align:null},"Начальная временная метка")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"price1")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")),Object(b.b)("td",{parentName:"tr",align:null},"Начальная цена (координата по оси Y)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"date2")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")," (timestamp, ms)"),Object(b.b)("td",{parentName:"tr",align:null},"Конечная временная метка (для линий и прямоугольников)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"price2")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")),Object(b.b)("td",{parentName:"tr",align:null},"Конечная цена (для линий и прямоугольников)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"size")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")),Object(b.b)("td",{parentName:"tr",align:null},"Размер фигуры (в пикселях)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"radius")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")),Object(b.b)("td",{parentName:"tr",align:null},"Радиус круга (по умолчанию 10)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"fill")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"string")," (hex, например ",Object(b.b)("inlineCode",{parentName:"td"},'"#FF0000"'),")"),Object(b.b)("td",{parentName:"tr",align:null},"Цвет заливки фигуры")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"opacity")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")," (0–1)"),Object(b.b)("td",{parentName:"tr",align:null},"Прозрачность заливки")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"stroke")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"string")," (hex, например ",Object(b.b)("inlineCode",{parentName:"td"},'"#000000"'),")"),Object(b.b)("td",{parentName:"tr",align:null},"Цвет обводки")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"strokeOpacity")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")," (0–1)"),Object(b.b)("td",{parentName:"tr",align:null},"Прозрачность обводки")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"strokeWidth")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")),Object(b.b)("td",{parentName:"tr",align:null},"Толщина линии обводки (в пикселях)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"strokeDasharray")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"array")," (например ",Object(b.b)("inlineCode",{parentName:"td"},"[5,5]"),")"),Object(b.b)("td",{parentName:"tr",align:null},"Стиль пунктирной линии")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"fontSize")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number")),Object(b.b)("td",{parentName:"tr",align:null},"Размер текста (в пикселях)")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"value")),Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"string")),Object(b.b)("td",{parentName:"tr",align:null},"Текстовое значение (для метода ",Object(b.b)("inlineCode",{parentName:"td"},"text"),")")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'plot.text("Text object", "Hello world!", 1757699100000, 115000, 10, "#00C8FF", 0.5);\nplot.straightLine(`${namePrefix} Open`, level.timeStart, level.open, level.timeEnd, level.open, color);\nplot.circle(`${namePrefix} High`, level.timeStart, level.high, 3, color);\n')),Object(b.b)("p",null,"Допустимо отобразить не более ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"3000"))," фигур на графике."),Object(b.b)("hr",null),Object(b.b)("h3",{id:"-серии-данных"},"🔹 Серии данных"),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"lineSeries(title, values, stroke, strokeOpacity, strokeWidth, strokeDasharray)")),Object(b.b)("td",{parentName:"tr",align:null},"Линейный график")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"barSeries(title, values, fill, opacity)")),Object(b.b)("td",{parentName:"tr",align:null},"Гистограмма")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"candleSeries(title, openValues, closeValues, highValues, lowValues, fill, opacity)")),Object(b.b)("td",{parentName:"tr",align:null},"Свечи")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'plot.lineSeries("EMA", ta.ema(closes, 20), "#00C8FF");\nplot.barSeries("Premium %", premiumPercents, ((d) => d > 0 ? color1 : color2), 1);\nplot.candleSeries(\n "Candles",\n opens, closes, highs, lows,\n (v, i) => {\n return opens?.[i] > closes?.[i] ? colorBuy : colorSell\n }\n);\n')),Object(b.b)("p",null,"Допустимо отобразить не более ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"10"))," серий данных на графике."),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-технический-анализ"},"📊 Технический анализ"),Object(b.b)("p",null,"Класс ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"ta"))," включает в себя набор функций, аналогичных PineScript."),Object(b.b)("h3",{id:"-вспомогательные"},"🔹 Вспомогательные"),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"highest(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Максимум за период")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"lowest(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Минимум за период")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"variance(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Дисперсия")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"stdev(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Стандартное отклонение")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"crossover(series1, series2)")),Object(b.b)("td",{parentName:"tr",align:null},"Проверка пересечения вверх")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"crossunder(series1, series2)")),Object(b.b)("td",{parentName:"tr",align:null},"Проверка пересечения вниз")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"cross(series1, series2)")),Object(b.b)("td",{parentName:"tr",align:null},"Любое пересечение")))),Object(b.b)("h3",{id:"-скользящие-средние"},"🔹 Скользящие средние"),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"sma(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Простая скользящая средняя")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"ema(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Экспоненциальная скользящая")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"wma(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Взвешенная скользящая")))),Object(b.b)("h3",{id:"-индикаторы"},"🔹 Индикаторы"),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"rsi(values, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Индекс относительной силы")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"macd(values, fast, slow, signalPeriod)")),Object(b.b)("td",{parentName:"tr",align:null},"MACD")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"bollinger(values, period, mult)")),Object(b.b)("td",{parentName:"tr",align:null},"Полосы Боллинджера")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"stoch(highs, lows, closes, period, smoothK, smoothD)")),Object(b.b)("td",{parentName:"tr",align:null},"Стохастический осциллятор")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"atr(highs, lows, closes, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Средний истинный диапазон")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"adx(highs, lows, closes, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Индекс направленного движения")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"cci(highs, lows, closes, period)")),Object(b.b)("td",{parentName:"tr",align:null},"Товарный канал")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"vwap(highs, lows, closes, volumes)")),Object(b.b)("td",{parentName:"tr",align:null},"Объемно-взвешенная средняя цена")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const candles = source.ohlcv();\nconst closes = candles.map(c => c.close);\nconst rsiValues = ta.rsi(closes, 14);\nplot.lineSeries("RSI", rsiValues, "#00C8FF");\n')),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-алерты"},"🔔 Алерты"),Object(b.b)("p",null,"Пользователи могут создавать алерты для вашего индикатора во вкладке ",Object(b.b)("strong",{parentName:"p"},"Алерты")," в настройках индикатора на графике.\nАлерты проверяются на стороне сервера каждые ",Object(b.b)("strong",{parentName:"p"},"30 секунд"),", уведомления отправляются в ",Object(b.b)("strong",{parentName:"p"},"Telegram")," и/или на ",Object(b.b)("strong",{parentName:"p"},"Webhook URL"),", указанный пользователем."),Object(b.b)("h3",{id:"️-настройки-алерта--alertinput"},"⚙️ Настройки алерта — ",Object(b.b)("inlineCode",{parentName:"h3"},"alertInput")),Object(b.b)("p",null,"Класс ",Object(b.b)("strong",{parentName:"p"},Object(b.b)("inlineCode",{parentName:"strong"},"alertInput"))," объявляет настройки алертов. Он работает так же, как ",Object(b.b)("inlineCode",{parentName:"p"},"input"),", но поля отображаются во вкладке ",Object(b.b)("strong",{parentName:"p"},"Алерты"),", и каждый пользователь задаёт свои значения для своего алерта."),Object(b.b)("p",null,"Скрипты без объявлений ",Object(b.b)("inlineCode",{parentName:"p"},"alertInput")," не могут использоваться для алертов."),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"number(title, defaultValue, min, max, step)")),Object(b.b)("td",{parentName:"tr",align:null},"Числовое поле")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"range(title, defaultValue, min, max, step)")),Object(b.b)("td",{parentName:"tr",align:null},"Ползунок")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"select(title, defaultValue, values)")),Object(b.b)("td",{parentName:"tr",align:null},"Выпадающий список")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"color(title, defaultValue)")),Object(b.b)("td",{parentName:"tr",align:null},"Выбор цвета")),Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"boolean(title, defaultValue)")),Object(b.b)("td",{parentName:"tr",align:null},"Логическое поле")))),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const alertVolumeThreshold = alertInput.number("Порог объёма", 1000, 0, 10000000, 1);\n')),Object(b.b)("h3",{id:"-срабатывание-алертов--alertfire"},"🚨 Срабатывание алертов — ",Object(b.b)("inlineCode",{parentName:"h3"},"alert.fire")),Object(b.b)("table",null,Object(b.b)("thead",{parentName:"table"},Object(b.b)("tr",{parentName:"thead"},Object(b.b)("th",{parentName:"tr",align:null},"Метод"),Object(b.b)("th",{parentName:"tr",align:null},"Описание"))),Object(b.b)("tbody",{parentName:"table"},Object(b.b)("tr",{parentName:"tbody"},Object(b.b)("td",{parentName:"tr",align:null},Object(b.b)("inlineCode",{parentName:"td"},"fire(title, message, date)")),Object(b.b)("td",{parentName:"tr",align:null},"Отправляет уведомление алерта")))),Object(b.b)("ul",null,Object(b.b)("li",{parentName:"ul"},"Все три параметра ",Object(b.b)("strong",{parentName:"li"},"обязательны")," — вызов без ",Object(b.b)("inlineCode",{parentName:"li"},"title"),", ",Object(b.b)("inlineCode",{parentName:"li"},"message")," или ",Object(b.b)("inlineCode",{parentName:"li"},"date")," пропускается (в лог записывается предупреждение)."),Object(b.b)("li",{parentName:"ul"},"Используйте ",Object(b.b)("strong",{parentName:"li"},"постоянный title"),", не генерируйте уникальные названия. Каждый title срабатывает только один раз за запуск (максимум ",Object(b.b)("strong",{parentName:"li"},"20")," названий за запуск)."),Object(b.b)("li",{parentName:"ul"},Object(b.b)("inlineCode",{parentName:"li"},"date")," — это ",Object(b.b)("inlineCode",{parentName:"li"},"startTime")," свечи, к которой относится сигнал: тот же title уведомит снова, только когда сработает для ",Object(b.b)("strong",{parentName:"li"},"более новой")," свечи. Сигналы со свечей старше момента создания алерта пользователем игнорируются (защита от спама).")),Object(b.b)("p",null,Object(b.b)("strong",{parentName:"p"},"Пример:")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'if (candle.volume > alertVolumeThreshold) {\n alert.fire("Высокий объём", `объём ${candle.volume}`, candle.startTime);\n}\n')),Object(b.b)("h3",{id:"-алерты-фигур--plotфигураalert"},"📐 Алерты фигур — ",Object(b.b)("inlineCode",{parentName:"h3"},"plot.<фигура>(...).alert(...)")),Object(b.b)("p",null,"Все геометрические фигуры (",Object(b.b)("inlineCode",{parentName:"p"},"box"),", ",Object(b.b)("inlineCode",{parentName:"p"},"square"),", ",Object(b.b)("inlineCode",{parentName:"p"},"diamond"),", ",Object(b.b)("inlineCode",{parentName:"p"},"triangle"),", ",Object(b.b)("inlineCode",{parentName:"p"},"circle"),", ",Object(b.b)("inlineCode",{parentName:"p"},"straightLine"),", ",Object(b.b)("inlineCode",{parentName:"p"},"text"),") возвращают объект с методом ",Object(b.b)("inlineCode",{parentName:"p"},".alert()"),".\nАлерт срабатывает с ",Object(b.b)("inlineCode",{parentName:"p"},"date1")," фигуры автоматически, поэтому защита от спама работает без дополнительного кода — это рекомендуемый способ для сигналов на конкретных свечах."),Object(b.b)("p",null,"Две формы:"),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'// простая: срабатывает каждый раз, когда фигура рисуется с новой датой\nplot.box(...).alert("Высокий объём", `объём ${candle.volume}`);\n\nplot.box(...).alert((shape) => {\n if (candle.volume > alertVolumeThreshold)\n alert.fire("High volume", `vol ${candle.volume}`, candle.startTime);\n});\n')),Object(b.b)("p",null,"Колбэк получает данные фигуры (",Object(b.b)("inlineCode",{parentName:"p"},"date1"),", ",Object(b.b)("inlineCode",{parentName:"p"},"price1"),", ",Object(b.b)("inlineCode",{parentName:"p"},"date2"),", ",Object(b.b)("inlineCode",{parentName:"p"},"price2"),", ...)."),Object(b.b)("h3",{id:"-алерты-серий--plotсерияalert"},"📈 Алерты серий — ",Object(b.b)("inlineCode",{parentName:"h3"},"plot.<серия>(...).alert(...)")),Object(b.b)("p",null,"Серии данных (",Object(b.b)("inlineCode",{parentName:"p"},"lineSeries"),", ",Object(b.b)("inlineCode",{parentName:"p"},"barSeries"),", ",Object(b.b)("inlineCode",{parentName:"p"},"candleSeries"),") тоже возвращают объект с методом ",Object(b.b)("inlineCode",{parentName:"p"},".alert()"),".\nКолбэк получает ",Object(b.b)("strong",{parentName:"p"},"последнюю точку данных")," и дату последней свечи, алерт срабатывает с этой датой."),Object(b.b)("ul",null,Object(b.b)("li",{parentName:"ul"},Object(b.b)("inlineCode",{parentName:"li"},"lineSeries")," / ",Object(b.b)("inlineCode",{parentName:"li"},"barSeries")," — колбэк получает последнее ",Object(b.b)("strong",{parentName:"li"},"значение")," (число)"),Object(b.b)("li",{parentName:"ul"},Object(b.b)("inlineCode",{parentName:"li"},"candleSeries")," — колбэк получает последнюю свечу ",Object(b.b)("inlineCode",{parentName:"li"},"{open, close, high, low}"))),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'plot.lineSeries("RSI", rsiValues, color).alert((rsi, date) => {\n if (rsi > alertRsiThreshold) alert.fire("Высокий RSI", `RSI ${rsi.toFixed(1)}`, latestCandle.startTime);\n});\n')),Object(b.b)("p",null,"Условие, которое остаётся истинным, уведомляет один раз на каждую ",Object(b.b)("strong",{parentName:"p"},"новую свечу"),". Для одноразовых сигналов используйте условия пересечения (",Object(b.b)("inlineCode",{parentName:"p"},"ta.crossover"),")."),Object(b.b)("h3",{id:"-полный-пример"},"🧩 Полный пример"),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const title = "Алерты объёма";\nconst description = "Показывает боксы на свечах с высоким объёмом";\ndefine(title, description, "onchart", true, true);\n\nconst color = style.color("Цвет", "#00C8FF");\nconst volumeThreshold = input.number("Порог объёма", 1000, 0, 10000000, 1);\nconst alertVolumeThreshold = alertInput.number("Порог объёма для алерта", 5000, 0, 10000000, 1);\nconst alertCloseThreshold = alertInput.number("Порог закрытия для алерта", 100000, 0, 10000000, 1);\n\nconst candles = source.ohlcv();\nconst latestCandle = candles.at(-1);\nconst closes = candles.map(c => c.close);\n\n// алерт серии: проверяет последнее закрытие\nplot.lineSeries("Closes", closes, color).alert((close, date) => {\n if (close > alertCloseThreshold) alert.fire("Закрытие выше порога", `close ${close}`, latestCandle.startTime);\n});\n\nfor (let i = 0; i < candles.length; i++) {\n const candle = candles[i];\n\n if (candle.volume > volumeThreshold) {\n const right = i < candles.length - 1 ? candles[i + 1].startTime : candle.startTime + 60000;\n\n // алерт фигуры: проверяется по порогу алерта пользователя\n plot.box(`Volume ${i}`, candle.startTime, candle.high, right, candle.low, "#00C8FF", 0.3)\n .alert(() => {\n if (candle.volume > alertVolumeThreshold)\n alert.fire("Высокий объём", `объём ${candle.volume}`, latestCandle.startTime);\n });\n }\n}\n')),Object(b.b)("hr",null),Object(b.b)("h2",{id:"-примеры-индикаторов"},"🧠 Примеры индикаторов"),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const title = "Your first indicator";\nconst description = "Shows closes lines on the chart";\nconst indicatorType = "onchart";\n\ndefine(title, description, type, true, true);\n\nconst color = input.color("Line Color", "#00C8FF");\nconst candles = source.ohlcv();\nconst closes = candles.map(c => c.close);\nplot.lineSeries("Closes", closes, color);\n\n')),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'define("Example Indicator", "Demonstrates basic plotting", "onchart", true, true);\n\nconst color = input.color("Line Color", "#00FF99");\nconst candles = source.ohlcv();\nconst closes = candles.map(c => c.close);\n\nconst ema20 = ta.ema(closes, 20);\nplot.lineSeries("EMA 20", ema20, color);\n\n')),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const title = "Colored Volume Bars"; \nconst description = "Volumes colored based on candle direction."; \nconst indicatorType = "onchart"; \nconst isPublic = true; \nconst isPublicCode = true; \n\ndefine(title, description, indicatorType, isPublic, isPublicCode); \n\n// Get OHLC candles\nconst candles = source.ohlcv(); \n\nconst colorUp = style.color("Color 1", "#2BB462"); // Greenish color for rising prices\nconst colorDown = style.color("Color 2", "#FB4C51"); // Reddish color for falling prices\nconst volumes = candles.map(candle => candle.volume); \n\nplot.barSeries("Volume", volumes, (value, index) => {\n const currentCandle = candles[index]; \n return currentCandle.close >= currentCandle.open ? colorUp : colorDown; \n});\n\n')),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},"define('Coinbase Premium Index', 'Coinbase Premium Index', 'offchart', true, false);\n\nconst color1 = style.color(\"Color 1\", \"#2BB462\");\nconst color2 = style.color(\"Color 2\", \"#FB4C51\");\n\n// Get OHLC candles\nconst cbCandles = source.ohlcv('coinbase', 'BTC-USD');\nconst binanceCandles = source.ohlcv('binance', 'BTCUSDT');\n\n// Extract closes\nconst cbCloses = cbCandles.map(c => c.close);\nconst binanceCloses = binanceCandles.map(c => c.close);\n\n// --- Coinbase Premium Index calculation ---\nconst premiumPercent = cbCloses.map((cb, i) => {\n const b = binanceCloses[i];\n return ((cb - b) / b) * 100;\n});\n\n// Plot premium index\nplot.barSeries(\"Premium %\", premiumPercent, ((d) => d > 0 ? color1 : color2)) // Percentage difference\n\n")),Object(b.b)("pre",null,Object(b.b)("code",{parentName:"pre",className:"language-js"},'const title = "Candles";\nconst description = "Simple candles draw";\nconst indicatorType = "offchart";\nconst isPublic = true;\nconst isPublicCode = true;\ndefine(title, description, indicatorType, isPublic, isPublicCode);\n\nconst colorBuy = style.color("Buy Color", "#2BB462");\nconst colorSell = style.color("Sell Color", "#7a3d3f");\nconst candles = source.ohlcv();\nconst closes = candles.map(c => c.close);\nconst opens = candles.map(c => c.open);\nconst highs = candles.map(c => c.high);\nconst lows = candles.map(c => c.low);\nplot.candleSeries(\n "Candles",\n opens, closes, highs, lows,\n (v, i) => {\n return opens?.[i] > closes?.[i] ? colorBuy : colorSell\n }\n);\n\n')))}void 0!==d&&d&&d===Object(d)&&Object.isExtensible(d)&&!Object.prototype.hasOwnProperty.call(d,"__filemeta")&&Object.defineProperty(d,"__filemeta",{configurable:!0,value:{name:"MDXContent",filename:"src/components/ru/Scripting.mdx"}}),d.isMDXComponent=!0}}]); //# sourceMappingURL=component---src-components-ru-scripting-mdx-0ac41821c8ebdc5a6831.js.map