Уточните, как именно Вы аварийно завершаете работу терминала? Так же просьба подробно описать последовательность Ваших действий. Для анализа проблемы просьба прислать скрипт с уточнениями нам на со ссылкой на данную ветку форума.
Ок. Раз Вы сами не можете проверить происходит ли переиндексация меток при каждом запуске терминала, вот два скрипта.
Первый добавляет метки:
Код
local path = _G.getScriptPath()
local sleep = _G.sleep
local log_file
local AddLabel = _G.AddLabel
local function init_log()
log_file = io.open(path.."\\add_labels_test.txt", "w")
end
local function close_log()
if io.type(log_file) == 'file' then
log_file:close()
end
log_file = nil
end
local function log_tostring(...)
local n = select('#', ...)
if n == 1 then
return tostring(select(1, ...))
end
local t = {}
for i = 1, n do
t[#t + 1] = tostring((select(i, ...)))
end
return table.concat(t, " ")
end
local function log(...)
if not log_file then return end
log_file:write(tostring(os.date("%c", os.time())).." "..log_tostring(...).."\n");
log_file:flush();
end
function _G.OnStop()
close_log()
end
function _G.main()
init_log()
log('start')
local tag = 'virt_test'
local date = tonumber(os.date('%Y%m%d', os.time())) or 0
local time = tonumber(os.date('%H%M%S', os.time() - 120)) or 0
local label_params = {}
label_params.YVALUE = 172.0
label_params.TEXT = ''
label_params.HINT = ''
label_params.DATE = date
label_params.TIME = time
label_params.FONT_FACE_NAME = 'Arial'
label_params.ALIGNMENT = 'RIGHT'
label_params.FONT_HEIGHT = 3
label_params.TRANSPARENT_BACKGROUND = 1
for i = 1, 100 do
label_params.TEXT = tostring(i)..': |||||||||||||||||||||||||||'
label_params.YVALUE = label_params.YVALUE + 0.1
local l_id = AddLabel(tag, label_params)
log('add label', i, 'id', l_id)
sleep(10)
end
end
Второй читает:
Код
local path = _G.getScriptPath()
local log_file
local GetLabelParams = _G.GetLabelParams
local function init_log()
log_file = io.open(path.."\\check_labels_test.txt", "w")
end
local function close_log()
if io.type(log_file) == 'file' then
log_file:close()
end
log_file = nil
end
local function log_tostring(...)
local n = select('#', ...)
if n == 1 then
return tostring(select(1, ...))
end
local t = {}
for i = 1, n do
t[#t + 1] = tostring((select(i, ...)))
end
return table.concat(t, " ")
end
local function log(...)
if not log_file then return end
log_file:write(tostring(os.date("%c", os.time())).." "..log_tostring(...).."\n");
log_file:flush();
end
function _G.OnStop()
close_log()
end
function _G.main()
init_log()
log('start')
local tag = 'virt_test'
for l_id = 1, 1000 do
local l_params = GetLabelParams(tag, l_id)
if l_params then
log('find label', 'id', l_id, 'text', l_params.text)
end
end
end
Запускаем терминал. Запускаем скурипт, добавляющий метки. Удаляем несколько меток, чтобы образовались дырки в последовательности id меток. Можно еще проще сделать - добавить метка, удалить все метки и заново добавить. В результате id меток будет начинаться не с 1.
Tue Mar 7 13:30:26 2023 start Tue Mar 7 13:30:26 2023 add label 1 id 101.0 Tue Mar 7 13:30:26 2023 add label 2 id 102.0 Tue Mar 7 13:30:26 2023 add label 3 id 103.0 Tue Mar 7 13:30:26 2023 add label 4 id 104.0 Tue Mar 7 13:30:26 2023 add label 5 id 105.0 Tue Mar 7 13:30:26 2023 add label 6 id 106.0 Tue Mar 7 13:30:26 2023 add label 7 id 107.0 Tue Mar 7 13:30:26 2023 add label 8 id 108.0 Tue Mar 7 13:30:26 2023 add label 9 id 109.0
Теперь закрываем терминал, даже не аварийно. Запускаем терминал заново. Запускаем второй скрипт и видим что метки получили индексы с 1, тем самым те индексы, что были получена при добавлении утеряны. Вывод: при каждом запуске терминала происходит переиндексация меток.
Tue Mar 7 13:30:02 2023 start Tue Mar 7 13:30:02 2023 find label id 1 text 1: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 2 text 2: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 3 text 3: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 4 text 4: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 5 text 5: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 6 text 6: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 7 text 7: ||||||||||||||||||||||||||| Tue Mar 7 13:30:02 2023 find label id 8 text 8: |||||||||||||||||||||||||||
Фильтрация транзакций "своего" робота
Пользователь
Сообщений: Регистрация: 27.01.2017
21.02.2023 13:03:56
Цитата
Максим написал: Тот же вопрос всплыл с новым аспектом. Заявки, поданные через терминал руками, теперь имеют связанные транзакции, у которых есть ID. И теперь совсем не ясно как роботу отличить свои транзакции от ручных. Идеи?
Для этого лучше использовать brokerref = комментарий транзакции
Волшебное исчезание меток
Пользователь
Сообщений: Регистрация: 27.01.2017
18.02.2023 11:23:02
Ну и сразу предложение:
Обязательно нужен метод ПолучитьВсеМетки - возвращает массив с индексами всех меток на указанном графике.
И желательно иметь метод ПриСдвигеМетки. Его, конечно, лучше сделать как регистрируемый колбек на метку, типа RegisterOnMoveLabel(id, chrt_id, func). Вызываемый по событию "MOUSE_RELEASED". Т.е. указателем взяли - отпустили. Сейчас же приходится постоянно опрашивать метку на предмет новых данных - не самое лучшее занятие.
Волшебное исчезание меток
Пользователь
Сообщений: Регистрация: 27.01.2017
17.02.2023 19:14:19
Все намного веселее, как оказалось.
Установил метки, запомнил их ID. Аварийно завершаю терминал. Перезапускаю терминал. Скрипт считывает метки и проверяет их.
Часть меток меняет свой id. Например, было 155 стало 162. Возможно часть меток исчезла, а может и сами как-то переиндексировались. В результате считывая метку, получаем чужие данные.
Но это очень плохо. Если нет гарантий, что id метки неизменен, то надо каждый раз искать, проверять, что метка та же, что и была.
ошибка в использовании io, вопрос по синтаксису
Пользователь
Сообщений: Регистрация: 27.01.2017
15.02.2023 18:39:53
Файл может быть не доступен для записи (права доступа, заблокирован другим процессом). Также может быть включен Контролируемый доступ к папкам Windows.
Максимальный лот для фьючерса., Подскажите формулу расчета максимального лота для фьючерсов.
Пользователь
Сообщений: Регистрация: 27.01.2017
24.01.2023 18:59:56
Цитата
awkozlov написал: Я не стремлюсь к хирургической точности цифры, мне хотя бы порядок сделки определить. Поэтому я сделал костыль: 1.покупаю для начала один лот, 2.записываю в файл, сколько он отъел свободной маржи после открытия позиции, 3.при следующем открытии свободные средства делю на это записанное в файл, и получаю максимальный лот. Теперь можно хоть как-то ориентироваться в размерности ценовых координат. Файлик обновляю при следующих сделках (на всякий случай). Но я крайне удивлен отсутствием базовой информации о торговле в торговом терминале. Может где-то есть стоимость лота в валюте депозита? Где это лежит?
Если речь про ГО, которое необходимое заплатить при открытии позиции по указанной цене, то это необходимо рассчитывать. Вот ветка с обсуждением
А если надо просто узнать сколько максимально можно открыть по этой цене, то можно воспользоваться методом CalcBuySell
вопрос к разработчикам QLUA
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2022 17:46:30
Цитата
nikolz написал: На самом деле это вам лишь видимость. Такая игра кошки с мышкой. Вы сами не торгуете.
Это все известно. На то он и брокер, в полном понимании этого слова. Но т.к., как Вы выразились, видимая часть разделена по субсчетам, то и указывать субсчет необходимо. Уж такая структура хранения у брокера. Не плохая, не хорошая - такая.
вопрос к разработчикам QLUA
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2022 15:05:59
Цитата
nikolz написал: ------------------------ Возможно изначально он был обязателен, но сейчас он подобен аппендиксу у человека. --------------------------- Типа есть, но нафиг нужен.
Нужен. Я меня счет один, а два кода клиента. И необходимо указывать тот, с которого идет торговля. Это субсчет - на одном ИИС, другой простой. На одном есть деньги, на другом нет.
вопрос к разработчикам QLUA
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2022 13:24:20
Да, счета и субсчета (т.е. коды) у брокера. Однозначно связать счет и код клиента нельзя, т.к. в таблице кодов больше ничего нет. Но.
Смотрим на таблицу money_limits (Лимиты по денежным средствам), для нее код имеет смысл. В ней есть фирма, есть счет, есть код клиента. Так и выходит, что можно только сказать - а можно ли с этим кодом, на этом счете, по этой фирме что-то сделать. Кодов же много может быть. На одном есть деньги, на другом нет. Хотя подать транзакцию можно, раз доступен код по фирме, счету. Ну и сколько брокеров не видел, фирма для срочного рынка отличается от фондового. По ней, как минимум, отсечь недоступные классы инструментов. И выбирая инструмент, по его классу даем список сочетаний доступных счетов, субсчетов.
вопрос к разработчикам QLUA
Пользователь
Сообщений: Регистрация: 27.01.2017
14.12.2022 11:07:03
Не разработчик, но, кажется, соответствие идет от фирмы, не счета. Счет от класса инструмента. Также от класса инструмента фирма. И по уже по фирме проверяем, что код клиента и счет для одной фирмы.
Ошибка при использовании loadstring в Lua 5.4.1
Пользователь
Сообщений: Регистрация: 27.01.2017
11.12.2022 10:16:45
в 5.4 для этого используется функция load
и такая дребедень Целый день
Пользователь
Сообщений: Регистрация: 27.01.2017
07.12.2022 13:40:34
Цитата
Попробуйте переподключиться, чтобы попасть на другой сервер
Если я правильно помню, Сбербанк убрал второй сервер. И он один. Соединения нет, а если есть, то данные асинхронны. Вопрос в другой ветке - почему сервер допускает такое, и есть ли контроль, без ответа.
Почему-то не происходит обновления табличных данных лучший спрос и лучшее предложение (брокер СБЕР) ??, Два дня на
Пользователь
Сообщений: Регистрация: 27.01.2017
07.12.2022 13:33:15
Ок. Правда с брокером Сбербанк - это бесполезная просьба. Техподдрежка не видит проблем, кроме очевидных - невозможно установить связь.
Правда я так и не понял какой ответ на вопрос: Есть ли контроль синхронности данных в серверной части. Если необходимы данные, то предположу, что нет. И каждый брокер сам решает свои проблемы. По идее, когда идет нарушение синхронности, то сервер должен просто блокировать передачу. Иначе такие данные могут навредить. Уж лучше ничего, чем такое.
Почему-то не происходит обновления табличных данных лучший спрос и лучшее предложение (брокер СБЕР) ??, Два дня на
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2022 15:15:27
Цитата
Anzhelika Belokur написал: , данные нам нужны с сервера брокера (конкретные файлы), чтобы понять на каком этапе данные в QUIK перестают обновляться.
И как Вы их получите? У нас же нет доступа к серверному окружения брокера.
Почему-то не происходит обновления табличных данных лучший спрос и лучшее предложение (брокер СБЕР) ??, Два дня на
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2022 13:36:10
Ок. Не очень ясно о каких данных идет речь. Но допустим.
Текущее время 13:18
Вот, что видим в терминале в этом время. График двигается, а данные в ТТТ нет. Вчера было наоборот - ТТТ менялся, график стоял на месте с подключения.
И сделайте что-нибудь с сохранением картинок на форуме. Вставить из буфера почти никогда невозможно, т.к. размер сообщения превышает лимит.
Почему-то не происходит обновления табличных данных лучший спрос и лучшее предложение (брокер СБЕР) ??, Два дня на
По данному вопросу Вам нужно обратиться к Вашему брокеру.
Это понятно, вопрос был другой: почему серверная часть допускает передачу несинхронизированных данных.
Почему-то не происходит обновления табличных данных лучший спрос и лучшее предложение (брокер СБЕР) ??, Два дня на
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2022 10:15:18
А прямо сейчас цена последней сделки в ТТТ, видимо, отстает от графика. Время сервера встало на 10 утра. Данные ТТТ видимо тоже. Для целей автоматизации брокер просто нерабочий. Да и для торговли тоже т.к. вчера графики просто стояли.
Почему-то не происходит обновления табличных данных лучший спрос и лучшее предложение (брокер СБЕР) ??, Два дня на
Пользователь
Сообщений: Регистрация: 27.01.2017
06.12.2022 09:49:28
Да, в данном случае может и брокер виноват, но на лицо отсутствие проверки синхронизации выдаваемых данных. Одно идет в реале, другое отстает. У меня вчера у Сбера не шли графики вовсе, ТТТ и стаканы обновлялись. Сбоит уже третий раз подряд у брокера. Два других брокера работаю корректно. Т.е. серверная часть позволяет это делать. Возникает вопрос - а почему сервер допускает это.
срочный рынок Московской биржи переходит на новую тарифную модель
Пользователь
Сообщений: Регистрация: 27.01.2017
02.12.2022 16:47:27
Как я понимаю такая форма окна ввода (и опция) доступна не на всех инструментах. Я вижу это только на валютной секции. Для срочной секции форма ввод заявки другая и такой опции нет. Для фондовой такой опции нет, хотя форма ввода похожа.
Обновление пользовательской таблицы/окна
Пользователь
Сообщений: Регистрация: 27.01.2017
29.11.2022 14:43:45
Я писал выше - вместе с обновлением текста ячейки вызываю Highlight - помогает.
Получить дату закрытия реестра по дивидендам
Пользователь
Сообщений: Регистрация: 27.01.2017
29.11.2022 12:30:52
Ничего хорошего в этом варианте нет. Во-первых, чтобы это сделать необходимо иметь программу DDE-сервер. По умолчанию это Excel. Но забывают что он платный (я вот не готов платить за него и у меня банально его нет) и в последнее время онлайн без локальной установки. Вот-вторых, это очень старая технология, которая в любой момент может уйти из новых версий операционной системы.
А было бы гораздо проще если бы в документации был список. При необходимости обновлять документацию. Впрочем, об этом говорится уже какой год.
SetUpdateCallback - не срабатывает после первого запуска скрипта
Ну еще счетчик циклов для повторной попытки загрузки
Не лучшее решение, оно блокирует исполнение кода. Запросы где время ответа неизвестно, лучше решать через очереди задач ожидания. Потоков в lua нет, но, как минимум, не блокировать весь код. Если, например, скрипт обрабатывает много инструментов и потоков данных, то ждать после каждого заказа - много времени пройдет пока до последнего дойдет. Или надо что-то другое постоянно контролировать, пока по другому инструменту заказ сделали. То что долго идет ответ - это не повод для уже работающих инструментов ждать.
как в луа брать данные из excel?
Пользователь
Сообщений: Регистрация: 27.01.2017
20.11.2022 10:25:36
Вычисления лучше в скрипте и произвести. И быстрее будет. Ексель нужен только когда это надо визуализировать, больше ни для чего он не нужен. Я не очень понимаю это странное "учеба на YouTube". В книге от автора языка все написано очень просто и понятно. Да и примеров очень много как прочитать файл, если просто поискать. А вот чтение xls - это уже использование сторонней библиотеки luaCOM. С учетом древности технологии COM, не думаю что будет много информации.
как в луа брать данные из excel?
Пользователь
Сообщений: Регистрация: 27.01.2017
20.11.2022 10:04:52
Библиотека luaCom поможет открыть COM объект и прочитать файл. Но я не очень понимаю зачем использовать тяжелый формат xls, а не перейти на простой текст с расширением csv, который читается очень просто, да и Excel открывает его как простую таблицу.
Как заполняется размер таблицы исторических свечей ?
Пользователь
Сообщений: Регистрация: 27.01.2017
19.11.2022 15:48:00
Я использую метод "догнать время последней сделки". Заказываем все сделки, далее ожидаем когда время из таблицы обезличенных сделок (или если угодно тика) равно времени последней сделки из ТТТ. Ждать надо, т.к. от заказа до прихода "последней" не одна минута может пройти. Также при восстановлении связи после обрыва тоже надо подождать. Ожидание точно не стоит делать блокирующим.
CreateDataSource("TQBR", "VTBR", 1), Получаю ошибку: TQBR - unknown class code.
Пользователь
Сообщений: Регистрация: 27.01.2017
19.11.2022 14:41:01
1 и работает. В примере же, совсем не ясно а какой момент производился запрос, какой сервер. Может это демо и там класс QJSIM.
CreateDataSource("TQBR", "VTBR", 1), Получаю ошибку: TQBR - unknown class code.
Пользователь
Сообщений: Регистрация: 27.01.2017
19.11.2022 13:21:11
Если выведете данные по переменной _G.INTERVAL_M1, то будет видно, что тип число, значение 1. В qlua много таких глобальных переменных ввели.
Можно даже просто вывести все, что есть в _G через pairs. Будут видны даже недокументированные.
Ошибка при выставлении заявки на валюту
Пользователь
Сообщений: Регистрация: 27.01.2017
18.11.2022 12:28:05
Ошибки отправки транзакции нет, поэтому и res пустой. Вам необходимо прочитать ответ колбека OnTransReply. И по номеру транзакции получить текстовое представление ошибки.
QUIK 10, Ошибки, зависания и пр.
Пользователь
Сообщений: Регистрация: 27.01.2017
11.11.2022 15:43:59
Цитата
nikolz написал: Все просто, если ошибки на уровне локального кода функций, то это модификация, а если ошибки на уровне метода, то это новая версия. Очевидно, что 9-я с ошибками на уровне метода. И ее на уровне кода функций уже не исправить.
Обычно, все же не так. Патчи - это третья цифра версии, методы - вторая, а первая цифра - это новые методы, модификации на грани совместимости с прошлыми релизами. Впрочем - все это субъективно. Хотя и вызывает некое недоумение столь частые мажорные релизы.
QUIK 10, Ошибки, зависания и пр.
Пользователь
Сообщений: Регистрация: 27.01.2017
11.11.2022 14:39:43
Больше вопросов взывает используемый SemVer.
Переход 7-8 логичен, внедрение x64 и lua 5.3.
А вот дальше уже как-то не очень. Что такого в 9-ой версии, что вызвало появление мажорного релиза. lua 5.4 просто дополнение, хотя, возможно, еще серверная часть сильно изменилась.
10-ая версия - еще менее логичная, как мажорная.
Конечно, "под капотом" может и много изменяется и никто никому не обязан объяснять. Но проблема в том, что брокеры не очень-то охотно переходят на новые мажорные релизы. Для примера, брокер Сбербанк (какой бы ни был этот брокер), очень долго был на 8-ом релизе. А потом перешел на проблемный 9.4, и уже не уверен, что перейдет на более стабильный 9.7, раз уже есть 10.
getParamEx
Пользователь
Сообщений: Регистрация: 27.01.2017
10.11.2022 09:53:54
Динамичность типов языка - это особенность, а не обязательство. Никто не заставляет это использовать. И даже вполне естественно в сложных скриптах не использовать вовсе, если даже не контролировать и запрещать.
Как из скрипта lua узначть что терминал QUIK загрузился полностью и подгрузил данные эккаунта ?, Как из скрипта lua узначть что терминал QUIK загрузился полностью и подгрузил данные эккаунта ?
Пользователь
Сообщений: Регистрация: 27.01.2017
10.11.2022 09:50:42
Всегда надо помнить, что Вы работаете с терминалом, получающим данные с сервера. Т.е. после установки соединения начинается передача данных. Вполне естественно, что сразу после установки соединения (Handshaking) данные еще не начали передаваться.
К сожалению терминал не предоставляет методов контроля окончания передачи данных, о чем на этом форуме много раз вели дискуссию. Но можете воспользоваться одним способом: у каждого переданного пакета данных с сервера есть "его время". Поэтому процесс ожидания можно построить на том, чтобы время последнего переданного пакета "догнало" время сервера.
Волшебное исчезание меток
Пользователь
Сообщений: Регистрация: 27.01.2017
05.11.2022 12:13:09
А метки да, исчезают. Как я понимаю из-за ошибки создания дампа состояния при падении. Приходится хранить параметры метки в файле состояния скрипта. Впрочем, я предпочитаю все хранить независимо, чтобы всегда иметь возможность при перезапуске проверить и выявить все различия.
Волшебное исчезание меток
Пользователь
Сообщений: Регистрация: 27.01.2017
05.11.2022 12:09:09
string.gsub возвращает два параметра, поэтому tonumber воспримет второй как базу, что и приводит к nil. Скобки добавить надо, чтобы ограничить одним параметром возвращаемое значение gsub.
getParamEx
Пользователь
Сообщений: Регистрация: 27.01.2017
04.11.2022 17:52:32
Цитата
Владимир написал: Я не нашёл тип данных integer ВООБЩЕ! И как же мне работать с битовыми масками? Как на Lua реализуется конструкция вида:if (iData & 0x80) { blah-blah-blah }?
Прямо из коробки. lua 5.3
3.4.2 – Bitwise Operators
Lua supports the following bitwise operators:
&: bitwise AND
|: bitwise OR
~: bitwise exclusive OR
>>: right shift
<<: left shift
~: unary bitwise NOT
All bitwise operations convert its operands to integers (see ), operate on all bits of those integers, and result in an integer.
Both right and left shifts fill the vacant bits with zeros. Negative displacements shift to the other direction; displacements with absolute values equal to or higher than the number of bits in an integer result in zero (as all bits are shifted out).
getParamEx
Пользователь
Сообщений: Регистрация: 27.01.2017
04.11.2022 16:32:16
Возможно стоит добавить, что с версии 5.3, есть и целочисленное деление //
Получение стакана без открытия стакана, Получение стакана без открытия стакана
Пользователь
Сообщений: Регистрация: 27.01.2017
03.11.2022 19:23:21
Зачем? После заказа данных и начала их поступления, Вы в любой момент времени можете получить данные через getQuoteLevel2. Это будут данные в момент запроса. Это же условно "непрерывный" поток данных. Т.о. Вы можете "смотреть" на данные хоть каждые 10 млс. Если хватит производительности по их обработке. При этом "слепок" данных может не отличаться от того, что смотрели 10 млс. назад. Поэтому и удобно и использовать колбек OnQuote для получения сигнала на повторное чтение. А если колбека нет, то данные те же, т.е. не требуется их заново читать.
Есть инструменты, где стакан изменяется раз в 10 минут. Какой смысл читать постоянно стакан. Пришел колбек OnQuote, установили некий флаг, что надо обновить данные, прочитали НОВЫЕ данные. Не пришел - данные те же самые.
Получение стакана без открытия стакана, Получение стакана без открытия стакана
Пользователь
Сообщений: Регистрация: 27.01.2017
03.11.2022 18:01:36
Нет. Да и смысла нет, т.к. истории по стакану нет.
getQuoteLevel2 - просто получить текущий стакан на момент запроса. А OnQuote - признак, что стакан изменился. Только признак. Здесь нет такого понятие готовы данные или нет. Пришел колбек OnQuote - значит есть изменения в данных.
Получение стакана без открытия стакана, Получение стакана без открытия стакана
Пользователь
Сообщений: Регистрация: 27.01.2017
03.11.2022 14:16:01
Код
local local_table_stock = getQuoteLevel2(class, sec)
ну так что это за переменные class, sec Где их инициализация?
Советую Вам использовать любой linter кода. Уйдут такого рода ошибки.
Получение стакана без открытия стакана, Получение стакана без открытия стакана
Пользователь
Сообщений: Регистрация: 27.01.2017
03.11.2022 14:10:59
Вы как-то странно воспринимаете документацию.
Терминал - это клиент. Данные на сервере. Поэтому: заказ-получение-обработка. Все как при любом клиент-серверном взаимодействии. Сервер же может и не ответить, например.
Поэтому и сделаны функции заказа потока данных для получения и обработки той или иной информации. Т.е. нужен стакан по инструменту:
Заказать поток на сервере - Subscribe_Level_II_Quotes Получить данные о текущем состоянии, если данные заказаны успешно - getQuoteLevel2 Колбек о изменении OnQuote можно использовать как триггер о необходимости повторного считывания данных. Обрабатавать данные в самом колбеке - не очень хорошая затея.
Есть смысл делать так ? Это экономит ресурсы ?
Пользователь
Сообщений: Регистрация: 27.01.2017
02.11.2022 10:40:29
Если надо обработать много (много) в цикле, то да. В обычной практике - это просто дело вкуса и привычки.
Код
local k = 10local s = 100
for i = 1, 10000000 do
k, s = math.max(k, s), math.min(k, s)
k, s = k*i, s*i
k, s = math.min(k, s), math.max(k, s)
end
[Done] exited with code=0 in 2.068 seconds
Код
local math_max = math.max
local math_min = math.min
local k = 10
local s = 100
for i = 1, 10000000 do
k, s = math_max(k, s), math_min(k, s)
k, s = k*i, s*i
k, s = math_min(k, s), math_max(k, s)
end
[Done] exited with code=0 in 1.597 seconds
Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?, Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?
Пользователь
Сообщений: Регистрация: 27.01.2017
29.10.2022 15:07:10
Цитата
-1. Если в описании SetUpdateCallback: "Позволяет задать пользователю функцию обратного вызова для обработки изменившихся СВЕЧЕК", то почему, Callback - вызывается не только при изменении индекса всечи, но и цены в пределах этой свечи ? Разве тогда- это не нарушение принципа работы SetUpdateCallback - завленного в описании ?
Потому что изменение сечи - это не только смена индекса, а еще изменение данных текущего бара, как то Close, High, Low, что как раз и происходит при совершении сделок.
Как уже говорилось решение зависит от задачи. Если задача - обработать все сделки без исключения, то это только таблица всех сделок. Если узнать как менялась цена на произвольном отрезке времени, то с некой долей погрешности можно использовать и другие способы, OnParam, например. Самому читать цену последней сделки, и да, колбек на ds. Либо, если это очень важно, опять таблицу всех сделок.
Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?, Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?
Пользователь
Сообщений: Регистрация: 27.01.2017
28.10.2022 18:19:36
Цитата
Quikos написал: 1)Ну так я тоже писал, что считаю подобный опрос в цикле - неправильным, некорректным, неэффективным. Опрашивая просто в цикле - во первых придется каждый раз заказывать ds:Size(). Во вторых - так вы 100% будете пропускать значения. 2)Насчет таблицы всех сделок - тоже писал, что не хочу запускать вручную в Квике что либо помимо скрипта.
Вопрос эффективности спорный. Если бы был колбек на событие "новый бар", то да. А т.к. его нет, то мы должны реагировать на каждый вызов колбека ds, только ради того чтобы узнать, что изменился Size. А если ТФ = 1 час, что, десятки тысяч вызовов обработать.
"Во вторых - так вы 100% будете пропускать значения." - что будет пропускаться? Новый индекс - однозначно нет. Промежуточные значения цен сделок - да, но т.к. колбек ds самый медленный, то используя его Вы однозначно будете пропускать цены сделок, если это конечная цель.OnParam быстрее, а таблица всех сделок хоть и медленно заказывается, но зато гарантирует все сделки.
Здесь же важна цель - обработать все сделки без исключения, то это только таблица всех сделок. Получит новый индекс - построить свой метод опроса, не прибегая к колбеку. В конечном итоге у Вас скрипт большую часть времени ничего не делает. Спросить какой сейчас Size - не сильно повлияет на работу. А вот заниматься обработкой колбека в основном потоке терминала - это уже вопрос целесообразности.
...Таблицы всех сделок заказывается прямо из скрипта - это ТФ = Tick
Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?, Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?
Пользователь
Сообщений: Регистрация: 27.01.2017
28.10.2022 15:01:12
Вам уже уже писали, что чтобы понять, что пришел новый бар, надо всего лишь сравнить запомненное при прошлом опросе значение ds:Size() с новым. При этом можно опрашивать не постоянно, а с периодичностью заказанного интервала. А чтобы узнать изменения цены можно использовать колбек OnParam, можете сами периодически читать через getParamEx, или таблицу всех сделок, если нельзя пропускать ни одной сделки. А можете и сами просто читать ds:Close() - это и будет текущая цена на момент запроса.
Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?, Номер свечи из SetUpdateCallback всегда будет равен размеру таблицы ?
Пользователь
Сообщений: Регистрация: 27.01.2017
28.10.2022 14:14:06
Как-то Вы "вцепились" в этот колбек. Он один из самых "бесполезных". Чтобы узнать изменения цены он не нужен. Чтобы понять, что пришел новый бар - тоже не нужен. Узнать значения на текущем баре - тоже. Узнать, что пришли данные с момента заказа - тоже. И это не учитывая, что он достаточно медленный и пропускает данные.
QUIK (версия 7.0.1.5), function OnTrade(trade), трехкратный вызов на одно событие.
Пользователь
Сообщений: Регистрация: 27.01.2017
24.10.2022 15:53:42
Цитата
Alexander написал: Вот ещё хочу тут спросить старожилов по такому поводу. Скрипт на Lua сначала делает продажу акций Лукойл по рынку в шорт 10 шт через sendTransaction() при этом естественно ставлю TYPE="M", PRICE="0". Транзакция проходит, заявка исполнилась нормально. Следующая транзакция на покупку фьючерса "LKZ2", т.е. LKOH-12.22 в количестве 1шт так же по рынку, где в sendTransaction() установлено так же TYPE="M", PRICE="0". Но при этом транзакция с ошибкой: Ошибка создания заявки. [GW][332] "Нехватка средств по лимитам клиента." Пытаюсь купить данный фьючерс вручную в квике, установив галочку в окне ввода заявки "Рыночная" - результат опять та же самая ошибка! В результате фьючерс купил таки вручную, указав цену на покупку из стакана равную лучшей цене продажи. Транзакция прошла без ошибок и заявка тут же исполнилась. Да мог бы поставить цену покупки и выше чем лучшая цена продажи на несколько пунктов, это я знаю, и заявка ушла бы так по лучшей рыночной цене. Но вопрос: почему sendTransaction() работает на покупку/продажу акций по рынку с значениями TYPE="M", PRICE="0", а на покупку/продажу фьючерса с значениями TYPE="M", PRICE="0" выдаёт ошибку: "Нехватка средств по лимитам клиента." и я вынужден ставить цену хуже рынка, чтобы заявка ушла по рынку? Заявка то в конечном итоге прошла, значит средств достаточно!
Рыночных заявок на срочном рынке нет, на самом деле. Брокер Они отправит их по верхней|нижней границе допустимого ценового диапазона. Так происходит, потому что размер ГО, блокируемого под сделку, зависит от цены сделки. И чем дальше цена от цены последнего клиринга, там ГО будет выше. Хотя реальная сделка и будет не так далеко, но расчет ГО у брокера будет по цене ордера. Так что на сделку в 200 пунктах от цены клиринга может и хватает, а вот уже на сделку в 2000 пунктах - нет. Но такое происходит, если торговать на границе доступных средств. Когда средств достаточно, то и "по рынку" пройдет сделка.
CreateDataSource SetUpdateCallbackcallback более чем для одного заказа, SetUpdateCallbackcallback более чем для одного заказа
Пользователь
Сообщений: Регистрация: 27.01.2017
20.10.2022 18:52:50
Ну, видимо, потому, что пытаетесь произвести конкатенацию числа и строки my_table_data_history_candle_:Size() .. "\n"
Обратно работает, а вот число..строка уже нет
> print(5..'a') stdin:1: malformed number near '5..' > print('a'..5) a5
Лучше не злоупотреблять динамичностью языка. Либо просто ошиблись с расстановкой скобки для tostring. Также не понятно что это за переменные my_int_1 и my_int_2. Не вижу инициализации. А раз они nil, то соединяете строку с nil.
CreateDataSource SetUpdateCallbackcallback более чем для одного заказа, SetUpdateCallbackcallback более чем для одного заказа
Пользователь
Сообщений: Регистрация: 27.01.2017
20.10.2022 18:03:25
Если Владимир сделал вывод, то, конечно, это приговор. Правда странно, почему же оно работает у остальных.
Вот, специально проверил, версия Квика 8.7.3
Код
local is_run = true
local function is_date(val)
local status = pcall(function() return type(val) == "table" and os.time(val); end)
return status
end
local function call_back_processor(action, context)
if not action then return end
return function(index)
action(index, context)
end
end
local function on_ds_action(index, context)
local time = is_date(context.ds:T(index)) and os.time(context.ds:T(index)) or nil
_G.message(string.format('new ds index %d %s %s|%s last close %.5f', index, time and os.date('%d.%m.%Y %H:%M:%S', time), context.sec_code, context.class_code, context.ds:C(index)))
end
local function create_ds(context, action)
if not context then return end
local ds, err = _G.CreateDataSource(context.class_code, context.sec_code, context.interval)
if not ds then
_G.message(err, 3)
return
end
if ds and action then
ds:SetUpdateCallback(call_back_processor(action, context))
end
context.ds = ds
return ds
end
function _G.main()
create_ds({sec_code = 'SBER', class_code = 'TQBR', interval = _G.INTERVAL_W1}, on_ds_action)
create_ds({sec_code = 'GAZP', class_code = 'TQBR', interval = _G.INTERVAL_MN1}, on_ds_action)
while is_run do
_G.sleep(100)
end
end
function _G.OnStop()
is_run = false
end
Описание базовых активов Si, SiZ2 ?
Пользователь
Сообщений: Регистрация: 27.01.2017
20.10.2022 15:32:42
Уже спрашивали
Отписка callback`а SetUpdateCallbackcallback - отписывает ВСЕ заказы, Отписка callback`а SetUpdateCallbackcallback - отписывает ВСЕ заказы