nikolz написал: Вы напишите, куда хотите передать, тогда отвечу более предметно.
Передать мне надо в программу на C++ Очень хотелось бы пример в виде кода.
пример можно посмотреть в книге Джеффри РИХТЕР " Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows" --------------------- Вам надо определиться с механизмом передачи.
Юрий написал: DLL создавать умею. Но вы меня не совсем правильно поняли. Вопрос не в том как вернуть что-то из DLL в скрипт на lua, вопрос в том как передать дальше данные из DLL в сторонний софт. То есть мне нужна трансляция данных из QLUA в стороннюю программу через DLL в одну сторону. Вот я не совсем понимаю как это сделать в связке DLL и сторонний софт. Надо подгружать DLL в стороннюю программу и регистрировать колбеки чтобы при получении данных DLL передавала их дальше в мою программу или как ?? Вот мне такой пример нужен в виде кода.
В сторонний софт однозначно надо будет делать dll, если в нем не предусмотрен какой-либо механизм получения данных из других процессов. ------------------ Вы можете сделать одну dll c функциями для Lua и вашего стороннего софта. --------------------- Например, я делал dll, в которой функции для СИ и обертка к ним для Lua. ------------------------------ В питоне и Luajit есть возможность подключать dll на CИ. Т е для них не надо писать специальную dll, а достаточно dll на СИ. ---------------
Уважаемые знатоки, кто переходил с последних х32 версий на новые х64, предлагаемые брокерами, на том же железе, стало в итоге хуже или лучше? Увеличение нагрузки на железо чувствуется? Стоит ли ради перехода сносить сносить свою 32-битную систему и переходить на х64? Квик поставил первый раз в 20-м году. Сначала все было нормально, вроде бы, но потом начались тормоза и подвисания, никакие чистки файлов не помогают. Пару раз сносил все под ноль, чистил реестр, ставил заново, пробовал терминалы от разных брокеров - ничего не помогает и везде одни и те же тормоза. Пришел на форум, почитал, понял, что я не один, и у людей, с намного более продвинутым железом и желанием что-то изменить - проблемы те же самые: квик тормозит. Брокеры меня много раз пугали, что в 7-й версии квика некорректно отображаются данные, что она больше не поддерживается, и вы работаете на свой страх и риск, что ее срочно нужно поменять и т.д., на что я им отвечал, что мне проще поменять брокера. Я даже вижу, что до некоторых из них начало доходить, и на сайтах теперь выложена 7-версия, хотя их все меньше. Вопрос у меня простой: по вашим ощущениям и опыту, нужно ли запариваться и переходить на новые версии? Что я теряю, сидя на 7? На том же железе, в новых версиях тормозов больше или меньше, и на сколько сильнее они грузят железо?
смотря какое железо. У меня 7-я версия без проблем работала на XP. перешел два года назад на 8-ю так как сменил брокера. тестирую сейчас 9.5. ------------------------- Все работает нормально и быстрее, так как железо быстрее работает. ------------------------------- Процессор грузится примерно на 10%, но подробно не замерял. На скриптах так вообще просто летает. --------------------------- Полагаю, что проблема бывает не в зеркале, а в танцоре.
just написал: Подскажите, пожалуйста, какой параметр указать при выставлении заявки, чтобы сделка использовала кредитное плечо. Лучше имя параметра на английском, русские у меня в этой процедуре не проходят, мне так помнится.
У Вас должно быть соглашение с брокером на использование маржинальных сделок. если оно есть, то ваша заявка будет автоматом маржинальной, если Вы превысите размер собственных средств или сделаете короткую позицию.
Есть необходимость получить данные о сделке в момент ее совершения в своей программе написанной на C++.
Как из QLUA отправить данные в свою DLL вроде нагуглил и разобрался. А как передать эти данные из DLL в свою программу, я что-то ума не дам. Опыта в этом нет, прошу помощи.
Мне необходимо в своей программе получать данные о сделке и инструменте в момент совершения сделки в Quik. И нужна именно реализация через свою dll. Ну то есть QLUA -> DLL -> C++ и все это в реальном времени.
Помогите примером, кто разбирается в теме, пожалуйста.
DLL умеете создавать? ---------------------------- В DLL пишите функцию на СИ, используя API C for lua см здесь подробности: https://www.lua.org/manual/5.4/manual.html#lua_pushlstring ------------------------------------------------------------------------------------------- Будет примерно следующее:
Код
static int zerro(lua_State *L){ //это заголовок вашей обертки. Он всегда такой
// если вам надо передать данные в DLL из lua то далее пишите прием этих данных в СИ
long x=lua_tointeger(L,1) ; // это получили целое
double z=lua_tonumber(L,2); // получили double
char*ps=(char*)lua_tostring(L,3); //получили строку
// здесь делаете что хотите на СИ
...
// если надо выдать что-то в скрипт из вашей dll то пишем
lua_pushinteger(L,x); // вывели целое
lua_pushnumberL,z); //вывели вещественное
lua_pushstring(L,ps); //вывели строку
return 3; //указали сколько вывели
}
Недавно предлагал на форуме библиотеку для передачи данных из процессов и потоков на любых языках для QUIK. Оказалась, что никому не нужно. =================== Сомневаюсь, что сможете решить вопрос синхронизации потоков и процессов, если говорите, что лишь читали как делать. ---------------
Рекомендую почитать книгу:
Джеффри РИХТЕР " Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows"
Функция CreateDataSource никогда не возвращает ошибку, И это создаёт большие проблемы при разработке. В неё можно запихнуть любой мусор, и она скажет: "Всё отлично".
Если используете колбек, то данные получаете поэлементно. ------------------------- Если используете DDE, то данные приходят блоками по 16384 элемента. ---------------------- Обнаружить наличие данных можно на первом же блоке. ------------------------- Время приема одного элемента по DDE не более 10 мкс. ----------------------- Время приема блока данных 16384 не более 0.1 секунды. --------------------- Зачем ждать годами, вместо того, чтобы изучить СИ и сделать то, что хотите. --------------------------------- "Без труда не бывает не ... я."
Прикольно, Посчитать сколько "заработал" очень просто Из того что стало в деньгах отнимите то, что было. И получите реально сколько пришло или ушло. А считать по цифирькам в табличках виртуальный приработок - это мазохизм какой-то.
Дмитрий написал: Спасибо за ответ. Но я понимаю, что функция OnStop не прерывает выполнение программы сама, а лишь вызывается при остановке и возвращает время на остановку скрипта. Я про другое. У меня эта 1мс никак не выходит. Любой скрипт останавливается ровно 5 секунд (которые заданы по умолчанию) и никак не реагирует на мои данные по return - делал и мало (1мс), и много (30с) - все одно пауза при нажатии "остановить" ровно 5с.
Владимир написал: Старые песни о главном. Чуть ли не с самых первых своих сообщений я говорил: несмотря на то, что Lua есть препоганейший язык, а С мой наилюбимейший язык на протяжении десятилеий, писать нужно только на чистом Lua. А уж привлекать сюда ещё какое-нибудь говно вроде Python и вообще есть мазохизм в чистом виде. И что задача организации торговли настолько тривиальна в техническом плане, что работать должен один-единственный скрипт написанный на одном-единственном языке Lua и, по возможности, работающий в одном-единственном потоке main. Блин, она ещё и платная?! Как говорил незабвенный Пётр Павлович Ершов: "Пусть полюбится кому, я и даром не возьму". ::
Вы уже не первый раз пишите на форуме эту глупость и чушь. Вам не стыдно за свое невежество? ------------------ Объясняю популярно для чайников. ----------------------- Не существует процессора, который может исполнить программу "чистого луа", так как она транслируется в байт код, а байт код не может исполнить процессор. ------------------------- Байт код луа исполняет другая программа, которая написана на чистом СИ. ----------------------------- QLUA - то тоже библиотека на чистом СИ. -------------------------- Все арифметические операции и обработку строк на луа исполняют программы на чистом СИ ----------------------- Моя библиотека - это одна из тысячи библиотек на чистом СИ, которые используются в Вашем чистом Луа. --------------------- Поэтому чистый луа - это птичий язык байт-кода, который без программ на СИ никто не понимает и не исполняет.
Предлагаю принять участие в тестировании моей библиотеки обмена сообщениями между процессами, потоками , приложениями, скриптами на любом языке программирования. ------------------------------- Как это работает Приложению или скрипту присваиваем номер NUM от 1 до 30000. ---------------- 1) Послать сообщение S: res=nkLp.send(NUM,S) , если успешно , то res=1. Num - номер получателя. 2) Принять сообщение S: на Lua S=nklP.get(NUM), на других языках nkLP(Num,S). Если нет, то пусто. Num-номер получателя. ================= Возможности 1) В скриптах для QUIK, колбеки можно размещать лишь в одном. Этот скрипт может рассылать информацию всем желающим. ----------------------------- 2) Индикаторы и скрипты могут обмениваться информацией. ------------------------------ 3) Любое внешнее приложение , например на питоне, может обмениваться информацией с QUIK или любым другим приложением, например, на луа. ================= Чем это решение лучше других 1) Другие таких решений нет . Если знаете, дайте ссылку. 2) Не блокирует потоки, не использует файлы, не обращается к ядру ОС. 3) Самый быстрый способ обмена. ================== Ограничения тестовой версии: В данном решении длина сообщения 64 символа. Используется лишь один ящик сообщений. Т е новое сообщение будет передано лишь после того, как прочитают предыдущее. В сообщении нет обратного адреса. Тестировал на Win10 64bit, Lua 5.4 =================== Как принять участие в тесте: Написать свою почту в личку.
Мне надо передать "строку" (string) из QUIK (lua) на скрипт Python. Подскажи пож самый простой способ, но не через жесткий диск. Может какой пример завалялся ?
В настоящий момент у меня реализована передача через текстовый Файл. То есть Quik записывает (постоянно перезаписывает) файл txt, а функция Watchdog на Python его подхватывает и обрабатывает
Спасибо
Написал библиотеку для обмена строкой приложений, процессов и потоков на Си,Lua,Python. ---------------------- Если надо, пишите в личку почту. --------------------------- Пока могу выслать бесплатно для тестирования вариант с максимальной длиной строки 63 символа .
Мне надо передать "строку" (string) из QUIK (lua) на скрипт Python. Подскажи пож самый простой способ, но не через жесткий диск. Может какой пример завалялся ?
В настоящий момент у меня реализована передача через текстовый Файл. То есть Quik записывает (постоянно перезаписывает) файл txt, а функция Watchdog на Python его подхватывает и обрабатывает
Anton Belonogov написал: Andrey Malyar , добрый день. Для того, чтобы данные последней торговой сессии сохранялись до установления нового соединения с сервером, выполните следующую настройку ( Система / Настройки / Основные настройки... (F9) ) в Рабочем месте QUIK: Программа / Сохранение данных - для параметра Очищать данные после смены даты: необходимо установить значение На сервере (при установлении связи) .
Спасибо! Проверил, именно так и стоит галочка. Может еще что пропустил, у меня вылетал квик и всё заново настраивал
если вылетает или закрываете крестом вверху справа, то не сохраняет.
Евгений написал: А почему зависают графики при отправке заявки, пока не пройдут сделки ? Специалисты по квику ответьте пожалуйста, иззза большого когл-ва графиков на вкладке может быть такое ?
Скорее всего тормозит процессор. ---------------------- чтобы выяснить причину, сделайте следующее: ----------------- 1) Если окон с графиками много, то сверните их и проверьте вашу гипотезу. --------------- 2) откройте диспетчер задач и посмотрите загрузку процессора и использование памяти .
Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа. Впоследствии, по результатам анализа, будет приниматься решение о реализации пожелания в будущих версиях ПО.
Так как отключить всплывающие окна сообщений биржи. С введением бессрочных фьючерсов, с ума сойти можно. Эти сообщения сплошным потоком идут. на русском. на английском. это дурдом полнейший... Заявку выставить не дают. Постоянно под руку выскакивают. Уже из-за них пару раз путаюсь, сбивают с толку. Сделайте что либо пожалуйста, что бы можно было отключить эти сообщения..
система->настройки -> основные настройки->сообщения убрать галочку с "обычные", если мало , то и с "отмеченные как важные"
kotopas написал: Извините, не могу понять мне нужно получить согласно скрину число 121.29 эта цена одной акции за которую я её купил это число получить с помощью функции нельзя можно только рассчитать?
см документацию по QLUA раздел "Функции для обращения к строкам произвольных таблиц" -------------------- таблица depo_limits -------- В цикле найдите в таблице эту акцию и прочитайте цену приобретения wa_position_price
Alex написал: Получается что mmap всё равно работает чем файловую систему.
Вот перечень методов обмена данными из моего арсенала: ------------------- 1) самый быстрый способ (почти) shared mеmory . Использую его для передачи небольших объемом и синхронизации потоков. ---------------------------- 2) DDE - использую его для получения таблицы ТТТ и доски опционов в луа . ---------------------------- 3) Mapping file - обмен любыми объемами данных между процессами и потоками. Использую его для индикаторов, ИИ, сбора исторических данных об инструментах на биржах. =========================== Маппинг это не обмен через файлы, а отображение файлов на адресное пространство процессов. Две большие разницы. ======================
Евгений написал: 1. Отправляю заявку через стакан по Si на покупку по рыночной цене 2.Заявка срабатывает и совершается сделка 3. Звук оповещения из настроек для сделки проигрывается 4. Через одну 1,5 секунды звук повторяется при появлении треугольника сделки
Почему разница между совершением сделки и появлением треугольника сделки пока не знаю возможно из за большого кол-ва графиков по Si так как по сберу SR такого нет, открыт 1 график.
Вероятно что именно из за задержки между совершением сделки и появлением треугольника сделки и происходит двойное проигрывание звукового сигнала.
полагаю что разница в том, что на графике стрелка появляется при приходе данных в таблицу сделок а информация о совершении сделки приходит в ответе на транзакцию раньше, чем информация в таблицу сделок. вот и получается два раза.
Alex написал: Подскажите как передать информацию из QUIK в скрипт PYTHON через память компа?
В настоящий момент реализована передача через текстовый Файл. То есть Quik записывает постоянно перезаписывает файл, а функция watchdog на Python его подхватывает и обрабатывает Но есть проблема - жуткие тормоза!
Подскажите как сделать через ПАМЯТЬ ??
Спасибо!
Я использую mapping для связи приложений и потоков. --------------------- Для питона можно посмотркть здесь:
Александр написал: nikolz Пологаю что Вы пологаете... Понятна Ваша с Дмитрием реакция и вполне предпологаема. Если спуфинг это болезнь которой нет то и лечить нечего (все просто легко и понятно) а если еще этой болезни в диагноз положить УК РФ то тем более говорить об этом даже запрещено. Психологически тяжелее болезнь признать, лечить и быть открытым. Но что-то нам все таки намекает о существовании манипуляций на рынке... кто-то об этом все таки говорит... что же это может быть... хм... кто эти люди??? Может быть закон и ЦБ говорят о запрете манипуляций??? А поскольку об этом говорят значит это есть???!!! Или я ошибаюсь и мы здесь разговариваем о чем-то неземном и если это где-то есть то только не у нас??? Поправте меня если я не прав. Теперь о толпе зевак у витрины... Без этой толпы зевак у витрины не исполнился бы ни один ордер. Говоря о сведении ордеров вы говорите уже о продолжении истории а начало как раз таки зарождает именно толпа зевак. Это именно те самые одни из зевак (покупатель и продавец) передвигают цену в область сведения ордеров. Биржа не сможет исполнить волю которой нет. Биржа сама ничего не двигает(предпологаю) Я Вам скажу даже больше уважаемый nikolz, никто не сможет исполнить волю которой нет(пологаю). Поэтому если у Вас в голове нет спуфинга то я очень этому рад, в этом месте нам обоим очень комфортно. Вам комфортно потому что лечить него и Вы вполне предпологаемо можете спокойно торговать, мне комфортно тем что чем больше неосведомленных зевак на рынке тем больше(пологаю) я смогу заработать. Я вас с Дмитрием услышал и вобщем-то жду ответа от поддержки.
вообще-то в период нормальной работы, глубина стаканов было 200, а не 20, как Вы пишите. 200 вам тоже мало? -------------------------------- Я например, вижу рынок иначе, чем Вы . Есть у меня индикатор отношения предложения к спросу. ---------------------------- мой анализ показывает, что это отношение в общем коррелировано с движением цены, но это было верно до войны. ----------------------------------- сейчас на бирже практически нет рынка. ------------------------ Но соотношение в стакане однозначно показывает сильный рынок или слабый ------------------------ Например , когда рынок на дне это отношение 0.5, когда рынок сильный и растет это отношение выше 2. ------------------------------- Но Важно не абсолютное значение, а еще и динамика. -------------------------- Если было 4 (по 5 вчера, то 2 (по 3 сегодня) -это падение рынка. ------------------- Примерно так. ---------------------------- как я понял, Вы пришли поплакаться, я вам сочувствую. ------------------------- Если же у Вас есть конкретные идеи и хотите обсудить, то кончайте скулить и начинайте лаять.
Александр написал: Видимо не совсем Вы меня поняли Дмитрий. То о чем Вы говорите это масло маслянное... вода мокрая, металл это железо.... понятное дело если за прилавком нет яблок то их не купишь но ведь это не наш случай. Тут речь о психологии, о манипулировании торгами. Высокий спрос всегда толкает цену вверх и наобарот избыток предложения вызывает падения цены... тут обсуждать нечего это аксиома. При чем тут сведение ордеров?
Полагаю Вы ошибаетесь. --------------------- Заявки в стакане - это не спрос, а толпа зевак у витрины магазина. -------------- Спрос - это именно рыночные заявки на покупку, а предложение - это рыночные на продажу. ---------------------- в итоге если предложений т е рыночных заявок на продажу будет больше, чем рыночный спрос, то цена пойдет вниз , и наоборот. ------------------------ У Вас спуфинг в голове. ========================== "А эти по три, но маленькие, но сегодня... А те вчера по пять... но большие... но вчера..."
У Вас написана какая-то хрень поэтому и не работает. ------------------- Поясняю: InfoS - это значение которое вы выводите на график. Оно у Вас получается так: InfoS =getBuySellInfo("MC0002500000","32MRT","TQBR","SBERP", 0).long_wa_price
согласно документации
17
long_wa_price
STRING
Средневзвешенная стоимость длинных позиций по инструментам
Т е Вы пытаетесь вывести на график строку текста. Вот терминал молча думает о Вас , поэтому и зависает.
Для тех, кому интересно. ---------------------- В результате тестов, получилось следующее решение: ---------------------------- 1) стаканы и обезличенные сделки принимаю в колбеках ----------------------- 2) свечи принимаю в main ------------------------- 3) индикаторы и алгоритмы решений реализую в отдельных потоках из пула потоков. ================== Вот затраты времени на тестовом сервере: Условие тестирование 220 инструментов 220 стаканов обезличенные сделки по всем акциям на демо сервер. =================
Информация к размышлению. Всем известна рекомендация не делать ничего в колбеках, а переносить все в main. -------------------------- Но не все то золото, что рекомендуют. =============== проведем эксперимент. Колбек AllTrade обработка данных выполняется так:
Код
local clas=t.class_code;
local sec=t.sec_code;
local t1=Data[clas]; if t1==nil then t1={}; Data=t1 end
local t2=t1[sec] if t2==nil then t2={} t1[sec]=t2 end
t2[#t2+1]={t.trade_num,t.flags,t.price,t.qty,t.value};
Рассмотрим два варианта ----------------- В первом случае все делаем в колбеке. ------------------- В результате получаем время исполнения (мкс)
При подаче и обработке лимитных заявок давно использую простую последовательность:
sendTransaction(...)( задание TRANS_ID) --> OnTransReply(...)(получение номера заявки order_num )-->OnTrade(...)(обработка исполнения заявки с номером order_num) Функцию OnOrder() тут не использую благо до сих пор не было необходимости.
Попытка сделать подобную схему для стоп-заявки типа тэйк-профит поставила в тупик - полученный от OnTransReply при выставлении стоп-заявки order_num бесполезен т.к. после срабатывания условий тэйка сервером выставляется новая заявка с новым номером order_num который нужно как-то отфильтровать и получить.
Прошу у знатоков совета по оформлению последовательности функций обратного вызова для этого типа заявок.
1) OnTransReply работает если заявку выставляете или снимаете скриптом. Если Выставляете или передвигаете руками, то работает лишь OnOrder. Т е Ваш робот пропускает мимо ушей все что делает человек. ---------------- 2) Аналогично OnStopOrder. В получаемой им информации есть
linkedorder
NUMBER
Номер заявки в торговой системе, зарегистрированной по наступлению условия стоп-цены
Артур написал: Мне нужно именно ето кто-то сможет помочь
он под 32 битную версию и использует старую библиотеку переписывать под 64 бит версию замучаетесь. На луа будет и код проще и возни меньше. ------------------------ К телеге пристроить двигатель конечно интересно, но малоперспективно. Бесплатно никто не будет его допиливать, а за плату он станет золотым.
Артур написал: Здравствуйте у меня есть шаблон для создания торгового робота на Delphi 7 когда питаюсь подключить к Qwik у выскочит окошка с ошибкой вот сам робот если вам не трудно исправте ошибку в коде https://disk.yandex.ru/d/Yba1ln8qfGDBQQ
Выкиньте это Г-но ( с большой буквы) 13 летней давности и пишите на луа.
Незнайка написал: Наверное, это можно проверить опытным путём.
Если обращение к хранилищу данных реализовано через одну дверь - основной поток, - то все остальные потоки, сколько бы их не было запущено, выстроятся в одну очередь у входа в дверь. И при запуске нескольких скриптов, "одновременно" запрашивающих, например, данные стаканов мы не увидим сколько-нибудь существенного ускорения по сравнению с одним скриптом, запрашивающим по очереди такое же количество стаканов. Проверим:
Код
function main ()
local t = os.clock ()
for _ = 1 , 100000 do
getQuoteLevel2 (class, sec)
end
message (tostring( os.clock () - t))
end
Проведём несколько тестов с 1-м, 2-мя, 3-мя, 4-мя одновременно запущенными скриптами.
Результаты: 1 скрипт: 6.5 сек 2 скрипта: по 15.2 сек каждый 3 скрипта: по 23.1 сек каждый 4 скрипта: по 30.4 сек каждый
При этом, во всех случаях было загружено только одно ядро процессора, что как бы намекает на использование только одного потока для доступа к данным.
Относительно приема с сервера данных в одном потоке я уже писал ранее и приводил тест аналогично вашему. ---------------------------- это связано с тем, что для реализации приема в майн используется общий глобальный стек луа - т е единственная область памяти и следовательно доступ к ней сделан с блокировкой. ================ Относительно приема данных в различных потоках есть разница в получении данных по свечам и по стаканам. -------------- История Стаканов очевидно не хранится в архиве, поэтому прием стакана выполняется в основном потоке и изменяет образ стакана в архиве. ---------------- Со свечами дело иначе. Закрытые свечи - это история и она накапливается в архиве. Прием же выполняется лишь по незакрытой свече. Поэтому чтение свечи из истории вполне допустимо в различных потоках одновременно. ------------------ Но чтобы это было возможно, надо реализовать в QLUA механизм работы с глобальным стеком Один пишет -все читают. А это очевидно разработчики делать не стали. Поэтому и не выходит каменная чаша. ============= Но даже в этом случае , прием в различных потоках пусть и последовательно позволяет ускорить вычисления по сравнению с приемом в одном потоке. ---------------- Приняв на грудь стакан, поток приступает к его обработке, а следующий поток примет свой стакан и начнет его обрабатывать параллельно с первым. ------------- Таким образом, даже в случае последовательного приема потоками стаканов, обработку их содержимого потоки будут делать параллельно . ------------------ Так как основное время умный робот тратит не на прием стаканов, а на анализ их содержимого и беседу с товарищами, которые тоже приняли по стакану, то прием даже по очереди стаканов актуален и перспективен.
nikolz написал: Прием данных от источника и стаканов реализуется в main. ----------------- Все работает замечательно. Но узким местом является прием данных всех инструментов в одном потоке main. ----------------------- Хочу принимать данные и стаканы в отдельном потоке каждого инструментов.
А разве приём данных идёт не через основной поток? Хоть тысячу отдельных потоков сделай, они все встанут в очередь при обращении к хранилищу. Или вы располагаете другой информацией?
Как сделали разработчики, знают лишь они. --------------- Могу предположить, что есть как минимум два слоя приема данных. ----------------------- Первый - это прием по каналу связи данных с сервера и запись их в архив терминала. ------------------------- Возможно, что на этом этапе мы можем данные получать через колбек источника. --------------------- Второй - это чтение уже принятых данных из хранилища терминала - это делают функции O,H,L,C,V,T. ================= Для многопоточного получения этих данных важным фактом является то, что нам не надо писать эти данные в архив. --------------------------- Так как в потоках мы лишь читаем из архива уже размещенные там банные , то никакой синхронизации потоков нам не требуется. ------------------- Т е в данном случае потоки работают по принципу один пишет - остальные читают. ============== Поэтому прием данных лишь в основном потоке реализуется в худшем случае лишь в первом слое. ================= Я не использую колбек источника данных для приема , поэтому предполагаю возможность одновременно ходить в архив любому количеству потоков.
nikolz написал: Так что HFT робот вполне реально, но должен быть в дата центре.
Дата центр вам не поможет. Вам надо арендовать для вашего QUIK специальный сервер на бирже с прямыми каналами доступа к торгам. Но и это вам не поможет при использовании стандартного рабочего места QUIK, так как API взаимодействия QLua с QUIK выполняется в среде Lua, в которой автоматическое управление памятью, и в произвольные моменты времени может запускаться сборка мусора. Сборка мусора может вносить заметные задержки (не исключено миллисекундные) при взаимодействии вашей программы с QUIK. Вы, конечно, можете отключить сборку мусора, но тогда флаг вам в руки :: . Попробуйте. ---------- Вообще, надо заниматься тем, о чем есть хоть какое-то понятие. HFT роботы не "манна небесная" и о проблемах их использования (как технических так и алгоритмических) достаточно информации в интернете.
объясняю почему у меня сборщик не мешает. Тестировал своего робота на выставлении и снятии заявок по 200 инструментам. При этом осуществлялся прием данных по каждому из инструментов по таймам 1,3,30 мин. Работал примерно 4 часа. выставил и снял 150 тысяч заявок. Размер памяти скрипта составил 5 Мбайт. При работе моих скриптов практически нет мусора. Если сборщик будет мешать, то я его могу отключить от слова навсегда. При этом размер матрицы -маппинг фалов на диске открывался по 2 Мбайта на инструмент. т е 400 Мбайт. -------------------
В функции main для каждого инструмента запускается свой поток. Потоки берутся из пула.
Без иллюстрации кодом вот этого момента, сказать что-то предметное - невозможно. Ибо не понятно чем ваши потоки (где не работает) отличаются от потока main (где работает).
У меня в потоках запускаются скрипты, но в них нет библиотеки QLUA. Как ее туда включит пока не разобрался. --------------------- Относительно main. Возможно ошибаюсь, Но как я понял, в main и основной программе скрипта используется общий глобальный стек. Делал так, и вроде бы работает получение данных, но неустойчиво. =============== В настоящее время я принимаю данные для всех инструментов в main. ---------- А в скриптах других потоков использую матрицу данных, которая реализована через мапинг. Через эту матрицу все скрипты получают доступ к любым данным любого потока. При этом нет дублирования данных, но могу работать с векторами данных до 2 миллиардов элементов и таким же числом векторов. -------------------- Так как реализую принцип - один пишет - все читают, то никакой синхронизации не требуется , так как нет конфликтов потоков. -------------------- Синхронизацию требуется между колбеком, main и вызовом потока для конкретного инструмента. ----------------------- Так как возможна ситуация, когда в очереди уже есть инструмент, либо для этого инструмента уже запущен поток. -------------- Тут я использую синхронизацию колбека и майн через системный event, а синхронизацию потока и очереди через атомарные операции. ----------------- Все работает просто замечательно. =============== Провел тест максимального числа потоков,. В результате получилось, что в пуле было открыто 11 потоков. ------------------ Причем первый поток запускался 23 тысячи раз, а одиннадцатый - 2 раза. ------------------ Потоки и прием данных активировались по колбеку onParam по 200 инструментам на тестовом сервере. -------------------- Время вызова колбека составляло в основном 10 мкс. ----------------------- Понятно, что данные на самом деле приходили пакетом и в данном случае это время реакции на очередную запись в пакете данных. ================ В итоге, пока не получилось разнести прием данных по различным потокам, чтобы работало устойчиво. ------------------ Причину не знаю. ------------------------- Если что-то подскажите, буду признателен.
и еще... ------------------- вам только кажется, что скрипт в main у Вас на чистом луа. --------------- На самом деле вы используете в main QLUA А она на СИ. ============ Кроме того, есть срытый от Вас тормоз, который заложен в основание main. ================= Дело в том, что все функции колбека объявляются как глобальные . все функции библиотеки QLUA тоже являются глобальными. -------------------------- Т е скрипт в основном потоке и в потоке main имеют общий глобальный стек. Это значит, что main и колбеки не могут одновременно как минимум записывать данные в глобальные переменные. А как максимум, вообще обращаются к глобальному стеку последовательно. ================= Т е поставьте тормоз в колбеке на глобальной функции и функция main начнет глючить и тормозить либо пропускать обработку Можно сделать и наоборот. =============== Поэтому периодически и вылетают непонятки, которые особо пытливые ловят и выкладывают на форуме. Но прикольно то, что разработчики такие глюки не поймают от слова никогда, так как им для этого надо весь глючный скрипт и соответствующий поток данных. ============== В итоге, так как проблема в концепции построения скриптов, то бороться с ней Вы будете вечно. Желаю успехов.
Владимир написал: nikolz, Ни секунды не было сомнений, что "робот с любым числом алгоритмов и любым числом инструментов должен работать в одном скрипте QUIK"
На весь скрипт имеется один-единственный колбек, который, естественно, существует в одном экземпляре.
Любой алгоритм для работы робота пишется в виде скрипта на чистом луа, без QLUA и выполняется в потоке main для всех инструментов.
Параметры по инструменту или портфелю хранятся в одной глобальной переменной (таблице Lua) и никуда не передаются.
И никаких индикаторов!
Тестировал данную реализацию на разном количестве инструментов - обычно до двух тысяч (пробовал и на 20000, но притормаживает).
Ну очень нравится как оно работает в любой из версии Lua и QUIK.
Всё это работает вообще без каких-либо библиотек.
Очень быстро у меня исчезли любые пожелания по допиливанию QUIK. Я их просто боюсь - не все ещё глупости сделаны.
А насчёт HFT на QUIK согласен: это диагноз. ::
Так тоже делал. ---------------------------- Но узкое место в таком решении - это один поток main для всех инструментов. -------------------- Если тестировали, то хорошо бы увидеть конкретное затраченное время на обработку изменений всех инструментов в потоке main. ------------------ Возможно, что вас устраивает такое решение, а мне интересно иное. ------------------ Мое решение позволяет масштабировать робота по алгоритмам , инструментам и приложениям. --------------- К сожалению, не видел пока каких-либо подробных тестов по быстродействию сторонних решений , в том числе и Ваших . =========== В моем варианте реакция робота на заявку и изменение цены составляет не более 100 мкс. ------------------------ Это время вполне соизмеримо с реакцией существующих HFT роботов. ----------------------------- А уж в сравнении с человеком, который играет в стакане с реакцией в 1000 раз медленнее, чем мое решение Вообще говорить не серьезно. ------------------------- Так что HFT робот вполне реально, но должен быть в дата центре. ============ Кроме того мое решение универсально и позволяет делать скрипты на луа многопоточные,. ============= Следующим этапом моего решения будет самообучающийся робот. ------------------- Следите за новостями.
Roman Azarov написал: Данные пожелания еще не были рассмотрены. Как только появится какая-то новая информация, мы сообщим об этом в данной ветке форума.
Мое предложение от 22.04.2021 15:59:54 https://forum.quik.ru/messages/forum10/message55019/topic6356/#message55019 Прошел год. ----------------- Напомню описание ситуации и вариант ее устранения. --- Бывают ситуации зависания в QLua, когда основной поток обслуживания колбеков всех скриптов пользователя, а также таблиц QUIK (это не таблицы Lua), блокируется выполнением длинного цикла пользовательской программы на «чистом» Lua, в котором нет ни вызова seep ни вызова дру-гих C-функций. Это может порождать ошибки, которые для многих пользователей QLua (использующих несколько запускаемых скриптов) являются неожиданными и труднообъяснимыми. Блокируются выполнения колбеков всех скриптов из-за выполнения длинного цикла пользовательской программы на «чистом» Lua в каком-то из запущенных пользователем скриптов. При этом зависает рабочее место QUIK. Это системная ошибка QLua. ---- Есть простой вариант реализации пожелания (далее список изменений, реализующих этот вариант в тексте исходников QLua ): 1. В файле lstate.h после строки: lu_byte allowhook; добавить: int Счетчик_для_переключения_State; 2. В файле lstate.с после строки: L->errfunc = 0; добавить: L->Счетчик_для_переключения_State = 0; 3. В файле lstate.с после строки: L1->stacksize = BASIC_STACK_SIZE; добавить: L1->Счетчик_для_переключения_State = 0; 4. В файле lvm.с после строки: StkId ra; добавить: if (++L->Счетчик_для_переключения_State > 1000) { // 1000 надо задать кон-стантой L->Счетчик_для_переключения_State = 0; lua_unlock(L); lua_lock(L); } ----------------------- В чем проблема реализации этого пожелания?
Таких проблем не существует, если делать как у меня. --------------------------- Робот с любым числом алгоритмов и любым числом инструментов работает в одном скрипте QUIK. ------------------------- Каждый колбек существует лишь в одном экземпляре. ------------------------ Любой алгоритм для работы робота пишется в виде скрипта на чистом луа, без QLUA и загружается в отдельный поток для конкретного инструмента функцией main скрипта QUIK. ------------------------ Параметры по инструменту или портфелю передаются как параметры функции в скрипт алгоритма, а данные и индикаторы - в виде mapping матрицы. ---------------------------- Тестировал данную реализацию на двух сотнях инструментах. ================= Ну очень нравится как оно работает на версии 9.4. ---------------------------- Можно делать HFT, чего раньше даже не думал, что на LUA в квике будет так быстро работать. ------------------------------- Правда все это работает с моей библиотекой на СИ. --------------------- В итоге , В настоящее время Вообще нет никаких пожеланий по допиливанию QUIK.
Добрый день, Ищу решение следующей проблемы. ---------------- Сейчас у меня реализовано так: -------------------- В функции main для каждого инструмента запускается свой поток. Потоки берутся из пула. Если свободного нет, то создается новый. ------------------ Данные передаются в поток через параметры скрипта и мапинг-файлы. ------------------ Прием данных от источника и стаканов реализуется в main. ----------------- Все работает замечательно. Но узким местом является прием данных всех инструментов в одном потоке main. ----------------------- Хочу принимать данные и стаканы в отдельном потоке каждого инструментов. ------------------ Применение общего глобального стека не дает результата. ---------------------- Если кто-то решил данную проблему, просьба сказать каким методом. ------------ Спасибо ================= Отдельная пожелание разработчикам. Реализовать указанные функции для приема данных и стаканов для произвольного потока.
Denis написал: В смысле как обозначаются эти параметры у Квика при экспорте по DDE?
сделайте вывод по DDE в excel c флагом формальные заголовки и получите все имена столбцов таблицы.
Вы видимо не поняли, вопрос совершенно в другом. Заголовки вывести не проблема. В настройке работы макроса с выводом по DDE необходимо указать следующие данные: DDEInitiate (App, Topic) DDERequest (Channel, Item).
то что напишите в окошке "вывод через DDE" "Рабочая книга" и "Лист"
Дмитрий написал: Напрочь отказывается вызываться функция OnTransReply для опционов. Один в один написан код для заявки на фьючерс и опцион, по факту обе заявки системой выставляются, по итогу OnTransReply для фьючерса вызывается, а для опциона нет. Пробовал и вместе, и отдельно опцион запускать - ни фига. p.s. подскажите, а есть на форуме поисковик по ключевым словам? может этот вопрос был в другим темах, но при отсутствии поисковика очень трудоемко все листать
если колбек на транзакцию не вызывается то ошибка в тексте заявки. эту ошибку можно прочитать а ответе sendTransaction (см документацию)
Владимир написал: Nikolay, Это если их инициализировать прямо в коде. У меня большинство массивов начинаются с нуля, а за дырками (в тех массивах, где они возможны) и размерами массивов слежу сам. Например, в стеках (заявок, сделок, прерываний) длина массива (она же ID последнего элемента) хранится как раз в его нулевом элементе. Очень удобно и очень надёжно, и плевать, что там "оператор #" по этому поводу думает - им я вообще не пользуюсь. Не говоря уже про "переопределенные метаметоды".
почти как у меня, тоже в нулевом - максимальный размер таблиц сделок и стопов, но храню не стеком.а таблицей. Стек - это кипа - LIFO. В этом случае у Вас последний обрабатывается первым, а до первого очередь может никогда не дойти. Должна быть либо очередь либо таблица.
Denis написал: Добрый день! Описание проблемы ниже, буду благодарен за помощь. В работе множество таблиц, поэтому переносить данные в ручном режиме каждый день не очень удобно.
Проблема: Есть макрос в Эксель, который сортирует данные из Квика. Макрос работает отлично, если данные в него добавить руками через "копи-паст". Эти же данные, точно так же экспортированные в Эксель через DDE макрос не видит.
Погуглив вопрос, узнал, что такая проблема имеет место быть. Для корректной работы макроса нужно сообщить, что данные поступают по DDE. Cудя по справке Excel нужно знать приложение ведущее вещание по dde и что-то типа "имени документа" этого приложения. Прилагаю два скриншота.
возможно поможет. При экспорте по DDE таблиц надо отключить все фильтры таблицы.
Дмитрий написал: sendTransaction (transaction_kill)
так как нет колбека, то ошибка вероятно в транзакции. -------------------------------- сделайте так: --------------- s=sendTransaction (transaction_kill) message( tostring(s))
Номер заявки совпадает с табличным в QUIKе (первое сообщение в коде). Транзакции на снятие заявки проходит - второе сообщение в конце с TRANS_ID выходит (т.е. транзакция прошла), а по факту снятие активной заявки не происходит, почему так? чего не хватает?
1) отобоазите сообщение которое возвращает sendTransaction; 2) если колбек OnTransReply(t) принимает ответ сервера, то выведите сообщения t.result_msg; а также t.error_code , t.error_source -------------------- и будет понятно что и где.
local S = "orders" ; local t = SearchItems (S, 0 , getNumberOf (S) - 1 , function (flag) if bit.band (flag, 3 )~ = 1 then return false end return true end , "flags" ) -- #t -число активных заявок
Спасибо. 1. А меняет ли что-то именно такая процедура в сравнении с простым перебором в цикле?
2. Для проверки активной заявки у Вас используется кроме бита активной заявки еще и бит "заявка снята", это же, не обязательно?
3. А вообще в моем случае вопрос можно решить очень просто. Ответ можно найти, просто внимательно изучив вопрос... :) Большое спасибо ВСЕМ за участие и советы...
1. быстрее. 2. бывает так, что приходит заявка с установленными 0 и вторым битом. такая заявка снята. Но бит активности есть. Проверка исключает эту ситуацию.
Старатель написал: Постоянно сканировать таблицу orders - не лучшая затея: при большом числе заявок гарантированы тормоза. Самый простой вариант - работать с колбеками OnOrder и OnCleanup. В OnOrder проверяете статус заявки, если активна добавляете в таблицу. Если заявка исполнена или снята (в т.ч. в клиринг), вы получите об этом OnOrder и удалите из таблицы активных. После смены сессии при получении OnCleanup таблицы активных полностью очищаете. Все возможные варианты (разрыв соединения, исполнение заявки пока терминал находился офлайн, восстановление соединения через день, месяц, год, задержка ответа по заявке на 10 мин и пр.) будут полность покрыты этими двумя колбеками.
Если заявки выставлены до запуска скрипта, то колбек на них не реагирует, пока они не изменятся. ------------------