Closed avently closed 4 years ago
Не очень понятно, в чем суть Вашего предложения (возможно, только для меня). Если я правильно Вас понял, то если мы сразу не получили от квика набор данных по свечам, то функция должна завершить свою работу и вернуть пользователю пустой результат. Если это так, то в этом случае мы никогда никаких данных по свечам получить не сможем. Объем запрашиваемых на сервере данных достаточно большой, и системе требуется время на его получение. Как Вы предлагаете "пропустить"то время которое требуется совокупности "приложение-коннектор-терминал-интернет-сервер" на получение данных?
@Pr0phet1c
Если это так, то в этом случае мы никогда никаких данных по свечам получить не сможем
Ну почему же. Квик же кэширует данные, и если повторно запросить информацию после завершения по таймауту, то данные уже будут готовы. Если данные в кэше, то они отдаются за миллисекунду. Считаю такой подход наилучшим вариантом.
Как Вы предлагаете "пропустить"то время которое требуется совокупности "приложение-коннектор-терминал-интернет-сервер" на получение данных?
Никак. Установить таймаут. Если данные не пришли, выкинуть ошибку. Юзер повторит еще раз, а пока он не повторит, другие запросы смогут исполнится успешно. И так по кругу до результата
Это означает, что Вы ВСЕГДА будете получать ошибку при первом вызове этой функции по каждому инструменту и каждому ТФ. Даже не знаю. Надо хорошенько подумать. Я, например, запрашиваю исторические данные, по нескольким десяткам инструментов, и по нескольким ТФ для каждого из них. Да, ждать приходится несколько минут, пока все данные будут получены и прогружены. Но если я получу ошибку, то робот тут же попытается переподписаться на все эти данные заново (т.к. будет считаться что подписка прошла неудачно), и теоретически это может привести к перезаказу данных, со всеми вытекающими последствиями. Хотя, вероятно, это надо проверять. Функцию писал не я, но я пока не нашел более адекватного варианта ее исполнения.
ВСЕГДА будете получать ошибку при первом вызове
Не страшно при первом вызове получать ошибку. Страшно не получать ответы от важных функций и не иметь возможности отменить ордер или ещё чего. Ну и наблюдать, как в программе ничего совершенно сделать нельзя в тот момент, когда луа зависла - такое себе удовольствие.
Можете привести пример того, как Вы видите реализацию этой функции?
Кстати, повнимательней изучив, я пришел к выводу, что именно эту функцию, я никогда не использую. Я применяю подписку на получение свечей. Там механика немного другая. Вы не пробовали пойти таким путем?
Можете привести пример того, как Вы видите реализацию этой функции?
Я этот код не тестировал, но примерно так можно реализовать:
local counter = 0
--- датасорс изначально приходит пустой, нужно некоторое время подождать пока он заполниться данными
-- если данные не придут через три секунды, возвращает nil вместо данных
while (ds:Size() == 0 and counter < 3000) do
sleep(1)
counter = counter + 1
end
if (ds:Size() == 0) then
msg.data = nil
ds:Close()
return msg
end
Я применяю подписку на получение свечей.. Вы не пробовали пойти таким путем?
У меня торговый терминал, в котором можно открыть много вкладок и много графиков с разными таймфреймами. Собирать по крупицам колбэки OnNewCandle (если вы об этом способе говорите) просто неудобно и нецелесообразно. Именно так бы я и поступил, если бы данные от биржи я получал по веб сокету, а не через Quik (который их хранит локально за меня). К тому же, мне нужно еще запрашивать счечи по 500 штук, скажем. Чтобы график можно было скроллить влево. Проще раз в минуту получать обновленные свечи, чем все это вот.
Что касается Вашего примера: Если этот кусок кода предполагается встроить внутрь указанной процедуры, то скорее всего, в тех случаях, когда получение исторических данных занимает больше 3-х секунд - Вы не получите их буквально никогда, т.к. после первого возврата nil, Ваш робот пошлет новый запрос на запуск той же самой функции, что в свою очередь приведет к обнулению ds и запуску процесса получения данных с самого начала. Что касается подписки: Мне кажется это все же более предпочтительный путь. Другое дело, что я сейчас понял, что у нас нет функции, позволяющей не следить за колбэками после подпииски, а просто вытащить набор свечей из данных, на которые мы подписались. Эту задачку действительно стоит решить.. Надо подумать на досуге о ее реализации
Как насчет coroutines? https://www.lua.org/pil/9.1.html
Это фича языка и не требует реальной многопоточности, но может в Квике не будет работать. Мы можем сделать это на уровне диспетчера: если функция X - в свою корутину, остальные в свою. Вместо Sleep - yield.
Это будет самый чистый/правильный подход, но не самый простой.
Как насчет coroutines?
Забавно, только сейчас смотрел справку по Lua и увидел там корутины. Подумал, почему же lua часть не сделана на них, чтобы не приходилось синхронно работать с сокетом. Идея хорошая, но понятия не имею, как lua справится с этой задачей и какие будут ограничения. Например, неясно, как там устроена работа с несколькими потоками.
Это будет самый чистый/правильный подход, но не самый простой.
В чем сложность такого подхода? Был опыт работы с корутинами на Lua?
Кстати, насчет синхронности работы с сокетом. Это у меня криво написана реализация или lua код не приспособлен для асинхронного приема и обработки сотен собщений сразу? Пытался как-то ускорить получение данных, но 10 секунд иногда не хватает, чтобы получить по сокету ответ в случае, если сотни запросов сразу. То есть часть приходит, а часть ответов - теряется.
Почему не сделано Х
Изначально (в 2014) цель была автоматизация, а не оптимизация, и use case - замена ручной торговли, а не быстрые роботы. Да и глубоких познаний в Луа не было. Предполагалось, что если нужна скорость, но нужно использовать не Квик.
Как я понимаю, корутины и multithreading - разные вещи. Чтобы корутины работали, нужна кооперация: без yield другие рутины не получат возможности работать. Там нет планировщика, который бы давал возможность каждой рутине исполниться по timeslice.
Ускорить работу наверное можно с помощью batching: получить все доступные линии из сокета и обработать, потом посылать in non-blocking manner. Но нужно будет обрабатывать ошибки если сокет занят. Проще новый транспорт прикрутить, возможно ZMQ неплохая идея в итоге, учитывая, что все равно пришлось всё компайлить самому.
Я пока не собираюсь кардинально что-то менять. Не уверен, что асинхронный транспорт решит проблему при однопоточной исполнении запросов в Lua, которая при этом вызывает синхронные функции Квика.
Как я понимаю, корутины и multithreading - разные вещи.
Обычно да. Но в Kotlin Coroutines упростили старт задачи в разных потоках. Может, и тут так можно.
Я пока не собираюсь кардинально что-то менять.
Аргументы понятны. А что делать с данным issue?
Можно попробовать корутины для этой функции и остальных функций на уровне диспетчера. Или изначальное предложение с пустым ответом и retry.
Если корутины работают в одном потоке в Квике, можно подумать о дальнейших оптимизациях.
Самое простое решение асинхронности - большой буффер сокета и non-blocking send/receive. Нужно будет обратаывать socket busy ошибку и не понятно, возможно ли это всё в Луа. Если да, то корутины тут идеально подходят - если сокет занят, yield в этот момент. Когда все корутины закончили работу
Pull requests на эту тему welcome.
Но тема совсем не простая, чтобы это довести до ума потребуется не мало времени, которого бесплатного сейчас у меня нет.
И такие изменения уже не будет наверное open source, учитывая с какой охотой QUIK# используют коммерческие проекты, не ставят ссылку и не приносят улучшения обратно сюда.
Интересно, готовы ли люди платить подкиску или разово за быстрый коннектор и техническую поддержку?
On Fri, Jun 5, 2020 at 11:38 AM avently notifications@github.com wrote:
Как я понимаю, корутины и multithreading - разные вещи.
Обычно да. Но в Kotlin Coroutines упростили старт задачи в разных потоках. Может, и тут так можно.
Я пока не собираюсь кардинально что-то менять.
Аргументы понятны. А что делать с данным issue?
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/finsight/QUIKSharp/issues/252#issuecomment-639371328, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADXS7FUFELHR4KEYDMBOYTRVC4INANCNFSM4NSNLH6Q .
Pull requests на эту тему welcome
Если от меня, то очень не скоро, работы море. С этим Квиком приходится половину архитектуры приложения переделывать... Я думаю, если идти предложенным вами путем, то надо хотя бы провести сначала тесты - стоит ли овчинка выделки вообще. Может, профита в плане скорости не добьемся.
Можно попробовать корутины для этой функции и остальных функций на уровне диспетчера. Или изначальное предложение с пустым ответом и retry.
А можете хотя бы для этой функции протестировать свою идею с корутинами, когда будет время? Если не получится, то уже пусть будет while с таймаутом, как я предложил. Только надо, чтобы именно nil отправлялся, а не []. Чтобы знать наверняка, что данные есть, но не получены еще.
И такие изменения уже не будет наверное open source. Интересно, готовы ли люди платить подкиску или разово за быстрый коннектор и техническую поддержку?
Не знаю насчет остальных, но я бы в таком случае делал свой велосипед. Но это я. Потому что мне проще сделать самому, чем использовать закрытую библиотеку в таком ответственном деле. Все таки делаю для пользователей, рисковать их деньгами не буду.
Вы делаете платный продукт неограниченному кругу или под заказ что-то?
On Fri, Jun 5, 2020, 12:13 PM avently notifications@github.com wrote:
Pull requests на эту тему welcome
Если от меня, то очень не скоро, работы море. С этим Квиком приходится половину архитектуры приложения переделывать... Я думаю, если идти предложенным вами путем, то надо хотя бы провести сначала тесты - стоит ли овчинка выделки вообще. Может, профита в плане скорости не добьемся.
Можно попробовать корутины для этой функции и остальных функций на уровне диспетчера. Или изначальное предложение с пустым ответом и retry.
А можете хотя бы для этой функции протестировать свою идею с корутинами, когда будет время? Если не получится, то уже пусть будет while с таймаутом, как я предложил. Только надо, чтобы именно nil отправлялся, а не []. Чтобы знать наверняка, что данные есть, но не получены еще.
И такие изменения уже не будет наверное open source. Интересно, готовы ли люди платить подкиску или разово за быстрый коннектор и техническую поддержку?
Не знаю насчет остальных, но я бы в таком случае делал свой велосипед. Но это я. Потому что мне проще сделать самому, чем использовать закрытую библиотеку в таком ответственном деле. Все таки делаю для пользователей, рисковать их деньгами не буду.
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/finsight/QUIKSharp/issues/252#issuecomment-639387120, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADXS7COV42G6ZCX4HM6BETRVDAMDANCNFSM4NSNLH6Q .
@buybackoff условно-бесплатная программа для Google Play, компа (пока что в виде консольного приложения). Потом другие платформы будут. Но пока так. На заказ ничего, связанного с Квиком, не делаю.
@avently
Не знаю насчет остальных, но я бы в таком случае делал свой велосипед. Но это я. Потому что мне проще сделать самому, чем использовать закрытую библиотеку в таком ответственном деле.
Поэтому ничего принципиального нового без pull requests тут скорее всего не будет. Какая причина тратить часы своего времени на это за бесплатно?
Для @Pr0phet1c функционал текущий подходит, если что - он для себя может поправить. Других активных контрибьютеров в последнее время не было.
Какая причина тратить часы своего времени на это за бесплатно?
Такая же причина, которая привела к созданию библиотеки QuikSharp. У каждого она своя. Мне бы на вашем месте было бы ценно получить прирост в производительности своего творения. Потому как корутины реально можно применить для увеличения производительности и параллелизации, ну и новые знания/мысли. Просто если есть время, то этот процесс может быть ценным. А если нет, то ничего интересно не будет. Я вот сам люблю законтрибьютить код, когда есть свободное время и потребность в функционале.
Классно, когда люди делают открытые проекты. Жалко, что зарабатывать на них неясно как, а время жизни человека ограничено. Так бы сутками код писал.
Мне бы на вашем месте было бы ценно получить прирост в производительности своего творения. Потому как корутины реально можно применить для увеличения производительности и параллелизации, ну и новые знания/мысли.
Lua кроме Квика мне встречалась в Redis (атомарные транзакции любой сложности очень удобно, если это нужно), в NginX, как встроенная БД, Kong целиком написал на Луа. За исключением последнего, везде это встроенный язык для быстрых однопоточных скриптов. Использовать Луа для построения системы целиком нецелесообразно, её сила во встроенности с интеграции с C, а не в языке и его фичах.
В случае с Квиком интереснее будет написать что-нибудь на Rust, скомпилировать как cdylib и вызывать из Луа C API. Это если говорить про спортивный интерес программирования ради новых знаний.
У меня есть куда тратить время: https://github.com/Spreads/Spreads и https://github.com/DataSpreads/DataSpreads. Интересно, что первая работала нормально для определенных целей уже 6 лет назад, а попытка "сделать лучше" 2 года назад завела в тупик. Вторая тоже работала 1,5 года назад, но зависит от первой, и тоже вторая итерация для исправления всего, что было выявлено в первой, оказалась очень большой с т.з. требуемого времени.
Так что не сломалось - не чини.
А я больше не в России и мне Квик не актуален сейчас совсем.
Review пулл реквестов, решение тупиковых проблем (как с 8.5) и релиз версий - это максимум, что я могу этому проекту уделять. @Pr0phet1c уже давно делает больше, чем я, для него.
Про корутины я просто вставил свои 2 цента из чисто программерского интереса.
Функция
get_candles_from_data_source
из lua кода фризит весь сокет на оооочень длительное время. Пока она исполняется, все остальные запросы к lua серверу истекают по таймауту. Я добавил логи в эту функцию, чтобы отловить баг и увидеть, насколько все плохо. Как всегда, если есть вечныйwhile
(в данном случаеrepeat
) - жди беды. Виновник тут: https://github.com/finsight/QUIKSharp/blob/master/src/QuikSharp/lua/qsfunctions.lua#L689С выводом логов получилась такая функция:
И результат исполнения функции:
2020-06-04 11:40:07.585 LOG 0: Inside candles request 2020-06-04 11:40:07.585 LOG 0: Created data source 2020-06-04 11:40:07.585 LOG 0: No error while creating 2020-06-04 11:41:09.612 LOG 0: After sleep
Такое бывает нечастно, но бывает. И все рушится на время простоя, все запросы фэйлятся по таймауту. И не удивительно, минуту ожидания в данном случае.
Причина такого поведения, видимо, никудышный интернет, который может перестать работать на минуту-другую. Но в других приложениях я такого "перерыва" не замечал. Возможно, брокерский сервер тупит и отсоединяет Квик временно. Хотелось бы как-то избавится от этого бага. Возможно, сделать внутренний таймаут на пару-тройку секунд до получения результата подписки на свечи, а если нет результата, то отправить null или пустой массив в ответ. А не просто фризить вечно.