Как при использовании функции t, n, l = getCandlesByIndex(tag, line, first_candle, getNumCandles(tag)); понять что последняя свеча уже закрылась или последнее значение индикатора уже рассчитано?
Sergey Gorokhov написал: Иван, Для этого нужно понять что сделок больше не будет. А этого никто не может знать, т.к. в будущее никто смотреть не умеет.
Нужно либо ждать появления новой свечи, либо проверять текущее время. Либо использовать оба варианта сразу.
А как тогда делать проверку - написал простое условие - если цена пересекла MA - то вылазит сообщение. Но проблема в том сообщение будет вылазить не 1 раз, а бесконечно...
Не вполне понятно, как связаны между собой вопрос о факте закрытия текущей свечи и проверка "простого условия" с пересечением графика МА и графика цены.
Первая задача решается проверкой времени - Вы знаете интервал, время начала/окончания торгов. На основании этих данных знаете какая свеча когда открывается и закрывается. Далее сравниваете текущее время - попадает ли оно в диапазон времени расчёта текущей свечи, или вышла за него. Касательно проверки "простого условия" - количество выполнения блока программы при выполнении определённого условия зависит от реализации самого условия и программы в целом - надо предусмотреть и/или пересмотреть механизмы от многочисленных малоинформативных срабатываний.
В текущей формулировке Вашей задачи едва ли можем предложить более содержательный ответ. Просьба уточнить суть Вашей задачи, которую пытаетесь решить.
Не вполне понятно, как связаны между собой вопрос о факте закрытия текущей свечи и проверка "простого условия" с пересечением графика МА и графика цены.
Первая задача решается проверкой времени - Вы знаете интервал, время начала/окончания торгов. На основании этих данных знаете какая свеча когда открывается и закрывается. Далее сравниваете текущее время - попадает ли оно в диапазон времени расчёта текущей свечи, или вышла за него. Касательно проверки "простого условия" - количество выполнения блока программы при выполнении определённого условия зависит от реализации самого условия и программы в целом - надо предусмотреть и/или пересмотреть механизмы от многочисленных малоинформативных срабатываний.
В текущей формулировке Вашей задачи едва ли можем предложить более содержательный ответ. Просьба уточнить суть Вашей задачи, которую пытаетесь решить.
Уже решил. Что бы не срабатывало по много раз когда идет одно и тоже событие, оно просто записывается в общую переменную и как итог срабатываем как и должно 1 раз.
Похоже не просто будет мне получить информацию о том, что текущая свеча закрылась. Из ответов выше кроме костылей с обработкой времени баров других вариантов нет? В питоне есть candle_close = true or false, в Амиброкере тоже есть свой костыль. Попробовал что-то изобразить, но сессия закончилась. У меня вроде стандартная задача - начинать расчет баров (обычное сравнение Bar-1 и Bar-2), но только когда текущая свеча закрылась. То что после закрытия текущей те бары сдвинуться на 1 - это понятно. Может есть какие варианты с меньшим количеством костылей? Спасибо.
Денис написал: Похоже не просто будет мне получить информацию о том, что текущая свеча закрылась. Из ответов выше кроме костылей с обработкой времени баров других вариантов нет? В питоне есть candle_close = true or false, в Амиброкере тоже есть свой костыль. Попробовал что-то изобразить, но сессия закончилась. У меня вроде стандартная задача - начинать расчет баров (обычное сравнение Bar-1 и Bar-2), но только когда текущая свеча закрылась. То что после закрытия текущей те бары сдвинуться на 1 - это понятно. Может есть какие варианты с меньшим количеством костылей? Спасибо.
закрытие свечи - это завершение интервала .Простейший алгоритм - синхронизируете ком от сервера точного времени и контролируете завершение текущего интервала времени. --------------------- Но относительно нового бара вы ошибаетесь. Новый бар возникнет не тогда, когда закроется предыдущая свеча, а тогда, когда появится сделка. Т е если сделки в новом интервале нет, то и бара нет.
Погуглив немного нашел кое-что похожее для определения нового бара. Подправил, сейчас переменная first_candle_index обновляет свой индекс как только появляется новая свеча. Но как это прикрутить для дальнейших вычислений, пока не допер. Тут на форуме нашел вот что, цитирую : SetUpdateCallback при смене индекса даст вам как раз момент открытия новой свечи. Вот как ее прикрутить к функции поиска индекса ниже? Или может есть другие методы какие?
function newbar() ds, error_desc = CreateDataSource("SPBFUT", "SiM3", INTERVAL_M1) local try_count = 0 while ds:Size() == 0 and try_count < 1000 do sleep(100) try_count = try_count + 1 end if error_desc ~= nil and error_desc ~= "" then message("Ошибка получения таблицы свечей:" .. error_desc) return 0 end
local today_day = tonumber(os.date("%m")) local current_candle = ds:Size() local max_candles = math.min(20, ds:Size()) local first_candle_index = nil
while first_candle_index == nil and current_candle > ds:Size() - max_candles do if tonumber(ds:T(current_candle).day) ~= today_day then
Если использовать источником данных DataSource, то использовать SetUpdateCallback для получения информации о том, что появилась новая свеча можно.
При появлении новой свечи в OnDataSourceUpdate изменится index и время свечи, пример:
-- Функция вызывается при изменении свечки в таблице data_source -- OnDataSourceUpdate(TABLE data_source, STRING class_code, STRING sec_code, NUMBER interval, STRING param, NUMBER index) function OnDataSourceUpdate(ds, class_code, sec_code, interval, param, index) ... local datetime = ds:T(index)
end
...
local ds, error = CreateDataSource(class_code, sec_code, interval, param) if ds ~= nil then ds:SetUpdateCallback(function (...) OnDataSourceUpdate(ds, class_code, sec_code, interval, param, ...) end) end
Денис написал: Погуглив немного нашел кое-что похожее для определения нового бара. Подправил, сейчас переменная first_candle_index обновляет свой индекс как только появляется новая свеча. Но как это прикрутить для дальнейших вычислений, пока не допер. Тут на форуме нашел вот что, цитирую : SetUpdateCallback при смене индекса даст вам как раз момент открытия новой свечи. Вот как ее прикрутить к функции поиска индекса ниже? Или может есть другие методы какие?
function newbar() ds, error_desc = CreateDataSource("SPBFUT", "SiM3", INTERVAL_M1) local try_count = 0 while ds:Size() == 0 and try_count < 1000 do sleep(100) try_count = try_count + 1 end if error_desc ~= nil and error_desc ~= "" then message("Ошибка получения таблицы свечей:" .. error_desc) return 0 end
local today_day = tonumber(os.date("%m")) local current_candle = ds:Size() local max_candles = math.min(20, ds:Size()) local first_candle_index = nil
while first_candle_index == nil and current_candle > ds:Size() - max_candles do if tonumber(ds:T(current_candle).day) ~= today_day then
first_candle_index = current_candle - 1 end end
return first_candle_index end
Рекомендую начать написание своего робота не в виде скрипта а в виде индикатора. Если будете торговать каким-то конкретным инструментом, то этого вполне достаточно, будет проще сделать работающий. ----------------- Кроме того, рекомендую писать не торговый робот, а торговый советник. Так будет меньше шансов слить свой счет. ----------------- Потом перепишите советник в робота, а затем если захотите большего -возьметесь за скрипты. -------------------- В итоге напишите все быстрее и качественнее.
Денис написал: Погуглив немного нашел кое-что похожее для определения нового бара. Подправил, сейчас переменная first_candle_index обновляет свой индекс как только появляется новая свеча. Но как это прикрутить для дальнейших вычислений, пока не допер. Тут на форуме нашел вот что, цитирую : SetUpdateCallback при смене индекса даст вам как раз момент открытия новой свечи. Вот как ее прикрутить к функции поиска индекса ниже? Или может есть другие методы какие?
function newbar() ds, error_desc = CreateDataSource("SPBFUT", "SiM3", INTERVAL_M1) local try_count = 0 while ds:Size() == 0 and try_count < 1000 do sleep(100) try_count = try_count + 1 end if error_desc ~= nil and error_desc ~= "" then message("Ошибка получения таблицы свечей:" .. error_desc) return 0 end
local today_day = tonumber(os.date("%m")) local current_candle = ds:Size() local max_candles = math.min(20, ds:Size()) local first_candle_index = nil
while first_candle_index == nil and current_candle > ds:Size() - max_candles do if tonumber(ds:T(current_candle).day) ~= today_day then
first_candle_index = current_candle - 1 end end
return first_candle_index end
Рекомендую начать написание своего робота не в виде скрипта а в виде индикатора. Если будете торговать каким-то конкретным инструментом, то этого вполне достаточно, будет проще сделать работающий. ----------------- Кроме того, рекомендую писать не торговый робот, а торговый советник. Так будет меньше шансов слить свой счет. ----------------- Потом перепишите советник в робота, а затем если захотите большего -возьметесь за скрипты. -------------------- В итоге напишите все быстрее и качественнее.
Так я, если честно, qLua в глаза второй раз вижу, я больше на питоне, амиброкер,... хотел работающего бота перевести на qLua на срочный рынок для попробовать, почти все перевел, уперся в этот блин новый бар (получить его закрытие/открытие, так как расчет баров ведется после закрытия текущего). Собственно qLua - это вопрос разового применения. Хотел из питона сразу в Квик - но увидев что там еще больше прокладок между кодом и биржей - забил на это дело.
Денис написал: Погуглив немного нашел кое-что похожее для определения нового бара. Подправил, сейчас переменная first_candle_index обновляет свой индекс как только появляется новая свеча. Но как это прикрутить для дальнейших вычислений, пока не допер. Тут на форуме нашел вот что, цитирую : SetUpdateCallback при смене индекса даст вам как раз момент открытия новой свечи. Вот как ее прикрутить к функции поиска индекса ниже? Или может есть другие методы какие?
function newbar() ds, error_desc = CreateDataSource("SPBFUT", "SiM3", INTERVAL_M1) local try_count = 0 while ds:Size() == 0 and try_count < 1000 do sleep(100) try_count = try_count + 1 end if error_desc ~= nil and error_desc ~= "" then message("Ошибка получения таблицы свечей:" .. error_desc) return 0 end
local today_day = tonumber(os.date("%m")) local current_candle = ds:Size() local max_candles = math.min(20, ds:Size()) local first_candle_index = nil
while first_candle_index == nil and current_candle > ds:Size() - max_candles do if tonumber(ds:T(current_candle).day) ~= today_day then
first_candle_index = current_candle - 1 end end
return first_candle_index end
Рекомендую начать написание своего робота не в виде скрипта а в виде индикатора. Если будете торговать каким-то конкретным инструментом, то этого вполне достаточно, будет проще сделать работающий. ----------------- Кроме того, рекомендую писать не торговый робот, а торговый советник. Так будет меньше шансов слить свой счет. ----------------- Потом перепишите советник в робота, а затем если захотите большего -возьметесь за скрипты. -------------------- В итоге напишите все быстрее и качественнее.
Так я, если честно, qLua в глаза второй раз вижу, я больше на питоне, амиброкер,... хотел работающего бота перевести на qLua на срочный рынок для попробовать, почти все перевел, уперся в этот блин новый бар (получить его закрытие/открытие, так как расчет баров ведется после закрытия текущего). Собственно qLua - это вопрос разового применения. Хотел из питона сразу в Квик - но увидев что там еще больше прокладок между кодом и биржей - забил на это дело.
Так все же просто в этом случае . Время свечи содержит счетчик тиков. Если счетчик меньше предыдущего то это открытие новой свечи. А предыдущая это последняя закрытая.
Станислав написал: Если использовать источником данных DataSource, то использовать SetUpdateCallback для получения информации о том, что появилась новая свеча можно.
При появлении новой свечи в OnDataSourceUpdate изменится index и время свечи, пример:
-- Функция вызывается при изменении свечки в таблице data_source -- OnDataSourceUpdate(TABLE data_source, STRING class_code, STRING sec_code, NUMBER interval, STRING param, NUMBER index) function OnDataSourceUpdate(ds, class_code, sec_code, interval, param, index) ... local datetime = ds:T(index)
end
...
local ds, error = CreateDataSource(class_code, sec_code, interval, param) if ds ~= nil then ds:SetUpdateCallback(function (...) OnDataSourceUpdate(ds, class_code, sec_code, interval, param, ...) end) end
Пробую прикрутить Ваш вариант, но чет не выходит, я уже и свой сократил, номера баров сыпет, время нет. Если раскомментирую --local datetime = ds:T(ndex) то квик дает ошибку.
stopped = false function OnStop() stopped = true return 3000 end
nikolz написал: Так все же просто в этом случае .Время свечи содержит счетчик тиков. Если счетчик меньше предыдущего то это открытие новой свечи. А предыдущая это последняя закрытая.
Нашел код где выводит время бара, время изменяется при открытии нового бара. Выдает в таком виде, это оно? sTime --1681312260
nikolz написал: Так все же просто в этом случае .Время свечи содержит счетчик тиков. Если счетчик меньше предыдущего то это открытие новой свечи. А предыдущая это последняя закрытая.
Нашел код где выводит время бара, время изменяется при открытии нового бара. Выдает в таком виде, это оно? sTime --1681312260
не время а счетчик тиков см док Функции O, H, L, C, V, T
Функции в качестве параметра принимают индекс свечи и возвращают соответствующее значение. Время свечи возвращается с точностью до миллисекунд в виде таблицы с полями:
Что-то счетчика тиков в чистоте я не обнаружил, в виде одной формулы (а я уж губы раскатал ) только готовые индикаторы видел где уменьшается время до закрытия свечи. Тики похоже надо получать и сравнивать. Вы хотите сказать, что часть блока тиков например из 500 штук на одной секунде времени может переходить на следующую секунду уже следующей минуты? Если так и есть, то видимо сравнивание тиков это то что нужно, посмотрю на днях, спасибо за наводку.
Вроде как нашел некий вариант в виде таблицы. Почти на финишной прямой :)) Код выгружает в таблицу номера баров быстрее чем таймфрейм 1М, визуально наблюдаю заполнение таблицы в реальном времени. И тут очередной тупик, не могу взять данные из ячейки для дальнейшего сравнения. Даже смог посчитать количество строк и столбцов. В документации одна строка про GetCell без примеров, перерыл пол интернета, попадались примеры но по аналогии у меня ничего не выходит. Вообще есть смысл использовать эту таблицу или просто кинуть данные эти в массив и дальше уже обычными методами?