Pine‑Script умеет работать с «матрицами» и предоставляет готовые функции
matrix.new, matrix.set, matrix.sort, matrix.get.
В Lua таких стандартных средств нет – обычно все делается через обычные таблицы (table) и функцию сортировки table.sort.
Ниже приведён эквивалент кода, который делает то же самое, но написан в стиле Lua
Код
--[[
rman(src, len)
src – таблица чисел (или «series»), длина которой должна быть >= len.
len – количество элементов, которые будем обрабатывать.
Возвращает: сумма квадратов разницы между позицией элемента после сортировки
по убыванию его значения и исходной позицией в массиве.
--]]
function rman(src, len)
-- 1) Собираем «матрицу» как таблицу вложенных таблиц:
-- {value = <значение>, idx = <исходный индекс>}
local m = {}
for k = 1, len do
local val = src[k] or 0 -- заменяем nil/NaN на 0 (nz в Pine)
local idx = k - 1 -- Pine использует индексы от 0,
-- поэтому смещаем на 1
m[#m + 1] = {value = val, idx = idx}
end
-- 2) Сортируем по убыванию значения (первый столбец)
table.sort(m, function(a, b)
return a.value > b.value -- descending order
end)
-- 3) Вычисляем сумму квадратов разницы позиций
local sum = 0.0
for i = 1, len do
local diff = m[i].idx - (i - 1) -- опять смещение индексов на 0
sum = sum + diff * diff -- math.pow(diff,2) можно заменить умножением
end
return sum
end
-- пример входных данных
local src = {5.2, nil, 3.7, 4.1, 0.9}
local len = #src -- считаем все элементы
print(rman(src, len)) -- выведет сумму квадратов разниц
Баг в работе скрипта Lua, В работе скрипта встречается баг, из-за которого у меня ломается весь скрипт:(
Пользователь
Сообщений: Регистрация: 30.05.2016
26.08.2025 23:34:15
В вашем скрипте вы открываете файл один раз при инициализации:
Код
secondfile = io.open('fifobuys.csv', 'r+');
После этого в функции OnParam вы пытаетесь пройтись по всем строкам файла
Код
for line in secondfile:lines() do … end
Но после первого прохода файловый дескриптор находится в конце файла.
Следующий вызов цикла начинает чтение с конца, поэтому в итоге не читается ни одна строка – условие if tonumber(line) == uprice никогда не выполняется и скрипт «не покупает».
Аналогично при удалении строки вы закрываете файл, потом открываете его заново. Это приводит к разного рода гонкам:
1‑й проход читает строку → переменная line уже содержит всё что было до конца;
второй проход пытается прочитать ещё одну строку, но файла нет → цикл завершается сразу.
Как исправить
1. Читайте файл каждый раз, а не держите его открытым
Код
local function read_all_lines(filename)
local lines = {}
for line in io.open(filename, "r"):lines() do
table.insert(lines, line)
end
return lines
end
2. Записывайте файл целиком после изменения
Код
local function write_all_lines(filename, tbl)
local f = io.open(filename, "w")
for _, l in ipairs(tbl) do
f:write(l .. "\n")
end
f:close()
end
3. Удаляйте строку из таблицы и перезаписывайте файл
Код
local function remove_line(filename, line_to_remove)
local lines = read_all_lines(filename)
table.remove(lines, line_to_remove) -- 1‑based index
write_all_lines(filename, lines)
end
4. Инициализация файлов
Код
local tradeFile = io.open("FifoTrades.csv", "a") -- открываем для дозаписи
-- Если файл не существует – создаём пустой
if not tradeFile then
tradeFile = io.open("FifoTrades.csv", "w")
end
tradeFile используется только для записи сделок; его можно держать открытым, но важно закрывать при завершении скрипта
Получения информации по купон, которые будут выплачены, купон, облигации
Пользователь
Сообщений: Регистрация: 30.05.2016
28.05.2025 23:50:54
Средствами квика нельзя, но можно через api московской биржи:
Тут же присутствуют амортизации и оферты.
Создание окна и кнопок в Quik.
Пользователь
Сообщений: Регистрация: 30.05.2016
10.03.2025 21:32:49
Существует не так много вариантов, советую начать с VCLua. Смотрите примеры вот тут:
Если я отправляю подряд 2 лимитные заявки, то я могу ожидать, что они исполнятся в том порядке, в котором отправил?
Пользователь
Сообщений: Регистрация: 30.05.2016
20.02.2025 21:47:48
Они исполняются в порядке очереди в стакане. Но это все не важно, ответы могут прийти в любой последовательности.
Имена параметров ТТП и других данных торгового сервера MOEX
Пользователь
Сообщений: Регистрация: 30.05.2016
19.02.2025 16:32:58
А эти названия параметров соответствуют передаваемых в getParamEx? По моему нет. Где, например SEC_SCALE, EV_SESS_ALLOWED?
Если я отправляю подряд 2 лимитные заявки, то я могу ожидать, что они исполнятся в том порядке, в котором отправил?
Пользователь
Сообщений: Регистрация: 30.05.2016
19.02.2025 15:47:25
Не гарантируется что отправленные транзакции будут обработаны в порядке отправки, а также не гарантируется что ответы о регистрации заявки придут последовательно.
написал: Еще бы кто рассказал как это выгрузить не имея Экселя (у меня Квик на Mac)
есть простой способ. настройки-программа-буфер обмена-формальные поля. далее капируем всё из таблицы и вставляем куда угодно. хоть в блокнот. там в полях столбцов будут нужные поля
Спасибо большое за эту информацию, так гораздо проще получать имена столбцов!Столько лет пользуюсь терминалом и впервые узнал об этой возможности.
Новый период и время проведения торгов на бирже.
Пользователь
Сообщений: Регистрация: 30.05.2016
15.02.2025 14:48:37
Можно использовать виртуальную машину и QUIK-Junior. Не так уж и часто требуется узнать имена параметров.
написал: Таблица текущих торгов MORN_SESS_ALLOWE и EV_SESS_ALLOWED это?
Кто-нибудь расскажите мне, убогому, где находится секретная документация включающая эти param_name. Раньше помню админ посылал на... QPile с этими вопросами. Но нет там этого.
Я их получаю выгрузкой таблицы в excel через DDE
Новый период и время проведения торгов на бирже.
Пользователь
Сообщений: Регистрация: 30.05.2016
05.02.2025 00:16:43
Таблица текущих торгов MORN_SESS_ALLOWE и EV_SESS_ALLOWED это?
В QUIK Junior в 11.4.1.3 перестала работать функция getDepoEx
Пользователь
Сообщений: Регистрация: 30.05.2016
04.02.2025 23:58:09
Цитата
Nikolay написал: Подход особо не изменился - найти максимальное числовое значение в таблице money_limit по полю limit_kind. Либо, если версия терминала выше 10.2.0, передавать не число, а строковое значение "Tx" - это такое тихое нововведние.
"Tx" это предлагает в соседней теме служба поддержки для их самописной функции, и хоть они в примере и передают этот параметр напрямую в getDepoEx, я бы так делать не стал, т.к. в справке limit_kind имеет тип number.
Цитата
Nikolay написал: В Junior транслируется в поле limit_kind дата в виде числа. Т.е. можно взять максимум.
Да, у себя так и сделал. Но еще нужно учесть что максимум необходимо вычислять каждый раз перед вызовом, т.к. если нет сделок, то максимумом будет являться сегодняшнее число, а после совершения сделки дата следующего торгового дня.
Еще один вопрос про потоки
Пользователь
Сообщений: Регистрация: 30.05.2016
04.02.2025 22:43:43
В скриптах используются всего 2 потока, один для колбэков и один в main.
В main для каждого скрипта создается отдельный поток, а вот колбэки находятся в некой очереди и вызываются синхронно, т.е. каждый колбэк ждет возвращения управления перед вызовом следующего.
Из-за этого имеем 2 особенности: 1. Нет нужды синхронизировать колбэки. 2. Надолго блокировать или производить тяжелые расчеты в колбэках не стоит, это приводит к подвисанию всех скриптов и даже терминала.
Если я ошибаюсь, поправьте.
Запустить скрипт Lua другим скриптом, Запустить скрипт Lua другим скриптом
Пользователь
Сообщений: Регистрация: 30.05.2016
02.02.2025 19:45:54
Ну вы конечно очень глубоко копнули, а человек спросил просто можно ли одним скриптом в окне "доступные скрипты" перевести второй скрипт из состояния "остановлен" в состояние "запущен".
Штатными средствами сделать этого нельзя. Понятно что имея возможность запускать любой код в подключаемых библиотеках можно сделать вообще все что угодно, однако это не будет хорошим решением.
В QUIK Junior в 11.4.1.3 перестала работать функция getDepoEx
Пользователь
Сообщений: Регистрация: 30.05.2016
02.02.2025 19:29:03
Цитата
Андрей написал: Последним параметром дату передавать что ли?
Ага, в виде 20250203. Но не просто дату, а дату следующего торгового дня (T+ T1), т.е. в пятницу нужно передавать дату на понедельник и не забыть учесть праздники если они есть.
SetUpdateCallback - как определить что начали приходить Не исторические данные., SetUpdateCallback - как определить что начали приходить Не исторические данные.
Пользователь
Сообщений: Регистрация: 30.05.2016
31.01.2025 19:35:55
Свечи могут вообще не приходить. Может быть так, что сделок вообще нет на минутках.
Запустить скрипт Lua другим скриптом, Запустить скрипт Lua другим скриптом
Пользователь
Сообщений: Регистрация: 30.05.2016
31.01.2025 19:19:16
Нет
limit_kind в таблице depo_limit
Пользователь
Сообщений: Регистрация: 30.05.2016
31.01.2025 15:55:22
Какое значение limit_kind принимает getPortfolioInfoEx?
limit_kind в таблице depo_limit
Пользователь
Сообщений: Регистрация: 30.05.2016
17.01.2025 17:22:49
Цитата
Anton Belonogov написал: Предлагаем воспользоваться следующими функциями - функции могут принимать на ввод в параметре limit_kind конкретную дату расчетов, либо значение "Tx".
А справку не нужно поправить? В ней limit_kind указан как NUMBER. Какой еще "Tx"? getBuySellInfoEx теперь тоже будет возвращать не пойми что? Тоже поправьте в справке.
А в целом кто так делает? По сути limit_kind это теперь новый параметр содержащий не вид лимита а дату, соответственно никакой обратной совместимости, это приведет к полной неработоспособности всех ранее написанных программ.
И снова CreateDataSource
Пользователь
Сообщений: Регистрация: 30.05.2016
04.12.2024 23:32:39
Цитата
Acaw написал: не повлечет ли это за собой то, что терминал будет обновлять кучу копий
Не повлечет. Вы в своих функциях работаете всего лишь со ссылкой на первоначальный ds.
Цитата
Acaw написал: И еще вопрос - после выполнения функции ее локальные переменные "разинициализируются" (обнуляются в памяти)?
Память отведенная под переменные на которые больше нет ссылок со временем будет очищена сборщиком мусора.
Цитата
Acaw написал: Также есть вопрос по параметру Interval в функции CreateDataSource. Его типа по документации Number, т.е. числовой, при этом он передается через константы, например INTERVAL_H1.А как его передать через переменную?
Ну просто переменной присвойте значение константы. Для INTERVAL_H1 это вроде 60.
Как в qlua разделить на группы облигации по типу купона
Пользователь
Сообщений: Регистрация: 30.05.2016
04.12.2024 20:01:07
Увы, другой информации биржа не транслирует (на сколько мне известно). Как вариант, через api биржи и http запрос, можно получить график выплаты купонов в формате json. Но это уже совсем другая история..
Как в qlua разделить на группы облигации по типу купона
Пользователь
Сообщений: Регистрация: 30.05.2016
03.12.2024 23:30:42
"COMPLEXPRODUCT" "Сложный продукт" содержит код «8» – облигации со структурным доходом;
По названию ОФЗ можно сразу понять, к какому классу бумаг относится конкретный выпуск. Существуют четыре основные категории гособлигаций, которые можно различать по номерам. Расскажем, как это делать Что означают эти 5 цифр
Первые 2 цифры в номере ОФЗ указывают на класс облигации:
• ОФЗ-ПД (постоянный доход) — номера начинаются на 25 и 26 • ОФЗ-ПК (переменный купон) — номера начинаются на 24 и 29 • ОФЗ-ИН (индексируемый номинал) — номера начинаются на 52 • ОФЗ-АД (амортизируемый доход) — номера начинаются на 46
событие Заявка активна в OnOrder() при попытке отмены заявки., При отправке транзакции на отмену заявки. приходят два события, в OnOrder() . 1 заявка активна. 2 заявка снята.
Пользователь
Сообщений: Регистрация: 30.05.2016
29.09.2024 23:31:02
Предположу, что есть какой-то флаг (возможно даже недоступный в lua), который изменяет свое состояние при попытке снять заявку и тем самым дергает коолл-бек.
Определение входящих остатков по инструментам на начало торговой сессии, Проблемы при определении входящих остатков по инструментам открытых позиций на начало торговой сессии
Пользователь
Сообщений: Регистрация: 30.05.2016
20.08.2024 15:54:48
swerg очень верно описал ситуацию с классами. В depo_limits мы имеем остаток, который может торговаться на бирже в разных режимах торгов с разными классами (самый простой пример: полные и неполные лоты).
сообщение в Telegram - это просто
Пользователь
Сообщений: Регистрация: 30.05.2016
14.08.2024 15:54:12
Можно делать запросы через библиотеку socket
require "socket"
http = require 'socket.http' local url = 'бла-бла/' http.request(url)
сообщение в Telegram - это просто
Пользователь
Сообщений: Регистрация: 30.05.2016
01.08.2024 12:59:16
Интересная тема!
В ботах также возможно добавить кнопки (в том числе динамические) и управлять скриптом прямо из приложения. Однако, встает вопрос на сколько это все безопасно, как никак речь идет про деньги.
И еще интересно, какие уведомления вы используете в своих скриптах, например, сделки и так отображаются в приложении брокера и более информативны чем просто текст.
Запись открытого интереса в файл.
Пользователь
Сообщений: Регистрация: 30.05.2016
29.02.2024 13:50:47
Открытый интерес можно добавить на график и читать как обычный индикатор.
Таблица текущих торгов в Quik., TTT
Пользователь
Сообщений: Регистрация: 30.05.2016
08.11.2023 20:09:23
Цитата
Vladimir spb написал: Я так понимаю, что стаканы, через подписки на них, мне не светят. Буду курить прямой запрос котировок по таймеру.
Без подписки не будет и данных в getQuoteLevel2().
Цитата
Когда стаканы приходят, повторить DOM Surface (история стаканов) на Питоне не сложно. Правда я нигде не нашел, что они называют Imbalance ?
Такие графики строятся по таблице обезличенных сделок.
Таблица текущих торгов в Quik., TTT
Пользователь
Сообщений: Регистрация: 30.05.2016
06.11.2023 22:44:16
В ручную удаляйте, изменяйте. В QLua вообще ничего нет для изменения параметров рабочего места.
Не могу заставить работать функцию Subscribe_Level_II_Quotes()
Пользователь
Сообщений: Регистрация: 30.05.2016
06.11.2023 15:26:19
Subscribe_Level_II_Quotes работает нормально, ищите проблему у себя. onQuote передает только изменения стакана, возможно вы торгуете неликвид, где стаканы обновляются раз в час.
Дополнительные флаги для таблицы «Стоп-заявки», Дополнительные флаги для таблицы «Стоп-заявки»
Пользователь
Сообщений: Регистрация: 30.05.2016
06.11.2023 15:21:40
Установите защитный спрэд в 5%, в 99% случаев заявка исполнится, если конечно ее объем не на миллионы.
Таблица текущих торгов в Quik., TTT
Пользователь
Сообщений: Регистрация: 30.05.2016
06.11.2023 15:15:04
Конечно нет
Доступ к таблице "Состояние счета"
Пользователь
Сообщений: Регистрация: 30.05.2016
03.11.2023 11:34:31
Если коротко то нет. Но можно получить доступ к данным по которым строится таблица "Состояние счета".
Функции для получения значений Таблицы текущих торгов, getParamEx, Как обновлять данные через функцию. getParamEx
Пользователь
Сообщений: Регистрация: 30.05.2016
01.11.2023 22:53:58
все правильно вам ответил.
Перенести запрос цены в main необходимо.
Все что расположено вне блоков выполняется первым и только один раз после запуска. getParamEx("QJSIM", "SPBE", "LAST").param_value может вернуть nil, если нет заказа данных с сервера этого параметра.
Для заказа данные должна быть открыта таблица ТТТ с данным инструментом и параметром или осуществлен заказ данных самим скриптом через:
Запрос не мгновенный, и серверу необходимо время что бы начать отправлять запрошенное значение, поэтому вызов getParamEx сразу после ParamRequest вернет все тот же nil. Хорошей практикой будет производить подписку в колбэке OnInit().
Помощь.
Пользователь
Сообщений: Регистрация: 30.05.2016
01.11.2023 22:21:57
Так сам квик сообщает что переменная num имеет значение nil.
очевидно что price == nil
Скрипт, запускающий и останавливающий экспорт по dde
Пользователь
Сообщений: Регистрация: 30.05.2016
21.10.2023 11:37:15
Горячих клавиш для вывода отдельных таблиц нет, поэтому надежное и простое решение не получится найти. Конечно есть разные программы для автоматизации и написания макросов (например, autoit) но все эти решения я не считаю надежными.
Скрипт, запускающий и останавливающий экспорт по dde
Пользователь
Сообщений: Регистрация: 30.05.2016
20.10.2023 11:23:18
Только внешними библиотеками, например w32
Расчет денег в лоты и обратно., Lot2Money и Money2Lot
Пользователь
Сообщений: Регистрация: 30.05.2016
17.10.2023 11:39:04
Скорее всего связано с этим:
Расчет денег в лоты и обратно., Lot2Money и Money2Lot
Пользователь
Сообщений: Регистрация: 30.05.2016
16.10.2023 15:33:32
1. getParamEx никогда не возвращает nil, но вот 0 там может быть запросто 2. Скорее всего у вас цена запрашивается тоже через getParamEx и тоже может быть 0, кроме того до первой сделки по инструменту, после открытия торговой сессии она гарантировано 0. 3. Money/(Price * LOTSIZE) Вызовет ошибку при 0 значениях в делителе.
getQuoteLevel2 Получение доходности облигаций
Пользователь
Сообщений: Регистрация: 30.05.2016
13.10.2023 12:36:47
Пожалуйста добавьте возможность получения доходности облигаций в функцию getQuoteLevel2, в стаканах в самой программе она есть, но по видимому ее забыли добавить в getQuoteLevel2.
Дублируются пользовательские сообщения из скрипта lua
Пользователь
Сообщений: Регистрация: 30.05.2016
27.09.2023 10:50:54
Порядок прихода сделок по возрастанию номера не гарантирован.
SearchItems не успевает обновить данные по заявкам при вызове в OnTrade
Пользователь
Сообщений: Регистрация: 30.05.2016
20.09.2023 10:57:21
OnTrade как правило приходит раньше OnOrder.
Сама по себе сделка содержит номер транзакции, номер заявки и цену исполнения.
После получения всех сделок, информация о состоянии заявки, нам больше не нужна.
Все еще интереснее, если снять эту заявку, то в таблице не обновляется значение, а по другой бумаге значение устанавливается в "-1" Вот скриншот, активных заявок нет. Была снята стоп-заявка POLY, в результате имеем AGRO "-1"
После выставления стоп-заявки (тейк-профит) признак ее наличия (колонка стоп-заявки) в таблице "состояние счета" отображается для совсем другой бумаги, для бумаги для которой в реальности выставлен стоп - не отображается. После перезаказа данных локальных справочников и перезапуска терминала отображение корректное.
Сейчас переменной присваивается значение 0 на каждой итерации цикла while. Очевидно, что инициализацию переменной нужно вынести за его пределы.
Дублируются пользовательские сообщения из скрипта lua
Пользователь
Сообщений: Регистрация: 30.05.2016
09.06.2023 17:32:58
Функции обратного вызова вызываются по нескольку раз и это обычное поведение. Вызываются они не только после изменения свойств входящего параметра доступных внутри луа, но и свойств которые остаются "за кадром".
Последовательность обработки функций обратного вызова
Пользователь
Сообщений: Регистрация: 30.05.2016
02.06.2023 17:06:15
Не нужно вставлять задержки в main, организуйте очередь задач и обрабатывайте их последовательно, возвращаясь к незавершенным (требующим ожидания) задачам уже после.
Последовательность обработки функций обратного вызова
Пользователь
Сообщений: Регистрация: 30.05.2016
02.06.2023 15:58:05
Согласен, коллбеки нужно обслуживать максимально быстро, т.к. во время обслуживания копится очередь из других коллбеков.
В идеале нужно записывать данные в таблицу с индексом и сразу возвращать управление, всю обработку производить уже в main.