Albert Eritsyan написал: Данная опция обеспечит возможность расположения этих файлов на HDD, в то время как программа сама будет находиться на SSD (чтобы не затирать SSD временными большими файлами).
Странное желание. Основное время запуска QUIK (а только это время волнует пользователя) занимает как раз чтение файлов с накопленными данными. Если у вас нет места на SSD - просто перенесите весь QUIK на HDD. Ну если вы готовы мириться с упавшей от этого скоростью запуска терминала.
Дада, снижение траффика - это как раз путь уменьшения размера служебных файлов. А если вы считаете, что все, что вы получаете, вам требуется - то тогда и служебные файлы будут вот такими, да.
Не должно быть никакой привязки к визуальной таблице Должен быть чисто программный интерфейс на манер CreateDataSouce c последующим вызовом call-back функции на каждую новость. И API перебора всех уже имеющихся новостей.
Roman Azarov написал: Как уже было сказано ранее, такова реализация работы OnStop() на текущий момент, это не является ошибкой.
Ограничения, не указанные в документации - есть ошибка.
Цитата
Roman Azarov написал: Просьба более подробно описать, как Вы хотели бы видеть логику работы функции в данном месте. Готовы зарегистрировать пожелание на доработку.
Регистрируйте. 1. В документацию включить список функций, которые нельзя вызывать из OnStop() по каким-либо причинам, как нарушающие корректность выполнения программ Lua или работу терминала. 2. После этого у вас будет список функций с ограничением по функционалу. Очевидно, далее следует работать над уменьшением размера этого списка, т.е. надо добавлением возможности всё же вызывать функции из этого списка из OnStop() (c постепенным удалением таковых функций из данного неприятного списка).
Sergey написал: У меня есть основной скрипт и еще несколько дополнительных, которые основной подключает через requare. Все скрипты расположены в отдельной папке но не внутри директирии QUIK (так нужно).
Указывайте полный путь к скриптам, тогда они всегда будут находиться. Как - см. выше
Я бы откопировал нужное количество Trans2QUIK.dll с разными именами или разными каталогами и подключал бы их динамически, указывая для каждого экземпляра свой путь до QUIK при вызове TRANS2QUIK_CONNECT
Roman Azarov написал: В текущей реализации, экспорт таблицы текущих торгов возможен только средствами DDE (не обязательно в Excel) и ODBC. Можем зарегистрировать пожелание на возможность экспорта в текстовый файл. Регистрируем?
Зарегистрируйте другое пожелание. Из ТТТ должен открываться таблица, отображающая соответствие названий параметров и их "формальное название". Тогда каждый сам легко и наглядно сможет это соответствие увидеть без всяких DDE и экселов. С обязательной возможностью копирования данных из такой таблицы!!! чтобы не приходилось перепечатывать названия параметров.
Вам в этом случае не придется поддерживать актуальность документации, просто отпадает надобность в документировании.
TGB написал: 1. Непонятно, почему таблицы QUIK обслуживаются в основном потоке обработки колбеков. В чем проблема сделать обслуживание таблиц QUIK в отдельном специальном для этого потоке?
Это как раз понятно: лезть в объекты интерфейса Windows и связанных с этим собственных структур данных из разных потоков - слишком сложная замута. Потому её всегда избегают.
Цитата
TGB написал: а все работу по завершению скрипта пользователя выполнять в потоке main.
Сам себя поток прибить не может. Должен кто-то "извне".
Цитата
TGB написал: 2. Зачем завершение скрипта пользователя выполняется в потоке обработки колбеков?
Не совсем так. Очевидно, что написан обычный стандартный код (который выполняется в основном потоке):
Код
вызвать OnStop()
подождать завершения потока main() или таймера на 5 сек <<-- вот тут проблема
if сработал таймер -> прибить поток для main()
Т.к. идет просто ожидание без процессинга очереди сообщений Windows и прочих действий - то и получаем, что и терминал в это время висит, и функции, которые через основной поток выполняются, не рабтают.
Положим как-то мы сформировали свечи для нестандартных TimeFrame Вопрос: есть ли возможность как-то их отрисовать штатными средствами QUIK, через Lua-индикаторы, например? Я не сумел придумать как это сделать. Ведь на графиках, на которые накладываются индикаторы, есть возможность выбирать только стандартные TimeFrame. Но может есть какие-то другие варианты?
Andrey Bezrukov написал: Описываемое Вами поведение, формально, не является проблемой или ошибкой в работе lua-скриптов в терминале.
Это несоответствие описанного в документации поведения программы, в значит - ошибка. Плюс, конечно, совершенно кривая и топорная реализация ожидания завершения main(), когда (из документации)
Цитата
"РМ QUIK может некоторое время находиться в «подвисшем» состоянии"
Итак, открываем документацию, файл "Использование Lua в Рабочем месте QUIK.pdf".
На картинке "Событийная модель" после OnStop мы видим фразу:
Цитата
"Прекращение вызова обработчиков событий терминала QUIK".
Однако далее в тексте мы видим другое объяснение:
Цитата
"Также необходимо иметь в виду, что функция OnStop() выполняется в основном потоке РМ QUIK, и, так как в момент ожидания завершения скрипта (5 секунд) он занимает основной поток РМ QUIK, то другие обработчики событий уже не вызываются, а само РМ QUIK может некоторое время находиться в «подвисшем» состоянии."
Т.е. это уже не "мы сознательно сделали так, чтобы обработчики не вызывались", а "ну, блин, ну так во вышло, что по случайному стечению обстоятельств из-за имеющейся реализации обработчики вызываться перестают". Между "мы сознательно так сделали" и "ну вот так вот получилось" - есть большая разница.
Окей, я продолжаю далее следовать рекомендациям из того же описания (официального). Чуть ранее:
Цитата
Возможные подходы написания скриптов Lua для плагина QLua в Рабочем месте QUIK .... 2. Вся необходимая логика описывается в функции с предопределенным именем main().
Супер. Такой подход нам и демонстрирует автор изначального сообщения этой темы. Он все делает в main(). Использует лишь один обработчик, связанный с интерфейсом пользователя OnStop(), т.к. надо же скрипту сообщить "остановись, хватит". Ибо иного пути нам не предоставлено.
И тут вдруг выясняется, что в этом описанном в документации подходе есть "особенности", когда часть функций попросту не работают в каких-то ситуациях! Как это так?? Это явная ошибка, которую необходимо исправить. Да, обработчики событий не должны вызываться после OnStop, в этом есть логика, да и это явно описано в документации. Но другие-то функции взаимодействия с терминалом почему не должны работать?? потому что "так получилось"? Нет уж, это не есть обоснование; это лишь признание кривоватой реализации данного места, которая, очевидно, является ошибкой и должна быть исправлена.
Mixa, пойми главное: ты можешь сейчас здесь спорить до посинения хоть два года - ничего не изменится. (см. комментарий про 10 лет) Пока сам не сделаешь как тебе надо, опираясь лишь на те средства, какие есть.
На что потратить следующие два года твоей жизни - решать тебе.
getNumberOf позволяет получить данные только из строго определённых таблиц, перечисленных в справке. И задавать там надо не имя таблицы, как вы его видите в терминале, а как указано в справке.
Получить значения параметров торгов (из таблицы параметров торгов) этой функцией нельзя.
Andrey Bezrukov написал: Правильно понимаем, что Вашу задачу решила бы возможность использования функции CreateDataSource, а также вызов callback-функций, связанных с источником данных, полученным через CreateDataSource?
Регистрируем пожелание в такой формулировке?
Не совсем так. Это же индикатор, а не просто данные.
Нужно иметь такую возможность:
1. получили, например, вызов OnCalculate для индекса 5 от основного источника данных (т.е. от источника, по которому построен индикатор, как сейчас). Отлично, что-то посчитали и нарисовали. 2. теперь получили данные по свече с индексом 4 по дополнительную DataSource. Значит что надо: а) получить вызов OnCalculate для индекса 4, где мы получили данные по основному и дополнительному источникам и тут же иметь возможность выставить новое значение индикатора в точке для свечи 4. б) дополнительно получить вызов OnCalculate для индекса 5, т.к. этот индекс, очевидно, надо заново пересчитать, ведь в свече 4 у нас получены новые значения, а от значения в точке 4 у нас зависит и значение индикатора в точке 5; после иметь возможность обновить значение индикатора в точке 5, т.к. оно изменилось
Maksimus написал: Я до этого программировал на mql4-5,там мне было более все понятно.
Мне просто любопытно: а вы также наугад составляли буквы в программах mql ? вот просто любопытно.
Цитата
Maksimus написал: И документация по Lua очень скудная.
Приведу тут тоже ссылку, потому как найти её на этой сайте в самом деле крайне затруднительно; я просто помню по каким словам ее гуглить, просто так фик найдёшь. https://arqatech.com/ru/support/files/ Внизу страницы "Документация по языку LUA в QUIK и примеры.zip"
Сейчас после построения LUA-индикатора при наведении мыши на линию индикатора отображается дата/время соотв. места и значение индикатора в точке указателя мыши. Требуется: добавить возможность для каждой вычисляемой точки (свечки) индикатора задавать значение (и наименование) пользовательского параметра (-ов), которые будут отображаться в легенде при наведении мыши. Это необходимо, чтобы отображать дополнительную информацию на индикаторе (можно отладочную - какие были промежуточные параметры вычисления, можно смысловую - дополнительные параметры состояния рынка в той или иной точке индикатора)
Требуется: иметь возможность строить Lua-индикаторы на основании нескольких источников данных. Легально и корректно.
Сейчас скрипт строится только по одному источнику данных.
Можно получать второй (трений и т.д.) источник - через метку другого графика читать с него значения вызовами getCandlesByIndex; - либо использовать data source, но каждый из этих путей неполноценный, т.к. а) нет уведомлений о приходе данных из "второго" источника, а значит нет возможности строить скрипт с учетом изменившихся данных второго источника; б) сложности в настройке / использовании. Основное это а), конечно.
Пример задачи: построить график стоимости нефти в рублях, используя график цены нефти в долларах и график курса рубля. Сейчас это корректно возможно сделать?
NUMBER AddLabel(STRING chart_tag, TABLE label_params) chart_tag – тег графика, к которому привязывается метка
Вопрос: если AddLabel вызывается из скрипта-индикатора - всё равно надо обязательно указывать chart_tag ? Индикатор же явно к графику и так привязан, если на этом же графике и хочу метку вывести. Да и индикатор - сам по себе график. По умолчанию (если chart_tag не задать) метка не привяжется к индикатору или графику, по которому он построен что ли?
Да, добавлю еще. С брокера хорошо бы стрясти формулу, по которой он считает ограничения. Ожидать, что трансляцию ограничений добавят как параметры в QUIK - я бы не стал, безнадёжно это.
Mikhail написал: По фьючерсам видимо их алготрейдеры уже задолбали и такие данные транслируются
На срочном рынке ММВБ т.н. "планки" - это ограничения самой биржи, и биржа их транслирует. Квик тут ни при чем.
На других рынках ограничения на диапазон цен брокер может установить, но не расскажет. А почему? А не понятно, вы ж клиент брокера, с брокера требуйте.
Egor Zaytsev написал: Вам нужно пересоздать таблицу. Либо, если сохранился бекап файла настроек от версии ниже 8.13.0, то можно его попробовать загрузить.
Т.е. создавал ты таблицу, настраивал - а теперь из-за явной ошибки версии должен обязательно её заново пересоздать Толково, чё
Артем написал: swerg, точно так же как в текущей реализации (в этом и суть предложения - поменьше изменений делать): выполнять всё это в одном треде, так что никакое "уже выполняется" там быть не может принципиально.
Напомню, ветка начиналась с "Добавить функции вида pauseCallbacks и resumeCallbacks, где первая приостанавливает вызовы многопоточных колбеков". И мы долго выясняли про какие многопоточности идёт речь. Вроде как выяснили (хотя явно вы это не писали, но я вас понял так), что pauseCallbacks и resumeCallbacks вызываются в main(). Ну иначе бы и проблемы не было, очевидно. Теперь внезапно все это в одном потоке, как так??
Так где вызываются pauseCallbacks и resumeCallbacks? и если не вmain(), то о какой многопоточности речь и как эти функции помогут, будучи вызванными не в main() ?
Цитата
Артем написал: Во-вторых, мой подход был бы создать на каждый скрипт отдельный тред-диспатчер колбеков, который и занимается собственно их запуском - главный тред тут принципиально не будет ничем блокироваться.
Давайте не менять условия задачи на ходу. Это совсем уже другая история, она здесь не обсуждается.
Самому то не стыдно искренне считать что все окружающие - пустоголовые кретины?
Видимо не только не стыдно, но даже наоборот - горделиво. Тфьу.
В самом деле: вы d каждом сообщении не договариваете половину важных деталей под девизом "и так очевидно", а когда совершенно не очевидные детали кое-как клещами из вас вытянешь - вы же других обвиняете в том, что кого-то там держат за идиотов. Самому-то не стыдно не уметь корректно и внятно общаться?
Alex написал: Конечная цель это отправка полученной информации в телеграмм бота. os.execute постоянно открывает окно CMD что мешает работе с терминалом Quik
Python тогда здесь при чем?
Напишите, как бы вы в Python отправляли информацию в телеграмм-бот. Приведите пример кода, попробуем переложить на Lua и библиотеки для Lua.
Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если таймфрейм отличается от стандартного., Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если интервал отличается от стандартного.
Roman Azarov написал: Так или иначе, функционалом не предусмотрено использование нестандартных интервалов.
Однако мне всё же интересно было бы тут услышать ответ тех. поддержки Неужели при указании нестандартного интервала в предыдущих версия QUIK корректно формировал и отдавал нестандартные свечи?
Roman Azarov написал: Не совсем понимаем актуальность данного пожелания. Опишите, пожалуйста, подробнее необходимость запускать повторно падающий скрипт.
Скрипты - они про автоматическую работу. Полностью. Без наблюдения человеком. При этом очень важно, чтобы скрипт работал. Да, в нём могут быть какие-то ошибки. Может быть ошибки при экзотических сценариях, приводящие к остановке скрипта. Но важно, чтобы скрипт все же работал, даже если наткнулся на какую-то непредвиденную ситуацию. Пусть и методом повторного перезапуска (фактически "с нуля"). Понятно, что стартовать скрипт "с места падения дальше" - невозможно. Как скрипт будет взлетать с нуля после аварии и восстанавливать своё состояние - уже проблема разработчика скрипта. Хотя можно и передать какой-то признак в OnInit, например, "рестартовано автоматически после ошибки", пригодится.
Если вы беспокоитесь, что скрипт "задолбает" терминал перезапусками - можно предусмотреть вариант: прекратить перезапуски, если скрипт упал 10 раз за какое-то время (за минуту, например). Хоть я и не уверен, что это нужно.
Артем написал: Хотя нет не семафоры а просто флаги. Как то так, С++ псевдокодом.
А если callback в момент вызова такой функции уже выполняется - как должно работать? Этим вопросом я намекаю на то, что приведённому вами коду видно, что в многопоток вы не умеете. Почитайте книжки, ознакомьтесь с объектами синхронизации и их использованием - и всё наладится. Никакие "отложенные колбеки" не понадобятся.
Однако пожелание для QUIK есть: штатные средства межпоточной синхронизации в QLua таки нужны.
Еще лучше, конечно, пересмотреть модель выполнения скриптов. Никакие конкурирующие потоки в рамках одного скрипта там явно не нужны.
Считаю это ошибкой, которую разработчики QUIK должны исправить. Интерфейс у терминала русский, по умолчанию для русских букв штатные upper / lower должны корректно работать.
Дмитрий написал: Внезапно во втором квике появился дополнительный поток info.exe!GET_INFO_PARAM+0x2380b0, который отъедает много ресурсов. С чем он связан и как его убрать? Информация на скриншоте.
Артем написал: Я вам только что про "недосказание не значит незнание" указал, а вы опять туда же. Самому то не стыдно искренне считать что все окружающие - пустоголовые кретины?
Вы хотите про это поговорить? Обратите внимание, я намеренно вырезал все эти эмоции из предыдущих цитирований, делая вид, что не замечаю, но может напрасно? может это суть проблемы, с которой вы пришли на форум? ну раз вы столько про это пишете.
Цитата
Артем написал: Обычные колбеки в скриптах (это контекст) вызываются когда скрипт сам дёргает процедуру вызова всех накопленых колбеков прямым или косвенным способом
Я бы не согласился. Callback-функция - это та, которую кто-то вызывает по какому-то событию. А сам это скрипт или среда исполнения этого скрипта - какая разница? По-моему, никакой для применения данного термина. Кстати, в самом начале следующей цитаты вы ровно про это и пишете, так что не совсем понимаю почему непременно "скрипт сам дёргает". Впрочем, вероятно это не суть важный момент.
Цитата
Артем написал: Так вот, колбеки которые вызывает хост-программа, вклинивающиеся прямо посреди мейна на первой же точке где снимается лок, это так-называемые "многопоточные колбеки"..
Вообще-то это нормальное, обычное и ожидаемое многопоточное выполнения кода.
Впрочем, наконец-то я, как представитель людей без IQ, понял о чем вы: вам, по сути, просто нужны средства межпоточной синхронизации, доступные их скриптов.
Цитата
Артем написал: В арке люди решили что они умнее всей планеты и хакнули некое подобие мультитрединга, от чего в итоге просто страдают пользователи (кучу тредов по этому поводу уже нафлудили)
Я согласен с тем, что многопоточность в скриптах была сделана напрасно; от нее оказалось больше проблем, чем пользы. Было ли это очевидно в момент проектирования - не уверен. Однако пользователи страдают по другим причинам, считаю: а) не умеют в многопоточность; б) сделав многопоточность в скриптах, ARQA не добавила функций для межпоточной синхронизации.
Пункт а) решается чтением книжек.
С пунктом б) чуть сложнее ввиду отсутствия готовых функций в QLua. Например, библиотека w32 для QLua содержит функции работы с мьтексами, что вполне можно использовать для синхронизации, если это необходимо. Правда мьютексы несколько избыточны и тяжеловаты, ведь синхронизируемся ты лишь внутри одного процесса (в терминологии Windows), надо будет добавить в нее и работу с более подходящим для этого случая объектом "критическая секция".
Ну и еще в QLua есть "Потокобезопасные функции для работы с таблицами Lua". В отдельных случаях они спасают, но в очень узком круге случаев, да.
Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если таймфрейм отличается от стандартного., Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если интервал отличается от стандартного.
Rusyan написал: В версиях до Quik 8.12 функция CreateDataSource возвращает правильное число при любом не стандартном интервале
Как-то не верится. Возможно, ранее возвращались левы цифры т.е. от какого-то другого тайм-фрейма ? в это я еще могу поверить. Вы уверены, что возвращались верные данные именно для указанного вами произвольно тайм-фрейма?
Старатель написал: В моменты конкуренции за разделяемый ресурс (луа-машину) основной поток квика ожидает .....
На мой взгляд вы куда-то не туда роете. Ну т.е. там, где нет практической пользы. Для практической пользы достаточно считать, что все main() работают параллельно, и параллельно с ними работают callback'и. Параллельно - значит любая часть кода этих main() и callback'ов может быть выполнена в произвольном порядке. Нужен точный порядок - надо придумывать синхронизацию, да. Иначе просто считать, что любой кусок кода может быть выполнен в любой момент.
На мой взгляд это всё, что требуется учитывать для практического использования.
Артем написал: swerg, тут колбек останавливает выполнение главного треда в произвольный момент времени
Нет, не в произвольный. В терминале возникает какое-то событие. 1) Терминал доделывает все свои дела, в том числе полностью завершается выполнение Lua-кода колбеков, отрисовывает интерфейс если надо и т.д. 2) Выбирает событие из своей очереди 3) Вызывает Lua-колбек произошедшего события (если таковой имеется), этот колбек до конца выполняется (т.е. до выхода из колбека), ведь так? 4) Если есть еще активные скрипты с таким же колбеком - все такие колбеки последовательно вызываются и завершаются (выходом из них) Всё это в рамках одного основного потока терминала 5) После этого терминал обрабатывает свой код, связанный с данным событием (никакие колбеки не вызываются в этот момент) 6) Терминал переходит к следующему пришедшему событию и далее на пункт 2)
Где ж вы тут видите "произвольный момент времени"? Нет произвольного момента, колбеки выполняются строго поочерёдно и лишь тогда, когда а) все ране вызванные колбеки (причем всех скриптов) полностью завершили свою работу б) терминал "сознательно" вызывает колбеки, когда "все к этому готово", а не "внезапно по событию".
Цитата
Артем написал: Так что функционально это прерывание а не колбек.
Очередное событие в очереди может висеть сколько угодно, если какой-то колбек будет слишком долго выполняться, верно ведь? так что ни о каком прерывании "внезапном" речи нет.
Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если таймфрейм отличается от стандартного., Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если интервал отличается от стандартного.
Вообще говоря по справке и не подразумевается передача произвольного интервала, только заранее заданные константы. Так что не понятно что именно надо исправить.
Список констант для передачи в параметр interval :
INTERVAL_TICK -- Тиковые данные INTERVAL_M1 -- 1 минута INTERVAL_M2 -- 2 минуты INTERVAL_M3 -- 3 минуты INTERVAL_M4 -- 4 минуты INTERVAL_M5 -- 5 минут INTERVAL_M6 6 минут INTERVAL_M10 10 минут INTERVAL_M15 15 минут INTERVAL_M20 20 минут INTERVAL_M30 30 минут INTERVAL_H1 1 час INTERVAL_H2 2 часа INTERVAL_H4 4 часа INTERVAL_D1 1 день INTERVAL_W1 1 неделя INTERVAL_MN1 1 месяц
При этом в справке есть уточнение:
Цитата
Функция возвращает таблицу data_source в случае успешного завершения. Если указан неверный код класса или параметр, то возвращается «nil».
Наверное было бы логично, если бы при неправильном значении interval тоже возвращалось nil
Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если таймфрейм отличается от стандартного., Quik 8.13 функция CreateDataSource возвращает пустой набор данных, если интервал отличается от стандартного.
Rusyan написал: Прошу исправить в Quik 8.13 функцию CreateDataSource, так как возвращает пустой набор данных, если интервал отличается от стандартного.
А как надо починить? Должно возвращать ошибку? или nil? Или должно возвращать данные? А может в предыдущей версии работало как-то иначе, а теперь поведение изменилось?
Артем написал: Тут еще конечно под "колбеками" понимаются прерывания, да и вообще система через задницу что никакие стандартные термины не подходят.
Вы зачем-то намешиваете совершенно разные термины, а потом пишете "никакие стандартные термины не подходят". Отлично подходят, именно термин callback-функция, которая вызывается в момент нужного события. Прерывания - это из другой оперы, не стоит их сюда примешивать.
Цитата
Артем написал: Но я людей за идиотов не считаю - думаю что они сами всё это соображают - а оказывается что нет.
Достаточно лишь внятно и полно излагать ваши мысли, не думая, что "это и так очевидно". Ведь то, что вам очевидно - может быть совершенно не очевидно другим, учитывая контекст, а в дополнение к этому и вы можете не совсем корректно и полно излагать ваши мысли, что вкупе с "и так очевидно" даёт совершенно гремучую смесь.
Артем написал: Но ввиду особенностей квика, колбеки тут многопоточные - вызываются из чужого треда в любой момент, причём вызываться они могут прямо посреди выполнения другого кода. Иногда это прямым образом разрушает стек ВМ и скрипт падает с ошибками обращения к нилам
Callback-функции вызываются в основном потоке работы терминала. В "другом потоке" работает main().
Так что что там вызывается "посреди выполнения другого кода" - мне не понять.
Цитата
Артем написал: А еще иногда колбек вызывается в момент обработки очереди данных, которые собирает этот же колбек, из-за чего соответственно происходит разрушение очереди, из-за чего скрипт тоже падает с ошибками обращения к нилам, хотя тут целостность стека не нарушается, просто данные были удалены из другого треда.
Callback-функции работают строго последовательно, т.к. выполняются все в одном потоке. Уберите код из main() (ну кроме заглушки про is_run) - и никакого "параллельного кода" у вас не останется, будет ровно то, что вы хотите - полностью однопоточный код без каких-либо проблем.
Так определение "многопоточных колбеков" будет уже или нет?