Александр Правилов написал: Николай Камынин , не согласен с вами, колбэками управлять нельзя, они приходят как приходят, посмотрите мой пример выше, как разрулить эту ситуацию?
А где Я Вам говорил, что колбеками надо управлять(ужас какой-то). Колбеки - это функции, которые вызываются системой ( в данном случае тарминалом КВИК) при наступлении определенного события. Т е они сообщают вам о событиях в КВИКЕ и ВСЕ. --------------------- Когда робот отсылает заявку - то он переходит из состояния - "послать" в состояние - "ждать ответа". А у Вас нет этих состояний т е Вашему роботу все по... Вот он у вас и шлет кучу заявок и ничего не ждет. Ну как-то так получается...
Николай Камынин написал: Надо строить робота на основе событийной модели, тогда таких проблем не будет. Т е робот - это конечный автомат, который полностью описывается набором его состояний. Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
Я с Вами полностью согласен, но в lua нет событийности, всё зависит от стека функций об.вызова, как они придут и потока всего два и основной стек находится в одном потоке.
Именно библиотека QLUA и дает Вам механизм событий в виде колбеков, что принципиально отличает ее от QPILE. Состояние же робота необходимо хранить в таблице состояний - это уже особенности алгоритма. Луа позволяет все это сделать.
Надо строить робота на основе событийной модели, тогда таких проблем не будет. Т е робот - это конечный автомат, который полностью описывается набором его состояний. Поэтому надо фиксировать эти состояния и программировать условия перехода из одного состояния в другое.
Иван Ру написал: Есть открытый текстовый файл, скажем, длинной в 100 строк. Необходимо дописать данные, скажем, в 79 строку (номер известен). Возможно ли такое средствами Lua, есть ли у кого пример реализации подобной функции?
Вашу задачу можно так: 1) Все записи делаем одинаковой длины, например 128 байт 2) Если запись короче 128 то добиваем ее либо пробелом либо нулями. 3) Если надо дописать, то ищем изменяемую запись , читаем ее, добавляем и пишем на свое место.
Возможно мы друг друга недопоняли. Записи я делаю в csv (текстовый) файл с разделителями в виде ";". Затем я его читаю в эксель. По-сути надо добавить дополнительные элементы данных в отдельные строки, де-факто они всегда оказываются ближе к концу файла. Кстати, попутный вопрос. Если у меня файл находится в открытом состоянии в режиме чтения-записи и его размер велик (скажем 100 мб.) -- отнимает ли это соответствующий объем оперативной памяти? Если да - как этого избежать? Только закрытием файла и повторным открытием для записи?
память под файлы расходуется, но это не 100 мб и беспокоится не стоит. Попробую объяснить про дозапись. Есть два режима записи - бинарный и текстовый. В текстовом инфа пишется в файл последовательно запись за записью . Каждая строка пишется в формате ASCIZ, т е признак конца строки - это ноль. поэтому просто добавить в конец какой- либо, не последней, строки в файле невозможно, так как нет места для этого. Поэтому я Вам предложил сделать строки одинаковыми по длине - это ускорит поиск нужной строки и создать место для дозаписи. Т е Вы создаете пустое место на диске и пишите в это место . ---------------------------- Если Вы пишите в файл лишь для передачи в Excel, то это можно делать через протокол Dynamic Data Exchange (DDE) сразу в Excel. Но это требует знаний в написании DLL на СИ для Lua.
Николай Камынин написал: 3) Если надо дописать, то ищем изменяемую запись , читаем ее, добавляем и пишем на свое место.
Ну так-то обычно все данные после места записи обрезаются. Нельзя просто так взять и вставить запись внутрь файла ;)
Отличным решением был бы например маппинг файла в память, но, боюсь на луа это не доступно.
Цитата
Иван Ру написал: Если у меня файл находится в открытом состоянии в режиме чтения-записи и его размер велик (скажем 100 мб.) -- отнимает ли это соответствующий объем оперативной памяти?
Нет, не отнимает.
Если будете правильно писать то данные не будут обрезаться. А вот память под файлы расходуется. т е "отнимает" Более того, если Вы не делаете выгрузку, то данные будут в памяти а не на диске.
Полагаю, что у Вас установлен флаг "Исходя из настроек открытых пользователем таблиц" Надо установить флаг "С учетом настроек, выбранных через пункт меню "Система/Заказ данных/Поток котировок" в "настройки клиентского места" в окне "Получение данных"
Иван Ру написал: Есть открытый текстовый файл, скажем, длинной в 100 строк. Необходимо дописать данные, скажем, в 79 строку (номер известен). Возможно ли такое средствами Lua, есть ли у кого пример реализации подобной функции?
Вашу задачу можно так: 1) Все записи делаем одинаковой длины, например 128 байт 2) Если запись короче 128 то добиваем ее либо пробелом либо нулями. 3) Если надо дописать, то ищем изменяемую запись , читаем ее, добавляем и пишем на свое место.
Загрузка своих данных в Quik, Требуется создать индикатор который на основании еxel таблицы будет формировать гистограмма с положительных и отрицательный значениями
Из ваших ответов стало понятно как считать N. А как считать волатильность?
Ищите все на сайте ммвб, а не спрашивайте на форуме. Потому, что Вам надо не ссылки на математику для начинающих, а методики расчета на бирже и чтобы у Вас все совпала с биржей. Поэтому бесплатных решений нет, а написать решения может тот, кто не задает подобные вопросы и профессионально пишет софт. Успехов в изучении программирования.
Николай Камынин написал: Но очень сомневаюсь, что Вы ее сможете запрограммировать.
Да ладно. Самое хитрое там - функция нормального распределения N(x). Но нам в помощь численные методы. Если интересна теория: 1. Hart, J.F. (1968). Computer Approximations. Наверно, наиболее цитируемая книга по численным методам. 2. Krishnamoorthy K. Handbook of Statistical Distributions with Applications (2006). Это, в частности, в области теории вероятностей. В ней надо смотреть раздел "10.10. Computing the Distribution Function".
Ну и код функции N(x) по этому методу, перенесенный на Луа. Точность 14 знаков этого приближения устроит?
Код
function NormCDF (x)
if type(x) ~ = "number" then return end
local z = math.abs (x)
local p
if z < 7 then
p = math.exp ( - z * z / 2 ) *
((((((( 2.49338129315143e-02 * z + 0.604737992686704 ) * z + 6.81311678753268 ) * z +
46.0649519338751 ) * z + 202.102090717023 ) * z + 580.109897562909 ) * z +
1024.60809538334 ) * z + 913.167442114756 ) /
(((((((( 0.0625 * z + 1.51584331855598 ) * z + 17.1406995062578 ) * z +
116.979524577666 ) * z + 523.596091947383 ) * z + 1566.10462582845 ) * z +
3044.77121163622 ) * z + 3506.42059774909 ) * z + 1826.33488422951 )
elseif z < 32 then
p = math.exp ( - z * z / 2 ) / 2.506628274631 /
(z + 1 / (z + 2 / (z + 3 / (z + 4 / (z + 5 / (z + 6 / (z + 7 )))))))
else
p = 0
end
return (x > 0 ) and ( 1 - p) or p
end
Не так страшно? С остальным в формулах Блэка-Шоулза наверно справитесь? Вот, например, расчет дельты колл опциона:
Код
function CallDelta (f, s, v, t)
return NormCDF(( math.log (f / s) + v^ 2 * t / 2 ) / (v * t^ 0.5 ))
end
Ну,ну... ------------------------------- "..не сумлевайтесь, милые: Коль что у вас не ладится — ну, там, не тот аффект, — Мы мигом к вам заявимся с лопатами и с вилами, Денёчек покумекаем — и выправим дефект!"
Поищите на сайте ммвб. Когда-то там находил. Но очень сомневаюсь, что Вы ее сможете запрограммировать. Сомневаюсь, что есть бесплатная прога. ------------------------ Ищущий да обрящет.
Надо прочитать документацию: sendTransaction Функция предназначена для отправки транзакций в торговую систему. Формат вызова: STRING result sendTransaction(TABLE transaction) Параметры:
result – строка, содержащая текст ошибки, если она случилась при обработке транзакции;
function ms (value)
if type(value)~="table" then
message (""..tostring(value),1)
else
for k,v in pairs(value) do
message (tostring(k).." "..tostring(v),1)
end
end
end
поделюсь своим решением. обрабатываю в колбеке. В таблице пассивные заявки удаляю. в колбеке обрабатываю все приходы и мне безразлично сколько их. ----------------- обрабатывал и в майн. =================== Последний вариант - один колбек на все скрипты. т е роботов много, но колбеков по одному для каждого вида (заявки, сделки, стаканы и т д)
для колбеков поток один - это точно. но возможно, что Вы работаете с таблицами в main. Тогда будет два потока. ----------------------------------------- проблема может быть в Вашем алгоритме обработки. Чтобы ответить точно, надо видеть как (вернее где) Вы обрабатываете сигналы заявки.
Роман Родников написал: Здравствуйте. Я хочу создать советника на Qlua, который на графике цены будет проставлять метки в зависимости от условий в скрипте.И у меня, как у новичка, есть несколько вопросов: 1.Нужно ли создавать отдельную область, где будет график цены, или можно будет как-то добавить свой скрипт как индикатор в Quik к штатному графику Price и получать на нем соответствующие метки? 2.Есть набор стандартных индикаторов в Qlua, они в папке INDICATORS. Обязательно ли вызывать стандартный индикатор строкой dofile ("C:\INDICATORS\MACD.lua"), или если индикатор стандартный, то можно его и так вызвать MACD ( параметр1, параметр2,...параметрN)? 3. Есть ли у кого-то шаблон такого советника, с которого можно было-бы начать?
Попробую объяснить сущность QLUA. QLUA - это библиотека функций обращения через терминал QUIK к брокеру, написанная для стандартной VM LUA. -------------------------------- Чтобы написать советник надо. ---------------------- 1) Изучить язык программирования луа. Это можно сделать без квика. ------------------------------ 2) Изучить функции библиотеки QLUA. --------------------------- 3) Написать программу на луа с использованием библиотеки qLUA..
Иван Джеммер написал: В функцию в качестве аргумента приходит таблица data = { 'a', 'b', 'c', 'd', 'e' } Для удобства я делаю следующее:
local var1 = data[1] local var2 = data[2] local var3 = data[3] local var4 = data[4] local var5 = data[5]
Вопрос состоит в следующем: при выходе из этой функции, что случится с переменными var1-5 и таблицей data ? Будут ли они храниться в окружении данной функции или уничтожатся? Если data будут храниться, то не будет ли расточительством делать переменные var1-5 ? (т.к. это по сути копии таблицы data ). Просто мне удобно использовать var1-5 (т.к. легче обращаться к значениям по имени переменной, а не по индексу в в таблице data ), но в то же время опасаюсь, что это будет лишним засорением памяти.
// Появилась ещё идея, после ввода переменных var1-5 выполнить код: data = nil. Что скажете?
обращение через локальные переменные и через индексные в массиве отличается тем, что локальные - это копия элементов, а индексное значение - это указатель. Если Вы в функции сделаете так: var1=0 то привыходе из функцию таблица data не изменится а если сделать так data[1]=0 то при выходе в таблице первый элемент будет равен 0. --------------------------- Что касается затрат памяти, то после завершения вызова, освободившуюся память соберет сборщик мусора. --------------------------- Если Вы много раз обращаетесь к данным внутри функции, то использование локальных переменных будет быстрее. ------------------------- Резюме: Делайте как удобно.
можно так: local x="12345" -- присваиваем номер заявки _G["_"..x]={} --создаем таблицу с именем _номер заявки _12345.order_price=65 --пишем цену в таблицу _12345 под именем order_price
Еще можно сделать следующее. 1) Попробуйте еще не загружать никаких приложений, в том числе и браузер, кроме квик. 2) Если умеете, то попробуйте оптимизировать службы винды, уберите, которые не нужны, чтобы освободить память.
сделайте это (из предыдущих советов): 5) Попробуйте работать с включенным флагом "Только данные, отражающие текущее состояние" (Настройки клиентского места)
Иван Ру написал: Я все же неверно определил источник проблемы, которая, к сожалению сохраняется. Теперь уже в самом терминале появляется сообщение "Операция не может быть выполнена т.к. недостаточно памяти". При этом объем памяти используемый двумя скриптами составляет порядка 2х150 = 300 мб, а совокупный объем памяти занятой терминалом (в тот же момент смотрел через диспетчер задач) -- 1,5 Гб. Вообще последний показатель никогда не превышает 2,5 Гб, т.е. ресурс не выбран. Что у меня включено: - трансляция обезличенных сделок (около 5 полей по 160 инструментам - все фьючи). - 2 окна "Текущие торги" - все фьючи и все акции, порядка 10 полей в каждом. - 2 тиковых графика - 2 стакана - около 15 окон с графиками - 2 окна с портфелями Т2 и Т0.
Отключение тиковых графиков проблему не решает, а вот отключение трансляции обезличенных сделок -- по первым ощущения ее устраняет. Мне они категорически нужны, не понимаю что делать.
Могу дать следующие советы. 1) Удалите из ТТП те акции, которыми не торгуете и фьючерсы которыми не торгуете. Но удалять надо из заказа данных. 2) Удалите параметры, которые не используете. 3) Проверьте отключены ли у Вас опционы. 4) Посмотрите сколько в действительности у Вас выбрано инструментов и параметров (В окне выбор принимаемых параметров и инструментов) 5) Попробуйте работать с включенным флагом "Только данные, отражающие текущее состояние" (Настройки клиентского места) ----------------------------------- Пишите, какой результат.
Николай Камынин написал: Это пример очень плохого скрипта. Зачем Вы храните все bid, ask с шагом 0.5 в таблице? Вы что обрабатываете всю таблицу от начал каждую секунду? Если нет, но хотите сохранить ( аля плюшкин, выбросить жалко, а нести тяжко), то пишите в файл.
Я не думаю, что опыт позволяет написать мне качественный код, однако, не стал бы столь решительно судить о нем по отдельным по внешним признакам :-) Конечно определенный смысл именно в таком подходе для меня есть. В определенные "критические", скажем так, моменты времени, мне надо подсчитывать разнопериодные средние (не по барам, а в привязке к критической точке), при этом делать это надо максимально быстро. По последней причине запись в файл для меня неприемлема, т.к. процедура открытия/чтения занимает время. Единственный выход - работать на укороченной истории. Если Вы предложите лучшее и более качественное решение моей задачи -- буду только признателен :-)
Есть два способа написать хороший скрипт. Первый - Вы знаете. Второй - изучать существующие технологии разработки подобного класса алгоритмов. ------------------------ Есть два вида программ. один из них - это программы реального времени. К ним относятся торговые роботы, работающие в реале. Они имеют одну особенность - их скорость работы в реале определяется временем выполнения наиболее длинной операции. У Вас - это подсчитывать разнопериодные средние. Для вычисления средней в правильном алгоритме надо три арифм операции на тик вне зависимости от длины истории (N). В вашем алгоритме надо N операций. Можете посчитать время исполнения. ------------------------ Кроме того, за восемь часов торгов вы получаете примерно 60 тысяч пар bid, ask . Что-то я сомневаюсь, что Вы считаете среднее с N=60000. Но тогда зачем это все хранить? Надо делать скользящее окно по максимальному N. А еще более эффективнее это переходить от средней к скользящей или к медиане. -------------------------------- Успехов
Иван Ру написал: Спасибо всем, в особенности _sk_ , за советы! Сообщаю предварительные выводы. Особых событий перед падением скриптов нет, обычно крашу случается по истечение нескольких часов после их запуска, что наводит на мысль о постепенном заполнении памяти в ходе работы скриптов. Логгирование это подтвердило -- происходит плавный рост использования памяти с течение времени в обоих моих основных скриптах, в особенности в последнем сварганенном. Собственно, я получил то что и должен был получить -- он сохраняет в таблицу последние bid, ask два раза в секунду и данные по сделкам по ВСЕМ фьючерсам. Каждый час объем памяти используемый этим скриптом растет приблизительно на 150 мегабайт. Падает чаще всего второй скрипт, который сохраняет меньше данных, но, по-видимому, делает это (т.е. обращается к памяти) чаще. Я полагаю что ручной запуск сборщика мусора мне мало чем поможет, т.к. проблема не в большом объеме мусорных данных, а в огромных таблицах (за 10 часов набирается порядка 70 тысяч элементов). Старые куски этих таблиц надо периодически удалять ограничивая их общий объем 1- 10 тысячами элементов. Это, между прочем, оказывается определенной проблемой, -- я не вижу стандартного инструмента. Многократное удаление отдельных элементов с использование table.remove и перенумерацией массива занимает много времени. В частности, удаление половины первых элементов из массива длинной 10000 у меня заняло 6 секунд! Косые способы решения этой проблемы обсужу в новой теме.
Это пример очень плохого скрипта. Зачем Вы храните все bid, ask с шагом 0.5 в таблице? Вы что обрабатываете всю таблицу от начал каждую секунду? Если нет, но хотите сохранить ( аля плюшкин, выбросить жалко, а нести тяжко), то пишите в файл. в результате у Вас освободится 90% занятой памяти. ---------------------------- Хороший алгоритм реального времени - это тот, в котором нет обработка данных в цикле.
_sk_ написал: Стандартная схема работы виртуальных машин: 1) выделяем какой-то объём памяти для работы; 2) работаем, периодически вызывая сборщик мусора (мелкая гребёнка); 3) если после сборки мусора осталось мало свободной памяти, выделяем больше памяти (периодическое повышение объёма) и продолжаем работать с пункта 2). Продвинутые виртуальные машины умеют уменьшать объём выделенной памяти, если потребность в ней снизилась. Похоже, что виртуальная машина lua к таким не относится.
Вы не правильно понимаете работу VMLua. Память выделяется при создании таблиц и их заполнении. Сборщик мусора запускается по времени. Время его запуска можно установить (можно вообще отключить сборщик). сборщик проверяет ссылки и если на данную область ссылок нет то отправляет эту область в кучу. таким образом уменьшается область занятой памяти. ---------------------- Если желаете экономить память и при этом существенно ускорить работу скриптов, то используйте всюду где можно local.
Проблема Вашего алгоритма в том, что Вы не контролируете состояние робота. Чтобы не открывать кучу позиций надо реализовать контроль . Например, если Вы послали заявку на открытие позиции, то надо отслеживать это состояние и блокировать дальнейшую работу робота, пока не поступит сигнал о выставлении либо отклонении вашей заявки. и т д. Все состояния (события) надо контролировать. ------------------------ относительно OnAllTrade Это колбек событий. Но события (сделки) приходят пакетом т е сделки с различным временем в одном пакете поступят одновременно. Если хотите синхронизировать их возникновение то надо обрабатывать время сделки.
Иван Ру написал: П.С. Версия quik - 7.12 Windows 10 64 бит 32 гб RAM.
Цитата
_sk_ написал: У меня компьютер аналогичный, только памяти 16 Гб
Ребят, вы поймите, квик - 32х битный процесс, он не может использовать больше 4гб от слова никак. И ему без разницы 16 у тебя или 32 гб рам.
Надо уменьшать кол-во данных внутри квика, и оптимизировать луа-скрипты.
1) посмотрите диспетчером задач используемый объем памяти. 2) Посмотрите объем используемой скриптом памяти сборщиком мусора ---------------------------------------------- Чтобы исчерпать всю память надо написать очень плохой скрипт .
Иван Ру написал: Любопытно... Я так понимаю картинка именно со срочного рынка?
Увы, у себя в меню "Доступные параметры" для инструментов срочного рынка я не вижу такого параметра "Начало вечерней сессии" и ничего аналогичного. Скажите какую версию терминала и какого брокера используете? (У меня 7911 финам)
В луа я (безуспешно) использовал такие параметры:
local STARTTIME = getParamEx('SPBFUT',value.sec, 'STARTTIME').param_value -- STRING Начало основной сессии local ENDTIME = getParamEx('SPBFUT',value.sec, 'ENDTIME').param_value -- STRING Окончание основной сессии local EVNSTARTTIME = getParamEx('SPBFUT',value.sec, 'EVNSTARTTIME').param_value -- STRING Начало вечерней сессии local EVNENDTIME = getParamEx('SPBFUT',value.sec, 'EVNENDTIME').param_value -- STRING Окончание вечерней сессии local MONSTARTTIME = getParamEx('SPBFUT',value.sec, 'MONSTARTTIME').param_value -- STRING Начало утренней сессии local MONENDTIME = getParamEx('SPBFUT',value.sec, 'MONENDTIME').param_value -- STRING Окончание утренней сессии
имена параметров надо задавать по англицки. Для этого делаете DDE вывод таблицы параметров с именами столбцов в excel и смотрите имя.
ЦитатаИван Ру написал: Сабж. Как известно иногда она начинается в 19.00, иногда - в 19.05 Пробовал разные средства - поля STATUS и TRAIDSTATUS всегда имеют значения 0. Данные о последней сделке и стакане заявок в период клиринга прекрасно выдаются, по ним судить о времени начала и окончания этого периода нельзя :-(getParamEx ---------------------------------- Параметр Начало вечерней сессии
Спасибо Николай, что напомнили. Этот параметр я опробовал еще раньше, с тем же результатом - одни нули. Там куча аналогичных параметров (время начала и конца дневной сессии и т.п.) которые также возвращают всегда нулевые значения.
Очевидно у Вас не выбран этот параметр Посмотрите его в ТТП. Картинка выше. Если есть то должно читаться в луа.
Напишите какой-нибудь индикатор для начала В нем можете сделать так: local tinfo=getDataSourceInfo(); local interval=tinfo.interval; -- интервал графика
Иван Ру написал: Сабж. Как известно иногда она начинается в 19.00, иногда - в 19.05 Пробовал разные средства - поля STATUS и TRAIDSTATUS всегда имеют значения 0. Данные о последней сделке и стакане заявок в период клиринга прекрасно выдаются, по ним судить о времени начала и окончания этого периода нельзя :-(
getParamEx ---------------------------------- Параметр Начало вечерней сессии
Nikolay Pavlov написал: Я уже выше описан, что шлюзы учитывают порядок полученных транзакций на снятие заявок только в момент отправки на Биржу запроса на снятие заявки, но если сама Биржа решит ответить сначала на 2 запрос, а после на 1, шлюз НЕ БУДЕТ ждать пока биржа пришлет ответ на запрос снятия заявки №1, он сразу отправит сообщение о снятии заявки №2 на сервер Quik и соответственно в терминале Вы увидите, что заявка №2 снялась раньше.
Вообще-то,шлюз ничего не может решать. Он работает по правилу FIFO. ----------------------------- Решать могут, например, маршрутизаторы. ----------------------------- Вы уж старайтесь не фантазировать, а придерживаться реальной схемы каналов.
Andrei2016, Суть в том , что Вы в своих вопросах хотите получить 100% гарантии синхронного прихода сообщений при асинхронной передаче потоков от биржи и асинхронной передачи пакетов по интернет. Т е ответ на Ваши вопросы один - гарантий никаких нет. Потоки не синхронизированы. Интернет допускает опережение пакетов, их потерю, повторный запрос. Это же допускают и потоки с биржи. т е можно терять сообщения и повторно их запрашивать т е нарушать последовательность.
что-то тема анекдот напомнила. ------------------------------ сидит группа зеков в тюрьме , все анекдоты давно рассказали и поэтому называют лишь номера анекдотов. Один зек кричит - номер 102. Вся камера - ну это уже не смешно, сколько можно этот анекдот рассказывать. Через пять минут, в дальнем углу раздается смех . Ты что, это? -удивленно спрашивает смотрящий. Так я этот анекдот первый раз слышу - отвечает смеющийся. -------------------------------------------
Василий Артёмов написал: Здравствуйте. Необходимо получать callback только после изменение позиции, без различных других вызовов данного колбэка. Как можно реализовать, подскажите пожалуйста?
Без различных других вызовов данного колбека нельзя. колбек на то и колбек, что вызывается по любому изменению FuturesClientHoldin (так оно задумано изначально). тоже самое касается и других колбеков. ------------------------------- Поэтому Вам надо внутри колбека поставить Ваше условие условие и по true совершать действия.
Пытаюсь написать скрипт, задачей которого является получение значения индикаторов с большого числа инструментов. Делать свыше 70-80 таблиц и называть в них индикаторы смысла не имеет.
Разобрался, что через CreateDataSource можно получить данные со свечей любого инструмента... но можно ли это применить для индикаторов? Для аллигатора или хотя бы обычной скользящей средней? Или есть какие-то другие альтернативы для решения данной задачи?
CreateDataSource получает данные с сервера. Поэтому с помощью этой функции можно получить лишь те индикаторы которые рассчитываются на сервере. Например, свечи. Встроенные индикаторы рассчитываются в терминале, поэтому их невозможно заказать с свервера т е надо считать либо в скрипте либо в терминале. В последнем случае надо открывать окна с графиками и ставить идентификаторы. Это совсем не страшно, так как очевидно делается один раз.
Let_it_go, Выкладываю вариант решения на луа указанной страницы сайта.
Код
require "socket"
http = require 'socket.http'
local address = 'http://smart-lab.ru/dividends/index/order_by_t2_date/desc/'
local ts={"tr","strong","span"}
local lMax=91 --число строк в таблице
--------------------
function nkdelspace(s)
local len=string.len(s); local z=""; local x1=32;
for i=1,len do local x=string.byte(s,i); if x<32 then x=32 end
if (x~=32 or x1~=32) then
if z=="" then z=string.char(x) else z=z..string.char(x) end
x1=x; end
end --убираем проблелы
return z;
end
----------------------
local body = http.request(address)
----------------------
for i=1,#ts do
body = string.gsub (body,"(<%s*"..ts[i].."[^>]*>)","")
body = string.gsub (body,"(<%s*/"..ts[i].."[^>]*>)","")
end
body = string.gsub (body," "," ")
local t={} -- результат
local j=0; local k=0; local text=0;
local m=1;
local n=string.find(body,"td>",m,#body,true);
local x=string.byte(body,n-1);
m=m+3;
-----------------
while #body>m do
n=string.find(body, "td>",m,#body,true);
if n then local n1=n;
if x~=47 then
x=string.byte(body,n-1); if x==47 then n=n-1; end
text = string.sub(body, m,n-2); text = nkdelspace(text);
local len=string.len(text);
if len<20 then
j=j+1; if j==1 then k=k+1; t[k]={} end
local tt=t[k]; tt[#tt+1]=text;
if j==8 then if k==lMax then break end
j=0 end
end
else
x=string.byte(body,n-1);
end
m=n1+3;
else break;
end
end
Результат - таблица t . 91 элемент ( это переменная lMax). каждый элемент - таблица из 8 элементов: -------------------- 1>table ....1 PHOR ....2 08.08.2017 ....3 10.08.2017 ....4 2016 ....5 н/расп ....6 21 ....7 2345 ....8 0,9% -------------------- ..2>table ....1 GAZP ....2 18.07.2017 ....3 20.07.2017 ....4 2016 ....5 год ....6 8,0397 ....7 122,28 ....8 6,6% ----------------- и т д
http = require 'socket.http' local address = 'http://smart-lab.ru/dividends/index/order_by_t2_date/desc/' htmls = http.request(address) ------------------------ а потом вытащить данные используя ручной способ из приведенного примера El El переписав его на луа.
Николай Камынин написал: Let_it_go , Ваша задача немного сложнее, чем пример который я написал. Дело в том,страница, которую вы хотите читать не содержит готовой таблицы. Поэтому кроме парсера Вам придется исполнять джава скрипты. ------------------- Поэтому более правильно решать вашу задачу через использование браузера в качестве ком объекта.
Эта страница - статический html. Пример выше именно ее и достает и парсит. По крайней мере, так было месяц назад, когда пример писался.
Пример очевидно хороший для тех, кто знает CPP и и работу c make. Полагаю, что 99% посетителей этого форума и не знают как с этим работать. Эти особенности и есть недостатки примера. -------------------------------------- Кроме того, пример содержит еще две особенности. 1) Скорректированная библиотека, т е недокументированная поделка. 2) Как сказано в примере: "Преобразование данных из HTML будет осуществляться для простоты "ручным" поиском строк и регулярными выражениями. В более серьезной архитектуре может применен XML-парсер и др., такой вариант оставляется читателю ручной способ поиска." ----------------------------- Следовательно, это скорее всего - готовое частное решение, а не пример для подражания. --------------------------------------- Полагаю, что более универсальное решение , может быть на luacom и InternetExplorer.Application. Т е решении исключительно в рамках стандартов Майкрософт и языка луа. -------------------------------
Let_it_go, Ваша задача немного сложнее, чем пример который я написал. Дело в том,страница, которую вы хотите читать не содержит готовой таблицы. Поэтому кроме парсера Вам придется исполнять джава скрипты. ------------------- Поэтому более правильно решать вашу задачу через использование браузера в качестве ком объекта.
Let_it_go написал: Господа, подскажите пожалуйста как реализовать такую задачу на Луа. 1. Робот заходит на страничку с дивидендами: http://smart-lab.ru/dividends/
2. Читает её 3. Формирует Луа-таблицу с полями Тикер - дата отсечки Т+2 Тикер - дата отсечки Т+2 4. В последний день перед дивидендым гэпом посылает сообщение в КВИК.
Мои роботы на Луа никогда не читали интернет-странички и не брали из них данных. Даже не знаю с чего начать. Спасибо за помощь.
local function off (events)
display.remove (events);
end
local function onGlobal (event )
if (floor = = event.object1) then
if ( event.phase = = "began" ) then
if (event.object2.myName > 0 ) then
mas = event.object2.myName
timer.performWithDelay ( 5000 , off(event.object2))
end
end
end
end
А что у Вас с таймером? Это же Вы написали и только Вы знаете, что у вас с таймером.