Anton (Все сообщения пользователя)

Выбрать дату в календареВыбрать дату в календаре

Страницы: Пред. 1 ... 18 19 20 21 22 23 24 25 26 27 28 След.
QUIK 8.0
 
Цитата
Imersio Arrigo написал:
 Супер. Каждый роет себе могилу сам. Но это если ты сам код пишешь.
А вот тому чуваку - совет переходить на *_s это лишняя куча проблем.
Куча проблем как раз будет, если программа не рухнет на переполнении буфера. Просто посмотрите, что будет после оверрана. В идеальнейшем варианте мы затрем стековый кадр и рухнем на ближайшем return'е, это будет просто подарок. А если мы затрем заголовок кучи? Через полчаса прога свалится на free и мы будем в мыле искать, что вообще произошло, а уж "где" это произошло найдем только чудом. А если буфер - часть структуры и мы затрем другие ее поля? Ничего вообще не рухнет, а на выходе будет мусор, и с хорошей вероятностью мы вообще ничего не найдем никогда. Нет уж, пусть оно рушится в момент преступления.

В данном конкретном случае как раз автор проверил длину перед sprintf, можно оставлять как есть, уже было признано.
QUIK 8.0
 
Цитата
Imersio Arrigo написал:
А самая подлянка в том, что в случае выхода за пределы буфера эти, т.н. "безопасные" функции бросают исключение. И программа просто падает.
И это правильно, я еще и ассертов натыкиваю через строчку. Пусть она у меня в отладчике лучше упадет, чем у юзера в самый ненужный момент. В чем, собственно, и отличие подходов "никсоводов" и "виндузятников". Первый пишет абы как, "потом поправлю либо кто-нибудь поправит, опенсорц же ж", потом никогда не наступает и этот код десятилетиями кочует по интернетам и проектам в первозданном недовиде. Второй знает, что ежли у юзера что обвалится, субботник будет именно у него, родимого, так что лучше полдня потерять, потом за пять минут долететь.
QUIK 8.0
 
Цитата
Анатолий написал:
 А есть хорошие ссылочки по которым можно на эту тему просветится более подробно, как правильно все эти несьюрные функции заменить на секьюрные? Или же это надо вообще Си изучать полностью?
Вкратце суть в том, что в "безопасную" функцию передается размер буфера, так что она может проверить, что не вылетела за его границу, старые функции такого параметра не имели и вынуждены были "верить", что кодер подготовил буфер достаточной длины, что не всегда просто, особенно для sprintf со сложным форматом. В той же вашей либе взгляните на строки 555-558, там как раз автор проверяет, что буфера достаточно. Конкретно в этом месте можно сказать, что безопасно и без замены. Заменить достаточно легко, большинство новых функций похожи на старые, только добавлен второй параметр "длина буфера". Но не все, некоторые возвращают другой тип (код ошибки вместо длины, например), некоторые (та же strerror) вообще отдаленно похожи, в каждом случае лучше в доку глянуть.

Обзорная статья https://docs.microsoft.com/en-us/cpp/c-runtime-library/security-features-in-the-crt?view=vs-2019 , конкретно по sprintf_s с друзьями https://docs.microsoft.com/en-us/cpp/c-runtime-library/security-features-in-the-crt?view=vs-2019
QUIK 8.0
 
Цитата
Анатолий написал:
 Заменил все те функции на их рекомендуемые секьюрные аналоги с добавкой _s, ошибок полезло еще больше
Ожидаемо, там сигнатуры другие, придется и окружающий код править. Расписывать реально долго, в принципе можно оставить strerror как есть, она в эту компанию попала можно сказать "случайно", а попробовать заменить только sprintf, но у sprintf_s надо будет добавить второй параметр - размер буфера (который в первом параметре передан), а дальше все то же самое.

Цитата
Анатолий написал:
Вписал _CRT_SECURE_NO_WARNINGS заодно и _CRT_NONSTDC_NO_WARNINGS
как мелкософт советуют
Можно и так оставить, конечно. Там проблема с безопасностью не самой этой либы, а что она с устаревшими функциями может вызывать переполнение буфера, никак не детектируемое, а уж этим могут воспользоваться вирусы и трояны (не из этой либы).
QUIK 8.0
 
Цитата
s_mike@rambler.ru написал:
вы бы вместо рассуждений о несовершенстве вселенной помогли человеку и собрали бы ему библиотеку.
время то же и польза для вселенной отлична от нуля.  
Попробую к таксисту так подойти, че мол сидишь в телефон пялишься, давай до ашана сгоняем, время-то то же, и польза для вселенной.
QUIK 8.0
 
Цитата
Анатолий написал:
 Выставил непомогло,
Включил multibyte ненпомогло
Таки помогло, E0144, E0167, C2440, C2664 же больше нет?
Цитата
Анатолий написал:
Тем более вытаскивать ничего ненадо, в луабинариях с сорсефоржа  https://sourceforge.net/projects/luabinaries/files/5.1.5/Windows%20Libraries/Static/ ,  которые для мингв64 есть либа - liblua5.1.a ,  это она ведь нужна?
Нет, не она, нужна именно вытащенная из qlua.dll и именно из вашей версии квика. Но это пока в сторону отложите, пусть компилятор сначала до конца отработает, потом будете линкер мучать. А чтобы компилятор отработал, разберитесь с вызовами strerror, sprintf и прочими, в ошибках написано даже как именно, либо заменить на sprintf_s сотоварищи (рекомендуется), либо в препроцессор вписать D_CRT_SECURE_NO_WARNINGS (что сделает код еще более говнокодом, но он скомпилируется). Таки да, если кодеру влом каст явный сделать и проверить диапазон size_t, прежде чем пихать его в int, такой код зовется говнокодом, независимо от его работоспособности.
QUIK 8.0
 
Ужос-то какой.

1. Чтобы студия компилировала как си без плюсов, надо расширение сделать .c, а не .cpp, либо кликнуть по файлу в дереве проекта правой кнопкой, открыть настройки файла и поставить ему "компилировать как си". Либо всему проекту поставить. Хотя, возможно, в мс-новоделии уже и нельзя это все, тут не в курсе.

2. Ваша qlua.dll, куда вы ее ни кладите, компилятору не нужна, он ее, как того Джо, не находит, потому что и не ищет. Даже линкеру она не нужна, ему нужна qlua.lib, как ее вытащить из qlua.dll тут где-то тема была.

3. Ошибки в студии (глядя по скрину) говорят о следующем: а) исходный код является говнокодом (E0144, C2440, C2664) даже с точки зрения сей без плюсов; б) в проекте стоит char type = UNICODE, а должен быть MULTIBYTE (E0167); в) аффтар не рассчитывал на винду (C4996); г) аффтар не рассчитывал на 64 бита (C4267). И это только что видно на скрине.

Если есть возможность, делегируйте компиляцию кому-нибудь. С помощью зала, конечно, что-нибудь в итоге накомпилируется, но что именно это будет - уже вопрос.
как мне скомпилировать или достать luasql
 
Вы и не найдете такого файла, потому что файл должен называться mysqlclient.lib или mysqlclient.a и лежать, по идее, в мускуловской папке lib. Вы ж линкеру указали E:/lua, он там и роется. Впрочем, и то, что он в ошибке пишет -lmysqlclient, а не истинное имя, правильным не выглядит.
ODBC-экспорт. Мониторинг, Проверка флагов ODBC-экспорта.
 
Цитата
Николай Камынин написал:
 стартуйте DDE  в скрипте LUA внешним скриптом например на AutoiT
Даже и внешний не нужен, ибо на сях все, но это уже несколько в сторону. Понимание кишок виндового приложения и умение их поковырять, несомненно, большой плюс, но, знаете ли, когда у юзера вся инфраструктура рухнет после очередного обновления квика, нужно иметь возможность (аргументированно) исполнить подобный танец.
ODBC-экспорт. Мониторинг, Проверка флагов ODBC-экспорта.
 
Цитата
s_mike@rambler.ru написал:
Как показывает практика, ODBC и DDE вряд ли получится заставить работать стабильно и надежно.
За ODBC не знаю, а DDE вполне себе надежно работает, если аккуратно серверную часть сделать. Другое дело, что чуть какая предобработка нужна и все равно придется подпиливать костылики на луа, и тут появляется фактор "ой, я DDE стартанул, а скрипт забыл запустить", так что в итоге все верно сказано, луа как луа или луа как интерфейс к сям-плюсам - единственный удобный вариант.
Плечо по ОФЗ
 
У брокера в тарифах, называться должно как-то типа "использование заемных средств при переносе позиции".
Функцию с двоеточием в таблицу, как запихнуть функцию string в таблицу.
 
Двоеточие всего лишь скрывает self, поэтому запихнуть можно в формате с точкой
Код
t.foo = string.reverse
и при вызове тоже точку использовать
Код
t.foo("123")
Возможно, у более лучших собаководов получше идеи найдутся.
Плечо по ОФЗ
 
Дык на споте плечо платное.
LuaSQL
 
Цитата
Старатель написал:
 Помимо этой библиотеки ещё что-то нужно?
Это нативная библиотека, нужна еще обертка для lua.
Запрос списка инструментов Lua
 
У текущего фьюча может быть только четыре кода, последняя цифра - год, последняя буква - месяц экспирации (H, M, U, Z), тут как раз выбрать несложно, если хотя бы сегодняшняя дата известна (а она известна в квике). Аналогично у опционов коды не с потолка берутся, там вся нужная информация уже содержится (на память не скажу, см. на бирже). А вообще в принципе порядок примерно такой и будет, только отчего же отфильтровать все и получить одну-единственную, можно фильтровать сразу по искомому списку.
Запрос списка инструментов Lua
 
Как выше сами написали, получаем список всех опционов по классу, потом для каждого получаем информацию, оставляем только те, у которых базовый актив интересный и что там еще нужно, дата экспирации или что. Это всяко быстрее и проще, чем парсить с биржи, там тоже не все радужно.
Запрос списка инструментов Lua
 
Есть же getSecurityInfo.
LuaSQL
 
Цитата
s_mike@rambler.ru написал:
Надеюсь, это Release.
Release + NDEBUG, SDK7.1, остальное все дефолтное.
LuaSQL
 
Берем amalgamation последней версии с офсайта, там нам нужны три файла, sqlite3.h, sqlite3ext.h и sqlite3.c. Создаем в студии пустой проект, добавляем в него эти три файла, крутим настройки проекта по желанию и умению, в sqlite3.c недрогнувшей рукой в самом начале пишем
Код
#define SQLITE_API __declspec(dllexport)
И все, запускаем компиляцию, 0 errors, 0 warnings, получили sqlite3.dll. По-хорошему это надо делать в той же студии, в которой все остальное компилируется, дабы рантайм был один и тот же, но вот ежли надо прям щас, собрал с встроенным рантаймом от студии 2010 (и ничего в настройках скьюлайта не крутил), https://dropmefiles.com/KyA8z
LuaSQL
 
Готового не покажу, но звучит странно, sqlite один из немногих пакетов, собирающихся на раз буквально чем угодно, надо только брать не подробный девелоперский исходник, а amalgamation.
Возможно связать Wealth-Lab и Quik через библиотеку trans2quik.dll?
 
Делал очень давно еще для WLD3 путем написания брокер-адаптера. Глючное было решение именно со стороны велса. Как там теперь с новым шарповым велсом дела обстоят не знаю.
Хозяйке на заметку: OnStop(), или "Зачем вы это делаете, мистер Андерсон?"
 
Цитата
swerg написал:
Как известно, QLua работает вот по такой модели:  https://quik2dde.ru/viewtopic.php?id=16
Спасибо, информативная штука. Кстати, Ваша диаграммка сильно помогла в свое время разобраться в порядке вызова колбеков.

Цитата
swerg написал:
Осталось лишь узнать мнение начальника транспортного цеха, зачем он использует столь изощрённый синтаксис. Какова хитрая цель? Быть может все будет полезно?
Куда поедет выполнение скрипта, зависит от результатов OnInit. В частности, если оказалось, что "файл настроек не найден или поврежден", то main будет с юаем, циклом сообщений и всем таким, при других условиях другая, наконец, если все прошло по "основному сценарию", то вообще

Код
void _on_main_regular(void * lua_state)
{
   TRACE();
   set_exception_handler(_on_exception);
   _mainthread = thread::current();
   // enable OnStop callback
   _replace_callback(lua_state, "OnStop", ::cbid_on_stop);
   wait::all(_stopevent, wait::infinite);
}
CreateDataSource, не делает квик сильнее
 
Цитата
swerg написал:
 Вот когда откроете полторы тысячи тиковых TOC - тогда и будет смысл говорить про "ничего не виснет".
И опять "об том и речь". Я прошу сделать ОДНУ ТОС из скрипта, но мне говорят, что это не фича а баг, поэтому не будем.
*AllTrade*, новые функции для qlua
 
Цитата
Sergey Gorokhov написал:
Для анализа просьба прислать на quiksupport@arqatech.com копию всей папки с проблемным терминалом QUIK (без ключей доступа)
В письме укажите ссылку на эту ветку форума.
Отправил.

Цитата
Старатель написал:
При каждом вызове CreateDataSource по тикам дергается info.ini: раз 15 повторяется цикл LockFile/ReadFile/UnlockFile/CloseFile и один раз даже WriteFile ))
Интересная информация по доступу к info.ini, спасибо. С одной стороны, винда должна кэшировать доступ к файлам, если, конечно, кодер сам не наставил флагов прямого доступа к диску, с другой, пара LockFile/UnlockFile может добавлять хороших тормозов. Косвенно также дан ответ на вопрос "что будет, если лезть в info.ini из скрипта", -- все будет хорошо, раз квик лочит файл перед чтением.

Цитата
Старатель написал:
Ну ещё и сравнивать надо в одинаковых условиях, например, какие были установлены фильтры, что было в файлах info.ini (в частности в секции [ALL_TRADES_DATA]), alltrade.dat до запуска скрипта.
Получается два контура торможения (двухконтурная тормозная система,  ага). Первый это доступ к info.ini, если там не стоят class_code=ALL,  квик будет добавлять открываемые инструменты в список, а он не может их  сразу все добавить, т.к. создает датасорцы по одному. Эти (и только эти)  тормоза можно увидеть, запустив подписку при сброшенных фильтрах и  пустом alltrade.dat. Второй контур - это когда в info.ini установлены  фильтры ALL для всех классов, тогда записи в info.ini не будет, как и не  будет поиска по info.ini, квик сразу увидит ALL. Тогда при пустом  alltrade.dat подписка произойдет мгновенно, но при заполненном получим  "тормоза второго рода", зависящие от размера alltrade.dat.
*AllTrade*, новые функции для qlua
 
Цитата
Sergey Gorokhov написал:
 для очистки dat файлов есть ключ -clear (в документации глава "Ключи запуска Рабочего места QUIK")
Спасибо, полезная штука в некоторых ситуациях, хотя в данном случае менее костыльным будет просто потребовать открытой ТВС.

Значит, нынче почистил все, до чего руки дотянулись, обновил квик (три длл подъехали), о дневных пробах писал уже. После закрытия биржи включил скрипт и вот до сих пор (скоро два часа как) он все жужжит, сейчас где-то в опционах ковыряется. То есть ничего нового. И такая резкая зависимость от количества записей в ТВС грустно намекает на "эн-квадрат" где-то внутри.

Таким образом, на текущий момент вариантов кроме "ТВС должна быть открытой" я не вижу, на будущее хотелось бы все же видеть что-то более легкое, чем CreateDataSource, без встроенного энквадрата.
*AllTrade*, новые функции для qlua
 
Цитата
Sergey Gorokhov написал:
Кроме того, попробуйте провести тест в разное время, утром до торгов, утром при старте торгов, в обед и вечером.
Сравните данные и сообщите нам.
Вот сейчас как раз пробовал. Похоже, причину разницы 20/500 понял. Значит, удаляем alltrade.dat, отключаем все фильтры ТВС, запускаем квик, подключаемся, убеждаемся, что ничего не едет (alltrade.dat 64кб, т.е. одна гранулярити отмэплена, скорей всего пустая). Запускаем (тиковую) подписку - подписались мгновенно, параллельно начинают дергаться OnAllTrade. Казалось бы, идиллия. Повторяем упражнение, подождав подкачки всех сделок в alltrade.dat (около 200 Мб), вот тут уже гораздо медленнее. И да, облигации сейчас где-то за 20 секунд и подписались (на глаз смотрел, плюс-минус километр). Вечером, когда в alltrade.dat будет весь день, думаю, все вернется на круги своя. Кстати, утром-то ситуация как раз такая, в alltrade.dat вся вчерашняя ТВС, так что хочешь не хочешь, а надо запускаться вот в таком окружении.
*AllTrade*, новые функции для qlua
 
Так вот я и не понял, где у меня в скрипте таймер что-то добавляет. Там нет слип(0), где действительно бы отдавался остаток таймслота до следующего тика, тиккаунт же поток не снимает, да и тот выполняется всего 20 раз за скрипт, на каждом классе, а не на каждом инструменте. Там запись в лог больше лопает.

Любопытно, что подписка на дневки в том же самом цикле происходит практически мгновенно, хотя квику приходится несколько тысяч файлов создать в архиве (почистил предварительно). А вот если добавить ds:SetUpdateCallback(), приходится подождать секунд 10 (опять же на все). К сожалению, на ТВС это не влияет, фильтры не устанавливаются и все сделки не едут, а то был бы вариант.

Вот по разнице во времени выполнения уже интереснее. Заметил, между прочим, что и открытие ТВС тоже как-то не то чтобы быстро происходит после обновления на восьмую версию, хоть и не часы конечно, но "раньше было лучше". Попробую у себя почистить все для начала и повторить эксперименты.

Где стартовать, дело даже не мое, а того, кто этим будет пользоваться. По опыту юзеры выдумывают такие юзкейсы, которые мне и в голову не могли прийти, и через икс времени переписывать весь код "по гарантии", сиречь даром, не очень улыбается. Это же относится и к недокументированным всяким возможностям, так что гипотетический вариант с хачением info.ini всерьез и не рассматривал. Вариант с info.ini кстати не работает, если вдруг кто еще возжелает попробовать. Чтобы квик увидел написанное, надо диалог фильтров "продернуть", а зачем тогда в файл писать, можно в диалоге кнопки подавить, раз уж его открывать все равно. В любом случае это все не вариант, одно "неудачное" обновление квика и попал на субботник.
*AllTrade*, новые функции для qlua
 
Sergey Gorokhov, благодарю за фидбек. Несколько обескураживает ваш ответ, если честно, особенно часть про таймер, особенно после ознакомления со статьей по ссылке. Таймер тут при чем? Равно как и сплит тут мало на что влияет, он выполняется один раз на класс, коих в тестовом случае всего 19. Перенос в мейн тоже ничего не меняет, интерфейс висеть не будет, но сам процесс подписки идет с той же скоростью. В общем, про таймер как раз добавило лишних вопросов. А так-то я больше 20 лет под винды пишу, краем уха слышал, как там внутри все устроено, даже, если поднапрячься, вспомню, на какое прерывание этот "таймер процессора" заведен.

Категорически не согласен с пунктом 5. Пример. Юзер в 23:45 запустил квик, чтобы скачать данные за день, запустил скрипт. В 0:15 брокер вырубил сервер. И вдруг внезапно оказывается, что наш скрипт за это время (когда вся ТВС уже приехала бы сто раз) не то чтобы не сохранил данные, а даже еще и не подписался на них. То есть сессия пропала (нет подписки -> нет данныех даже в alltrade.dat), завтра утром на сервере ее уже не будет. Нормальный такой скрипт, удобный. Зато уж компом рычит как зверь по три часа кряду, сразу видно, что важным делом занят.

Таки да, мне в соседней ветке говорили про мейн и между делом намекнули на "другой подход", не знаю вот, стоит ли тут публично контору палить. Этим (или не этим) "другим способом" я подписался на все за пару секунд, но там другой вопрос возникает, такой способ сработает только когда глобальные фильтры уже установлены все на ALL, а при отписке (и закрытой ТВС) квик их сбрасывает. Тогда вопросы другие - а если я в info.ini их из скрипта запишу? Квик это увидит? А если квик со скриптом пересечется на доступе к info.ini, будет ждать анлока или упадет? А если через версию квика вы решите в другом месте фильтры хранить?
CreateDataSource, не делает квик сильнее
 
s_mike@rambler.ru, однако ж спасибо за идею/ключевик, кое-что интересное вырисовывается. Главно дело чтобы это не пофиксили в "одной из будущих версий".
CreateDataSource, не делает квик сильнее
 
О том и речь в конечном итоге, CreateDataSource делает ненужную в данном случае работу. При открытии ТОС ничего же не виснет. Очевидно, что в ближайшие годы требование держать ТОС открытой снять не удастся, даже если прямо сейчас арка бросится теряя тапки реализовывать "просто подписку на ТОС".
CreateDataSource, не делает квик сильнее
 
В мейне тот же тайминг абсолютно (особо долго не ждал)
Код
EQOB (1464 securities) subscribed in 561 seconds
EQDB (30 securities) subscribed in 11 seconds
SMAL (233 securities) subscribed in 89 seconds
INDX (52 securities) subscribed in 19 seconds
TQBR (264 securities) subscribed in 100 seconds
TQDE (12 securities) subscribed in 4 seconds
TQOB (43 securities) subscribed in 16 seconds
TQIF (69 securities) subscribed in 25 seconds
TQTF (26 securities) subscribed in 9 seconds
EQQI (0 securities) subscribed in 0 seconds
OQQI (12 securities) subscribed in 4 seconds

и та же загрузка ядра на 100% с сопутствующим воем кулера. Это не то, что спасет отца русской демократии. Самое ж смешное, что "пожелание" можно реализовать, просто создавая невидимую ТОС (ну, без условий по невмешательству в фильтры, но это можно пережить). Это можно и из скрипта-длл сделать вообще-то, просто хачить не хочется, бо апдейтонеустойчиво.
CreateDataSource, не делает квик сильнее
 
Какая разница, он и в мейне полтора часа кряхтеть будет, только что юзеру не так заметно, юай не виснет.
*AllTrade*, новые функции для qlua
 
Как показывает практика, полноценно использовать CreateDataSource для подписки на таблицу обезличенных сделок не представляется возможным. Посему предлагаю добавить в qlua несколько новых функций.

1. Функция getAllTradeFilters
Код
STRING getAllTradeFilters(STRING class_code)
Возвращает строку в формате, аналогичном возвращаемому getClassSecurities(class_code), содержащую список бумаг указанного класса, для которых включен заказ всех сделок (попросту строку из INFO.ini для данного класса). Если для класса нет выбранных инструментов (эквивалентно отсутствию класса в INFO.ini или же там записано class_code=), возвращает пустую строку. Если для класса выбраны все инструменты (эквивалентно class_code=ALL в INFO.ini), возвращает то же самое, что и getClassSecurities(). В случае ошибки возвращает nil.

2. Функция setAllTradeFilters
Код
BOOLEAN setAllTradeFilters(STRING class_code, STRING security_code_list)
Устанавливает список бумаг, для которых включен заказ всех сделок, для указанного класса. Если security_code_list является пустой строкой, отключает заказ всех сделок для всего класса (эквивалентно class_code= в INFO.ini). Если security_code_list содержит ту же строку, что вернула бы getClassSecurities(class_code), включает заказ всех инструментов класса (эквивалентно class_code=ALL в INFO.ini). Возвращает true, если фильтры были изменены, false в случае ошибки (и гарантирует, что во втором случае имевшиеся до вызова фильтры остались неизменными). Определенная сложность видится при наличии открытых в терминале ТОС, что делать, если данный вызов пытается отменить заказ данных для используемых таблицами инструментов?

3. Функция SubscribeAllTrades
Код
TABLE SubscribeAllTrades(STRING class_code, STRING security_code_list)
Выполняет подписку на ТОС по указанному классу и списку инструментов, как если бы пользователь открыл ТОС с аналогичными фильтрами в терминале, но, в отличие от таблицы, не изменяет глобальные фильтры заказа данных, даже если установлена автонастройка фильтров по открытым таблицам. Возвращает таблицу, одним из полей которой является функция close() для последующей отписки, и, возможно, в таблице имеются поля с кодом класса и списком инструментов, прошедших глобальные фильтры, т.е. по которым действительно произошел заказ данных. Возвращает nil в случае ошибки.

Квик должен гарантировать, что при любом (нормальном/принудительном) завершении скрипта, выполнившего подписки на ТОС, все эти подписки будут автоматически отменены, что легко достижимо установкой метаметода __gc для возвращенной из SubscribeAllTrades таблицы на ее же метод close().


-----------------------------------

*Мячты конечно мячты.
CreateDataSource, не делает квик сильнее
 
Немного конкретики. Квик 8.0.2.3, брокер настоящий (не демо), на момент запуска скрипта соединения с сервером нет, в квике открыта ТОС, в которой чуть меньше 2 млн вчерашних сделок. Полный код скрипта
Код
local split = function(str, delimiter)
   local t = {}
   local pat = "([^" .. delimiter .. "]+)"
   for s in string.gmatch(str, pat) do
      table.insert(t, s)
   end
   return t
end

local SubscribeAllTrades = function()
   local sublog = io.open(getScriptPath() .. "\\SUBLOG.txt", "w")
   local cls = split(getClassesList(), ',')
   local dss = {}
   for k, v in pairs(cls) do
      local sec = split(getClassSecurities(v), ',')
      sublog:write(string.format('%s (%u securities)', v, table.getn(sec)))
      sublog:flush()
      local tim = os.clock()
      for kk, vv in pairs(sec) do
         local ds = CreateDataSource(v, vv, INTERVAL_TICK)
         if nil == ds then
            sublog:write(string.format(' CreateDataSource failed on %s\n', vv))
            break
         end
         table.insert(dss, ds)
      end
      sublog:write(string.format(' subscribed in %u seconds\n', os.clock() - tim))
      sublog:flush()
   end
   for k, v in pairs(dss) do
      if not v:SetEmptyCallback() then
         sublog:write('SetEmptyCallback failed\n')
      end
   end
   sublog:close()
end

OnI nit = function()
   SubscribeAllTrades()
end
После ну очень долгого жужжания всеми вентиляторами компа получен следующий лог
Код
EQOB (1464 securities) subscribed in 556 seconds
EQDB (30 securities) subscribed in 11 seconds
SMAL (233 securities) subscribed in 89 seconds
INDX (52 securities) subscribed in 20 seconds
TQBR (264 securities) subscribed in 100 seconds
TQDE (12 securities) subscribed in 4 seconds
TQOB (43 securities) subscribed in 16 seconds
TQIF (69 securities) subscribed in 26 seconds
TQTF (26 securities) subscribed in 9 seconds
EQQI (0 securities) subscribed in 0 seconds
OQQI (12 securities) subscribed in 4 seconds
EQRP_INFO (2377 securities) subscribed in 909 seconds
TQQI (36 securities) subscribed in 13 seconds
TQOD (100 securities) subscribed in 37 seconds
CROSSRATE (7 securities) subscribed in 2 seconds
SPBFUT (212 securities) subscribed in 80 seconds
SPBOPT (10062 securities) subscribed in 3837 seconds
RTSIDX (261 securities) subscribed in 99 seconds
INSTR (4 securities) subscribed in 1 seconds
Опуская вопли и фейспалмы, резюмируем: для подписки на ТОС CreateDataSource не годится от слова совсем, слишком много ненужной работы (какой, интересно) выполняется внутри нее. Посему "ща буит пожелание" в соответствующем подфоруме.

Кстати говоря, есть пара любопытных замечаний, к делу прямо не относящихся.
1. То же самое, реализованное в длл на сях, работает чутка (ну так раза в два) быстрее. Хотя, казалось бы, какая разница.
2. Пока основной (с окнами) поток висит на нашей OnInit, другие потоки квика продолжают себе спокойно работать. В частности, если есть подключение к серверу, оно не рвется, в фоне нормально подъезжают все сделки, что видно по растущему файлу alltrade.dat. Откуда возникает интересный вопрос, а что происходит с OnAllTrade в это время? Вызываться она не должна, т.к. мы еще не вышли из OnInit, но данные-то едут, там какая-то очередь накапливается или приехавшие во время OnInit новые сделки не приведут к последующему вызову OnAllTrade? По моим наблюдениям пропусков не происходит, но тут нужны более тщательные исследования (либо авторитетное заявление разработчиков).
Экспорт значений "Price" и "Volume" в Excel, Экспорт значений "Price" и "Volume" в Excel
 
Быстро и легко это скачать с финама в текстовом формате и дальше хоть в эксель хоть куда.
CreateDataSource, не делает квик сильнее
 
Введение
Нужно экспортировать всю ТОС луа-скриптом. Дело не то чтобы сложное, если обязать юзера держать ТОС открытой. Но хочется покрасивше, давайте на старте подпишемся на все доступные инструменты? А давайте...

Глава первая, шапкозакидательская
Код
local SubscribeAllTrades = function()
   local cls = split(getClassesList(), ',')
   for k, v in pairs(cls) do
      local sec = split(getClassSecurities(v), ',')
      for kk, vv in pairs(sec) do
         local ds = CreateDataSource(v, vv, INTERVAL_TICK)
         if nil ~= ds then
            ds:SetEmptyCallback()
         else
            message(v .. ':' .. vv)
         end
         ds = nil
      end
   end
end

OnI nit = function()
   SubscribeAllTrades()
end
запускаем - и квик намертво виснет, загрузив одно ядро на 100%. Через час-другой экперимент прекращен через прибитие квика. В научных целях упражнение повторялось неоднократно, результат один.

Глава вторая, исследовательская
Добавляем логи, смотрим, что происходит. Квик резво создает датасорцы, добирается до класса с опционами (а их там ой как много) и процесс начинает постепенно замедляться. Моего терпения хватило до момента, когда создание одного датасорца занимало 6 секунд, проверить апорию об ахиллесе и черепахе не вышло, квик был снова прибит.

Глава третья, кулхацкерская
Где-то между неудачными запусками в волшебном INFO.ini была ручками очищена секция [ALL_TRADES_DATA], так что содержала только
Код
[ALL_TRADES_DATA]
req-all-trades-from-curr-moment=0
Запускаем наш недоскрипт снова и что мы видим? Квик по мере создания датасорцев пишет в эту секцию коды инструментов. Ну, это логично и ожидаемо, пока дело не доходит до секции с опционами. Их и так много, но квику все мало и он начинает добавлять и добавлять опционы по второму, третьему и так далее кругу. Удалось получить INFO.ini размером в 200 с лишним мегабайт, дальше ждать смысла не было. Весь этот объем был набран исключительно классом SPBOPT, остальные классы были "нормальные", хотя я бы и ожидал от квика чуть большего интеллекта, чтобы самому заменить исчерпывающий список класса на ALL (при выборе всех инструментов в диалоге настройки получаемых данных он же как-то догадывается).

Глава четвертая, предположительная
Судя по всему, при подписке на опционы (лучше сказать на класс с большим количеством инструментов) квик где-то попадает в бесконечный цикл. Предположительно из-за жесткого лимита на размер буфера, т.е. после достижения определенного размера строки с инструментами квик дальше уже не смотрит, делает вывод "инструмент не найден" и добавляет его еще раз. История с INFO.ini, скорее всего, лишь внешнее проявление внутренней проблемы, поскольку поведение не меняется даже если там для всех классов вручную выставлено ALL.

Глава пятая, вопросительная
Опуская множество сопутствующих вопросов, я спрошу:
1) как из скрипта при закрытой ТОС подписаться на все доступные инструменты, чтобы это было выполнено в обозримое время?
2) если я из скрипта залезу в INFO.ini и перепишу секцию [ALL_TRADES_DATA], дабы освободить юзера от ковыряния в диалоге заказа данных, это будет грязный хак или не очень?

Глава пятая, пожелательная
Уже было такое пожелание здесь, но и я добавлю. Пусть CreateDataSource со вторым параметром nil и третьим INTERVAL_TICK подписывается сразу на весь класс (и при необходимости выставляет в INFO.ini для этого класса ALL).
Хозяйке на заметку: OnStop(), или "Зачем вы это делаете, мистер Андерсон?"
 
Олег, да, почему-то ожидалось, что раз эти функции описаны в доке, они должны существовать на момент запуска скрипта в виде каких-то внутренних заглушек, ан нет. Ну да ничего страшного, сами заглушек наделали, делов на копейку.
Время квоты в милли/микро секундах
 
Позвольте вклиниться вперед арки в пекло. Чтобы отслеживать, кто по чему ударил, надо подписываться на бирже на полный ордерлог, который стоит весьма неплохих денег. То, что нам в квике показывают забесплатно, это нечто непонятным образом из этого самого ордерлога произведенное, чтобы и юзерам что-то показать, и биржа не предъявила за слив платных данных. То есть ответ простой: тут нечего синхронизировать, стаканы уже "усреднены" и "размазаны".
Хозяйке на заметку: OnStop(), или "Зачем вы это делаете, мистер Андерсон?"
 
Утро вечера мудренее. Вот так будет работать
Код
stopflag = false

main = function()
end

OnS top = function()
end

OnI nit = function()
   main = function()
      while not stopflag do
         sleep(1000)
      end
   end
   OnS top = function()
      message("Hello, I'm OnStop")
      stopflag = true
      return 10000
   end
end
Или, словами говоря, сначала создаем функции-заглушки, потом в процессе работы их можно переопределять на что угодно. Естественно, речь больше о lua_pushcclosure() / lua_setglobal(), скрипты просто иллюстрация.
Хозяйке на заметку: OnStop(), или "Зачем вы это делаете, мистер Андерсон?"
 
Код
stopflag = false

OnI nit = function()
   OnS top = function()
      message("Hello, I'm OnStop")
      stopflag = true
      return 10000
   end
end

main = function()
   while not stopflag do
      sleep(1000)
   end
end

Три дня в отладчике, три раза свой код переписал, "где ж я дедлок-то устроил". Ан нет, не я. Все колбеки как колбеки, OnStop почему-то кэшируется где-то до начала OnInit, так что в OnInit ее переопределять уже бесполезно. Зачем, зачем вы это делаете, мистер Андерсон?

П.С. Тут ответа мистера Андерсона в общем-то не требуется, равно как и желать особо нечего, ну так оно вот есть и есть, жаль только, что нигде об этом не написано. Теперь написано - здесь.

П.П.С. OnI nit, OnS top это не я так написал, это движок форума упорно поправляет.
OnMainInit(), Новый луа-колбек
 
Цитата
Alexander Kopyatkevich написал:
Здравствуйте, Anton.
На данный момент проблема с отработкой функции OnInit() все еще разбирается.
Ваше предложение зарегистрировали как пожелание на создание функции OnMainInit(). Мы постараемся рассмотреть его и сообщить Вам результаты анализа.  Впоследствии, по результатам анализа, будет приниматься решение о  реализации пожелания в будущих версиях ПО.
Благодарю за регистрацию пожелания. Пара замечаний вдогонку.

1. Подобный колбек призван не столько победить ошибку с OnInit(), сколько сильно облегчить программирование встраиваемой длл, поскольку, будучи уже в потоке main в то время как квик нас ждет, мы можем сделать много чего полезного, что нельзя сделать из основного потока квика и в настоящее время откладывается до начала main(), где зачастую уже "неинтересно" это все делать, т.к. квик отпущен и поезд ушел. Как писал выше, можно сделать свой мейн с преферансом и прочим, но это плюс один поток.

2. По поводу OnInit() попался мне на глаза кусочек кода и, думается, примерно как-то так в квике и сделано. Тогда возникает подозрение, что после поимки ошибки в OnInit ссылка на луа-стек для main не выпускается и отсюда не происходит сборка мусора. Так сказать, в меру сил пытаюсь помочь в поисках (а-ля Чумак, через телевизор).
OnMainInit(), Новый луа-колбек
 
В нынешнем виде пара OnInit() / main() не позволяет надежно инициализировать скрипт, поскольку в момент выполнения OnInit() поток main еще не существует (или существует, но недоступен из скрипта), а в момент начала выполнения main() после выхода из OnInit() уже произоошли (или могли произойти) какие-то события, которые без принятия специальных мер будут пропущены. Очень удобно было бы иметь дополнительный колбек, назовем его условно OnMainInit(), выполняемый после создания потока main в контексте этого потока, но при условии, что основной поток квика ждет завершения этого колбека, то есть ни один другой колбек между OnInit и OnMainInit гарантированно не был дернут.

Очень грубо, только чтобы идею донести, как это могло бы выглядеть в коде квика

Код
void QuikInitializeLuaScript(...)
{
   // ...
   HANDLE hevent = CreateEvent(...);
   HANDLE hmainthread = _beginthreadex( ... , scriptmainproc, hevent, CREATE_SUSPENDED);
   script->OnInit();
   ResumeThread(hmainthread);
   WaitForSingleObject(hevent);
   // (по-хорошему тут надо на двух объектах ждать, на событии и самом потоке, кто первый выстрелит)
   // и только теперь продолжаем основной поток квика
}

unsigned __stdcall scriptmainproc(void * pvoid)
{
   HANDLE hevent = reinterpret_cast<HANDLE>(pvoid);
   myscript->OnMainInit();
   SetEvent(hevent);
   myscript->main();
   return 0;
}

Собственно, так и приходится делать, просто жаль создавать еще один поток, а main использовать только для ожидания завершения этого лишнего потока, когда то же самое могло бы быть из коробки.

lua_error() в OnInit, Неправильное поведение
 
Цитата
Alexander Kopyatkevich написал:
В качестве временного решения рекомендуем построить код иным образом,  чтобы обойти эту проблему.
Да, начал переписывать практически сразу, т.к. шансы на серебряную пулю были мизерные, да и хачить квик не хочется. Жаль, конечно, красивую архитектуру, try-catch -> lua_error и квик нас сам выгрузит. К сожалению, "иным образом" -- это сильно больше кода, но кому легко.


Для товарищей в теме замечу, что в таком режиме строго try-catch-(lock-custom_unload) в колбеках и cpcall -> throw во всех случаях, когда вызывается луа, единственное послабление - когда луа-функция точно не кидает ошибок, даже out of memory. Плюс можно местами извернуться, некоторые (в общем небезопасные) луа-функции ошибок не кидают при определенных условиях, например, lua_tostring не кидает, если не происходит приведения типа. Только что придется доку держать все время открытой и на каждый вызов лезть проверять, оборачивать его или обошлось, что, конечно, довольно-таки жесть.
как подключить .dll к lua скрипту , который выполняется в quik?, как подключить .dll к lua скрипту , который выполняется в quik?
 
Цитата
Денис написал:
Как можно сделать так же ?
Пока не смог найти никакой информации об этом.
https://www.lua.org/pil/24.html

Но добавлю бесплатный совет: если собаку не съели на сях и винапи, лучше так не делать. Из голого луа хотя бы квик не уроните.
lua_error() в OnInit, Неправильное поведение
 
Еще со своей стороны могу добавить.

1. Более наглядный вариант тестового скрипта

Код
sleep(1000)
message("Userdata object creation")
t = newproxy(true)
mt = getmetatable(t)
mt["__gc"] = function(self) message("Hi, I'm Garbage Collector") end

function OnInit()
   sleep(1000)
   error "Error in OnInit"
end

function main()
   error "Error in main()"
end
показывает, что при повторном запуске после ошибки мусор собирается сразу же, еще до пересоздания глобального объекта с финализатором. Что как бы намекает, что достаточно просто дать луа шанс доработать после ошибки, т.е. квику нужно после прибития скрипта выполнить какой-то (возможно, любой) луа-код в том же контексте. Однако,

2. Попытался проделать это, а именно запустил перед OnInit отдельный поток, который, если через секунду ничего не произойдет, будет дергать lua_gc(context_from_on_init, LUA_GCCOLLECT, 0). Не работает. Значит, объект еще не отмечен мусорным, его кто-то держит. Дальше уже надо в кишки квика смотреть, так что мне остается перейти на сторону зрителей.
lua_error() в OnInit, Неправильное поведение
 
Дополню. Проблема воспроизводится безо всяких длл следующим скриптом

Код
t = newproxy(true)
mt = getmetatable(t)
mt["__gc"] = function(self) message("Hi, I'm Garbage Collector") end

function OnInit()
   --error "Error in OnInit"
end

function main()
   error "Error in main()"
end

В приведенном виде после ошибки в main выводится сообщение гарбидж коллектора. Если, однако, раскомментировать генерацию ошибки в OnInit, сообщения от коллектора не будет.

Очевидным решением было воспользоваться lua_atpanic, установив свой колбек и затем из него вызвав стандартный. Но это не работает, квик, похоже, вообще до паники не доходит, а сваливает скрипт где-то раньше своим особенным путем.

Как говорится, какие будут предложения? Вариант "будет исправлено когда-нибудь" тоже хорош, но нам надо работать сегодня с, хайли лайкли, позавчерашним квиком. Если что, опыты на восьмой версии проводились.
lua_error() в OnInit, Неправильное поведение
 
Контекст: луа-скрипт загружает длл, все остальное делается в длл через луа-си интерфейс. В том числе создаются луа-объекты с метатаблицами и обработчиками сборки мусора (финализаторами). Наблюдаю два случая.

1. Где-то в main() вызывается lua_error(). Все вообще здорово, main() завершается, отрабатывают финализаторы для созданных луа-объектов, длл выгружается, в окне квика с луа-скриптами выводится описание ошибки.

2. Вызываем lua_error() в OnInit(). Скрипт также мгновенно останавливается, в окне квика с луа-скриптами появляется описание ошибки, дополнительно выводится окно сообщений с тем же описанием. Но вот внутри длл происходит адъ и израиль. Финализаторы луа-объектов не вызываются, длл остается загруженной в квик. Дальше возможны варианты:

2.1. Если закрыть квик, длл выгружается средствами ос, естественно, ни о каких финализаторах из луа речь уже не идет.

2.2. Если повторно запустить этот же скрипт, "зависшие" объекты из предыдущего экземпляра финализируются, отрабатывает вся последовательность очистки, как в случае с ошибкой в main(). Но, естественно, новый экземпляр скрипта остается "недобитым".

2.3. Если запустить какой-нибудь другой скрипт, на "недобитый" скрипт это никак не влияет.

Выводы:

1. На текущем этапе допускать lua_error() в OnInit() и, возможно, в каких-то еще колбеках (не проверял еще) не представляется возможным без сочинения костылей для принудительной очистки в случае ошибки.

2. Разработчикам квика просьба посмотреть, что можно "дернуть" после ошибки в OnInit(), чтобы скрипт был "добит" как положено. Думается, достаточно будет гарбидж коллектор попросить собрать мусор в контексте убитого скрипта.
Недосистема Quik, Недосистема Quik
 
Grasp Grasp, таки ответ неправильный. Лимитная заявка - это заявка с указанной ценой, которая матчится со встречными с такой же или лучшей ценой, а остаток ставится в стакан. В отличие от заявки по рынку. Не тот вы какой-то букварь изучали.
Недосистема Quik, Недосистема Quik
 
Grasp Grasp, прошу прощения, что вторгаюсь в Вашу тему, но
Цитата
Стоп заявка и Тек-профит - это частный случай лимитной заявки.
и следующие несколько предложений кагбэ намекают, что терминологией не владеете именно Вы.
ТВС: количество в штуках, Альтернатива полю quantity
 
Прогресс налицо ) Спасибо, ждем.
Страницы: Пред. 1 ... 18 19 20 21 22 23 24 25 26 27 28 След.
Наверх