sam063rus пишет: Хотелось бы получить на них ответы с примерами правильного QLUA-кода.
Добрый день. В общем виде нет корректного решения задачи, которую Вы поставили. Либо надо подробнее формулировать задачу, либо принимать во внимание возможные ограничения и допущения и упрощать алгоритм. Лично я бы использовал в качестве счетчика таблицу, в которой ключами являются строки из кода класса, бумаги и времени на сделке с точностью до секунд. И при получении сделки накручивал значение в нужном поле.
sam063rus пишет: извиняюсь за оффтоп, конечно но, думаю пора уже завязывать с квиком и клуой. бо как даже такой "корифей", как михаил булычев - всё чаще начал убегать "в кусты".
Я тоже извиняюсь, но в этой ветке я ничего не писал еще. Есть какие-то вопросы?
Возможно насчет глобальных я не совсем корректно выразился. Выполнение функции sinsert заблокирует выполнение кода в другом потоке до окончания работы функции.
Добрый день. В терминале обеспечивается физическая целостность данных. В случае с обычным присвоением a = b проблем нет - вы не сможете получить неопределенное значение переменной a. Либо значение до присвоения, либо после. В случае с table.insert проблема в том, что это не "атомарная" операция, а целая функция, которая делает следующее: - все элементы с индексом больше либо равным заданному получают индексы на единицу больше; - указанный элемент вставляется по заданному индексу; Обращение в момент выполнения функции к элементам таблицы может привести к неопределенной ситуации. Для этого были сделаны потокобезопасные функции - получить доступ к таблице можно лишь после завершения их работы.
Добрый день. В терминале обеспечивается физическая целостность данных. В случае с обычным присвоением a = b проблем нет - вы не сможете получить неопределенное значение переменной a. Либо значение до присвоения, либо после. В случае с table.insert проблема в том, что это не "атомарная" операция, а целая функция. которая делает следующее:
Добрый день. 1 Да, это не безопасно. можете получить что в A[1] == nil
2. Если A и B таблицы, то B=A не копирует содержимое таблиц, а присваивает ссылку на таблицу A в переменную B, и все изменения в A отражаются в B. Далее аналогично п. 1
3 и 4 Примеры не очень понятны. A это таблица или переменная со значением ноль?
5. getQuoteLevel2 всегда возвращает текущий слепок стакана. Что значит "процесс присваивания чтения" не совсем понятно, поясните.
Это не заплатки. перечитайте еще раз внимательно документацию по string.gsub и tonumber
string.gsub('23:23:23', ':', '') возвращает два значения: '232323' и 2, которые передаются в tonumber В свою очередь, tonumber пытается перевести '232323' в число по основанию 2 и возвращает nil
str = "23:23:23"
--[[
if tonumber(str:gsub(':','')) > 100 then -- так не работает - " attempt to compare number with nil "
print('111')
end
--]]
if tonumber((str:gsub(':',''))) > 100 then -- так работает
print('111')
end
PFelix Paulossky пишет: PS. Нужен не номер п/п изменения параметра, а номер п/п ВСЕХ изменений (т.е. в списке по изменениям всех параметров, на которые подписан клиент посредством CreateDatasource, либо всех изменений по инструменту). "всех изменений по инструменту" подразумевается, как таблица изменений параметров приходит в QUIK. Подозреваю, -- что полностью, т.к. на завтра, добавив в таблицу изменений параметров колонку, мы получаем ее в QUIK с данными. С первым изменением в новой секунде,Count можно -- снова с единицы. Спасибо.
Добрый день. нет нужды упражняться в конспирологии. На данный момент в Lua мы отдали все что смогли. Проблема не забыта и мы постараемся дать доступ из lua к таблице истории изменений параметров.
Добрый день. Логику пока не понял, похоже Вам не нужны корутины. Пример кода с Вашей ошибкой:
Код
function test()
print(1)
coroutine.yield()
end
co = coroutine.create(test()) -- вот тут ошибка, надо так: co = coroutine.create(test)
--[[
1
C:\Program Files (x86)\Lua\5.1\lua.EXE: attempt to yield across metamethod/C-call boundary
stack traceback:
[C]: in function 'yield'
c.lua:3: in function 'test'
c.lua:10: in main chunk
[C]: ?
--]]
Юрий пишет: Подскажите пож-та, можно ли где-то взять набор функций Qlua , что бы добавить в стандартный набор функций Автозаполнения в программу SciTe (наверное не важно в какую программу).
Как пример для SciTE qlua.api
Скрытый текст
Код
getWorkingFolder ()\n Функция возвращает путь, по которому находится файл info.exe
isConnected ()\n Возвращает «1», если клиентское место подключено и «0», если не подключено
getScriptPath ()\n Функция возвращает путь, по которому находится запускаемый скрипт, без завершающего обратного слэша
getInfoParam (param)\n Функция возвращает значения параметров информационного окна
message(message, type) Функция отображает сообщения в терминале QUIK
sleep (time)\n приостанавливает выполнение скрипта
getItem (table, index)\n возвращает элемент из хранилища table[index]
getOrderByNumber (class_code, order_id)\n возвращает заявку из класса class_code по ее номеру order_id
getNumberOf (table_name) возвращает количество элементов из хранилища table_name
SearchItems (table_name, start_index, end_index, f_compare, params)\n
getClassesList ()\n Возвращает список классов через ',' После последнего класса стоит ','
getClassInfo (class_code)\n Возвращает таблицу с информацией о классе
getClassSecurities (class_code)\n Возвращает список бумаг в классе через запятую. После последнего кода бумаги ставится запятая
getDepo (client_code, firmid, sec_code, account)\n deprecated!!!
getMoney (client_code, firmid, tag, currcode)\n deprecated!!!
getParamEx (class_code, sec_code, param_name)\n Возвращает таблицу со сначением параметра из ТТП
getQuoteLevel2 (class_code, sec_code)\n Возвращает стакан
getSecurityInfo (class_code, sec_code)\n Возвращает информацию по бумаге
getTradeDate ()\n Возвращает дату текущей торговой сессии
sendTransaction ()\n Отправляет транзакцию на сервер
getPortfolioInfo (firm_id, client_code)\n Функция предназначена для получения значений параметров таблицы "Клиентский портфель" (устарела)
getPortfolioInfoEx (firm_id, client_code, limit_kind)\n Функция предназначена для получения значений параметров таблицы "Клиентский портфель"
getBuySellInfo (firm_id, client_code, class_code, sec_code, price)\n Функция предназначена для получения параметров таблицы "Купить/Продать" (устарела)
getBuySellInfo (firm_id, client_code, class_code, sec_code, price)\n Функция предназначена для получения параметров таблицы "Купить/Продать"
CreateDataSource (class_code, sec_code, interval, param)\n Создание источника данных
getCandlesByIndex (tag, line, first_candle, count)\n Возвращает таблицу свечек заданного диапазона, реальное количество и легенду
getLinesCount (tag)\n Возвращает количество линий на графике
getNumCandles (tag)\n Возвращает количество свечек на графике
SetUpdateCallback (callback_function)\n Задает функцию обратного вызова для источника данных
AddColumn (t_id, iCode, name, is_default, par_type, width)\n Добавляет описание столбца в таблицу
AllocTable ()\n Создает описание таблицы
Clear (t_id)\n Очищает содержимое таблицы
CreateWindow (t_id)\n Отображает таблицу в терминале
DeleteRow(t_id, row)\n Удаляет строчку в таблице
DestroyTable(t_id)\n Удаляет таблицу
InsertRow(t_id, key)\n Добавляет строчку в таблицу, возвращает номер добавленной строки
IsWindowClosed(t_id)\n Возвращает true если таблицы закрыта
GetCell(t_id, row, col)\n Возвращает таблицу {image, value} для заданной ячейки
GetTableSize (t_id)\n Возвращает размер таблицы
GetWindowCaption (t_id)\n Возвращает текущий заголовк окна
GetWindowRect (t_id)\n Возвращает текущие координаты окна top, left, bottom, right
Highlight (t_id, row, col, b_color, f_color, timeout)\n Подсветка ячейки, столбца, строки
RGB (red, green, blue)\n Упаковка компонентов цвета
SetCell (t_id, key, code, text, value)\n Задает значение для ячейки таблицы
SetColor (t_id, row, col, b_color, f_color, sel_b_color, sel_f_color)\n Задает цвет для выбранной ячейки, строки, столбца или всей таблицы
SetTableNotificationCallback (t_id, f_cb)\n Задает нотификационный колбек для таблицы
SetWindowCaption (t_id, str)\n Задает заголовок окна для таблицы
SetWindowPos (t_id, x, y, dx, dy)\n Задает координаты окна
qlua.abbrev
Скрытый текст
Код
# Lua Abbreviations
#New script file
1=--[[--------------------------------------------------\n%FileNameExt%\nAuthors: |\nVersion: 1.0\n------------------------------------------------------\nDescription:\n\n------------------------------------------------------\nConnection:\n In file SciTEStartup.lua add a line:\n \n Set in a file .properties:\n \n--]]--------------------------------------------------\n
#Code Snippets
if=if (|) then\n\t\nend
for=for i = _start, _end,do\n\t|\nend\n
while=while (|) do\n\t\nend\n
rep=repeat\n\t\nuntil (|)-- repeat until condition is true\n
tabf=for param, value in pairs(tbl) do\n\t|\nend\n
tabs=table.sort(table_name, function(a, b) return a:upper() < b:upper() end)\n
gmatch=for w in string.gmatch(s, "%%a+") do\n\t|\nend\n
gmatch=for p, v in string.gmatch(s, "(%%w+)=(%%w+)") do\n\t|\nend\n
#Functions
tabprint=-- Print Table Content\ntable.foreach(tbl, print)\n
tabshow=-- Show Table Content\nlocal function print_table(tbl, tbl_name)\n\tif tbl_name == nil then tbl_name = '.' end\n\tfor fields, value in pairs(tbl) do\n\t\tif type(fields)=='string' then fields = "'"..fields.."'" end\n\t\tif type(value) == "table" then\n\t\t\tprint("+", tbl_name.."["..fields.."] =", value)\n\t\t\tprint_table(value, tbl_name.."["..fields.."]")\n\t\telse\n\t\t\tprint("-", tbl_name.."["..fields.."] =", value)\n\t\tend\n\tend\nend\n
fileread=-- Reading all content fr om file\nlocal function file_read_all(filename)\n\tlocal text = ''\n\tlocal file = io.open(filename)\n\tif file then\n\t\ttext = file:read("*a")\n\t\tfile:close()\n\tend\n\treturn text\nend\n
file2table=-- Reading file to table\nlocal function file_read(filename)\n\tlocal table_lines = {}\n\tlocal file = io.open(filename)\n\tif file then\n\t\tfor line in file:lines() do\n\t\t\ttable_lines[#table_lines+1] = line\n\t\tend\n\t\tfile:close()\n\tend\n\treturn table_lines\nend\n
filewrite=-- Write file\nlocal function file_write(filename, text)\n\tio.output(filename)\n\tio.write(text)\n\tio.close()\nend\n
#Event handlers
main=function main()\n\t|\nend\n
On AccountBalance=function OnAccountBalance(acc_bal)\n\t|\nend\n
On AccountPosition=function OnAccountPosition(acc_pos)\n\t|\nend\n
On AllTrade=function OnAllTrade(t)\n\t|\nend\n
On CleanUp=function OnCleanUp()\n\t|\nend\n
On Close=function OnClose()\n\t|\nend\n
On Connected=function OnConnected()\n\t|\nend\n
On DepoLimit=function OnDepoLimit(limit)\n\t|\nend\n
On DepoLimitDelete=function OnDepoLimitDelete(limit)\n\t|\nend\n
On Disconnected=function OnDisconnected()\n\t|\nend\n
On Firm=function OnFirm(firm)\n\t|\nend\n
On FuturesClientHolding=function OnFuturesClientHolding(pos)\n\t|\nend\n
On FuturesLimitChange=function OnFuturesLimitChange(lim)\n\t|\nend\n
On FuturesLimitDelete=function OnFuturesLimitDelete(lim)\n\t|\nend\n
On Init=function OnInit(path)\n\t|\nend\n
On MoneyLimit=function OnMoneyLimit(limit)\n\t|\nend\n
On MoneyLimitDelete=function OnMoneyLimitDelete(lim it)\n\t|\nend\n
On NegDeal=function OnNegDeal(deal)\n\t|\nend\n
On NegTrade=function OnNegTrade(trade)\n\t|\nend\n
On Order=function OnOrder(order)\n\t|\nend\n
On Param=function OnParam(class_code, sec_code)\n\t|\nend\n
On Quote=function OnQuote(class_code, sec_code)\n\t|\nend\n
On Stop=function OnStop(s)\n\tstopped=true|\nend\n
On TransReply=function OnTransReply(reply)\n\t|\nend\n
#indicator settings template
Settings=Settings=\n{\tName = "|",\n\tproperty = 100,\n\tline=\n\t{\n\t\t{\n\t\t\tName = "line1",\n\t\t\tColor = RGB(255, 0, 0),\n\t\t\tType = TYPE_LINE,\n\t\t\tWidth = 1\n\t\t}\n\t}\n}\n
файлы старые, возможно не соответствуют документации, показаны в качестве примера.
sam063rus пишет: а вообще - Michael Bulychev мог бы, действительно и подробно расписать механизм работы событий в квике. Уверен, что это никак бы не отразилось на "коммерческой тайне", а наоборот - повысило бы понимание этого вопроса для пользователей и сократило бы кучу "глупых" вопросов и "догадок" на форуме. А также, уменьшило бы их стремление получить ответы на свои вопросы другими путями.
Добрый день. Вроде уже все было описано достаточно подробно. Интересует что-то конкретное?
Добрый день. В вашем случае можно данные из функций обратного вызова (OnOrder, OnTrade ...) складывать в одну или несколько очередей и обрабатывать данные в main(). В этом случае Вы сами будете контролировать порядок обработки данных.
Кирилл, давайте сбавим немного эмоции. qchart.dll не является "плагином", у этой библиотеки пока нет необходимого интерфейса чтобы сделать ее поддержку в Lua
Добрый день. Если Вы расскажете подробнее что именно нужно реализовать, то мы рассмотрим это пожелание. Пока в голову приходят только именованные события. Что такое "native callbacks" не очень понятно.
Серж пишет: Да, правильно. И, несмотря на то, что разработчикам был предложен вариант решения, который бы всех устраивал, они всё равно включают... в общем вы поняли... И делают вид, что не понимают, чего от них хотят.
Взял код из это ветки, все работает корректно, даже при изменении параметров на графике или индикаторе. Версия терминала 6.17. Можете пояснить что именно работает не корректно?
Прямо сейчас я не вспомню точно где я видел Ваше имя. Да, если Вам удобнее, можете писать мне в почту, оставлять личные сообщения. Пошли уже вторые сутки как я пытаюсь получить от Вас дополнительные сведения об ошибке. Что хранится в минидампе я привел по ссылке выше, там нет никаких секретных данных о Вас. Мне удалось вызвать ошибку у себя, но я не уверен что это описанный Вами случай. Случается это в ситуации когда привод выбрасывает MessageBox с ошибкой или сообщением и в этот момент попытаться остановить скрипт. Либо нажать на кнопку Run и попытаться остановить скрипт из терминала. В этом случае привод так же не реагирует на действия пользователя и пишет какой-то лог в сотни мегабайт. В обоих случаях стек падения не содержит qlua.dll и выглядит примерно так:
Добрый день. Сергей, вот по этой ссылке http://www.debuginfo.com/articles/effminidumps.html#minidumpnormal можно прочитать об информации, которая сохраняется в минидампе. Кирилл, если дамп прислать невозможно, то опишите подробно по шагам последовательность действий (можно с картинками), попытаемся воспроизвести у себя.
Декомпилировать скрипты желания нет, без дампа разбираться не получится. Процесс winros.exe никак не связан с коннектом к серверу. Если Вы не используете экспорт данных в метасток или омегу, то можете удалить из каталога с терминалом файлы iwr.dll и winros.exe
Если бы я это воспроизвел, то не просил бы Вас прислать дампы. Только что скачал с сайта эту программу и не смог получить такой эффект. А какую информацию из мини дампа Вы считаете критичной для своей безопасности?
Пример зависит от ваших задач. но навскидку можно так: Выбираете понравившийся код отсюда: TableSerialization
Код
gScriptPath = getScriptPath()
settings_file = gScriptPath .. "\\cfg.lua"
package.path =gScriptPath .. "\\?.lua;" .. package.path
dofile(gScriptPath.."\\persistence.lua")
Settings={
AutoStart = true
}
function OnInit()
t = persistence.load(settings_file)
Settings = t or Settings
end
function OnStop(s)
stopped =true
end
function main()
if Settings.AutoStart then
while not stopped do
sleep(100)
end
end
Settings.AutoStart = not Settings.AutoStart
persistence.store(settings_file, Settings)
end
в общем идея в том, чтобы сохранить нужные настройки в конфигурационный файл и при запуске анализировать их. Сериализация таблиц в файле в этом смысле довольно удобна - позднее можно вносить изменения руками. Вот пример файла cfg.lua
Код
-- Persistent Data
local multiRefObjects = {
} -- multiRefObjects
local obj1 = {
["AutoStart"] = false;
}
return obj1