Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
02.05.2025 16:04:15
Благодарю за помощь в поиске решений, но вопрос с самого начала был не в этом. Решение было найдено сразу после возникновения ситуации. Вопрос в том, как получить конкретный ответ на конкретную транзакцию если OnTransReply не вызывается, а sendTransaction не выдает ошибку.
Еще раз: При попытке выставить заявку в аукцион открытия OnTransReply вызывается с описанной ошибкой и эта же ошибка попадает в таблицу сообщений. А попытке снять заявку в аукцион открытия, OnTransReply не вызывается, но ошибка так же попадает в таблицу сообщений. Почему OnTransReply не вызывается при снятии заявки в аукцион открытия?
Если вызов OnTransReply при снятии заявки в аукцион открытия не предусмотрен просто "потому что", то зарегистрируйте пожелание реализовать такую возможность. Если на то есть причина, то расскажите какая и зарегистрируйте пожелание добавить описание этой причины в документацию.
Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
11.04.2025 23:42:08
Цитата
Nikolay написал: Если нет ответа транзакции (т.е. ответа шлюза биржи), то, скорее всего, транзакция не прошла дальше сервера брокера. А значит есть ответ и ошибка самого метода sendTranscation. Где тоже необходимо проверять - ушла ли транзакция на биржу.
При попытке отправки транзакции в неторговое время, sendTranscation возвращает ошибку: Ошибка снятия заявки: Указанная транзакция по указанному классу не найдена: "SPBFUT".
Нашел старые логи по которым видно, что c 08:50 до 08:59 идет аукцион открытия.
Моя ситуация возникла вчера в 08:59:21, тогда еще был аукцион открытия, поэтому sendTranscation не выдал ошибку.
Поэтому мой вопрос остается открытым)
Цитата
Владислав написал: Как роботу понять что произошла ошибка снятия конкретной заявки, если колбеки не вызываются?
Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
11.04.2025 13:32:34
Код
function KillOrder (sec_info, order_num)
local transaction = {
["TRANS_ID"] = '1',
["ACTION"] = "KILL_ORDER",
["CLASSCODE"] = sec_info.class_code,
["ORDER_KEY"] = tostring(order_num)
}
local result = sendTransaction(transaction)
if result == '' then return order_num end
for key, val in pairs(transaction) do result = result..'\n'..key.." = "..tostring(val) end
error("\nОшибка снятия заявки: "..result)
end
Проверка осуществляется, ошибки нет, робот продолжил работу.
Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
11.04.2025 12:28:55
Я не предлагаю использовать OnTransReply для проверки состояния сессии. OnTransReply вызывается в том числе когда мы выставляем заявку и получаем сообщения: "Сейчас эта сессия не идет" "Идет пром. клиринг, нельзя совершать торговые операции" "Инструмент недопустим в аукционе открытия" "Торги по этому финансовому инструменту сейчас не проводятся" "Превышен лимит отправки транзакций для данного логина" ... И робот видит этот вызов и что он произошел на конкретную транзакцию и дальше обрабатывает эту ошибку.
Сейчас речь идет о том, что при попытке снять заявку вызов OnTransReply не произошел и робот ждет ответ на снятие, но в ответ - ничего. Только сообщение в таблице сообщений которое он не видит. И нам остается проверять состояние сессии и делать предположение о том, что заявка не снята потому-что попытка снятия отклонена с ошибкой "Сейчас эта сессия не идет." А если вызов OnTransReply происходил еще и при снятии, то в робота не пришлось бы включать предположения, он мог бы обработать конкретную ситуацию.
Цитата
Nikolay написал: Подавать их необходимо когда торги по инструменту проводятся.
Цитата
Владислав написал: Мы можем проверять состояние сессий перед отправкой транзакции, но даже так мы будем натыкаться на ошибки транзакций в первые секунды неторгового времени.
Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
11.04.2025 09:56:30
Цитата
paluke написал: А sendTransaction ничего не возвращает?
Не возвращает
Цитата
Ziveleos написал: А зачем Вы отправляете транзакцию, если сессия в это время закрыта?
Транзакция отправляется автоматически в ответ на срабатывание заявки. Заявка сработала в 08:59:21, на что робот среагировал и снял оставшуюся заявку, после чего получил ошибку, которая отобразилась в таблице сообщений.
Цитата
Ziveleos написал: Если нет OnTransReply и сессия закрыта, какой вывод должен сделать робот?
Вывод робот делает, но это как-то костыльно. А если это не ошибка, а долгая задержка ответа или косяки на сервере. Хотелось бы получать конкретный ответ, тем более, учитывая что в таблицу сообщений он приходит.
Мы можем проверять состояние сессий перед отправкой транзакции, но даже так мы будем натыкаться на ошибки транзакций в первые секунды неторгового времени. Поэтому я проверяю состояние сессии после получения ошибки на транзакцию. Как ошибка появляется, тогда уже ждем начала торгов и обрабатываем ошибку.
На данный момент вопрос в том, как роботу получить ответ Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет." который отображается в таблице сообщений. Если никак, то нужно реализовать в QUIK такую возможность т.к. OnTransReply вызывается в ответ на выставление и было бы логично вызывать его в ответ на снятие.
Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
10.04.2025 18:43:53
Это не решение. Я отправляю транзакцию и хочу получить на нее ответ, чтобы продолжить работу. Пока ответа нет, робот не может выставлять новые заявки. Где роботу взять этот ответ?
Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет."
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
10.04.2025 14:13:20
Добрый день! При попытке снять заявку возникла ошибка: Ошибка снятия заявки. [GW][3] "Сейчас эта сессия не идет." При этом ни OnOrder, ни OnTransReply небыли вызваны. Как роботу понять что произошла ошибка снятия конкретной заявки, если колбеки не вызываются?
Ошибка при совершении операции "Скорректированное значение НПР1 -65572.12 (RUB) меньше 0"
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
21.03.2025 09:39:01
Столкнулся с той-же проблемой. Решил получением необходимых полей из кармана транзакций. Создать окно - Все типы окон - Карман транзакций - ETF - Вод заявки - Добавить все - Да В кармане - ПКМ - Положить в карман - ETF - Ввод заявки - Выполнить - Вводим значения - Да В кармане нажимаем на транзакцию ПКМ - Сохранить в tri-файл - Сохраняем Открываем файл в редакторе кода и копируем поля в вашу функцию отправки транзакции.
В моем случае так:
Код
function SendOrder (sec_info, quantity, price)
local transaction = {
["TRANS_ID"] = getTransId(),
["Торговый счет"] = sec_info.account,
["CLASSCODE"] = sec_info.class_code,
["Режим"] = sec_info.class_code,
["Инструмент"] = sec_info.sec_code,
["Примечание"] = sec_info.client_code,
["Цена"] = tostring(rounding(price, sec_info.scale)),
["Лоты"] = tostring(rounding(math.abs(quantity))),
["К/П"] = quantity > 0 and "Купля" or "Продажа",
["ACTION"] = "Ввод заявки",
["Тип"] = "Лимитная",
["Тип по цене"] = "По разным ценам",
["Тип по остатку"] = "Поставить в очередь",
["Тип ввода значения цены"] = "По цене",
["Назначение заявки"] = "По умолчанию",
["Тип события активации заявки"] = "Обычная заявка",
["Объем заявки"] = "0.0",
}
local result = sendTransaction(transaction)
if result == '' then
return tonumber(transaction.TRANS_ID)
end
for key, val in pairs(transaction) do result = result..'\n'..key.." = "..tostring(val) end
error("\nОшибка транзакции: "..result..'\n'..debug.traceback())
end
Хотя до это момента, был клиент который тоже заказывал для ETF и у него работало с таким набором полей: "TRANS_ID", "CLASSCODE", "SECCODE", "ACCOUNT", "OPERATION", "QUANTITY", "PRICE", "ACTION", "CLIENT_CODE"
FUTSPREAD сделки за планкой
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
30.01.2023 13:41:35
Цитата
uuh написал: Не то что слышал, а лично видел. При этом система мне так же не давала ставить заявки за планкой. Но кто-то их туда точно ставил и сделки за планкой проходили.
Я заметил, что если до клиринга выставить заявку, а после клиринга планка сместится, то наша заявка может остаться за планкой. Таким образом контрагент может свести нашу заявку с заявками из стаканов фьючерса, при том, что она будет за планкой.
FUTSPREAD сделки за планкой
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
30.01.2023 12:43:17
Здравствуйте. Несколько раз встречал информацию, что на календарных спредах, роботы выставляли заявки за планкой. Я пробовал выставлять вручную и через lua, итог один "Цена сделки вне лимита", при этом видно, что за планкой проходят сделки. Буду благодарен, если подскажете почему так происходит или где можно найти об этом информацию ? И если работаете с данным классом инструментов, то какая у Вас логика работы с планкой ?
Как создать свою форму (окно) и разместить на ней элементы формы (чекбокс, список, кнопка, поле для ввода и тд), Создание новых элементов интерфейса
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
23.09.2022 19:21:31
Цитата
swerg написал: А вы какой версией терминала пользуетесь? У вас точно Lua5. 1 в терминале?
Lua 5.1 в терминале нет, только 5.4.1 и 5.3.5. Получается, что использование iuplua в новых версиях терминала невозможно ?
Как создать свою форму (окно) и разместить на ней элементы формы (чекбокс, список, кнопка, поле для ввода и тд), Создание новых элементов интерфейса
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
23.09.2022 14:32:46
Прошу прощенья, архив скачивал не 32 битный, а 64. При скачивании 32 битного, появлялась ошибка D:\DEVELOPMENT\Exchange\Роботы\iup\iuptest.lua:1: %1 не является приложением Win32.
Как создать свою форму (окно) и разместить на ней элементы формы (чекбокс, список, кнопка, поле для ввода и тд), Создание новых элементов интерфейса
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
23.09.2022 13:59:46
Здравствуйте. Подскажите пожалуйста, что делать с данной ошибкой ? С сайта скачал архив . Из этого архива, в папку с квиком скопировал файлы iup.dll и iuplua51.dll. Создал скрипт с кодом:
Скрытый текст
Код
assert(package.loadlib(getScriptPath() .. "\\iuplua51.dll", "luaopen_iuplua"))()
function main()
dlg = iup.dialog
{
iup.vbox
{
iup.label {title="Test iupLUA in QUIK"},
iup.button{title="Button Very Long Text"},
iup.button{title="short", expand="HORIZONTAL"},
iup.button{title="Mid Button", expand="HORIZONTAL"}
}
;title="IupDialog", font="Helvetica, Bold 14"
}
dlg:show()
iup.MainLoop()
end
При запуске скрипта в терминале возникает ошибка: ACCESS VIOLATION at address 00007FFDB6692850 Что делать ?
Принципы написания скриптов, Разделять или объединять?
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
01.09.2022 14:56:02
Цитата
Владимир написал: Про несколько скриптов я и вообще говорить не хочу - это алгоритмический идиотизм
Вы различные стратегии в одном скрипте реализуете ?
Принципы написания скриптов, Разделять или объединять?
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
01.09.2022 10:24:17
Владимир, nikolz, Благодарю за советы. На примере кода представленного Антоном выше, сделал тесты скорости получения ответа на транзакцию. По итогу думаю, что в рамках нескольких скриптов действительно смысла с заморочками нет. Тем более если скрипт работает с различными таблицами в QUIK. В моем случае, после отправки транзакции, происходит расчет прибыли от совершенной сделки, запись этой сделки в файл и т.п. Для того, что бы исключить возможные несостыковки, связанные с длительностью поступления данных в таблицу сделок и таблицу поз. по. кл. счетам, скрипт делает паузу в 1000мс. При такой реализации программы, смысла в заморочках точно нет. Но если речь идет о большом количестве скриптов, в которых все завязано на коллбеках, смысл думаю что есть.
Код для тестирования скорости:
Скрытый текст
Код
_G.client = {}
_G.client.account = "SPBFUT000he"
_G.client.class_code = "SPBFUT"
_G.client.sec_code = "BRV2"
_G.time = 0
local function toftime(a)
local aa = a.hour
aa = aa * 60
aa = aa + a.min
aa = aa * 60
aa = aa + a.sec
aa = aa * 1000000
aa = aa + a.mcs
return aa
end
function OnTransReply (trans_reply)
if trans_reply.sec_code == _G.client.sec_code then
local x = toftime(os.sysdate()) - toftime(_G.time)
PrintDbgStr("OnTransReply: "..(x).."мкс "..(x / 1000).."мс "..(x / 1000000).."с")
end
end
function OnTrade (trade)
if trade.sec_code == _G.client.sec_code then
local x = toftime(os.sysdate()) - toftime(_G.time)
PrintDbgStr("OnTrade: "..(x).."мкс "..(x / 1000).."мс "..(x / 1000000).."с")
end
end
function sendMarketOrder (client, quantity, comment)
local number = getNumberOf("trades")
local transaction = {
["TRANS_ID"] = '1',
["CLASSCODE"] = client.class_code,
["SECCODE"] = client.sec_code,
['ACCOUNT'] = client.account,
['OPERATION'] = quantity > 0 and 'B' or 'S',
['QUANTITY'] = tostring(math.abs(quantity)),
["ACTION"] = "NEW_ORDER",
["TYPE"] = "M",
['PRICE'] = "0",
["CLIENT_CODE"] = comment
}
_G.time = os.sysdate()
local result = sendTransaction(transaction)
if result == '' then
for count = 1, 30000 do
local new_number = getNumberOf("trades")
if new_number ~= number then
for i = new_number -1, 0, -1 do
local item = getItem("trades", i)
if item.trans_id == tonumber(transaction.TRANS_ID) then
local x = toftime(os.sysdate()) - toftime(_G.time)
PrintDbgStr("sendMarketOrder: "..(x).."мкс "..(x / 1000).."мс "..(x / 1000000).."с "..count)
return true
end
end
end
sleep(1)
end
end
local fields = ""
for k, val in pairs(transaction) do
val = tostring(val)
fields = fields == '' and fields..k.." = ".."\""..val.."\"" or fields..", "..k.." = ".."\""..val.."\""
end
PrintDbgStr("sendMarketOrder: Ошибка транзакции: "..result..' '..fields)
return false
end
function main()
for i = 1, 10 do
PrintDbgStr("i: "..i)
sendMarketOrder(_G.client, 1)
sleep(3000)
end
end
Принципы написания скриптов, Разделять или объединять?
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
30.08.2022 17:08:53
Цитата
nikolz написал: Существующая структура QLUA имеет существенный недостаток. Все колбеки вызываются из одного потока и каждый из них повторяется в различных скриптах. В итоге получается дублирование одних и тех же действий многократно. Я устранил эту проблему и сделал механизм при котором колбеки в скриптах не повторяются, а скрипты могут запускать функции друг у друга и получать данные из других скриптов.. ------------------------- В итоге не только повышается скорость, но и размер кода сокращается в десятки раз.
Цитата
nikolz написал: Тот механизм, о котором я написал, позволяет очень просто делать много роботов по различным алгоритмом для одного инструмента. Колбеки не дублируются в скриптах Каждый колбек существует в своем скрипте и вызывается всего один раз квиком для получения данных вне зависимости от числа роботов. Роботы получают требуемые данные от этого скрипта. т е потоки синхронизируются и обмениваются данными , а также чтобы не дублировать код, могут запускать функции других скриптов через механизм колбеков между скриптами. Сравнительно просто в этом варианте отдавать данные совершенно независимым процессам.
Здравствуйте. Подскажите пожалуйста, как реализовать подобный механизм ?
Повторное выставление меток на график при смене инструмента
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
20.12.2021 10:51:27
Здравствуйте. Прикрепляю видео с демонстрацией данной ошибки в терминалах версии 9.2.3.15 и 8.13.1.16.
Повторное выставление меток на график при смене инструмента
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
08.12.2021 18:19:37
Скрипт тестировался в "боевом" терминале версии 9.2.3.15 и в демо терминале версии 8.13.1.16 И там и там была данная ошибка
Повторное выставление меток на график при смене инструмента
Пользователь
Сообщений: Регистрация: 08.12.2021
TreottTrade
08.12.2021 17:28:44
Здравствуйте. Написал индикатор, добавляющий на график метку с номером последней свечи. После добавления индикатора на график, изменении его свойств в настройках графика и смене тайм-фрейма ошибок не происходит. Но при смене инструмента (график привязан к таблице "Текущие торги"), на графике появляется дополнительная мистическая метка. Функция AddLabel не возвращает номер этой метки, ее нельзя удалить вручную (перетаскивать по графику можно) и с помощью функции DelLabel, но при этом она удаляется функцией DelAllLabels.
Добавляем индикатор на график и меняем инструмент. На графике появится новая метка и поверх нее еще одна мистическая. Мистическую перетаскиваем в сторону, заходим в настройки индикатора, меняем параметр "Отступ от максимума" (или просто меняем тайм-фрейм) и видим, что мистическая метка остается на месте а вторая изменяется.
По умолчанию, для удаления меток при их перерисовке, индикатор использует функцию DelLabel. Но, если в поле параметра "Удаление всех меток" поставить значение "да [да/нет]", то индикатор будет использовать функцию DelAllLabels и в таком случае, при изменении настроек индикатора или смене тайм-фрейма, мистическая метка будет удаляться.
Если я правильно понял, то данная проблема уже обсуждалась и была решена (topic3532)
Код
-- [[ Индикатор добавляет на график метку с номером последней свечи ]]--
-- Заметки:
-- GetLabelParams возвращает таблицу с названиями параметров в нижнем регистре, тогда как эти параметры в функции AddLabel задаются в верхнем регистре.
-- GetLabelParams возвращает значения всех параметров в строковом виде, несмотря на то, что часть параметров типа number.
-- getDataSourceInfo().class_code работает только после вызова OnChangeSettings()
-- getNumCandles() и getParamEx() работают только после вызова OnCalculate()
Settings = {}
Settings.Name = "- IndexCandleFF"
Settings["Отступ от максимума"] = 100
Settings["Идентификатор графика"] = "one_graph"
Settings["Удаление всех меток"] = "нет [да/нет]"
TableLabel = {}
index_old = 0 -- Функция OnCalculate вызывается несколько раз для каждой свечи. index_old нужен для того, что бы не захламлять таблицу TableLabel.
flag_error = true -- В случае ошибки параметров в настройках индикатора, предотвращает повторный вывод сообщения об ошибке и добавление меток на график.
flag_first = true -- Предотвращаем повторный вызов OnChangeSettings.
flag_init = false -- Флаг для корректной работы getParamEx и getNumCandles
del_labels = string.match(Settings["Удаление всех меток"], "(.*) .*")
interval = 0
function isChartExist (chart_name) -- Возвращает true, если график с идентификатором "Идентификатор графика" существует, иначе false
if chart_name == nil or chart_name == '' then return false end
local n = getNumCandles (chart_name)
if n == nil or n < 1 then return false end
return true
end
function place_label(index)
PrintDbgStr("place_label")
local positionY = H(index) + Settings["Отступ от максимума"]
local DateTime = T(index)
local Y = DateTime.year
local M = DateTime.month if #tostring(M) == 1 then M = '0'..M end
local D = DateTime.day if #tostring(D) == 1 then D = '0'..D end
local HO = DateTime.hour if #tostring(HO) == 1 then HO = '0'..HO end
local MI = DateTime.min if #tostring(MI) == 1 then MI = '0'..MI end
local SE = DateTime.sec if #tostring(SE) == 1 then SE = '0'..SE end
label_params = {}
-- label_params.IMAGE_PATH = getScriptPath() .. "\\1.bmp"
label_params.YVALUE = positionY -- Значение параметра на оси Y, к которому будет привязана метка
label_params.DATE = Y..M..D -- Дата в формате «ГГГГММДД», к которой привязана метка
label_params.TIME = HO..MI..SE -- Время в формате «ЧЧММСС», к которому будет привязана метка
label_params.TRANSPARENCY = 0 -- Прозрачность метки в процентах. Значение должно быть в промежутке [0; 100]. Применяется только для картинки.
label_params.FONT_FACE_NAME = "Arial" -- Название шрифта (например «Arial»)
label_params.FONT_HEIGHT = 8 -- Размер шрифта
label_params.TEXT = tostring(index) -- Если подпись не требуется то оставить строку пустой ""
label_params.HINT = "Index candle" -- Текст всплывающей подсказки
label_params.R = 0 -- Красная компонента цвета в формате RGB. Число в интервале [0;255]
label_params.G = 0 -- Зеленая компонента цвета в формате RGB. Число в интервале [0;255]
label_params.B = 0 -- Синяя компонента цвета в формате RGB. Число в интервале [0;255]
label_params.TRANSPARENT_BACKGROUND = 1
table.insert(TableLabel, AddLabel(Settings["Идентификатор графика"], label_params)) -- Добавляем метку и запоминаем ее ID
end
function Init ()
PrintDbgStr("Init")
flag_init = false
return 1
end
function OnDestroy ()
PrintDbgStr("OnDestroy")
if del_labels == "да" then
DelAllLabels(Settings["Идентификатор графика"])
else
-- for label_id = 1, #TableLabel do
-- DelLabel(Settings["Идентификатор графика"], TableLabel[label_id])
-- end
for label_id = 1, 100000 do -- 100000 - максимально возможное количество меток на графике.
local L = GetLabelParams(Settings["Идентификатор графика"], label_id) -- table or nil
if L ~= nil then
if L.hint == "Index candle" then
DelLabel(Settings["Идентификатор графика"], label_id)
end
end
end
end
index_old = 0
end
function OnChangeSettings()
-- Функция вызывается при редактировании свойств индикатора после нажатия кнопок «Применить» или «OK».
PrintDbgStr("OnChangeSettings")
if flag_init then -- При переходе на другой тайм-фрейм, сначала вызывается функция Init, затем OnChangeSettings затем OnCalculate, но для работы функций getParamEx и getNumCandles необходимо, что бы сначала была вызвана OnCalculate, поэтому, сначала игнорируем автоматический вызов OnChangeSettings, а затем после того как вызовется OnCalculate, вызываем ее сами.
PrintDbgStr("OnChangeSettings_Body")
del_labels = string.match(Settings["Удаление всех меток"], "(.*) .*")
--[ Исключение ошибок в настройках графика ]--
if not isChartExist(Settings["Идентификатор графика"]) then
if flag_error then
message("Ошибка значения в поле: \"Идентификатор графика\"")
flag_error = false
end
elseif del_labels ~= "да" and del_labels ~= "нет" then
if flag_error then
message("Ошибка значения в поле: \"Удаление всех меток\"")
flag_error = false
end
else flag_error = true
end
--[ Удаление меток с графика ]--
if flag_error then
OnDestroy()
end
--[ Задаем отступ для метки ]--
local sec_code = getDataSourceInfo().sec_code
local class_code = getDataSourceInfo().class_code
local step = getParamEx(class_code, sec_code, "SEC_PRICE_STEP").param_image -- Минимальный шаг цены
local scale = tonumber(getParamEx(class_code, sec_code, "SEC_SCALE").param_image) -- Точность цены.
if scale == nil then
error("local ER: Для корректной работы индикатора необходимо установить соединение с сервером !")
else
if scale > 0 then
step = tonumber("0."..step:match(",(.*)")) -- Заменяем запятую на точку и преобразуем строковый формат в числовой.
end
Settings["Отступ от максимума"] = step * Settings["Отступ от максимума"]
end
flag_first = false -- Предотвращаем повторный вызов OnChangeSettings.
interval = getDataSourceInfo().interval
end
end
function OnCalculate (index)
-- Если изменился тайм-фрейм. При изменении тайм-фрейма необходимо удалить старые метки.
if interval ~= getDataSourceInfo().interval then
flag_init = true
PrintDbgStr("interval")
OnDestroy()
interval = getDataSourceInfo().interval
end
if index > index_old then
if flag_first then
PrintDbgStr("flag_first")
OnChangeSettings()
end
--[ Добавление меток на график ]--
if flag_error then
if index == Size() then
place_label(index)
end
end
index_old = index
end
return
end