[BUG] Не рассчитывается максимальное возможное количество лотов в заявке
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
17.08.2020 09:10:26
Цитата
Anna Lozenko написал: сформировать архив рабочего места QUIK
Это не моя работа. Вся необходимая информация, когда и при каких обстоятельствах возникает ошибка, вам предоставлена более трёх месяцев назад:
Цитата
Старатель написал: После расширения планок в результате стоп-торгов в поле ввода заявки не рассчитывается максимальное возможное количество лотов по ценам выше/ниже каких-то (непонятных) границ (и эти границы не связаны с макс./мин. возможной ценой инструмента).
Цитата
Старатель написал: после расширения лимитов в следующий клиринг ситуация исправляется
Так, ситуация, скрины, которой представлены в сообщении , продолжалась до следующего клиринга 14:00 12.08.20
Есть ощущение, что вы не понимаете, что делаете. Что вы искали через два дня после события - большой вопрос. Подробно про клиринг, стоп-торги и расширение ценового коридора (планок) можно прочесть на сайте биржи.
В помощь могу написать скрипт:
Скрытый текст
Код
local run = true
function main()
while run do
for sec in getClassSecurities("SPBFUT"):gmatch("([^,]+)") do
local price = getParamEx("SPBFUT", sec, "PRICEMIN").param_value
if price and price ~= 0 then
local qty = CalcBuySell("SPBFUT", sec, "", Account, price, true)
if qty <= 0 then
message(sec .. ' B: ' .. qty, 2)
end
end
price = getParamEx("SPBFUT", sec, "PRICEMAX").param_value
if price and price ~= 0 then
local qty = CalcBuySell("SPBFUT", sec, "", Account, price, false)
if qty <= 0 then
message(sec .. ' S: ' .. qty, 2)
end
end
end
sleep(60000)
end
end
function OnStop()
run = nil
return 100
end
Запускаете и ждёте. Но ждать придётся долго, может несколько недель или месяцев, т.к. стоп-торги бывают не каждый день.
Надо делать так, как надо. А как не надо - делать не надо.
Потокобезопасные функции в Lua 5.3
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
15.08.2020 23:52:36
QUIK 8.8.1.5 Можно , чтобы наверняка.
Надо делать так, как надо. А как не надо - делать не надо.
Потокобезопасные функции в Lua 5.3
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
15.08.2020 22:53:42
Скрипт 1:
Скрытый текст
Код
local run = true
function main()
local id = AllocTable()
AddColumn(id, 1, 'Количество', true, QTABLE_INT_TYPE, 13)
CreateWindow(id)
InsertRow(id, -1)
while run do
local len = getNumberOf('all_trades')
SetCell(id, 1, 1, tostring(len), len)
sleep(100)
end
end
function OnStop()
run = nil
end
Скрипт 2:
Скрытый текст
Код
local run = true
local AllTrades = {}
function OnAllTrade(alltrade)
table.sinsert(AllTrades, alltrade)
--[[table.ssort({0, 0}, function()
AllTrades[#AllTrades+1] = alltrade
return true
end)]]
end
function main()
while run do
while #AllTrades > 0 do
table.sremove(AllTrades, 1)
end
sleep(1)
end
end
function OnStop()
run = nil
end
При запущенных обоих скриптах изредка в строке
Код
while #AllTrades > 0 do
возникает странная ошибка:
Цитата
attempt to compare number with function
Для воспроизведения можно Получить заново данные по обезличенным сделкам.
Надо делать так, как надо. А как не надо - делать не надо.
[BUG] Не рассчитывается максимальное возможное количество лотов в заявке
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
14.08.2020 21:03:57
Anna Lozenko, когда и во сколько пытались воспроизвести?
Надо делать так, как надо. А как не надо - делать не надо.
[BUG] Не рассчитывается максимальное возможное количество лотов в заявке
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
14.08.2020 18:23:26
Anna Lozenko, когда и во сколько пытались воспроизвести?
Надо делать так, как надо. А как не надо - делать не надо.
Получение данных из таблиц при автостарте
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
13.08.2020 10:51:36
Andrey Bezrukov, Никакого архива, конечно же, не будет. В этом нет смысла. Вероятность воспроизвести точно такую же ситуацию не высока, и ваш ответ ("проблема не воспроизводится") очевиден. Вы можете только подтвердить или опровергнуть гипотезу:
Цитата
Старатель написал: Первый список загружается вместе с QUIK. Второй загружается вместе с файлом настроек уже после того, как стартуют скрипты.
А заодно проверить в своём коде терминала, что в момент подмены списков таблица trade_accounts сначала очищается, а затем вставляются списки из info.wnd. И в этот момент как раз существует гипотетическая вероятность получения nil из вышеприведённого кода. Как-то так, других вариантов у меня нет.
И зарегистрировать пожелание на доработку: стартовать скрипты после полной загрузки настроек. Если, конечно пользы от этого будет больше, чем вреда.
Пример ещё нескольких функций, которые зависят от последовательности загрузки настроек: getNumCandles, getLinesCount, getCandlesByIndex
Надо делать так, как надо. А как не надо - делать не надо.
Таблица текущих торгов
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
13.08.2020 10:20:24
При редактировании таблицы текущих торгов параметры, добавленные в правую часть (Заголовки столбцов) убирать из списка "Доступные параметры".
Надо делать так, как надо. А как не надо - делать не надо.
Получение данных из таблиц при автостарте
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
12.08.2020 19:22:55
Выяснилось следующее: имеются два списка trade_accounts. Первый - в acnt.dat, второй - в info.wnd. Первый список загружается вместе с QUIK. Второй загружается вместе с файлом настроек уже после того, как стартуют скрипты. И, видимо, так сошлись звёзды, что в этот раз, скрипт обратился к таблице trade_accounts как раз в момент подмены списков, когда таблица была очищена.
Внимание вопрос: это баг или было сделано злонамерено? Почему бы не стартовать скрипты уже после полной загрузки настроек?
Надо делать так, как надо. А как не надо - делать не надо.
session status
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
12.08.2020 14:07:07
session_status QUIK заполняет или он едет вместе с позициями из торговой системы?
Надо делать так, как надо. А как не надо - делать не надо.
Получение данных из таблиц при автостарте
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
12.08.2020 13:41:05
Support?
Надо делать так, как надо. А как не надо - делать не надо.
[BUG] Не рассчитывается максимальное возможное количество лотов в заявке
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
12.08.2020 11:00:01
QUIK Junior 8.8.1.5
Скрытый текст
Надо делать так, как надо. А как не надо - делать не надо.
Quik 8.5.1.18 вылетает без видимых причин.
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
11.08.2020 16:47:03
Цитата
Юрий написал: периодически вылетает во время торговли без видимых ошибок и причин. То есть вот он работает и в следующий момент он уже не запущен вообще в системе.
QUIK 8.8.1.5 Вылеты продолжаются
Надо делать так, как надо. А как не надо - делать не надо.
Старатель написал: при первичном старте скрипт берёт данные из кэша.
Надо делать так, как надо. А как не надо - делать не надо.
Получение данных из таблиц при автостарте
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.08.2020 16:30:44
Добрый день.
Есть скрипт, который стартует автоматически при запуске QUIK. В самом начале идёт поиск заданного торгового счета:
Код
function main()
local Index = SearchItems("trade_accounts", 0, getNumberOf("trade_accounts")-1, function(trdaccid) return trdaccid == Account end, "trdaccid")
...
end
В настройках стоит "Очищать данные после смены даты: На сервере (при установлении связи)". Т.е., при первичном старте скрипт берёт данные из кэша. Запуск QUIK происходит долго, открыто несколько тиковых графиков и индикаторов. Но обычно скрипт работает нормально. Но сегодня SearchItems не нашла торговый счёт и вернула nil. Повторный запуск скрипта вручную (до подключения к серверу) отработал корректно.
По какой причине данный код мог дать сбой?
Надо делать так, как надо. А как не надо - делать не надо.
luasql (проблема с cursor:fetch)
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.08.2020 16:26:59
Это Антону спасибо!
Цитата
Anton написал: Не очень удачная конфигурация на мой взгляд
Почему?
Надо делать так, как надо. А как не надо - делать не надо.
luasql (проблема с cursor:fetch)
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
03.08.2020 17:52:43
Цитата
Nikolay написал: блокировки транзакций на уровне базы
C версии 3.7.0 появился режим журнала , в котором, как утверждается, читатели БД и писатели в БД уже не мешают друг другу.
Цитата
Anton написал: Сам sqlite3 интегрирован в эту же длл, отдельно его добавлять не нужно.
Если не сложно, можете сделать с отдельной sqlite3.dll, чтоб без проблем обновить можно было.
Надо делать так, как надо. А как не надо - делать не надо.
luasql (проблема с cursor:fetch)
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
03.08.2020 17:46:39
Цитата
Но к сожалению ссылка на архив с ответом больше не доступна. Не поможете, вспомните.. как мой вопрос решается??
К сожалению, не помню про что это.
Надо делать так, как надо. А как не надо - делать не надо.
Отладка QUIK 8.8
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
03.08.2020 17:33:13
Цитата
Sergey Gorokhov написал: Действительно в ПО QLUA есть ошибка так же иногда приводящая к завистанию терминала при вызове Lua функции DestroyTable. Мы исправим её в очередном обновлении ПО.
Как скоро? Временное решение есть?
Надо делать так, как надо. А как не надо - делать не надо.
Отладка QUIK 8.8
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
31.07.2020 16:04:19
Sergey Gorokhov, если у вас sleep(1) больше 1 мс, откройте больше окон, чтоб наверняка:
Код
for i = 1, 30 do
Надо делать так, как надо. А как не надо - делать не надо.
Отладка QUIK 8.8
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
31.07.2020 15:33:12
Sergey Gorokhov, я не знаю, как у вас не повторяется. Только если ничего не делать.
Надо делать так, как надо. А как не надо - делать не надо.
Массив (таблица) в OnCalculate
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
28.07.2020 18:37:27
В вашем примере результат как раз предсказуем. Главное присвоить элементу nil, а вот если ничего не присвоить
Код
A = {[2] = 1, [3] = 2}
тогда да, непредсказуем.
Надо делать так, как надо. А как не надо - делать не надо.
Массив (таблица) в OnCalculate
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
28.07.2020 16:53:48
Цитата
s_mike@rambler.ru написал: Не используйте unpack, если индикатор может иметь значение Ия nil в любой линии.
Почему?
Надо делать так, как надо. А как не надо - делать не надо.
Почему скрипты в QUIK выполняются дольше
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
28.07.2020 14:55:12
Цитата
Anton написал: Трудно придумать, как арка могла бы это изменить в текущей архитектуре с отдельным мейном.
Делать лок перед началом колбека и анлок по окончании, не?
Надо делать так, как надо. А как не надо - делать не надо.
написал: При вызове InsertRow / DeleteRow в какой момент происходит смещение индексов?
В смысле?
Что есть DeleteRow (InsertRow)? Это не только удаление (добавление) физической строки, но и смещение всех индексов строк во внутреннем представлении. Ожидается, что операция смещения строк - цельная. Т.е., если выполнить код в таком порядке:
При вызове InsertRow / DeleteRow в какой момент происходит смещение индексов?
Цитата
Evgeniy Karnaukhov написал: Проблема вызвана тем, что работа с таблицей в скрипте осуществляется из разных потоков без синхронизации.
Это чья зона ответственности, скриптера или приложения?
Надо делать так, как надо. А как не надо - делать не надо.
Появляется лишняя строка в таблице
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
27.07.2020 13:03:17
Откуда лишняя строка в ?
Надо делать так, как надо. А как не надо - делать не надо.
Появляется лишняя строка в таблице
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
27.07.2020 10:37:36
Цитата
Anton написал: работа с таблицей так или иначе приводит к SendMessage окну (в основной поток то есть)
Что-то никак не пойму, работа с QLua-таблицей - это синхронные или асинхронные сообщения? Саппорт, можете просветить?
Надо делать так, как надо. А как не надо - делать не надо.
Почему скрипты в QUIK выполняются дольше
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 23:55:10
Хотя есть от main и польза: перенос сложных расчётов в main при одновременной работе двух и более таких скриптов (при достаточном количестве процессоров и условии, что колбеки не будут мешать расчётам).
Надо делать так, как надо. А как не надо - делать не надо.
Почему скрипты в QUIK выполняются дольше
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 20:44:05
Добавим блокировку для "монопольного" вычисления в колбеке:
Код
local abs = math.abs
local function f()
local t = os.clock()
for i = 1, 100000000 do abs(-1234.56789) end
return os.clock() - t
end
function main()
message(string.format('Расчёт в одном потоке: %0.1f', f()))
run = true
while run do
if param then
message(string.format('Расчёт в двух потоках [main]: %0.1f', f()))
param = nil
else sleep(1) end
end
end
function OnParam(class_code, sec_code)
if not run then return end
param = true
local t
table.ssort({0, 0}, function()
t = f()
return true
end)
message(string.format('Расчёт в двух потоках [OnParam]: %0.1f', t))
run = nil
end
Результат:
Цитата
Расчёт в одном потоке: 7.4 Расчёт в двух потоках [OnParam]: 6.7 Расчёт в двух потоках [main]: 7.3
Т.ч. вреда от main больше, чем пользы. И, если уж угораздило переносить расчёты в main, то то, что осталось в колбеках, лучше делать под блокировкой, чтобы main ни в коем случае не делал вычислений одновременно с колбеками. Последовательная работа потоков положительно скажется на общей производительности.
Надо делать так, как надо. А как не надо - делать не надо.
Почему скрипты в QUIK выполняются дольше
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 19:50:49
Немного модифицируем первоначальный скрипт:
Код
local abs = math.abs
local function f()
local t = os.clock()
for i = 1, 100000000 do abs(-1234.56789) end
return os.clock() - t
end
function main()
message(string.format('Расчёт в одном потоке: %0.1f', f()))
run = true
while run do
if param then
message(string.format('Расчёт в двух потоках [main]: %0.1f', f()))
param = nil
else sleep(1) end
end
end
function OnParam(class_code, sec_code)
if not run then return end
param = true
message(string.format('Расчёт в двух потоках [OnParam]: %0.1f', f()))
run = nil
end
Результат:
Цитата
Расчёт в одном потоке: 7.5 Расчёт в двух потоках [OnParam]: 32.2 Расчёт в двух потоках [main]: 31.9
Выводы делайте сами.
Надо делать так, как надо. А как не надо - делать не надо.
Выделять объём на тиковом графике цветом в зависимости от направления сделки
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 13:49:37
Цитата
Игорь М написал: Если искать по идентификатору сделки порядковый номер в таблице
Сравнение в скорости линейного поиска с SearchItems:
Скрытый текст
Код
local function linSearch (t, id, num_1, num_2) -- функция линейного поиска
while num_1 <= num_2 do
local t_trade_num = getItem(t, num_1).trade_num -- номер сделки в таблице
if id == t_trade_num then -- сравнение идентификационных номеров
return num_1
else
num_1 = num_1 + 1
end
end
return nil
end
local os_clock = os.clock
local function test1(n, TradeNum)
local t = os_clock()
for i = 1, n do
NumTrade = linSearch("all_trades", TradeNum, 0, getNumberOf ("all_trades")-1)
end
t = os_clock() - t
message(tostring(NumTrade))
return t
end
local function test2(n, TradeNum)
local t = os_clock()
for i = 1, n do
local Index = SearchItems("all_trades", 0, getNumberOf("all_trades")-1, function(trade_num)
if trade_num == TradeNum then return nil else return false end
end, "trade_num")
NumTrade = Index and Index[1] or nil
end
t = os_clock() - t
message(tostring(NumTrade))
return t
end
function main()
local n = 100000
local TradeNum = getItem("all_trades", 0).trade_num -- Номер первой сделки
message(string.format("Искомый элемент в начале таблицы:\nlinSearch: %0.3f\nSearchItems: %0.3f", test1(n, TradeNum), test2(n, TradeNum)))
local numbers = getNumberOf("all_trades")
message(string.format("Numbers: %u", numbers))
TradeNum = getItem("all_trades", numbers-1).trade_num -- Номер последней сделки
message(string.format("Искомый элемент в конце таблицы:\nlinSearch: %0.3f\nSearchItems: %0.3f", test1(1, TradeNum), test2(1, TradeNum)))
end
Цитата
Искомый элемент в начале таблицы: linSearch: 0.660 SearchItems: 0.495
Цитата
Искомый элемент в конце таблицы: linSearch: 18.437 SearchItems: 4.919
Бинарный поиск можно использовать только по монотонно возрастающему (или убывающему) параметру.
Надо делать так, как надо. А как не надо - делать не надо.
Выделять объём на тиковом графике цветом в зависимости от направления сделки
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
26.07.2020 00:09:45
Игорь М, добрый день. Спасибо за информацию. Но есть сомнения относительно верности результатов. По моим исследованиям SearchItems быстрее линейного поиска даже если искомый элемент находится первым в таблице. Если же искомый элемент глубже, то SearchItems может быть быстрее в несколько раз. Линейный поиск имеет преимущество только при поиске в обратном направлении, если искомый элемент находится ближе к концу таблицы. Что касается бинарного поиска, то, как верно заметил Anton, в общем случае его использовать не получится.
Применительно к тиковым индикаторам тут вот какая проблема. Ниже индикатор, показывающий время построения индикатора.
Скрытый текст
Код
Settings = {
Name = "Time",
search = 0,
line = {
{ Name = 'Time' }
}
}
function Init()
return 1
end
local search
local Clock
function OnCalculate(index)
if index == 1 then
if Settings.search == 1 then
function search()
getItem("all_trades", getNumberOf("all_trades")-1)
end
elseif Settings.search == 2 then
function search()
local function fn(qty,flags)
return nil
end
SearchItems("all_trades", 0, getNumberOf("all_trades")-1, fn, "qty,flags")
end
else
function search() end
end
Clock = os.clock()
end
local Volume = V(index)
if CandleExist(index) then
search()
end
return (os.clock() - Clock) * 1000
end
С вызовом getItem или SearchItems на каждый тик время увеличивается в 4-5 раз. И это только вызов функций, без поиска сделки.
Надо делать так, как надо. А как не надо - делать не надо.
Отладка QUIK 8.8
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
24.07.2020 08:52:26
Проблема, описанная в теме , актуальна.
Надо делать так, как надо. А как не надо - делать не надо.
Не обновляется таблица при добавления цикла repeat...until
Проблема явно не цикле repeat, а в том, что когда цикл заканчивается, вы возвращаетесь к следующей итерации цикла while, где проверяете позицию
Код
local asset = getFuturesHolding("SPBFUT", "SPBFUT****","SRU0",0).totalnet
которая отличается от нужной вам, т.к., вы только отправили транзакции, надо ещё дождаться, когда сделки исполнятся, сервер соизволит обновить позицию и отправит её клиенту.
Надо делать так, как надо. А как не надо - делать не надо.
контроль исколнения многоконтрактовой заявки в quik 8.6
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
18.07.2020 23:55:05
Цитата
Коля Маржин написал: при сделке на один контракт OnTrade() может срабатывать дважды) - как это всё контролировать?
По trade_num фильтровать
Надо делать так, как надо. А как не надо - делать не надо.
контроль исколнения многоконтрактовой заявки в quik 8.6
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
18.07.2020 23:48:29
flags в OnOrder подскажет, когда заявка исполнена
Надо делать так, как надо. А как не надо - делать не надо.
Выделять объём на тиковом графике цветом в зависимости от направления сделки
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
17.07.2020 22:01:57
Цитата
Sergey Gorokhov написал: Ваше пожелание зарегистрировано. Мы постараемся рассмотреть его и сообщить Вам результаты анализа.
Удалось рассмотреть и проанализировать?
Или добавьте параметр flags к тиковым графикам, чтобы при построении пользовательских индикаторов не лазить в таблицу "all_trades" в поисках нужной сделки - очень сильно затормаживает расчёт: сам только вызов SearchItems увеличивает время расчёта в 10 и более раз.
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Но чтобы она также давала информацию получен ли параметр с момента последней подписки: nil - подписка не включена false - подписка включена, но параметр ещё не получен true - подписка включена, параметр получен Или: 0, 1, 2
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 23:54:58
Скрытый текст
Цитата
Старатель написал: PS: Обратил внимание, что после остановки скрипта, подписка на стакан не закрывается автоматически. Надо бы исправить.
Хотя Unsubscribe_Level_II_Quotes достаточно. Ладно, пока работает, стакан лучше не трогать
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 23:44:25
Цитата
Sergey Gorokhov написал: Вам по сути нужен способ узнать включена ли подписка.
Пример с getQuoteLevel2 показателен. Если вы про аналог функции IsSubscribed_Level_II_Quotes, то она бесполезна, т.к. показывает, что подписка включена в то время когда, данные ещё не получены. Но дуэт Subscribe_Level_II_Quotes и getQuoteLevel2 самодостаточен и позволяет получать только актуальные данные. PS: Обратил внимание, что после остановки скрипта, подписка на стакан не закрывается автоматически. Надо бы исправить.
Для ParamRequest и getParamEx2 хотелось бы такой же работы.
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 20:07:36
Sergey Gorokhov, сможете привести однозначный алгоритм получения параметра, который работает всегда и надёжно, и который даёт гарантированно актуальное значение, а не старые данные из кеша? И чтобы не нужно было ждать полдня, пока ожидаемый параметр поменяет своё значение.
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 19:38:35
Цитата
Sergey Gorokhov написал: Если параметр уже заказан, до запуска скрипта, то getParamEx2 и так получит "актуальные данные" без всяких ParamRequest и OnParam ждать нет нужды.
Вы поспорить или по делу? Как в скрипте узнать, что параметр уже заказан?
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 18:36:52
Цитата
Sergey Gorokhov написал: Для понимания что заказанный параметр начал ехать нужно ждать коллбэк OnParam()
С первого сообщения пытаюсь объяснить. Если параметр уже заказан (а проверить мы это никак не можем) до запуска скрипта (в ТТТ али другим скриптом), то если брать данные только в OnParam(), придётся ждать следующего обновления параметров. А для неликвидного инструмента это может быть очень не скоро. Глядишь к концу сессий чё-нить дождёмся... А если вызывать getParamEx2 до прихода OnParam(), то нет гарантии, что там не старьё.
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
От вас, признаться, не ожидал такой некомпетентности. В 17:07 была закрыта ТТТ В 17:17 запущен ваш скрипт на демо. Результат ниже:
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 16:14:19
Alexander Kopyatkevich, мне даже не удобно вас об этом спрашивать: полагаете ваш код покажет актуальную котировку? А если я два часа назад добавлял параметр "BID" в ТТТ, а потом убрал его. То какую котировку мне покажет ваш код: текущую или двухчасовой давности?
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
10.07.2020 08:23:31
Alexander Kopyatkevich, можете написать код для получения параметров через getParamEx2? С getQuoteLevel2 всё просто:
Код
if isConnected() ~= 1 then return end
function main()
-- Заказываем получение котировок:
Subscribe_Level_II_Quotes(class, sec)
-- Получаем актуальные котировки, если они есть:
Quotes = getQuoteLevel2(class, sec)
-- Если открыт стакан или котировки были раннее заказаны другим скриптом, то сразу получим актуальные данные
-- В противном случае в Quotes будет незаполненная таблица
...
end
-- Дальнейшие изменения в стакане можно ловить в OnQuote
function OnQuote(class_code, sec_code)
if sec_code == sec and class_code == class then
Quotes = getQuoteLevel2(class, sec)
...
end
end
Я уверен, что в Quotes будут актуальные котировки или незаполненная таблица. Таблицы с неактульными котировками не будет. Причём, даже если стакан по инструменту изменяется раз в час, получу текущие котировки, не дожидаясь следущего обновления стакана.
С getParamEx2 так не получается. Можете написать для следующего кейса: Получить зачение параметра для неликвидного инструмента с учётом того, что неизвестно был ли заказан параметр до запуска скрипта.
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
08.07.2020 18:41:06
Цитата
Alexander Kopyatkevich написал: Если речь идет исключительно об актуальности данных, то рекомендуем перед тем, как вызывать getParamEx (getParamEx2), сначала вызывать ParamRequest.Таким образом, после вызова getParamEx (getParamEx2) отобразятся только актуальные данные.
Вы уверены в том, что вы пишите? Актуальные данные клиент покажет только после того, как они попадут с сервера на клиента. И когда это будет нам неведомо. А до тех пор getParamEx2 может показывать что угодно.
Цитата
Старатель написал: Если getParamEx2 вернул данные, то они актуальные или старые? Может, пять часов назад их заказывали, потом подписку отменили, а данные остались в кеше.
Надо делать так, как надо. А как не надо - делать не надо.
SearchItems
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
07.07.2020 19:37:24
Цитата
Старатель написал: В таком случае хорошо иметь возможность задавать направление поиска: с начала или с конца таблицы.
Цитата
Zoya Skvorcova написал: ,добрый день. Дополнили пожелание
Напомните, вот это, что дополнили, уже реализовали?
Надо делать так, как надо. А как не надо - делать не надо.
ParamRequest и getParamEx2, Как получить актуальные данные через getParamEx2?
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
07.07.2020 13:33:56
Начну из далека. При заказе таблицы котировок используем
Код
Subscribe_Level_II_Quotes(class, sec) -- Для заказа котировок с сервера
getQuoteLevel2(class, sec) -- Для получения котировок
Мы либо получаем актуальные котировки, если стакан открыт, либо незаполненную таблицу, если стакан закрыт или котировки ещё не подгрузились с сервера. Если закрыть стакан (отменить заказ на получение котировок с сервера), то getQuoteLevel2 вернёт незаполненную таблицу. Т.о., мы понимаем, что, если getQuoteLevel2 вернул данные, то они актуальны. Использование простое:
Код
function main()
Subscribe_Level_II_Quotes(class, sec)
-- Получаем актуальные котировки, если они есть:
Quotes = getQuoteLevel2(class, sec)
end
-- Дальнейшие изменения в стакане можно ловить в OnQuote:
function OnQuote(class, sec)
Quotes = getQuoteLevel2(class, sec)
end
С getParamEx2 намного сложнее. Если getParamEx2 вернул данные, то они актуальные или старые? Может, пять часов назад их заказывали, потом подписку отменили, а данные остались в кеше. Если же брать парамтры только в OnParam, то по неликвидному инструменту их можно ждать бесконечно долго.
Надо делать так, как надо. А как не надо - делать не надо.
Контекстное меню в Lua-таблицах
Пользователь
Сообщений: Регистрация: 30.01.2015
Роботорговец
06.07.2020 20:22:41
Когда баг будет исправлен?
Надо делать так, как надо. А как не надо - делать не надо.