Не могу получить стаканы по акциям, В последние дни не открываются стаканы по акциям (пустые поля при открытии соответствующего окна), программно их получить тоже не удается.
Иван Ру написал: Выдает сообщение: "превышено ограничение на количество котировочных окон..." -- хотя их открыто всего 3 штуки.
Добрый день. Иван, проверьте не настроен ли у Вас экспорт котировочных стаканов, например по ODBC. Посмотреть список настроенных инструментов можно через команду меню терминала "Сервисы->Экспорт\Импорт данных->Экспорт инструментов по ODBC". Возможно настроен экспорт по большому числу инструментов.
Нет, там пусто. Ничего не экспортируется. Мне это не нужно, не пользуюсь. Имеет ли значение большое число инструментов в "Потоке обезличенных сделок..."
Не могу получить стаканы по акциям, В последние дни не открываются стаканы по акциям (пустые поля при открытии соответствующего окна), программно их получить тоже не удается.
Не могу получить стаканы по акциям, В последние дни не открываются стаканы по акциям (пустые поля при открытии соответствующего окна), программно их получить тоже не удается.
В последние дни не открываются стаканы по акциям (пустые поля при открытии соответствующего окна), программно их получить тоже не удается. Стаканы по фьючерсам открываются нормально. Данные по акциям заказаны - с этим все ок.
Брокер Финам. В мобильном приложении финама все работает. Версия 7.12
Александр М написал: В какой кодировке у вас файл, когда вы туда копируете данный текст? Должна быть Windows-1251
Большое спасибо за правильно подсказанное направление! В отдельных файлах кодировка не выбрана, в большинстве стоит UTF8 почему-то. Это и создавало проблему! Даже не могу понять откуда такая засада возникла
Notepad++ автоматически кодировку подбирает, что ему покажется, ту и подставит, лучше всегда проверять при создании нового файла скрипта, дальше он уже сам не меняет.
Я пробовал в этом редакторе сбросить выбор кодировки - не получается. (В "нормальных" файлах ни одна из опций не выбрана).
Александр М написал: В какой кодировке у вас файл, когда вы туда копируете данный текст? Должна быть Windows-1251
Большое спасибо за правильно подсказанное направление! В отдельных файлах кодировка не выбрана, в большинстве стоит UTF8 почему-то. Это и создавало проблему! Даже не могу понять откуда такая засада возникла
Есть у меня файл с вот-таким кодом отправки заявки с русскими полями и возможностью переноса через клиринг / ночь. (Когда-то формировал его на основе три-файла) t = { -- Задаем базовые параметры ордера ["CLASSCODE"] = CLASS_CODE , ["Инструмент"] = SEC_CODE, ["ACTION"] = "Ввод заявки", ["Торговый счет"] = ACCOUNT, ["Тип"] = "Лимитированная", ["Комментарий"] = RoboName, ["К/П"] = tradeDir, ["Количество"] = tostring(lots), ["Условие исполнения"] = "Поставить в очередь", ["Переносить заявку"] = "Да", ["Цена"] = tostring(PRICE), ["TRANS_ID"] = "1" , ["Дата экспирации"] = expDate
} res=sendTransaction(t);
Как только я копирую его в другой файл (текстовый файл Notepad++, Copy-Paste), он перестает работать. Выдает ошибку "Неправильно указан вид транзакции" + крикозябли "Р’РІРѕРґ заявки", то бишь "Ввод заявки". Чего только не делал -- все перепроверял до буквы, переписывал, сверял переменные. Никак не работает. Чтобы интегрировать этот код в новый файл, приходится делать копию оригинального и вокруг этого загодочного блока вставлять остальные куски кода скрипта. Тогда работает. Что это? Сталкивался кто-либо с таким?
Zoya Skvorcova написал: Иван Ру ,добрый день. Как вариант, Вы можете скопировать настроенный график с индикатором (Ctrl+N) и внастройках заменить инструмент
мне нужно вставлять данный график в новое окно - так не получается
Zoya Skvorcova написал: Иван Ру ,добрый день. Как вариант, Вы можете скопировать настроенный график с индикатором (Ctrl+N) и внастройках заменить инструмент
Допустим я наворотил на график 5-6 индикаторов. Настроил их. Хочу чтобы они с такими же настройками появились на множестве моих других графиков, или на графиках создаваемых вновь. Сохраняю шаблон исходного графика с индикаторами. И... опаньки, параметры графика (таймфрейм и т.п.) использовать при построении нового можно, а вот индикаторы - нет. Есть ли такая возможность в принципе? Если нет -- очень неудобно, прошу зарегистрировать пожелание!
Александр Правилов написал: Иван Ру , спасибо, я уже понял, что доп.таблицы мне не избежать, буду продумывать как это всё лучше организовать. Kill balance это снятие заявки, если выполнена частично?
Предложу свои решения. 1. Возможно Вам подойдет задание особых параметров заявки - Fill or kill или Kill balance, которые в случае неисполнения уничтожаются автоматически. 2. У меня каждая заявка / позиция выставляется с формированием уникальной для него таблицы с несколькими полями, куда записываются уникальный идентификатор транзакции, номер заявки на сервери биржи и другие параметры, например placed = true - если получен "положительный" (status = 3) отклик в OnTransReply. Там же фильтруются и вторичные отклики: инфа о полученных откликах сохраняется, если вновь приходит сообщение с тем же номером заявки, что уже приходил ранее, оно игнорируется как повторное. Конструкция сложная, но неизбежная в нашей ситуации
Спасибо за внимание! Я знаком с рекомендациями и следую большинству из них (регулярная очистка данных, бесконечные счетчики, тиковые данные), за исключением пунктов категорически неподходящих для полноценной алгоритмической торговли (данные нужны в реальном времени, не порционно). Отчасти причина появления ошибки установлена - это запуск скриптов. При этом: 1) Один и тот же скрипт в большинстве случаев запускается нормально, но иногда (при том что он не модифицируется) выдает данную ошибку -- когда и при каких условиях, пока понять не могу. 2) Ошибка спонтанно появляется при запуске в том числе и тех скриптов, которые вообще никак не работают с окнами и даже стаканами котировок. Ну вообще никакого отношения к ним не имеют -- вроде банальных "внутренних" математических расчетов, без обработки колбэков. 3) Изначальное предположение о комплексном характере глюков - неверно. описываемая ошибка проявлялась сразу после переустановки терминала, в то время как весь прочий функционал работал исправно. При очередном глюке вышлю скрипт и архив терминала.
После копирования всех папок и корневых файлов в директорию со скриптами запуск кода привод к следующей ошибке C:\QuikFinam\scripts\mail.lua:48: attempt to call global 'mtp_send' (a nil value)
Settings = { host = "smtp.TEST.ru", port = 25, from = "TEST@TEST.ru", to = "TEST@TEST.ru", subject = "Qlua notification", cc = "TEST@TEST.ru", user = "TEST", password = "123", rcpt = { " " } } function smtp_send(settings, msg) local mesgt = { headers = { to = settings.to, cc = settings.cc, subject = settings.subject or "Qlua Notification", ["content-type"] = 'text/plain; charset="windows-1251"' }, body = msg }
r, e = smtp.send{ from = settings.from, rcpt = settings.rcpt, source = smtp.message(mesgt), server = settings.host, port = settings.port, user = settings.user, password = settings.password } end
smtp_send(Settings, "TEST")
Разъясните пожалуйста, куда и что конкретно копировать . архив какой конкретно по ссылке ? luasocket-2.0.2-lua-5.1.2-Win32-vc8.zip\socket - ZIP archive, unpacked size 275 170 bytes - пойдет? В архиве файлы и подпапки. Нужно распаковывать все или нужна только core.dll? В корневую директорию или в папку с скриптами?
Иван Ру написал: Превышено ограничение на количество котировочных окон
Добрый день.
Правильно понимаем, что сообщение появляется при построении 4 окна? На других вкладках нет открытых "стаканов" ? Если не включаться скрипт, то ошибка повторяется, ошибка повторяется всегда или в определенных условиях?
Нет, никаких действий по построению и изменению окон не произвожу, ни "вручную", ни программно. Причина появления до конца не ясна, по-видимому - при запуске скриптов, которые никаких окон не строят, но стандартным способом считывают стаканы фьючерсов. Сейчас переустановил квик - полет нормальный, проблемы нет.
В таком случае при повторении проблемы, закройте QUIK, сделайте архив без ключей и пришлите нам на quiksupport@arqatech.com со скриптом.
Хорошо. По-видимому проблема комплексная. По истечении некоторого времени после установки у моего квика 7.12.1.10 (финам) начинаются разноплановые глюки-- 1) долго загружается, а потом -- вообще не может загрузиться при старте, 2) падение из-за нехватки памяти, 3) теперь,-- и указанная выше проблема с превышением лимита на стаканы. Проблемы стали появляться после очередного обновления пару месяцев назад. Опытным путем установил, что: 1) скрипты не причем (отключение не помогает), 2) удаление файлов alltrades и info.log и установка регулярной очистки данных в настройках - не помогают, 3) сброс настроек окон (wnd) - не помогает , 4) по-видимому проблемы в неосновных файлах программы, т.к. простая переустановка программы не помогает решить проблему, нужна очистка всех файлов находящихся в КОРНЕВОЙ директории. После такой чистики и переустановки квик опять полноценно работает.
П.С. Раньше (тоже после обновления) еще возникала проблема с жуткими тормозами при открытом окне "Состояние счета", но сейчас ее нет. Что-то исправили?
Иван Ру написал: Превышено ограничение на количество котировочных окон
Добрый день.
Правильно понимаем, что сообщение появляется при построении 4 окна? На других вкладках нет открытых "стаканов" ? Если не включаться скрипт, то ошибка повторяется, ошибка повторяется всегда или в определенных условиях?
Нет, никаких действий по построению и изменению окон не произвожу, ни "вручную", ни программно. Причина появления до конца не ясна, по-видимому - при запуске скриптов, которые никаких окон не строят, но стандартным способом считывают стаканы фьючерсов. Сейчас переустановил квик - полет нормальный, проблемы нет.
В таком случае при повторении проблемы, закройте QUIK, сделайте архив без ключей и пришлите нам на quiksupport@arqatech.com со скриптом.
Хорошо. По-видимому проблема комплексная. По истечении некоторого времени после установки у моего квика 7.12.1.10 (финам) начинаются разноплановые глюки-- 1) долго загружается, а потом -- вообще не может загрузиться при старте, 2) падение из-за нехватки памяти, 3) теперь,-- и указанная выше проблема с превышением лимита на стаканы. Проблемы стали появляться после очередного обновления пару месяцев назад. Опытным путем установил, что: 1) скрипты не причем (отключение не помогает), 2) удаление файлов alltrades и info.log и установка регулярной очистки данных в настройках - не помогают, 3) сброс настроек окон (wnd) - не помогает , 4) по-видимому проблемы в неосновных файлах программы, т.к. простая переустановка программы не помогает решить проблему, нужна очистка всех файлов находящихся в КОРНЕВОЙ директории. После такой чистики и переустановки квик опять полноценно работает.
Николай Камынин написал: Полагаю, что у Вас установлен флаг "Исходя из настроек открытых пользователем таблиц" Надо установить флаг "С учетом настроек, выбранных через пункт меню "Система/Заказ данных/Поток котировок" в "настройки клиентского места" в окне "Получение данных"
Спасибо за разъяснения. Не совсем понимаю, что будет происходить с открытой таблицей и заказаом данных при экспирации и появлении новых фьючерсов, т.е. при изменении их списка?
Иван Ру написал: Превышено ограничение на количество котировочных окон
Добрый день.
Правильно понимаем, что сообщение появляется при построении 4 окна? На других вкладках нет открытых "стаканов" ? Если не включаться скрипт, то ошибка повторяется, ошибка повторяется всегда или в определенных условиях?
Нет, никаких действий по построению и изменению окон не произвожу, ни "вручную", ни программно. Причина появления до конца не ясна, по-видимому - при запуске скриптов, которые никаких окон не строят, но стандартным способом считывают стаканы фьючерсов. Сейчас переустановил квик - полет нормальный, проблемы нет.
При этом работают два скрипта, которые перестали читать данные стакана... Чтение данных стакана через Lua с недавних пор приравнивается к открытию котировочного окна что-ли?
Sergey Gorokhov написал: т.е. вопрос совершенно никак не связан с LUA
Здесь я задал вопрос про конкретный способ решения проблемы - проверку и установку настроек Квик через Луа. Так и не понял, есть ли в принципе такая возможность. В принципе она для разных целей интересна.
Иван Ру написал: Есть открытый текстовый файл, скажем, длинной в 100 строк. Необходимо дописать данные, скажем, в 79 строку (номер известен). Возможно ли такое средствами Lua, есть ли у кого пример реализации подобной функции?
Вашу задачу можно так: 1) Все записи делаем одинаковой длины, например 128 байт 2) Если запись короче 128 то добиваем ее либо пробелом либо нулями. 3) Если надо дописать, то ищем изменяемую запись , читаем ее, добавляем и пишем на свое место.
Возможно мы друг друга недопоняли. Записи я делаю в csv (текстовый) файл с разделителями в виде ";". Затем я его читаю в эксель. По-сути надо добавить дополнительные элементы данных в отдельные строки, де-факто они всегда оказываются ближе к концу файла. Кстати, попутный вопрос. Если у меня файл находится в открытом состоянии в режиме чтения-записи и его размер велик (скажем 100 мб.) -- отнимает ли это соответствующий объем оперативной памяти? Если да - как этого избежать? Только закрытием файла и повторным открытием для записи?
Таблица у меня действительно, не открыта. Действительно, галочка "Сохранять настройки" не была установлена. Надеюсь это отчасти решит проблему. Благодарю за совет. Сброс иногда происходит и при нормально работающей программе. Вот как сегодня.
Мне нужны данные по всем фьючам. Соответственно, я выбираю их и заказываю в упомянутом выше разделе. Периодически - после перезапуска квик, или даже во время его работы, обнаруживаю, что выбрано только несколько инструментов - обычно 4-6 ликвидных фьючей. Я так понимаю - это какая-то настройка по умолчанию до которой из-за каких-то причин сбрасывается внешний параметр. Почему и с чем связано такое событие - точно не знаю. Иногда, возможно, это связано с перезагрузкой и аварийным завершение работы. Вот сегодня так было вновь при работающем квике, возможно это произошло после того как квик предложил заменить несколько фьючей с истекшим сроком действия на новые. Мне это уже много раз создавало проблемы, хочу себя обезопасить программно.
Хочу средствами Луа проверить и, при необходимости, выбрать все фьючи в Заказа данных / Поток обезличенных сделок. Мои настройки почему-то постоянно сбрасываются. Возможно ли такое и какова реализация?
vgi написал: Если требуется именно дописать, а не изменить, то для случая дописывания в конец строки самым простым представляется прочитать из файла, открытого как io.open( filename, "r+" ), N (=79) строк. Затем шагнуть назад file:seek( "cur", -EOL ), где EOL = "\n":len() - длина перевода на новую строку. А потом дописать с помощью file:write то, что Вам требуется. Для случая дописывания не в конец строки придётся искать позицию иначе.
Если файл создаётся периодически из того же кода, можно отдельно запоминать offset для file:seek нужного для дозаписи места.
Дело обстоит так. Файл открыт постоянно в работе скрипта - в него записывается информация об особых событиях (несколько десятков за сессию), с течением времени дописывается инфа об изменении цены с момента события (до часа). Ну точнее хочу чтобы дописывалась, -- продумываю реализацию. Можно конечно записывать строку целиком через час, но в случае остановки скрипта или других проблем она будет утеряна целиком.
Есть открытый текстовый файл, скажем, длинной в 100 строк. Необходимо дописать данные, скажем, в 79 строку (номер известен). Возможно ли такое средствами Lua, есть ли у кого пример реализации подобной функции?
lergen написал: Такая же проблема (ошибка по nil) после обрывов связи хотя проверка на соединение проводится, т.е. если связи нет параметры не должны запрашиваться. Как избежать остановки скрипта при кратковременных обрывах связи? function main() while not stopped do if (isConnected()==1 and GetServerTimeNumber()~=nil) then if TimeJob() then qtnF=getQuoteLevel2 (ClassCode, nFuture) bid=qtnF.bid[qtnF.bid_count-0].price ... ... else ... ...
end end sleep(200) collectgarbage() end end
Интернет-соединение и соединение с торговым сервером - не одно и то же. Интернет соединение может быть, а соединения с сервером - нет, если не введен пароль или ночью. В таком случае можно и не получить данные таблиц. Я проверяю наличие соединения с сервером пытаясь считать время сервера, если значение возвращаемых полей nil -- значит соединения с сервером нет.
Настройки окон сохраняются в файл wnd, а в какой файл сохраняются настройки задаваемые в разделах "Система/Настройки", в частности - параметры заявок, оповещения и т.п.? Можно ли сохранять и копировать данный файл из-разных/одной версии Quik?
С помощью параметра ["EXECUTION_CONDITION"] можно задавать тип транзакции, для рынка фьючей, я смог найти три возможных параметра
'PUT_IN_QUEUE' -- поставить в очередь заявок -- обычная лимитная заявка 'FILL_OR_KILL' -- исполнитель немедленно или выполнить «KILL_BALANCE» – снять остаток
Заявка 'FILL_OR_KILL' исполняется на весь объем или отменяется, однако мне нужна заявка, которая могла бы исполниться частично, и затем - отменялась автоматически. Такой тип на зарубежных площадках есть -- это "Immediate or canceled" (IOC). Однако, насколько я понимаю в QUIK/LUA такая возможность не реализована.. Прав ли я и с чем это связано? Кто как обходит проблему?
П.С. Чтобы не разводить базар "зачем": 1) чтобы не было нужды писать реализацию по удалению заявок, 2) чтобы экономить на количестве транзакций генерируемых роботом.
Николай Камынин написал: и еще, самое главное: Уберите свои скрипты и посмотрите как будет работать. С этого надо было начинать. Но можно и закончить этим.
Пункт 5 пробовал. Полное удаление и переустановку пробовал, правда, ставил в тот же каталог. Отключать скрипты пробовал и, еще раз, -- я внутри них вставил контроль объема памяти. Сейчас они забирают не более 500 мб в сумме. Кроме того, иногда квик крашится уже после 23.50, когда у меня скрипты автоматически останавливаются. Вот вчера квик ни разу не упал -- редкий удачный день! П.С. Переслал письмо с архивом рабочего места и пометкой для Вас.
Иван Ру написал: Я все же неверно определил источник проблемы, которая, к сожалению сохраняется. Теперь уже в самом терминале появляется сообщение "Операция не может быть выполнена т.к. недостаточно памяти". При этом объем памяти используемый двумя скриптами составляет порядка 2х150 = 300 мб, а совокупный объем памяти занятой терминалом (в тот же момент смотрел через диспетчер задач) -- 1,5 Гб. Вообще последний показатель никогда не превышает 2,5 Гб, т.е. ресурс не выбран. Что у меня включено: - трансляция обезличенных сделок (около 5 полей по 160 инструментам - все фьючи). - 2 окна "Текущие торги" - все фьючи и все акции, порядка 10 полей в каждом. - 2 тиковых графика - 2 стакана - около 15 окон с графиками - 2 окна с портфелями Т2 и Т0.
Отключение тиковых графиков проблему не решает, а вот отключение трансляции обезличенных сделок -- по первым ощущения ее устраняет. Мне они категорически нужны, не понимаю что делать.
Могу дать следующие советы. 1) Удалите из ТТП те акции, которыми не торгуете и фьючерсы которыми не торгуете. Но удалять надо из заказа данных. 2) Удалите параметры, которые не используете. 3) Проверьте отключены ли у Вас опционы. 4) Посмотрите сколько в действительности у Вас выбрано инструментов и параметров (В окне выбор принимаемых параметров и инструментов) 5) Попробуйте работать с включенным флагом "Только данные, отражающие текущее состояние" (Настройки клиентского места) ----------------------------------- Пишите, какой результат.
Я оставил заказ данных только на фьючерсы, пробовал удалять файлы info.log и alltrade.dat, сократил количество параметров до минимума. К сожалению не помогает. Хотя изменился характер ошибок. Теперь чаще наблюдается краш программы (предлагает отладку или закрыть) или сообщение "не хватило памяти под объекты..." В момент краша общий объем используемой памяти, как показывает монитор Windows - 1-2 ГБ.
Увы, проблема продолжается в разных ипостасях. Теперь периодически начали появляться сообщения другого рода -- просто ошибка, после которой терминал предлагает включить отладку или закрыть себя или сообщение "Не хватило памяти под объекты, без которых терминал работать не может..." Сообщения появляются обычно вечером после многих часов работы терминала. Какое-то время еще была проблема с очень долгим запуском (по пол часа), сейчас вроде нет. Удаление файлов alltrades.log и info.log проблему с дефицитом памяти и крашем терминала не решает.
Я все же неверно определил источник проблемы, которая, к сожалению сохраняется. Теперь уже в самом терминале появляется сообщение "Операция не может быть выполнена т.к. недостаточно памяти". При этом объем памяти используемый двумя скриптами составляет порядка 2х150 = 300 мб, а совокупный объем памяти занятой терминалом (в тот же момент смотрел через диспетчер задач) -- 1,5 Гб. Вообще последний показатель никогда не превышает 2,5 Гб, т.е. ресурс не выбран. Что у меня включено: - трансляция обезличенных сделок (около 5 полей по 160 инструментам - все фьючи). - 2 окна "Текущие торги" - все фьючи и все акции, порядка 10 полей в каждом. - 2 тиковых графика - 2 стакана - около 15 окон с графиками - 2 окна с портфелями Т2 и Т0.
Отключение тиковых графиков проблему не решает, а вот отключение трансляции обезличенных сделок -- по первым ощущения ее устраняет. Мне они категорически нужны, не понимаю что делать.
Николай Камынин написал: Надо делать скользящее окно по максимальному N
Y Согласен. Собственно здесь и обсуждалась качественная реализация этого решения. Я встроил собственное решение в оба скрипта, первый день - работает все нормально и оперативно. Меня удивляет, что в луа нет встроенного механизма "обрезки" части массива.
Николай Камынин написал: Это пример очень плохого скрипта. Зачем Вы храните все bid, ask с шагом 0.5 в таблице? Вы что обрабатываете всю таблицу от начал каждую секунду? Если нет, но хотите сохранить ( аля плюшкин, выбросить жалко, а нести тяжко), то пишите в файл.
Я не думаю, что опыт позволяет написать мне качественный код, однако, не стал бы столь решительно судить о нем по отдельным по внешним признакам :-) Конечно определенный смысл именно в таком подходе для меня есть. В определенные "критические", скажем так, моменты времени, мне надо подсчитывать разнопериодные средние (не по барам, а в привязке к критической точке), при этом делать это надо максимально быстро. По последней причине запись в файл для меня неприемлема, т.к. процедура открытия/чтения занимает время. Единственный выход - работать на укороченной истории. Если Вы предложите лучшее и более качественное решение моей задачи -- буду только признателен :-)
Я не претендую на звание хорошего программиста и отчасти согласен с высказанными замечаниями, но все же вопрос не в качестве моего кода, а в принципиальной проблеме языка. Записывать в файл - не вариант, т.к. это существенно понизит быстродействие при расчетах.
Я продолжил исследование проблемы not enough memory и увидел, что мой первоначальный вывод не вполне верен. После добавления функции обрезки массивов объем памяти используемой скриптами сократился до (не более) 150 мегабайт (300 в сумме). Монитор показывает, что объем памяти используемый рабочим местом quik не превышает 2 Гб. Однако ошибка все равно выскакивала несколько раз, кроме того в последний раз, при переключении на тиковый график терминал уже сам выкинул ошибку "Недостаточно памяти для отображения данных" (в этот момент монитор показал, что квик занимает где-то полтора ГБ, резерв памяти и ресурсов процессора есть). В терминал у меня открыты следующие окна: - 2 портфеля (ТО, Т2) - сделки - заявки - текущие торги, все фьючи - текущие торги, все акции - около десяти минутных и часовых графиков - два тиковых графика (в привязке к выбранным в других таблицах инструментам)_ - одно окно котировок.
В чем дело? Похоже в работе терминала? П.С. Бывает, я его не перезагружаю 2-3 дня.
Удаление элементов в больших таблицах., Крайне медленная работа table.remove и возможные обходные пути для быстрого удаления большого числа элементов крупных массивов/таблиц.
вам действительно нужно хранить в памяти все эти десятки тысяч записей? Я понимаю, когда речь идет о текущей итерации скрипта, но ведь вы храните даже не агрегированные данные, а непосредственно данные по сделкам. Какой в этом смысл, если сделка прошла, условно говоря, 15 минут назад, а за это время вы получили еще 5000 сделок? Если вам необходимо сохранять эти сделки для последующей обработки сторонним приложением, так пишите их сразу в файл, но не сохраняйте в памяти. Все же мое мнение со стороны (оно может быть ошибочным): необходимо оптимизировать логику скрипта как такового, "облегчая" его.
Это не принципиально - т.к. речь о проблеме кодинга и языка. Есть ли нужда в таком? Не скажу что критичная, но есть -- данные нужны для оперативного подсчета средних значений, и не по барам, а за произвольный период. Причем этот подсчет должен производиться максимально быстро.
Удаление элементов в больших таблицах., Крайне медленная работа table.remove и возможные обходные пути для быстрого удаления большого числа элементов крупных массивов/таблиц.
Пока что вижу для себя такое решение -- формируем временную таблицу куда записываем только те элементы большой таблицы, которые нужно сохранить. Затем ставим знак равенства между большой нуждающейся в "обрезке" таблицей и временным вариантом (второй вариант, см. код ниже). Быстрее стандартного варианта в несколько сотен раз.
function tabInit (number) local tab ={} for i =1,number do tab[i]=i end return tab end
function tabCount2 (Thetab) local count = 0 for k,v in ipairs (Thetab) do count = count+1 end return count end
-- Первая реализация local start = os.clock() while #tab1 > ElemToKeep do table.remove (tab1,1) end local ne1 = tabCount2 (tab1) local finish1 = os.clock() local time1 = finish1 - start message (tostring(time1).."-"..tostring(ne1))
-- Вторая реализация local tempTab = {} local numElement = #tab2 local startElement = numElement - ElemToKeep + 1 local minus = numElement - ElemToKeep
for i=startElement, numElement do tempTab[i-minus] = tab2[i] end tab2 = tempTab local ne2 = tabCount2 (tab2) local finish2 = os.clock() local time2 = finish2 - finish1 message (tostring(time2).."-"..tostring(ne2))
У меня на машине обрезка первым способом заняла 1,69 сек, а вторым - 0,002 сек.
Удаление элементов в больших таблицах., Крайне медленная работа table.remove и возможные обходные пути для быстрого удаления большого числа элементов крупных массивов/таблиц.
Столкнулся с проблемой - скрипты "падают" из-за нехватки памяти. В одной из них формируется несколько сотен таблиц, в каждую из которых два раза в секунду добавляется новые элемент (история бид, оффер и сделок, подробнее см. https://forum.quik.ru/forum10/topic2958/). Я пришел к выводу, что без удаления "старых" исторических значений из этих таблиц в течение сессии / одного запуска не обойтись. Однако, обнаружилось, что это очень затратная по ресурсам / времени процедура для которой я не вижу удобных альтернатив. Стандартный подход - использовать table.remove. Однако, он дает возможность удалять только один элемент, при удалении первых элементов в массиве, многократно меняются индексы всех последующих элементов, что требует много времени. Так удаление первых 5 тысяч элементов таблицы с 10 тыс. полей заняло у меня 6,5 сек. - непозволительно долго. Пример кода: local ElemToKeep = 5000 tab1 = tabInit (1000000) while #tab1 > ElemToKeep do table.remove (tab1,1) end
Есть обходные пути. Можно использовать простое удаление элементов, например, так: --local numElement = #tab2 --local toremove = numElement - ElemToKeep --for k = 1, toremove, 1 do --tab2[k] = nil --end Работа такого кода происходит гораздо быстрее (приблизительно в 2 тысячи раз в упомянутых условиях!). Однако, если мы удалим элементы в начале таблицы, например, с 1 по 2000, мы не сможем использовать их перебор через ipairs, и хуже того, мы не сможем оперативно посчитать число элементов в таблице с использованием #. Их число можно будет получить только путем перебора с вставкой счетчика в цикл pairs. Можно изголяться дальше в этом направлении. Например, каждый раз вставлять новые элементы в таблицу с использованием table.insert и присваивать им индекс 1, сдвигая все остальные в конец. Это решит проблему с ipairs, # и подсчетом элементов - достаточно будет обрезать "хвост" массива/таблицы, индексы будут начинаться с единицы и будут идти без пробелов. Однако, такой подход означает, что мы все равно выполняем ресурсозатратную процедуру (переименование индексов) -- с меньшей потерей времени, но чаще (при каждом добавлении нового элемента). Есть ли у кого-то пример эффективного решения подобной проблемы?
Вот, собственно, картинка использования памяти наиболее тяжелым скриптом С чем связана "гребенка", мне кажется понятным -- это работа сборщика мусора. А вот почему объем памяти большую часть времени увеличивается маленькими скачками с длинными плато, не совсем понимаю.
Спасибо всем, в особенности _sk_, за советы! Сообщаю предварительные выводы. Особых событий перед падением скриптов нет, обычно крашу случается по истечение нескольких часов после их запуска, что наводит на мысль о постепенном заполнении памяти в ходе работы скриптов. Логгирование это подтвердило -- происходит плавный рост использования памяти с течение времени в обоих моих основных скриптах, в особенности в последнем сварганенном. Собственно, я получил то что и должен был получить -- он сохраняет в таблицу последние bid, ask два раза в секунду и данные по сделкам по ВСЕМ фьючерсам. Каждый час объем памяти используемый этим скриптом растет приблизительно на 150 мегабайт. Падает чаще всего второй скрипт, который сохраняет меньше данных, но, по-видимому, делает это (т.е. обращается к памяти) чаще. Я полагаю что ручной запуск сборщика мусора мне мало чем поможет, т.к. проблема не в большом объеме мусорных данных, а в огромных таблицах (за 10 часов набирается порядка 70 тысяч элементов). Старые куски этих таблиц надо периодически удалять ограничивая их общий объем 1- 10 тысячами элементов. Это, между прочем, оказывается определенной проблемой, -- я не вижу стандартного инструмента. Многократное удаление отдельных элементов с использование table.remove и перенумерацией массива занимает много времени. В частности, удаление половины первых элементов из массива длинной 10000 у меня заняло 6 секунд! Косые способы решения этой проблемы обсужу в новой теме.
Иван Ру написал: Проблема решена по совету Николая Камынина. После того как включил параметр "Время начала вечерней сессии" в таблице "Текущие торги" строка local EVNSTARTTIME = getParamEx('SPBFUT',value.sec, 'EVNSTARTTIME').param_value -- STRING Начало вечерней сессии начала возвращать нужное значение в строковом формате
пардон - формат NUMBER вида 190500, можно отнять 190000 и получить время в минутах, помножить его на 60 и скорректировать время в формате posix
Проблема решена по совету Николая Камынина. После того как включил параметр "Время начала вечерней сессии" в таблице "Текущие торги" строка local EVNSTARTTIME = getParamEx('SPBFUT',value.sec, 'EVNSTARTTIME').param_value -- STRING Начало вечерней сессии начала возвращать нужное значение в строковом формате