Подскажите, пожалуйста, как получить значение минимума последней закрытой свечи.
У меня ещё очень мало опыта. Единственное, что делал, это скачал очень старый пример "Простой MA-робот.lua" и переписал его, чтобы он, наконец-то заработал. Пришлось переписывать неожиданно достаточно много. Сейчас хочу сделать себе другой пример, но чем больше пытаюсь понять как сделать, тем меньше понимаю, как. Алгоритм самый простой: выставить заявку по минимуму предыдущей свечи, через час изменить заявку на минимум нового закрытого часа, а если исполнится, то выставить заявку по максимуму последнего закрытого часа.
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 16:18:58
Насколько понимаю, ответ тут получить трудно. Может быть, тогда кто-нибудь подскажет адрес форума на котором могут помочь или на котором могут дать ссылку на подобные примеры?
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 16:40:46
Если вдруг кому-нибудь из тех, кто так же как и я, ничего не знает, вдруг так же как и мне захочется это узнать, то вот так: DS,Error = CreateDataSource('QJSIM', 'SBER', INTERVAL_H1); local Price = DS:H(1); message('Price: '..Price); H - здесь High, ещё есть L, O и т.д. (в документации).Теперь надо попытаться понять как убедиться, что это нужная мне, то есть, последняя закрытая свеча. А далее буду искать как через час изменить выставленную заявку по новому минимуму.
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 17:01:41
Цитата
Сергей написал: DS,Error = CreateDataSource('QJSIM', 'SBER', INTERVAL_H1); local Price = DS:H(1); message('Price: '..Price);
Это не моя последняя свеча, а вообще хрен знает какая, так как на графике этой цены даже близко нет. Буду искать дальше.
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2020 18:04:49
У объекта ds есть метод Size(), который вернет последний индекс бара. При этом закрытый он или нет надо проверять по времени. В большинстве случаев ds:Size() - это послдений текущий бар. Т.е. закрытый будет ds:Size().
А 1 - это будет первый бар. В Квике, в отличии от MT, нумерация от 1.
Также важно отметить, что получать поток данных через CreateDataSource надо делать один раз, сохранив его в переменную.
Все методы объекта ds описаны в документации к языку.
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 18:13:15
Спасибо большое за ответ! Вот этот момент не понял. Чем будет ds:Size(), текущим или закрытым?
Цитата
Nikolay написал: В большинстве случаев ds:Size() - это послдений текущий бар.Т.е. закрытый будет ds:Size().
Если я правильно понимаю мне в моём случае нужно писать так, да? DS,Error = CreateDataSource('QJSIM', 'SBER', INTERVAL_H1); local Last = math.max -- что-то там, что даст мне индекс последней полученной свечи local Price = DS:L(Last); message('Price: '..Price);
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2020 18:25:15
ds:Size() - это текущий бар. Но новый бар появляется только по совершению сделки. Допустим минутный бар. Он может быть уже по факту завершенным, т.е. уже началась новая минута. Но т.к. еще нет сделок в новом интервале, то нового бара (увеличения индекса) еще не будет.
Если алгоритм требует простого увеличения номера бара, то можно просто контролировать увеличение номера при получении ds:Size(). А если алгоритм требует совершения действий именно при наступлении нового временного интервала, то надо контролировать время сервера и время бара.
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2020 18:26:42
Цитата
Сергей написал: Если я правильно понимаю мне в моём случае нужно писать так, да? DS,Error = CreateDataSource('QJSIM', 'SBER', INTERVAL_H1); local Last = math.max -- что-то там, что даст мне индекс последней полученной свечи local Price = DS:L(Last); message('Price: '..Price);
Если задача получить последний бар (текущий), то это ds:Size()
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 18:31:30
Спасибо большое, Николай! Мне нужен закрытый, предыдущий. Сделал так: local Last = DS:Size()-1 local Price = DS:L(Last); Посмотрел цену, вроде бы, всё правильно.
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 18:53:17
Получается, что для того, чтобы мне получить последнюю свечу, мне нужно заново CreateDataSource, который заново создаёт таблицу. Ладно мне, для примера, допустим и раз в час достаточно , но если захочется обновлять данные каждую минуту, то это нормальное решение, создавать таблицу заново каждую минуту? Или после CreateDataSource уже не нужно его повторно запускать, а можно просто к индексу свечи добавлять единичку, чтобы получить данные по новой свече?
Пользователь
Сообщений: Регистрация: 30.01.2015
14.12.2020 19:12:14
Цитата
Сергей написал: Получается, что для того, чтобы мне получить последнюю свечу, мне нужно заново CreateDataSource, который заново создаёт таблицу. Ладно мне, для примера, допустим и раз в час достаточно , но если захочется обновлять данные каждую минуту, то это нормальное решение, создавать таблицу заново каждую минуту? Или после CreateDataSource уже не нужно его повторно запускать, а можно просто к индексу свечи добавлять единичку, чтобы получить данные по новой свече?
на газету "пионерская правда" подписываешься однажды. А попадает в почтовый ящик она сама собой, регулярно, волшебным образом.
Пасхалочка для Алексея Иванникова:
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 19:27:53
Цитата
написал: на газету "пионерская правда"
Ну да, наверное, смешно наблюдать, когда сам точно знаешь как это работает. У меня, в общем, не получается чего-то никак. Попробовал на минутном графике так: for i=1,10 do DS,Error = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL); local Space = ' _ '; local Last = DS:Size()-1; local Price = DS:L(Last); message('Price: '..Price..Space..Last); sleep(10000); end; Получается одна и та же цена, один и тот же индекс последней свечи. Так тоже пробовал: DS,Error = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL); for i=1,10 do
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2020 19:37:17
Подписываетесь на поток данных один раз
local ds, err = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL); if not ds then действия при ошибке end
Далее можете в бесконечном основном цикле просто тыкать в поток и проверять изменился ли ds:Size(). Для этого, естественно нужны переменная, где хранится прошлое значение. Можете ее глобальной сделать, можно через замыкаение все сделать, можно через класс, как угодно.
Если интервал минута, то индекс и будет увеличиваться раз минуту при наличии сделок, не раньше. Это же индекс временного интервала. Пока новый не наступил, чего ему увеличиваться.
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2020 19:40:25
Вот Вам документация и примеры
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 19:44:49
Nikolay, спасибо! Я вот попробовал сейчас так на минутном графике: DS,Error = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL); for i=1,10 do local Space = ' _ '; local Last = DS:Size()-1; local Price = DS:L(Last); message('Price: '..Price..Space..Last); sleep(20000); end; промежуток достаточно большой, цена точно менялась, но в моих принтах она одна и та же.
Сейчас подумал, что скорее всего неправильно то, что у меня это происходит в OnInit(), а не в main() и сам квик из-за этого на этом цикле висит, пока цикл не отработает.
Пользователь
Сообщений: Регистрация: 14.12.2020
14.12.2020 19:46:54
Да, переместил в main(), вижу работает правильно.
Пользователь
Сообщений: Регистрация: 30.01.2015
19.12.2020 07:23:54
if DS==nil then DS,Error = CreateDataSource(CLASS_CODE, SEC_CODE, INTERVAL); end