Michael Bulychev написал: Просто есть два подхода в использовании Lua: 1. Вы пишете на Lua и тогда корутины это то что Вам надо 2. Lua используете как язык для связки своих библиотек и QUIK. В этом случае реализация полностью на ваших плечах. Но я все еще не понимаю полностью как Вы хотите вызывать функции одного работающего скрипта из другого. Проблем и ограничений в таком подходе явно больше чем преимуществ.
Добрый день, Хоть и не верю в то, что из этого будет толк, но все же отвечу: -------------------------------------- 1) Я пишу на луа и СИ. Либо любом другом языке, который лучше подходит для решения конкретной задачи. ----------------------------- 2) Полагаю, что Вы не внимательно прочитали то, что я написал ранее. ----------------------------------- Увы без лекции не обойдемся. ------------------------ Корутины - это виртуальный поток. Его задача уменьшить простои процессора при ожидании асинхронных позиций, без которых дальнейшие вычисления невозможны. Это тоже самое, что потоки в одноядерной винде. Такие потоки решают лишь две задачи - уменьшение простоя ядра при ожидании задачей асинхронных событий и исключение зависания задач. Т е в таких системах задачи решаются последовательно. Так как параллельно нет на чем решать. Эти потоки не могут ускорить вычислительные задачи, т е те, в которых используется лишь память и вычислитель(процессор) и нет ожидаемых событий. ------------------------------- Ранее я уже написал , что поток - это фактически вычислитель ( т е процессор и код программы) Так вот, возвращаясь ранее определенным задачам, я решаю задачу параллельных вычислений в роботах на основе Вашей QLUA библиотеки. Поэтому речь идет о реальных потоках в многоядерной (многопроцессорной) системе. ---------------------------------- Вообще-то я эту задачу решил. Поэтому сделаете ли Вы это для других или нет, мне все равно. --------------------------- Корутины я тоже использую, например в системе мониторинга умных вещей на основе чипа ESP. Но это уже другая история. --------------------------------------- Примерно так..
тут уже приводилась ссылка на статью, где товарищ пытался ускорить выполнение расчетной программы разбивкой на потоки на одноядерной машине. и удивился, не получив никакого ускорения.
загрузка процессора КВИКОМ от 7 до 40% ( в зависимости от открытия графиков) торгую лишь 1 инструментом (сбербанк акции и фьючерсы) Подписан лишь на 8 акций и 20 фьючерсов тики не подписываю, опционы не принимаю файл info.log за сутки всего 11 мб.
тот самый написал: задам лишь один вопрос: винчестер - сильно фрагментирован? Оперативка - не маленькая?
винчестер оптимизирован по фрагментации. свобоно на диске, где файл подкачки 30 Гб, где QUIK 30 Гб. оперативка 2 Гб. Обычно свободно не менее 1 Гб оперативной памяти.
Michael Bulychev написал: Добрый день. Если Вы подробнее расскажете о том что хотите нам будет проще принять решение о возможностях и способах реализации.
добрый день, попробую объяснить. ------------------------ Скрипт луа , который создается на основе библиотеки QlUA можно представить как обертку потока. --------------------------------- Таким образом, запуск скрипта - это запуск самостоятельного потока. ----------------------------- В данной версии доступ к потоку имеют лишь функции внутри скрипта и колбеки из QLUA. Поэтому я поставил задачу обеспечить доступ к потоку из других скриптов или индикаторов. это можно реализовать, если создание колбеков разрешить внутри скриптов и индикаторов. ------------------------- Что дает такое решение? ---------------------------- Как известно (по крайней мере я так строю роботов), технология создания торговых роботов, как правило, включает несколько модулей, большая часть которых не зависит от торгуемого инструмента. ---------------------------------- В существующей версии QLUA, для каждого робота необходимо в скрипт включать все модули. ------------------------------ Например, если мы делает роботов для торговли 10 инструментами, то каждый из них будет содержать модули обработки заявок сделок. т е это 10 колбеков onOrder, onTrade, которые в очередь обрабатывают одно и тоже в основном потоке QUIK. ------------------------ можно конечно, все 10 роботов запихнуть в один скрипт. Но тогда будут в очередь в одном дополнительном потоке работать 10 генераторов торговых сигналов. ------------------------------- можно конечно еще создать свои потоки в этом скрипте, но тогда возникает вопрос синхронизации потоков, а скудные сведения о внутренности QLUA и архивов QUIK приводят к танцам с бубном. ------------------------------- Что дает мой вариант. --------------------- 1) колбеки QLUA вызываются однократно вне зависимости от количества роботов 2) генераторы торговых сигналов обрабатываются каждый в отдельном потоке. 3) синхронизация потока с глобальными переменными внутри скрипта решена в QLUA потобезопасными функциями работы с таблицами. ------------------------ Резюме: И будет всем счастье. ----------------------- примерно так.
вот последняя картинка мониторинга. уж БОЛЬНО хороша!!! розовая линия - задержка информации ТВС синяя - погрешность измерения задержки (отставание локальных часов от атомных)
Добрый день, В качестве пожелания. 1) Очень удобно иметь возможность создавать колбеки в скриптах и индикаторах и вызывать их из любого скрипта или индикатора. 2) Очень удобно иметь возможность прочитать любые глобальные данные из любого скрипта или индикатора и вызвать на исполнение любую функцию в любом скрипте из любого скрипта или индикатора. -------------------- Я в настоящее время реализовал у себя эти механизмы в версии 6.17.3.6 Доволен, как кот у миски со сметаной. -------------------------- Благодарю за внимание.
Николай Камынин написал: про потоки я знаю все или почти все.
остаётся, лишь только добавить...: "если ты такой умный - то, почему такой бедный?"
или ещё:
"должны ж быть у талантов - меха и бруллианты!?..."
можно добавить еще "Если ты такой богатый, то почему такой глупый?" ---------------------- Но если ты богатый и умный, то будь скромным. ----------------------- Вот я и скромный.
Michael Bulychev написал: Сервер 10 секунд занимался тем, что отдавал вам очередь более приоритетных данных. По моему, наиболее адекватная оценка будет по времени последней сделки на ликвидном рынке.
так как ТВС - это приоритетные данные, а вечером особо ничего срочного нет, но получаем все теже 0.2-10 секунд, то Ваши рассуждения - это просто Ваши гипотезы, ничем не подтвержденные. -------------------------------------------------------- мечтать не вредно, но бесполезно.
Добрый вечер Всем, Вот и подошел к концу мой мониторинг сервера брокера БКС Как я и обещал себе, провел мониторинг задержки данных, приходящих в ТВС. Вот кусок свежеиспеченных данных
что же мы видем: 03/30/16 20:32:53 -это время лога dt=19.8 - это отставание локальных часов компьюткра от атомных, dms=237 -- это запаздывание данных которые приходят через брокера ,HMS=193252,D=20160330 -- это время и дата свечи Как видим, задержка данных сервером брокера составляет от 0.2 до 10 секунд Т е задержка данных вполне соответствует получаемой величине параметра LASTPINGDURATION ---------------------------------------------- "И вот тут некоторые стали себе позволять нашивать накладные карманы и обуживать рукав. Вот это позволять мы не будем!"
очень слабая статья. В ней пытаются ускорить выполнение задачи с использованием потоков на одноядерном железе. как я уже заметил раньше поток - это вычислитель т е процессор или ядро как модно называть. многопоточность на одном ядре - это виртульное создание вычислителей на которых запускаются исполняемые фрагменты кода по очереди. Для интересующего меня вопроса не имеет значение есть потоки или нет. Информация о тиках одна и та же для обоих колбеков. Вопрос ,в том она отправляется с сервера один раз или два и кому раньше. Но так как начальник транспортного цеха молчит, пусть эти вопросы останутся открытыми.
про потоки я знаю все или почти все. ---------------------------- Но дело в том, что в QUIK все колбеки On... вызываются в одном потоке друг за другом. Сомневаюсь, что для колбека cratedatasource нагородили что-то особенное. -------------------------------------------------- Но хотелось бы по данному вопросу послушать начальника транспортного цеха.
поясняю: возможно... есть 2 потока: главный поток квика и обработка коллбека OnAllTrade и.. возможно, ещё один поток cratedatasource
таким образом, вы никогда не узнаете и не сможете гарантировать, какой из них быстрее сработает и обработает долгожданный коллбек. Бо как помимо потоков - есть ещё и системный планировщик, а также целас система (ОС), которая всё переиграет так - как ей это будет нужно - в данный момент
Попробую объяснить свое понимание. 1) Поток - это в общем случае просто вычислитель. Какой вычислитель из имеющихся в системе будет задействован не имеет значение. 2) есть две функции OnAllTrade и колбек cratedatasource. Каждая из них вызывается по приходу запрошенной с сервера информации. Если для работы OnAllTrade достаточно сделать cratedatasource, то это означает, что обе функции из п 2 работают с одной и той же информацией. Если это не так, то для работы OnAllTrade требовалось бы еще какие-то настройки. 3) Таким образом, будут ли эти функции вызываться в разных потоках или в одном не имеет значение. Вопрос лишь в том в какой последовательности они вызываются. Примерно так.
Николай Камынин написал: 1) В чем отличие обработки этих колбеков.
OnAllTrade - в первую очередь колбек таблицы а SetUpdateCallback создает колбек на график. Это значит что во втором случае Вы можете получить только ту информацию которая есть на графиках (в данном случае речь тиковом графике).
Цитата
Николай Камынин написал: 2) Какой колбек вызывается раньше.
Очередность нигде не прописана.
Цитата
Николай Камынин написал: 3) как во втором случае получить всю информацию первого.
Вы можете обратиться к любому элементу data_source по номеру.
Поясните плиз тогда следующее. Ранее на мой вопрос было сообщение что для работы onAllTrade не требуется открывать ТВС а можно лишь подписаться на источник тиков data_source. Верно? но тогда не понятно, каким образом onAllTrade работает без ТВС если оно для ТВС. А колбек data_source для графиков если график из тиков не рисуем. Спасибо
Николай Камынин написал: Во-вторых, в колбеке CreateDataSource
могу ошибаться, конечно (не работаю с CreateDataSource ввиду его "сырости") - под него, если не изменяет память (читал где-то) - заводится отдельный поток ОС. Поэтому - сравнивать его с OnAllTrade - было бы неверно.
Поясните Вашу мысль. почему не верно. Оба механизма создаются для получения информации о сделках. Полагаю, что так как получается однотипная информация то сравнивать вполне возможно. ------------------------------ По аналогии, можно сравнивать лапшу и кашу. Но нельзя сравнивать кислое и синее. В данном случае - это лапша и каша.
петя петров, Не буду цитировать написанное выше. Простой вопрос - Вы это запрограммировали в КВИКЕ? А я то, что нарисовал на картинке выше - сделал в квике на луа. Когда запрограммируете свой алгоритм покажите картинку.
Зачем смотреть на гланды через зад? Есть луа Это на порядок проще, чем на C# городить огород с DDE или ODBC ------------------------------------ "Нам легкие пути не нужны, мы трудности любим преодолевать. Но для этого мы их сначала создадим." (из дневника начинающего разработчика роботов)
Борис написал: В одной области заведены 2 графика цены в виде линий по инструментам GZ и SR. Как построить разностный график по ним? По сути это спред между ними. Спред = GZ-SR
Соглашусь с михаилом, задача не тяп-ляп и не на полчаса. Проблема в том что данные на графики приходят асинхронно. Поэтому приходится при построении спреда учитывать это и синхронизировать временные ряды. Один из способов упрощения этой задачи - это построить изначально оба исходных графика в одном окне, друг под другом с единым масштабом. Примерно так
Как выставить стоп заявку,чтобы при срабатывании по одному инструменту,сформировалась рыночная заявка по другому инструменту?, Как выставить стоп заявку,чтобы при срабатывании по одному инструменту,сформировалась рыночная заявка по другому инструменту?
Добрый день,Михаил Если есть параметр, то он что-то значит. Я его измеряю как один из .... Где Вы увидели, что я его соотношу с пингом ( вообще-то я даже не понимаю , что Вы понимаете под словом "соотношу") ----------------------------------------- Но любой измеряемый параметр позволяет делать определенные оценки в отношении испражняющего его объекта. ------------------------------- Вот и Ваш параметр, который Вы назвали "Задержка данных при обмене с сервером" что-то показывает. ------------------------------- Назвали бы его горшком, и никаких бы оценок задержек обмена на его основе не делал бы. ----------------------------- А так - я вам верю... относительно Ваших теоретических изысканий, попробуйте объяснить , что может делать сервер 10 секунд, чтобы не отсылать ответ на этот запрос? У лишь оно придумал - сервер пошел курить. А Вы что придумали?
Добрый день, Олег Демо сервер Ваш. график сжат. т е на нем отображаются лишь значения запаздывания, которые не равны предыдущему значению. ------------------------------------------ Я собственно хочу выяснить, какие реально задержки в прохождении данных есть. Кроме того, разработанный мною индикатор позволяет в реальном времени проверить сервера брокеров на предмет их стресс нагрузок и понять что же мы реально получаем. ------------------------------- Если интересно, то измеряю я задержки так
1 Измерение торговых транзакций. Включаем таймер с шагом 100 нс. Посылаем команду выставить стоп-заявку Фиксируем разность относительно старта время прихода колбеков ---------------------------------- 2 измерение запаздывания данных с сервера (зеленая линия) Это параметр LASTPINGDURATION -------------------------------------- 3) пинк на IP адрес сервера - это ICMP запрос короткой посылкой на IPADDRESS (красная линия) ---------------------------------- 4) стабильность локального времени SHTP запросы на сервер точного времени (синея линия) Стабильность локальных часов не хуже 10 ms, что позволяет измерить запаздывание тиков. Но это следующий этап. ------------------------------ Какая-либо помощь пока не требуется. Брокером собственно по барабану, как быстро доходят данные до клиентов. ---------------------------------------------------------- Главное, чтобы костюмчик сидел...
измерил время запаздывания ответов по выставлению и снятию стоп-заявки для демо сервера. получилось следующее: ответ OnTransReply через 180 ms ответ OnStopOrder через 280 ms В индикатор отображающий задержки сервера добавил запаздывание локального времени относительно атомных часов (синий цвет) ( т е биржи) получилась такая картинка
Фёдор Сухов написал: Все необходимые тики собираю через onAllTrade, пока не требовалось использовать 2-й вариант, но, если рассуждая логически, то 2-й вариант должен быть быстрее, потомучто на экране, как минимум, нет окна всех сделок, т. е. нет доп. вывода в окно текстовой информации. Надо измерить время.
Как выяснилось ранее, для onAllTrade не надо открывать ТВС на экране (по крайней мере так утверждают разработчики для версии 7) Хотелось бы услышать начальника транспортного цеха.
сделал мониторинг задержки ответов демо сервера получил такую картинку. красная линия - это величина пинга на IP сервера = Стабильно 15 ms. Учитывая ранее полученные данные для сервера БКС, можно предположить, что скорость обработки запросов сервером КВИК не очень..
Добрый день, Как известно, обращаться к тикам можно двояко. Во-первых , в колбеке onAllTrade Во-вторых, в колбеке CreateDataSource ----------------- вопросы к знатокам: 1) В чем отличие обработки этих колбеков. 2) Какой колбек вызывается раньше. 3) как во втором случае получить всю информацию первого. Спасибо
Это тарифы для брокеров. Про отдельный сервер: к трем оброкерам обращался ( в т.ч. к БКС) - никакого толку. Кто нибудь пользует "прямые соединения", вроде обещаемых БКСом "плазы и тд."?
Возможно, что при использовании прямых подключений минуя Quik надобность в брокере отпадает напрочь. Ведь это уже собственный "терминал" (робот, программа) зачем для этого кому-то платить? Проще купить фирму с лицензией и оформиться как надо, не?
Согласно ФЗ О рынке ЦБ на бирже имеют право торговать лишь проф участники. Проф участниками могут быть лишь юр лица. ----------------------- Поэтому - желаете торговать без брокера 1) станьте юр лицом 2) получите лицензию ЦБ 3) купите доступ на биржу ---------------------- Мало не покажется. -------------------------- Если решите и нужна помощь, обращайтесь.
запаздывание расчета индикатора на графике происходит по причине запаздывания данных по свечам, которые рассчитывает сервер брокера. Поэтому это запаздывание не зависит от версии квика и будет всегда. ----------------- Я же говорю не о исходных данных для расчета, а о функциях расчета. Если подставите в них тики то получите тот же результат что и получаете сейчас, но немного быстрее и без лишнего кодирования в луа.
т е речь идет о следующем. сейчас, чтобы применить в скрипте робота EMA я должен либо написать его на луа либо поместить индикатор на график и потом читать с графика. Я же хочу просто в своем скрипте обратится к уже существующей в терминале функции расчета EMA и вызвать ее в своем скрипте без отображения индикатора и написания его на луа.
За примеры спасибо. Но вопрос мой был совершенно о другом. Написать индикатор на луа для меня не проблема. Но зачем писать то, что уже встроено в терминал? Т е я просил включить в QLUA возможность обратится к уже встроенным в терминал индикатора.
Михаил если вы считаете то, что у нас нет физической возможности принудительно заставлять брокеров выполнять те или иные настройки дырой в архитектуре то да такая дыра есть. Но извините, если бы один человек мог принудить другого человека что-то делать это уже была бы не демократия.
В политике это называется "принуждение к миру" В таком духе - это можно назвать "принуждение к уважению интересов клиентов" Часто демократию подменяют демагогией.
Вячеслав + написал: Если между вызовами Си функций из Lua, то можно сохранить это значение в LUA_REGISTRYINDEX - это специальная таблица, видимая только из Си и хранящая важную информацию (удалять из неё что-то не своё точно не надо). См. API idx = luaL_ref(L, LUA_REGISTRYINDEX) luaL_unref(L, LUA_REGISTRYINDEX, idx) lua_rawgeti(L, LUA_REGISTRYINDEX, idx)
Спасибо, эти функции у меня в коде есть. Меня насторожило то, что если сохранить ссылку
Код
idx = luaL_ref(L, LUA_REGISTRYINDEX) ,
потом вытолкнуть её из стека
Код
lua_pop(L, 1 ),
затем попытаться вернуть
Код
lua_rawgeti(L, LUA_REGISTRYINDEX, idx) ,
то Quik падает при выполнении таких операций.
Видимо, при удалении единственной ссылки на таблицу, Lua удаляет её содержимое.
Видимо, выходом в такой ситуации будет, как Вы писали:
Код
lua_setglobal(L, "myDS" );
Правда, в этом случае, придётся склеивать индивидуальное символьное имя для каждого источника данных.
Про разные потоки callback'ов и main'a знаю, но про синхронизацию доступа пока не думал. Нужно будет это учесть.
А все callback'и выполняются в одном потоке?
Стек в луа - это просто область памяти, указатель на которую находится по адресу L->base При вталкивании в стек данные записываются по адресу, который записан в L->top Сначала там записан L->base, после каждого заталкивания L->top=L->top+1 При выталкивание происходит обратное действие. При этом происходит контроль границ стека и если адрес выходит за границы выдается сообщение луа. ------------------------------- Таким образом, КВИК падать не может из-за операций со стеком. ---------------------------- Если у Вас квик падает без сообщений, то ошибка в Вашем коде CИ, которай приводит к фатальной ошибке, которую никто не обрабатывает. Возможно Вы в своей программе куда-то не туда чего-то пишите. -------------------------------- Все колбеки выполняются в одном потоке. Но вот открытие источников надо делать в main. Не знаю для чего так сделано, но уж сделано.
Я тоже передаю данные и туда и обратно, но это не мешает использовать и си функции и луа. Из опыта могу сказать что на Си надо делать то, что нет в луа например работу с различными форматами, потоками памятью.
редактор текста SciTE Version 1.75 Apr 25 2009 11:30:59 by Neil Hodgson. December 1998-November 2007. http://www.scintilla.org Lua scripting language by TeCGraf, PUC-Rio http://www.lua.org имеет встроенный отладчик луа. очень простой в применении и удобный в работе. Написан полностью на луа. Можно встраивать свои средства. Пользую и Вам советую.
прошу прощение, перепутал параметры номер линии и число отсчетов в функции getCandlesByIndex (давно не использовал) поэтому замечание о приеме всех свечей в исходном примере ошибочно. ----------------------------------- Но про последний индекс замечание остается Поэтому я предлагаю сделать так:local t_ind2={}
Код
local t_ind2={}
local len2;
function OnCalculate (index)
if index == 1 then
t_ind2={};
len2=0;
else
local len=getNumCandles (Settings.ID)-len2;
if len>0 then
local t,n,l = getCandlesByIndex (Settings.ID,0,len2,len )
if n>0 then
local i=0; while n>i do len2=len2+1; t_ind2[len2]=t[i] i=i+1; end
end
return t_ind2[len2].close
end
end
end
local t_ind2={}
local len2;
function OnCalculate (index)
if index == 1 then
t_ind2={};
len2=0;
elseif getNumCandles (Settings.ID) >=index then
local t,n,l = getCandlesByIndex (Settings.ID,len2 ,index - 1 , 1 )
if n>0 then
local i=0; while n>i do len2=len2+1; t_ind2[len2]=t[i] i=i+1; end
return t_ind2[len2].close
end
end
end
local t_ind2={}
local len2;
function OnCalculate (index)
if index == 1 then
t_ind2={};
len2=0;
elseif getNumCandles (Settings.ID) >=index then
local t,n,l = getCandlesByIndex (Settings.ID,len2 ,index - 1 , 1 )
if n>0 then
local i=0; while n>i do t_ind2[#t_ind2+1]=t[i] i=i+1; end
return t_ind2[#t_ind2].close
end
end
end
и еще Вы на каждый тик читаете весь массив свечей с другого графика а это 3000 штук. в результате большой тормоз. Вот примерный код, как надо сделать (не отлаживал ошибки исправьте сами)
Код
local t_ind2={}
local len2;
function OnCalculate (index)
if index == 1 then
t_ind2={};
len2=0;
elseif getNumCandles (Settings.ID) >=index then
local t,n,l = getCandlesByIndex (Settings.ID,len2 ,index - 1 , 1 )
if n>0 then
local i=0; while n>i do t_ind2[#t_ind2+1]=t[i] i=i+1; end
return t_ind2[#t_ind2]
end
end
end
function OnCalculate (index) if index == 1 then --здесь делаем инициализацию переменных при изменении масштаба этого графика elseif getNumCandles (Settings.ID) >=index then t,n,l = getCandlesByIndex (Settings.ID, 0 ,index - 1 , 1 ) if t[ 0 ].doesExist == 1 then --проверяем если свечки нет, рассчет не ведется if t[ 0 ].close~= 1e10 then --проверяем если новое значение свечки не получено, рассчет не ведется if t[ 0 ].close~= value then value = t[ 0 ].close end t[ 0 ].close = 1e10 return value end end end end
Возможно проблема возникает в операторе t,n,l = getCandlesByIndex (Settings.ID, 0 ,index - 1 , 1 ) если index-1 ,больше, чем число свечей на первом графике?