Задача: рассчитать индикатор по данным с графика. Устанавливаем колбек CreateDataSource(ClassCode, SecCode, Interval):SetUpdateCallback(fCB). В ответ приходят данные всех свечей с графика, по которым заполняем таблицу Candles[index].
Но! Если открыт график по данной бумаге, то в колбек приходят только данные с момента установки колбека.
Решение? (getCandlesByIndex не интересует)
Надо делать так, как надо. А как не надо - делать не надо.
извиняюсь за оффтоп, конечно но, думаю пора уже завязывать с квиком и клуой. бо как даже такой "корифей", как михаил булычев - всё чаще начал убегать "в кусты".
Серж пишет: Задача: рассчитать индикатор по данным с графика. Устанавливаем колбек CreateDataSource(ClassCode, SecCode, Interval):SetUpdateCallback(fCB). В ответ приходят данные всех свечей с графика, по которым заполняем таблицу Candles[index].
Но! Если открыт график по данной бумаге, то в колбек приходят только данные с момента установки колбека.
Решение? (getCandlesByIndex не интересует)
Код
ds = CreateDataSource (ClassCode, SecCode, Interval)
for i = 1, ds:Size() do -- не уверен, что тут нумерация начинается с 1, а не с 0
Candles[i] = ds:C(i)
end
ds = CreateDataSource (ClassCode, SecCode, Interval)
for i = 1, ds:Size() do -- не уверен, что тут нумерация начинается с 1, а не с 0
Candles[i] = ds:C(i)
end
А потом продолжать брать данные из колбека.
Да, я совсем забыл, что CreateDataSource возвращает таблицу data_source :)
Цитата
Дмитрий пишет: не уверен, что тут нумерация начинается с 1, а не с 0
Тут нумерация идёт с 1. Только я написал:
Код
ds = CreateDataSource (ClassCode, SecCode, Interval)
repeat sleep(1) until ds:Size() ~= 0 -- тут надо поиграть с задержкой
for i = 1, ds:Size() do
Candles[i] = ds:C(i)
end
Надо делать так, как надо. А как не надо - делать не надо.
Дмитрий пишет: А есть способ получать данные свечей с графика, не сохранив ни в какой переменной таблицу data_source, которую возвращает CreateDataSource ?
Здравствуйте, Без таблицы это значит на прямую с графика. Для этого есть функция getCandlesByIndex.
sam063rus пишет: извиняюсь за оффтоп, конечно но, думаю пора уже завязывать с квиком и клуой. бо как даже такой "корифей", как михаил булычев - всё чаще начал убегать "в кусты".
Я тоже извиняюсь, но в этой ветке я ничего не писал еще. Есть какие-то вопросы?
Серж пишет: ds = CreateDataSource (ClassCode, SecCode, Interval) repeat sleep(1) until ds:Size() ~= 0 -- тут надо поиграть с задержкой for i = 1, ds:Size() do Candles = ds:C(i) end
Дмитрий пишет: А есть способ получать данные свечей с графика, не сохранив ни в какой переменной таблицу data_source, которую возвращает CreateDataSource ?
Здравствуйте, Без таблицы это значит на прямую с графика. Для этого есть функция getCandlesByIndex.
Я имел в виду без использования getCandlesByIndex, а именно после вызова CreateDataSource и SetUpdateCallback. Я подумал, что Серж, возможно, как-то получает эти данные внутри колбэка, не сохраняя при этом в переменной таблицу data_source, которую вернула функция CreateDataSource.
Николай Камынин пишет: надо не со sleep играть, а колбек использовать.
Да, вы правы. С помощью CreateDataSource получаем уже загруженные на текущий момент данные, а в колбеке новые:
Код
function OnInit(script_path)
ds = CreateDataSource(ClassCode, SecCode, Interval)
local function GetPrice(index)
for i = 1, ds:Size() do
Candles[i] = ds:C(i)
end
end
ds:SetUpdateCallback(GetPrice)
end
Правда, чтобы между for i = 1, ds:Size() do и ds:SetUpdateCallback ничего не потерять пришлось запихать это всё в OnInit. А поскольку функция CreateDataSource работает очень медленно, при большом количестве запрашиваемых бумаг/интервалов получаем нехилую задержку на старте. :(
Цитата
sam063rus пишет: а можно поинтересоваться для чего это?
Чтобы рассчитать индикатор. Любой, даже тот что уже есть в QUIK. Мы можем поступить двумя способами:
1) Открыть график по интересующей бумаге, выставить нужный таймфрейм, наложить индикатор, задав нужные параметры. И с помощью getCandlesByIndex получать значения индикатора с графика. Ах, да, забыл: надо задать ещё идентификатор графика. При большом числе бумаг/таймфреймов/параметров индикатора эту процедуру нужно проделывать множество раз.
2) Вариант второй. Написать один раз скрипт для получения цен по любой бумаге/таймфрейму и расчёта индикатора, как функции от параметров. И применять без необходимости открывать сам график.
Если нужного индикатора в QUIK нет, то остаётся только вариант 2.
Надо делать так, как надо. А как не надо - делать не надо.
function OnInit(script_path)
local function GetPrice(index)
Candles[index] = ds:C(index)
end
ds = CreateDataSource(ClassCode, SecCode, Interval)
for i = 1, ds:Size() do
Candles[i] = ds:C(i)
end
ds:SetUpdateCallback(GetPrice)
end
Иначе коллбэк будет вместо обновления данных при каждом вызове полностью сканировать источник данных от самого начала до конца.
А описание функции GetPrice(index) поместил на всякий случай впереди, чтобы интерпретатор Луа не тратил время на разбор ее описания между окончанием чтения источника данных и установкой коллбэка.
Есть еще правда ненулевая вероятность того, что пока будет выполняться цикл for i = 1, ds:Size() do с сервера успеют поступить новые свечи, которые не были учтены ранее в ds:Size(). Поэтому ds:SetUpdateCallback(GetPrice) наверное лучше поместить до цикла чтения свечей из источника данных.
Дмитрий пишет: По-моему, правильней было бы написать так
Да, при перепечатывании на форум "накосячил". Надо так:
Код
function OnInit(script_path)
ds = CreateDataSource(ClassCode, SecCode, Interval)
local function GetPrice(index)
Candles[i] = ds:C(i)
end
for i = 1, ds:Size() do GetPrice(index) end
ds:SetUpdateCallback(GetPrice)
end
ds должна быть объявлена до её использования в функции GetPrice
Цитата
Дмитрий пишет: Поэтому ds:SetUpdateCallback(GetPrice) наверное лучше поместить до цикла чтения свечей из источника данных.
У меня в функции GetPrice, помимо получения цены, идёт ещё расчёт значений индикатора, которые должны вычисляться по порядку.
Цитата
Дмитрий пишет: Есть еще правда ненулевая вероятность того, что пока будет выполняться циклfor i = 1, ds:Size() doс сервера успеют поступить новые свечи, которые не были учтены ранее в ds:Size().
Поэтому я и поместил всё это дело в OnInit. В этом случае колбеки будут вызываться только после выхода из функции OnInit.
Надо делать так, как надо. А как не надо - делать не надо.
function OnInit(script_path)
ds = CreateDataSource(ClassCode, SecCode, Interval)
local function GetPrice(index)
Candles[index] = ds:C(index)
end
for i = 1, ds:Size() do GetPrice(i) end
ds:SetUpdateCallback(GetPrice)
end
Надо делать так, как надо. А как не надо - делать не надо.
Серж пишет: колбеки будут вызываться только после выхода из функции OnInit
А где об этом написано? Или это следует из того, что OnInit и колбеки выполняются в основном потоке терминала, поэтому пока не отработает OnInit ничего другое выполняться не будет?
И, насколько я понимаю, в вашем варианте для новых свечей, которые успеют добавиться в источник данных за время от начала до конца работы цикла, колбэк уже не будет вызван никогда, т.е. они выпадут из обработки.
1) колбек не может ничего сканировать. по определению -это функция,которая вызывается при наступлении события. в данном случае - это событие - получение новых исторических данных с сервера, которые дописываются к существующим данным. ------------------ 2) Таким образом, колбек позволяет обнаружить приход новых данных, а не ждать их. Осуществлять обработку при поступлении новых данных.
Дмитрий пишет: А где об этом написано? Или это следует из того, что OnInit и колбеки выполняются в основном потоке терминала, поэтому пока не отработает OnInit ничего другое выполняться не будет?
OnInit и колбеки выполняются последовательно в основном потоке терминала, поэтому пока не отработает одна функция остальные свою работу не начнут.
Цитата
Дмитрий пишет: И, насколько я понимаю, в вашем варианте для новых свечей, которые успеют добавиться в источник данных за время от начала до конца работы цикла, колбэк уже не будет вызван никогда, т.е. они выпадут из обработки.
Где-то тут на форуме сотрудники техподдержки отвечали, что, если один колбек выполняется длительное время, то остальные колбеки встают в очередь и после завершения первого продолжают обрабатываться.
Но вот вопрос, который требует разъяснения: Поскольку колбек регистрируется после полного выполнения цикла for i = 1, ds:Size() не получится ли так, что те изменения свечей, что поступят в терминал во время этого цикла, действительно не вызовут колбека?
Поэтому я соглашусь с вами:
Цитата
Дмитрий пишет: Поэтому ds:SetUpdateCallback(GetPrice) наверное лучше поместить до цикла чтения свечей из источника данных.
Всё равно таблица Candles по старым свечам в OnInit будет заполнена до вызовов колбеков.
Надо делать так, как надо. А как не надо - делать не надо.
1) читаем документацию: OnInit Функция вызывается терминалом QUIK перед вызовом функции main(). 2) Чтобы ничего цикл можно поставить в колбеке будет нечто такое: -------------------------- local ind_old=1 function cd() local size=ds:Size() for i = ind_old, size do Candles[i] = ds:C(i) end ind_old=size end
не знаю, спрашивал ли кто до этого - поэтому спрошу сейчас: есть функции CreateDataSource и SetUpdateCallback (как я понял - это альтернатива OnCandle, предложенная ранее одним из пользователей). Вопрос: Создаётся ли под новый источник отдельный поток ОС, как это делается в квике при экспорте в ту или иную систему теханализа?
Добрый день. сама qlua.dll поток не создает. Если Вы используете это где-то в своих собственных библиотеках, то лучше всего сделать их потокобезопасными.
тут много говрилось о какой-то особой "магии" этой функции, что я даже грешным делом подумал, что под её функционал создаётся отдельный поток. Потом - понял, что её также можно с эмулировать на основе коллбеков и классовой обёртки, как это сделано у вас. Понятное дело, что свои данные она реально получает не из коллбеков OnAllTrade или OnParam - она лишь следит каждый цикл выполнения скрипта за обновлёнными данными и вызывает свой коллбек.
Michael Bulychev пишет: Она не следит, а получает с сервера уже готовые посчитанные интервалы
Значит, если нужно получить только свечки графика, сформированные до вызова CreateDataSource, а сформировавшиеся или изменившиеся после этого свечи нас не интересуют, то ни SetUpdateCallback, ни SetEmptyCallback() использовать нет надобности?
Раз уж тут у нас получился "Вечер откровений" касательно работы функции CreateDataSource, то предлагаю вернуться к проблеме (CQ01544135), когда CreateDataSource не заказывает данные параметров с сервера, как изначально планировалось. Предлагаю создать новую функцию, предназначенную непосредственно для заказа параметров бумаг, аналог меню "Связь - Списки...", и не завязывать получение этих параметров на CreateDataSource.
Т.е., если нужно получить только последнее значение параметра (без истории) через getParamEx или колбек OnParam, то заказывать данные с помощью новой функции. Если нужна истории параметров, то CreateDataSource.
Надо делать так, как надо. А как не надо - делать не надо.
Старатель пишет: Раз уж тут у нас получился "Вечер откровений" касательно работы функции CreateDataSource, то предлагаю вернуться к проблеме (CQ01544135), когда CreateDataSource не заказывает данные параметров с сервера, как изначально планировалось. Предлагаю создать новую функцию, предназначенную непосредственно для заказа параметров бумаг, аналог меню "Связь - Списки...", и не завязывать получение этих параметров на CreateDataSource.
Т.е., если нужно получить только последнее значение параметра (без истории) через getParamEx или колбек OnParam, то заказывать данные с помощью новой функции. Если нужна истории параметров, то CreateDataSource.
sam063rus пишет: Предлагаю сначала "решить вопрос с галками"
А что не так с галками? Галка, о которой речь ("Получать информацию по всем сделкам с текущего момента") призвана уменьшить трафик, если вы подключаетесь в течение торговой сессии, т.е. "старые" сделки в терминал не приходят. Как вы хотите получать данные этих сделок в скрипте?
Цитата
sam063rus пишет: Очевидно, чтоб докопаться до того где и главное, ЧТО это за "CQ01544135"
Очевидно, это предложение было адресовано не вам, а разработчикам.
И, да, вернёмся к первоначальному вопросу темы:
Код
function OnInit(script_path)
ds = CreateDataSource(ClassCode, SecCode, Interval)
-- тут приходят данные (1)
local function GetPrice(index)
Candles[index] = ds:C(index)
end
ds:SetUpdateCallback(GetPrice)
-- тут приходят данные (2)
for i = 1, ds:Size() do GetPrice(i) end
-- тут приходят данные (3)
end
Куда попадут данные (1), (2) и (3)?
Надо делать так, как надо. А как не надо - делать не надо.
я к тому, что галки (высказываю своё личное мнение) - должны влиять лишь на интерфейс но, когда они также влияют на скрипты - начинается хаос, а всего-то надо - пропустить или забыть одну из них поставить. насчёт CQXXXXXX: я не старался на вас "наезжать" по этому поводу. Так что извиняюсь. Это сигнал разработчикам, что если они в темах ссылаются на подобные "тикеты" - то пусть будут добры, как говорится "огласить весь список пожалуйста". Но разумеется, они это делать не собираются (как неоднократно у них выяснялось.) -> так пусть, значит и не ссылаются. Также это сигнал и другим пользователям - не стоит указывать то, что весьма трудно найти (а порой и вовсе невозможно) на форуме.
я к тому, что галки (высказываю своё личное мнение) - должны влиять лишь на интерфейс но, когда они также влияют на скрипты - начинается хаос, а всего-то надо - пропустить или забыть одну из них поставить. насчёт CQXXXXXX: я не старался на вас "наезжать" по этому поводу. Так что извиняюсь. Это сигнал разработчикам, что если они в темах ссылаются на подобные "тикеты" - то пусть будут добры, как говорится "огласить весь список пожалуйста". Но разумеется, они это делать не собираются (как неоднократно у них выяснялось.) -> так пусть, значит и не ссылаются. Также это сигнал и другим пользователям - не стоит указывать то, что весьма трудно найти (а порой и вовсе невозможно) на форуме.
CQ01544135 нормально ищется в поиске. и вообще - чтобы что-то требовать надо из себя хоть что-то представлять, Ты кто такой? Давай...кинь ссылку на любой другой форум где такой умный и требовательный, клавитурный рэмбо )
sam063rus пишет: Это сигнал разработчикам, что если они в темах ссылаются на подобные "тикеты" - то пусть будут добры, как говорится "огласить весь список пожалуйста". Но разумеется, они это делать не собираются (как неоднократно у них выяснялось.) -> так пусть, значит и не ссылаются. Также это сигнал и другим пользователям - не стоит указывать то, что весьма трудно найти (а порой и вовсе невозможно) на форуме.
Клиент брокера? Свои умозаключения туда. Крутой? Колбась на своём сервере квика, требуй с квика. Брокер? Раздавай рекомендации своим клиентам что и где публиковать...
Вас уже спрашивали на тему кто Вы? То Вы пользователь квика, то не пользователь, то вы публично сами себя обзываете последними словами, то Вам мерещется, что я пользователь с ником Nikolz. Вы в себе сначала разберитесь, а то, чувствую, у Вас с адекватностью не всё в порядке. Возможно Вам к доктору?
Люди не меняются, они как строчили по 10-15 сообщений в день на этом форуме под определёнными никами, так и остаётся годами, что бы ты не делал чтобы тебя не просчитали.... там где ты наивный плохо учился шифроваться....гасись дальше ущербный
Правильно - Не буду. Если в моих репликах не видишь аллегории и попытки разрядить обстановку - всего лишь ограниченность и однообразность мышления. Моё личное мнение - вымораживаешь своей требовательностью и диктовкой кому как и чего....уверен что в жизни ты не более чем серая мышь в очках.